Просмотр исходного кода

remove 2.6.21 patches and config, too

SVN-Revision: 19579
Imre Kaloz 16 лет назад
Родитель
Сommit
a9f0a09c02
47 измененных файлов с 0 добавлено и 22089 удалено
  1. 0 1782
      target/linux/generic-2.6/config-2.6.21
  2. 0 4160
      target/linux/generic-2.6/patches-2.6.21/001-squashfs.patch
  3. 0 788
      target/linux/generic-2.6/patches-2.6.21/002-lzma_decompress.patch
  4. 0 107
      target/linux/generic-2.6/patches-2.6.21/003-squashfs_lzma.patch
  5. 0 12
      target/linux/generic-2.6/patches-2.6.21/004-extra_optimization.patch
  6. 0 11
      target/linux/generic-2.6/patches-2.6.21/006-gcc4_inline_fix.patch
  7. 0 36
      target/linux/generic-2.6/patches-2.6.21/007-samsung_flash.patch
  8. 0 169
      target/linux/generic-2.6/patches-2.6.21/009-revert_intel_flash_breakage.patch
  9. 0 19
      target/linux/generic-2.6/patches-2.6.21/010-disable_old_squashfs_compatibility.patch
  10. 0 19
      target/linux/generic-2.6/patches-2.6.21/011-mips_boot.patch
  11. 0 18
      target/linux/generic-2.6/patches-2.6.21/012-mips_cpu_tlb.patch
  12. 0 32
      target/linux/generic-2.6/patches-2.6.21/013-mips_generic_gpio_support.patch
  13. 0 150
      target/linux/generic-2.6/patches-2.6.21/024-mips_disable_fpu.patch
  14. 0 488
      target/linux/generic-2.6/patches-2.6.21/060-rootfs_split.patch
  15. 0 112
      target/linux/generic-2.6/patches-2.6.21/065-block2mtd_init.patch
  16. 0 2106
      target/linux/generic-2.6/patches-2.6.21/100-netfilter_layer7_2.21.patch
  17. 0 109
      target/linux/generic-2.6/patches-2.6.21/101-netfilter_layer7_pktmatch.patch
  18. 0 166
      target/linux/generic-2.6/patches-2.6.21/120-openswan-2.4.0.kernel-2.6-natt.patch
  19. 0 237
      target/linux/generic-2.6/patches-2.6.21/140-netfilter_time.patch
  20. 0 872
      target/linux/generic-2.6/patches-2.6.21/150-netfilter_imq.patch
  21. 0 947
      target/linux/generic-2.6/patches-2.6.21/160-netfilter_route.patch
  22. 0 20
      target/linux/generic-2.6/patches-2.6.21/180-netfilter_depends.patch
  23. 0 789
      target/linux/generic-2.6/patches-2.6.21/200-sched_esfq.patch
  24. 0 352
      target/linux/generic-2.6/patches-2.6.21/201-multiple_default_gateways.patch
  25. 0 12
      target/linux/generic-2.6/patches-2.6.21/202-mips-freestanding.patch
  26. 0 56
      target/linux/generic-2.6/patches-2.6.21/204-jffs2_eofdetect.patch
  27. 0 9
      target/linux/generic-2.6/patches-2.6.21/207-powerpc_asm_segment_h.patch
  28. 0 24
      target/linux/generic-2.6/patches-2.6.21/208-rtl8110sb_fix.patch
  29. 0 7779
      target/linux/generic-2.6/patches-2.6.21/209-mini_fo.patch
  30. 0 11
      target/linux/generic-2.6/patches-2.6.21/210-d80211_compat.patch
  31. 0 11
      target/linux/generic-2.6/patches-2.6.21/211-no_block2mtd_readahead.patch
  32. 0 11
      target/linux/generic-2.6/patches-2.6.21/212-block2mtd_erase_scan.patch
  33. 0 37
      target/linux/generic-2.6/patches-2.6.21/213-kobject_uevent.patch
  34. 0 29
      target/linux/generic-2.6/patches-2.6.21/30-fix_conflicting_getline.patch
  35. 0 21
      target/linux/generic-2.6/patches-2.6.21/31-use_kbuild.h.patch
  36. 0 17
      target/linux/generic-2.6/patches-2.6.21/32-time_fix_timespec_add_ns.patch
  37. 0 26
      target/linux/generic-2.6/patches-2.6.21/420-gpiodev.patch
  38. 0 17
      target/linux/generic-2.6/patches-2.6.21/510-yaffs_support.patch
  39. 0 80
      target/linux/generic-2.6/patches-2.6.21/511-yaffs_reduce_compiler_warnings.patch
  40. 0 46
      target/linux/generic-2.6/patches-2.6.21/900-headers_type_and_time.patch
  41. 0 138
      target/linux/generic-2.6/patches-2.6.21/902-darwin_scripts_include.patch
  42. 0 154
      target/linux/generic-2.6/patches-2.6.21/903-hostap_txpower.patch
  43. 0 17
      target/linux/generic-2.6/patches-2.6.21/903-stddef_include.patch
  44. 0 20
      target/linux/generic-2.6/patches-2.6.21/904-ls_time_locale.patch
  45. 0 7
      target/linux/generic-2.6/patches-2.6.21/990-buildfix.patch
  46. 0 52
      target/linux/generic-2.6/patches-2.6.21/999-backport_ip_hdr_and_friends.patch
  47. 0 14
      target/linux/generic-2.6/patches-2.6.21/999-use_preinit_as_init.patch

+ 0 - 1782
target/linux/generic-2.6/config-2.6.21

@@ -1,1782 +0,0 @@
-# CONFIG_6PACK is not set
-# CONFIG_8139CP is not set
-# CONFIG_9P_FS is not set
-# CONFIG_ACENIC is not set
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_AFS_FS is not set
-# CONFIG_AIRO_CS is not set
-# CONFIG_AIRO is not set
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_APPLICOM is not set
-# CONFIG_ARCH_AAEC2000 is not set
-# CONFIG_ARCH_AT91 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_DAVINCI is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_EP93XX is not set
-CONFIG_ARCH_FLATMEM_ENABLE=y
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_GEMINI is not set
-# CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_IOP13XX is not set
-# CONFIG_ARCH_IOP32X is not set
-# CONFIG_ARCH_IOP33X is not set
-# CONFIG_ARCH_IXP2000 is not set
-# CONFIG_ARCH_IXP23XX is not set
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_KIRKWOOD is not set
-# CONFIG_ARCH_KS8695 is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_LH7A40X is not set
-# CONFIG_ARCH_LOKI is not set
-# CONFIG_ARCH_MMP is not set
-# CONFIG_ARCH_MV78XX0 is not set
-# CONFIG_ARCH_MXC is not set
-# CONFIG_ARCH_NETX is not set
-# CONFIG_ARCH_NS9XXX is not set
-# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_PNX4008 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_REALVIEW is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_S3C64XX is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCNET is not set
-CONFIG_ARPD=y
-CONFIG_ASK_IP_FIB_HASH=y
-# CONFIG_ATA is not set
-# CONFIG_ATALK is not set
-# CONFIG_ATA_NONSTANDARD is not set
-# CONFIG_ATA_OVER_ETH is not set
-# CONFIG_ATARI_PARTITION is not set
-CONFIG_ATA_SFF=y
-# CONFIG_ATL1 is not set
-# CONFIG_ATM_AMBASSADOR is not set
-CONFIG_ATM_BR2684_IPFILTER=y
-# CONFIG_ATM_BR2684 is not set
-# CONFIG_ATM_CLIP is not set
-CONFIG_ATM_CLIP_NO_ICMP=y
-# CONFIG_ATM_DRIVERS is not set
-# CONFIG_ATM_DUMMY is not set
-# CONFIG_ATMEL is not set
-# CONFIG_ATM_ENI is not set
-# CONFIG_ATM_FIRESTREAM is not set
-# CONFIG_ATM_FORE200E_MAYBE is not set
-# CONFIG_ATM_HE is not set
-# CONFIG_ATM_HORIZON is not set
-# CONFIG_ATM_IA is not set
-# CONFIG_ATM_IDT77252 is not set
-# CONFIG_ATM is not set
-# CONFIG_ATM_LANAI is not set
-# CONFIG_ATM_LANE is not set
-# CONFIG_ATM_MPOA is not set
-# CONFIG_ATM_NICSTAR is not set
-# CONFIG_ATM_TCP is not set
-# CONFIG_ATM_ZATM is not set
-# CONFIG_AUDIT is not set
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AX25_DAMA_SLAVE is not set
-# CONFIG_AX25 is not set
-# CONFIG_B44 is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-CONFIG_BASE_FULL=y
-CONFIG_BASE_SMALL=0
-# CONFIG_BASLER_EXCITE is not set
-# CONFIG_BAYCOM_EPP is not set
-# CONFIG_BAYCOM_PAR is not set
-# CONFIG_BAYCOM_SER_FDX is not set
-# CONFIG_BAYCOM_SER_HDX is not set
-CONFIG_BCM43XX_DEBUG=y
-CONFIG_BCM43XX_DMA_AND_PIO_MODE=y
-# CONFIG_BCM43XX_DMA_MODE is not set
-CONFIG_BCM43XX_DMA=y
-# CONFIG_BCM43XX is not set
-# CONFIG_BCM43XX_PIO_MODE is not set
-CONFIG_BCM43XX_PIO=y
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_BLK_DEV_AEC62XX is not set
-# CONFIG_BLK_DEV_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD74XX is not set
-# CONFIG_BLK_DEV_ATIIXP is not set
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_CMD64X is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-# CONFIG_BLK_DEV_CS5520 is not set
-# CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_CS5535 is not set
-# CONFIG_BLK_DEV_CY82C693 is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_DELKIN is not set
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDECS is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDEPCI is not set
-# CONFIG_BLK_DEV_IDEPNP is not set
-# CONFIG_BLK_DEV_IDE_SATA is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_BLK_DEV_IT8213 is not set
-# CONFIG_BLK_DEV_IT821X is not set
-# CONFIG_BLK_DEV_JMICRON is not set
-# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_OFFBOARD is not set
-# CONFIG_BLK_DEV_OPTI621 is not set
-# CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_BLK_DEV_PDC202XX_OLD is not set
-# CONFIG_BLK_DEV_PIIX is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_RZ1000 is not set
-# CONFIG_BLK_DEV_SD is not set
-# CONFIG_BLK_DEV_SIIMAGE is not set
-# CONFIG_BLK_DEV_SIS5513 is not set
-# CONFIG_BLK_DEV_SLC90E66 is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_BLK_DEV_SVWKS is not set
-# CONFIG_BLK_DEV_SX8 is not set
-# CONFIG_BLK_DEV_TC86C001 is not set
-# CONFIG_BLK_DEV_TRIFLEX is not set
-# CONFIG_BLK_DEV_TRM290 is not set
-# CONFIG_BLK_DEV_UB is not set
-# CONFIG_BLK_DEV_UMEM is not set
-CONFIG_BLOCK=y
-# CONFIG_BNX2 is not set
-# CONFIG_BONDING is not set
-# CONFIG_BPQETHER is not set
-# CONFIG_BRIDGE_EBT_802_3 is not set
-# CONFIG_BRIDGE_EBT_AMONG is not set
-# CONFIG_BRIDGE_EBT_ARP is not set
-# CONFIG_BRIDGE_EBT_ARPREPLY is not set
-# CONFIG_BRIDGE_EBT_BROUTE is not set
-# CONFIG_BRIDGE_EBT_DNAT is not set
-# CONFIG_BRIDGE_EBT_IP is not set
-# CONFIG_BRIDGE_EBT_LIMIT is not set
-# CONFIG_BRIDGE_EBT_LOG is not set
-# CONFIG_BRIDGE_EBT_MARK is not set
-# CONFIG_BRIDGE_EBT_MARK_T is not set
-# CONFIG_BRIDGE_EBT_NFLOG is not set
-# CONFIG_BRIDGE_EBT_PKTTYPE is not set
-# CONFIG_BRIDGE_EBT_REDIRECT is not set
-# CONFIG_BRIDGE_EBT_SNAT is not set
-# CONFIG_BRIDGE_EBT_STP is not set
-# CONFIG_BRIDGE_EBT_T_FILTER is not set
-# CONFIG_BRIDGE_EBT_T_NAT is not set
-# CONFIG_BRIDGE_EBT_ULOG is not set
-# CONFIG_BRIDGE_EBT_VLAN is not set
-# CONFIG_BRIDGE_NETFILTER is not set
-# CONFIG_BRIDGE_NF_EBTABLES is not set
-CONFIG_BRIDGE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_BSD_DISKLABEL=y
-# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_BSD_PROCESS_ACCT=y
-# CONFIG_BT_BNEP is not set
-CONFIG_BT_BNEP_MC_FILTER=y
-CONFIG_BT_BNEP_PROTO_FILTER=y
-# CONFIG_BT_CMTP is not set
-# CONFIG_BT_HCIBCM203X is not set
-# CONFIG_BT_HCIBFUSB is not set
-# CONFIG_BT_HCIBLUECARD is not set
-# CONFIG_BT_HCIBPA10X is not set
-# CONFIG_BT_HCIBT3C is not set
-# CONFIG_BT_HCIBTUART is not set
-# CONFIG_BT_HCIDTL1 is not set
-CONFIG_BT_HCIUART_BCSP=y
-CONFIG_BT_HCIUART_H4=y
-# CONFIG_BT_HCIUART is not set
-# CONFIG_BT_HCIUSB is not set
-CONFIG_BT_HCIUSB_SCO=y
-# CONFIG_BT_HCIVHCI is not set
-# CONFIG_BT_HIDP is not set
-# CONFIG_BT is not set
-# CONFIG_BT_L2CAP is not set
-# CONFIG_BT_RFCOMM is not set
-CONFIG_BT_RFCOMM_TTY=y
-# CONFIG_BT_SCO is not set
-CONFIG_BUG=y
-# CONFIG_CAPI_AVM is not set
-# CONFIG_CAPI_EICON is not set
-# CONFIG_CAPI_TRACE is not set
-CONFIG_CARDBUS=y
-# CONFIG_CARDMAN_4000 is not set
-# CONFIG_CARDMAN_4040 is not set
-# CONFIG_CASSINI is not set
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_CHELSIO_T1 is not set
-# CONFIG_CHELSIO_T3 is not set
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_CHR_DEV_SCH is not set
-# CONFIG_CHR_DEV_SG is not set
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CICADA_PHY is not set
-# CONFIG_CIFS_DEBUG2 is not set
-# CONFIG_CIFS_EXPERIMENTAL is not set
-# CONFIG_CIFS is not set
-CONFIG_CIFS_POSIX=y
-# CONFIG_CIFS_STATS2 is not set
-CONFIG_CIFS_STATS=y
-# CONFIG_CIFS_WEAK_PW_HASH is not set
-# CONFIG_CIFS_XATTR is not set
-CONFIG_CLS_U32_MARK=y
-CONFIG_CLS_U32_PERF=y
-CONFIG_CMDLINE=""
-# CONFIG_CODA_FS is not set
-# CONFIG_CONFIGFS_FS is not set
-# CONFIG_CONNECTOR is not set
-# CONFIG_CPU_FREQ is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_CRC16 is not set
-CONFIG_CRC32=y
-# CONFIG_CRC_CCITT is not set
-CONFIG_CROSSCOMPILE=y
-# CONFIG_CRYPTO_AES is not set
-# CONFIG_CRYPTO_ALGAPI is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_ARC4 is not set
-# CONFIG_CRYPTO_BLKCIPHER is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_CBC is not set
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_ECB is not set
-# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_GF128MUL is not set
-# CONFIG_CRYPTO_HASH is not set
-# CONFIG_CRYPTO_HMAC is not set
-# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_LRW is not set
-# CONFIG_CRYPTO_MANAGER is not set
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_NULL is not set
-# CONFIG_CRYPTO_PCBC is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_TEST is not set
-# CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_TWOFISH_COMMON is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-# CONFIG_CRYPTO_WP512 is not set
-# CONFIG_CRYPTO_XCBC is not set
-CONFIG_CRYPTO=y
-# CONFIG_DAVICOM_PHY is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_DEBUG_FS is not set
-# CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DECNET is not set
-# CONFIG_DEFAULT_AS is not set
-# CONFIG_DEFAULT_BIC is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_CUBIC is not set
-CONFIG_DEFAULT_DEADLINE=y
-# CONFIG_DEFAULT_HTCP is not set
-CONFIG_DEFAULT_IOSCHED="deadline"
-# CONFIG_DEFAULT_NOOP is not set
-# CONFIG_DEFAULT_RENO is not set
-CONFIG_DEFAULT_TCP_CONG="westwood"
-# CONFIG_DEFAULT_VEGAS is not set
-CONFIG_DEFAULT_WESTWOOD=y
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-# CONFIG_DEVFS_DEBUG is not set
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DGRS is not set
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_DL2K is not set
-# CONFIG_DLM is not set
-# CONFIG_DMA_ENGINE is not set
-# CONFIG_DNOTIFY is not set
-# CONFIG_DRM is not set
-# CONFIG_DTLK is not set
-# CONFIG_DUMMY is not set
-# CONFIG_DVB is not set
-# CONFIG_E1000 is not set
-# CONFIG_E100 is not set
-# CONFIG_ECONET is not set
-# CONFIG_EEPRO100 is not set
-# CONFIG_EFI_PARTITION is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_ELF_CORE is not set
-CONFIG_EMBEDDED=y
-# CONFIG_ENABLE_MUST_CHECK is not set
-# CONFIG_EPIC100 is not set
-CONFIG_EPOLL=y
-# CONFIG_EQUALIZER is not set
-CONFIG_EXPERIMENTAL=y
-# CONFIG_EXPORTFS is not set
-# CONFIG_EXT2_FS is not set
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT2_FS_XIP is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_EXT3_FS_XATTR is not set
-# CONFIG_EXT4DEV_FS is not set
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-# CONFIG_FAT_FS is not set
-# CONFIG_FB_BACKLIGHT is not set
-# CONFIG_FB_CFB_COPYAREA is not set
-# CONFIG_FB_CFB_FILLRECT is not set
-# CONFIG_FB_CFB_IMAGEBLIT is not set
-# CONFIG_FB_DDC is not set
-# CONFIG_FB_IBM_GXT4500 is not set
-# CONFIG_FB is not set
-# CONFIG_FB_MACMODES is not set
-# CONFIG_FB_MBX is not set
-# CONFIG_FB_MODE_HELPERS is not set
-# CONFIG_FB_PXA is not set
-# CONFIG_FB_S1D13XXX is not set
-# CONFIG_FB_SVGALIB is not set
-# CONFIG_FB_TILEBLITTING is not set
-# CONFIG_FB_VIRTUAL is not set
-# CONFIG_FDDI is not set
-# CONFIG_FEALNX is not set
-CONFIG_FIB_RULES=y
-CONFIG_FLATMEM_MANUAL=y
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_FORCEDETH is not set
-# CONFIG_FS_POSIX_ACL is not set
-# CONFIG_FTL is not set
-# CONFIG_FUSE_FS is not set
-# CONFIG_FUSION_FC is not set
-# CONFIG_FUSION is not set
-# CONFIG_FUSION_SAS is not set
-# CONFIG_FUSION_SPI is not set
-CONFIG_FUTEX=y
-CONFIG_FW_LOADER=y
-CONFIG_GACT_PROB=y
-# CONFIG_GAMEPORT is not set
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_TIME=y
-# CONFIG_GFS2_FS is not set
-# CONFIG_GPIO_DEVICE is not set
-# CONFIG_HAMACHI is not set
-CONFIG_HAMRADIO=y
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_HEADERS_CHECK is not set
-# CONFIG_HERMES is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_HID_DEBUG is not set
-# CONFIG_HID_FF is not set
-# CONFIG_HIPPI is not set
-# CONFIG_HOSTAP_CS is not set
-# CONFIG_HOSTAP is not set
-# CONFIG_HOSTAP_PCI is not set
-# CONFIG_HOSTAP_PLX is not set
-# CONFIG_HOTPLUG_PCI is not set
-CONFIG_HOTPLUG=y
-# CONFIG_HP100 is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_HUGETLB_PAGE is not set
-# CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
-CONFIG_HZ=100
-# CONFIG_HZ_1000 is not set
-CONFIG_HZ_100=y
-# CONFIG_HZ_1024 is not set
-# CONFIG_HZ_128 is not set
-# CONFIG_HZ_250 is not set
-# CONFIG_HZ_256 is not set
-# CONFIG_HZ_300 is not set
-# CONFIG_HZ_48 is not set
-# CONFIG_I2C_ALGOPCA is not set
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALI1535 is not set
-# CONFIG_I2C_ALI1563 is not set
-# CONFIG_I2C_ALI15X3 is not set
-# CONFIG_I2C_AMD756 is not set
-# CONFIG_I2C_AMD8111 is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_ELEKTOR is not set
-# CONFIG_I2C_I801 is not set
-# CONFIG_I2C_I810 is not set
-# CONFIG_I2C is not set
-# CONFIG_I2C_NFORCE2 is not set
-# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PCA_ISA is not set
-# CONFIG_I2C_PIIX4 is not set
-# CONFIG_I2C_PROSAVAGE is not set
-# CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_I2C_SIS5595 is not set
-# CONFIG_I2C_SIS630 is not set
-# CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_VIA is not set
-# CONFIG_I2C_VIAPRO is not set
-# CONFIG_I2C_VOODOO3 is not set
-# CONFIG_I2O is not set
-# CONFIG_I82092 is not set
-# CONFIG_IDEDISK_MULTI_MODE is not set
-CONFIG_IDE_MAX_HWIFS=4
-# CONFIG_IDE_TASK_IOCTL is not set
-# CONFIG_IEEE1394 is not set
-# CONFIG_IEEE80211_CRYPT_CCMP is not set
-# CONFIG_IEEE80211_CRYPT_TKIP is not set
-# CONFIG_IEEE80211_CRYPT_WEP is not set
-# CONFIG_IEEE80211_DEBUG is not set
-# CONFIG_IEEE80211 is not set
-# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
-# CONFIG_IEEE80211_SOFTMAC is not set
-# CONFIG_IFB is not set
-# CONFIG_IKCONFIG is not set
-# CONFIG_IKCONFIG_PROC is not set
-# CONFIG_IMQ_BEHAVIOR_AA is not set
-# CONFIG_IMQ_BEHAVIOR_AB is not set
-CONFIG_IMQ_BEHAVIOR_BA=y
-# CONFIG_IMQ_BEHAVIOR_BB is not set
-# CONFIG_IMQ is not set
-CONFIG_IMQ_NUM_DEVS=2
-# CONFIG_INET6_AH is not set
-# CONFIG_INET6_ESP is not set
-# CONFIG_INET6_IPCOMP is not set
-# CONFIG_INET6_TUNNEL is not set
-# CONFIG_INET6_XFRM_MODE_BEET is not set
-# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
-# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_DCCP_DIAG is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TCP_DIAG is not set
-# CONFIG_INET_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_TUNNEL is not set
-CONFIG_INET=y
-# CONFIG_INFINIBAND is not set
-# CONFIG_INFTL is not set
-CONFIG_INIT_ENV_ARG_LIMIT=32
-# CONFIG_INOTIFY is not set
-# CONFIG_INOTIFY_USER is not set
-# CONFIG_INPUT_ATI_REMOTE2 is not set
-# CONFIG_INPUT_ATI_REMOTE is not set
-# CONFIG_INPUT_EVBUG is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_FF_MEMLESS is not set
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_KEYSPAN_REMOTE is not set
-CONFIG_INPUT_MISC=y
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_PCSPKR is not set
-# CONFIG_INPUT_POWERMATE is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_UINPUT is not set
-# CONFIG_INPUT_WISTRON_BTNS is not set
-# CONFIG_IOSCHED_AS is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_NOOP=y
-# CONFIG_IP6_NF_FILTER is not set
-# CONFIG_IP6_NF_IPTABLES is not set
-# CONFIG_IP6_NF_MANGLE is not set
-# CONFIG_IP6_NF_MATCH_AH is not set
-# CONFIG_IP6_NF_MATCH_EUI64 is not set
-# CONFIG_IP6_NF_MATCH_FRAG is not set
-# CONFIG_IP6_NF_MATCH_HL is not set
-# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set
-# CONFIG_IP6_NF_MATCH_LIMIT is not set
-# CONFIG_IP6_NF_MATCH_MH is not set
-# CONFIG_IP6_NF_MATCH_OPTS is not set
-# CONFIG_IP6_NF_MATCH_OWNER is not set
-# CONFIG_IP6_NF_MATCH_RT is not set
-# CONFIG_IP6_NF_QUEUE is not set
-# CONFIG_IP6_NF_RAW is not set
-# CONFIG_IP6_NF_TARGET_HL is not set
-# CONFIG_IP6_NF_TARGET_IMQ is not set
-# CONFIG_IP6_NF_TARGET_LOG is not set
-# CONFIG_IP6_NF_TARGET_REJECT is not set
-# CONFIG_IP6_NF_TARGET_ROUTE is not set
-CONFIG_IP_ADVANCED_ROUTER=y
-# CONFIG_IPC_NS is not set
-CONFIG_IP_DCCP_ACKVEC=y
-# CONFIG_IP_DCCP_CCID2_DEBUG is not set
-# CONFIG_IP_DCCP_CCID2 is not set
-# CONFIG_IP_DCCP_CCID3_DEBUG is not set
-# CONFIG_IP_DCCP_CCID3 is not set
-CONFIG_IP_DCCP_CCID3_RTO=100
-# CONFIG_IP_DCCP is not set
-# CONFIG_IP_DCCP_TFRC_LIB is not set
-CONFIG_IP_FIB_HASH=y
-# CONFIG_IP_FIB_TRIE is not set
-# CONFIG_IPMI_HANDLER is not set
-CONFIG_IP_MROUTE=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_MULTIPLE_TABLES=y
-# CONFIG_IP_NF_AMANDA is not set
-# CONFIG_IP_NF_ARPFILTER is not set
-# CONFIG_IP_NF_ARP_MANGLE is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
-CONFIG_IP_NF_CONNTRACK_MARK=y
-# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
-CONFIG_IP_NF_CONNTRACK=y
-CONFIG_IP_NF_CT_ACCT=y
-# CONFIG_IP_NF_CT_PROTO_SCTP is not set
-CONFIG_IP_NF_FILTER=y
-# CONFIG_IP_NF_FTP is not set
-# CONFIG_IP_NF_H323 is not set
-CONFIG_IP_NF_IPTABLES=y
-# CONFIG_IP_NF_IRC is not set
-CONFIG_IP_NF_MANGLE=y
-# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
-# CONFIG_IP_NF_MATCH_AH is not set
-# CONFIG_IP_NF_MATCH_ECN is not set
-# CONFIG_IP_NF_MATCH_HASHLIMIT is not set
-# CONFIG_IP_NF_MATCH_IPP2P is not set
-# CONFIG_IP_NF_MATCH_IPRANGE is not set
-# CONFIG_IP_NF_MATCH_OWNER is not set
-# CONFIG_IP_NF_MATCH_RECENT is not set
-# CONFIG_IP_NF_MATCH_SET is not set
-# CONFIG_IP_NF_MATCH_TIME is not set
-# CONFIG_IP_NF_MATCH_TOS is not set
-# CONFIG_IP_NF_MATCH_TTL is not set
-# CONFIG_IP_NF_NAT_AMANDA is not set
-# CONFIG_IP_NF_NAT_FTP is not set
-# CONFIG_IP_NF_NAT_H323 is not set
-# CONFIG_IP_NF_NAT_IRC is not set
-CONFIG_IP_NF_NAT_NEEDED=y
-# CONFIG_IP_NF_NAT_PPTP is not set
-# CONFIG_IP_NF_NAT_SIP is not set
-# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
-# CONFIG_IP_NF_NAT_TFTP is not set
-CONFIG_IP_NF_NAT=y
-# CONFIG_IP_NF_NETBIOS_NS is not set
-# CONFIG_IP_NF_PPTP is not set
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_RAW is not set
-CONFIG_IP_NF_SET_HASHSIZE=1024
-# CONFIG_IP_NF_SET_IPHASH is not set
-# CONFIG_IP_NF_SET_IPMAP is not set
-# CONFIG_IP_NF_SET_IPPORTHASH is not set
-# CONFIG_IP_NF_SET_IPTREE is not set
-# CONFIG_IP_NF_SET_IPTREEMAP is not set
-# CONFIG_IP_NF_SET is not set
-# CONFIG_IP_NF_SET_MACIPMAP is not set
-CONFIG_IP_NF_SET_MAX=256
-# CONFIG_IP_NF_SET_NETHASH is not set
-# CONFIG_IP_NF_SET_PORTMAP is not set
-# CONFIG_IP_NF_SIP is not set
-# CONFIG_IP_NF_TARGET_CLUSTERIP is not set
-# CONFIG_IP_NF_TARGET_ECN is not set
-# CONFIG_IP_NF_TARGET_IMQ is not set
-# CONFIG_IP_NF_TARGET_LOG is not set
-CONFIG_IP_NF_TARGET_MASQUERADE=y
-# CONFIG_IP_NF_TARGET_NETMAP is not set
-CONFIG_IP_NF_TARGET_REDIRECT=y
-CONFIG_IP_NF_TARGET_REJECT=y
-# CONFIG_IP_NF_TARGET_ROUTE is not set
-# CONFIG_IP_NF_TARGET_SAME is not set
-# CONFIG_IP_NF_TARGET_SET is not set
-CONFIG_IP_NF_TARGET_TCPMSS=y
-# CONFIG_IP_NF_TARGET_TOS is not set
-# CONFIG_IP_NF_TARGET_TTL is not set
-# CONFIG_IP_NF_TARGET_ULOG is not set
-# CONFIG_IP_NF_TFTP is not set
-# CONFIG_IP_PIMSM_V1 is not set
-# CONFIG_IP_PIMSM_V2 is not set
-# CONFIG_IP_PNP is not set
-CONFIG_IP_ROUTE_FWMARK=y
-CONFIG_IP_ROUTE_MULTIPATH_CACHED=y
-# CONFIG_IP_ROUTE_MULTIPATH_DRR is not set
-# CONFIG_IP_ROUTE_MULTIPATH_RANDOM is not set
-# CONFIG_IP_ROUTE_MULTIPATH_RR is not set
-# CONFIG_IP_ROUTE_MULTIPATH_WRANDOM is not set
-CONFIG_IP_ROUTE_MULTIPATH=y
-CONFIG_IP_ROUTE_VERBOSE=y
-# CONFIG_IP_SCTP is not set
-CONFIG_IPSEC_NAT_TRAVERSAL=y
-# CONFIG_IPV6 is not set
-# CONFIG_IPV6_MIP6 is not set
-# CONFIG_IPV6_MULTIPLE_TABLES is not set
-# CONFIG_IPV6_PRIVACY is not set
-# CONFIG_IPV6_ROUTE_INFO is not set
-CONFIG_IPV6_ROUTER_PREF=y
-# CONFIG_IPV6_SIT is not set
-# CONFIG_IPV6_TUNNEL is not set
-# CONFIG_IP_VS is not set
-# CONFIG_IPW2100_DEBUG is not set
-# CONFIG_IPW2100 is not set
-CONFIG_IPW2100_MONITOR=y
-# CONFIG_IPW2200_DEBUG is not set
-# CONFIG_IPW2200 is not set
-CONFIG_IPW2200_MONITOR=y
-# CONFIG_IPW2200_PROMISCUOUS is not set
-# CONFIG_IPW2200_QOS is not set
-# CONFIG_IPW2200_RADIOTAP is not set
-# CONFIG_IPX is not set
-# CONFIG_IRDA is not set
-# CONFIG_ISCSI_TCP is not set
-# CONFIG_ISDN_CAPI_CAPI20 is not set
-CONFIG_ISDN_CAPI_CAPIFS_BOOL=y
-# CONFIG_ISDN_CAPI_CAPIFS is not set
-# CONFIG_ISDN_CAPI is not set
-CONFIG_ISDN_CAPI_MIDDLEWARE=y
-# CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON is not set
-# CONFIG_ISDN_I4L is not set
-# CONFIG_ISDN is not set
-# CONFIG_ISO9660_FS is not set
-# CONFIG_IXGB is not set
-# CONFIG_JBD_DEBUG is not set
-# CONFIG_JBD is not set
-# CONFIG_JFFS2_CMODE_NONE is not set
-CONFIG_JFFS2_CMODE_PRIORITY=y
-# CONFIG_JFFS2_CMODE_SIZE is not set
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_JFFS2_FS_DEBUG=0
-CONFIG_JFFS2_FS_WRITEBUFFER=y
-# CONFIG_JFFS2_FS_XATTR is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_RTIME=y
-# CONFIG_JFFS2_RUBIN is not set
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_JFFS2_ZLIB=y
-# CONFIG_JFFS_FS is not set
-# CONFIG_JFS_DEBUG is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_JFS_POSIX_ACL is not set
-# CONFIG_JFS_SECURITY is not set
-# CONFIG_JFS_STATISTICS is not set
-CONFIG_JOLIET=y
-# CONFIG_KALLSYMS is not set
-# CONFIG_KARMA_PARTITION is not set
-# CONFIG_KEXEC is not set
-# CONFIG_KEYS is not set
-CONFIG_KMOD=y
-# CONFIG_LAPB is not set
-# CONFIG_LASAT is not set
-# CONFIG_LBD is not set
-# CONFIG_LDM_PARTITION is not set
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-# CONFIG_LEDS_TRIGGER_IDE_DISK is not set
-# CONFIG_LEDS_TRIGGER_MORSE is not set
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_TIMER=y
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_LIBCRC32C is not set
-# CONFIG_LLC2 is not set
-CONFIG_LLC=y
-CONFIG_LOCALVERSION=""
-# CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_LOCKDEP_SUPPORT=y
-# CONFIG_LOCKD is not set
-CONFIG_LOCKD_V4=y
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_LSF is not set
-# CONFIG_LXT_PHY is not set
-# CONFIG_MAC_EMUMOUSEBTN is not set
-# CONFIG_MAC_PARTITION is not set
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_MARKEINS is not set
-# CONFIG_MARVELL_PHY is not set
-# CONFIG_MD is not set
-# CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_MEGARAID_NEWGEN is not set
-# CONFIG_MEGARAID_SAS is not set
-# CONFIG_MFD_SM501 is not set
-CONFIG_MII=y
-CONFIG_MINI_FO=y
-# CONFIG_MINIX_FS is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_MIPS_FPU_EMU is not set
-# CONFIG_MKISS is not set
-CONFIG_MMC_BLOCK_BOUNCE=y
-# CONFIG_MMC_BLOCK is not set
-# CONFIG_MMC_DEBUG is not set
-# CONFIG_MMC is not set
-# CONFIG_MMC_PXA is not set
-CONFIG_MMU=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODVERSIONS is not set
-# CONFIG_MSDOS_FS is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_AFS_PARTS is not set
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-CONFIG_MTD_BLKDEVS=y
-# CONFIG_MTD_BLOCK2MTD is not set
-CONFIG_MTD_BLOCK=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-CONFIG_MTD_CFI_AMDSTD=y
-# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
-CONFIG_MTD_CFI_NOSWAP=y
-# CONFIG_MTD_CFI_STAA is not set
-CONFIG_MTD_CFI_UTIL=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CHAR=y
-# CONFIG_MTD_CMDLINE_PARTS is not set
-CONFIG_MTD_COMPLEX_MAPPINGS=y
-# CONFIG_MTD_CONCAT is not set
-# CONFIG_MTD_DEBUG is not set
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-CONFIG_MTD_GEN_PROBE=y
-# CONFIG_MTD_JEDECPROBE is not set
-# CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_NAND_CAFE is not set
-# CONFIG_MTD_NAND_DISKONCHIP is not set
-# CONFIG_MTD_NAND_ECC_SMC is not set
-CONFIG_MTD_NAND_IDS=y
-# CONFIG_MTD_NAND is not set
-# CONFIG_MTD_NAND_MUSEUM_IDS is not set
-# CONFIG_MTD_NAND_NANDSIM is not set
-# CONFIG_MTD_NAND_PLATFORM is not set
-# CONFIG_MTD_NAND_VERIFY_WRITE is not set
-# CONFIG_MTD_ONENAND is not set
-# CONFIG_MTD_OTP is not set
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_PCI is not set
-# CONFIG_MTD_PHRAM is not set
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_PLATRAM is not set
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_RAM is not set
-CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
-# CONFIG_MTD_REDBOOT_PARTS is not set
-CONFIG_MTD_REDBOOT_PARTS_READONLY=y
-# CONFIG_MTD_ROM is not set
-CONFIG_MTD_ROOTFS_ROOT_DEV=y
-CONFIG_MTD_ROOTFS_SPLIT=y
-# CONFIG_MTD_SLRAM is not set
-CONFIG_MTD=y
-# CONFIG_MYRI10GE is not set
-# CONFIG_NATSEMI is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_NET_ACT_GACT is not set
-# CONFIG_NET_ACT_IPT is not set
-# CONFIG_NET_ACT_MIRRED is not set
-# CONFIG_NET_ACT_PEDIT is not set
-# CONFIG_NET_ACT_POLICE is not set
-# CONFIG_NET_ACT_SIMP is not set
-CONFIG_NET_CLS_ACT=y
-# CONFIG_NET_CLS_BASIC is not set
-# CONFIG_NET_CLS_FW is not set
-CONFIG_NET_CLS_IND=y
-CONFIG_NET_CLS_POLICE=y
-# CONFIG_NET_CLS_ROUTE4 is not set
-CONFIG_NET_CLS_ROUTE=y
-# CONFIG_NET_CLS_RSVP6 is not set
-# CONFIG_NET_CLS_RSVP is not set
-# CONFIG_NET_CLS_TCINDEX is not set
-# CONFIG_NET_CLS_U32 is not set
-CONFIG_NET_CLS=y
-# CONFIG_NETCONSOLE is not set
-# CONFIG_NETDEBUG is not set
-CONFIG_NETDEVICES=y
-# CONFIG_NET_EMATCH_CMP is not set
-# CONFIG_NET_EMATCH_META is not set
-# CONFIG_NET_EMATCH_NBYTE is not set
-CONFIG_NET_EMATCH_STACK=32
-# CONFIG_NET_EMATCH_TEXT is not set
-# CONFIG_NET_EMATCH_U32 is not set
-CONFIG_NET_EMATCH=y
-CONFIG_NET_ESTIMATOR=y
-CONFIG_NET_ETHERNET=y
-# CONFIG_NET_FC is not set
-# CONFIG_NETFILTER_DEBUG is not set
-# CONFIG_NETFILTER_NETLINK is not set
-CONFIG_NETFILTER_XTABLES=y
-# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
-# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set
-# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set
-CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
-# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
-# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
-# CONFIG_NETFILTER_XT_MATCH_ESP is not set
-# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
-# CONFIG_NETFILTER_XT_MATCH_HELPER is not set
-# CONFIG_NETFILTER_XT_MATCH_LAYER7_DEBUG is not set
-# CONFIG_NETFILTER_XT_MATCH_LAYER7 is not set
-# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
-CONFIG_NETFILTER_XT_MATCH_LIMIT=y
-# CONFIG_NETFILTER_XT_MATCH_MAC is not set
-# CONFIG_NETFILTER_XT_MATCH_MARK is not set
-CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
-# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set
-# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
-# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
-# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
-# CONFIG_NETFILTER_XT_MATCH_REALM is not set
-# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
-CONFIG_NETFILTER_XT_MATCH_STATE=y
-# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
-# CONFIG_NETFILTER_XT_MATCH_STRING is not set
-CONFIG_NETFILTER_XT_MATCH_TCPMSS=y
-# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
-# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set
-# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
-# CONFIG_NETFILTER_XT_TARGET_MARK is not set
-# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
-# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
-# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set
-CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
-CONFIG_NETFILTER=y
-CONFIG_NET_IPGRE_BROADCAST=y
-# CONFIG_NET_IPGRE is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_KEY is not set
-# CONFIG_NET_KEY_MIGRATE is not set
-CONFIG_NET_PCI=y
-# CONFIG_NET_PCMCIA is not set
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_NETPOLL is not set
-CONFIG_NET_RADIO=y
-# CONFIG_NETROM is not set
-# CONFIG_NET_SCH_ATM is not set
-# CONFIG_NET_SCH_CBQ is not set
-# CONFIG_NET_SCH_CLK_CPU is not set
-# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
-CONFIG_NET_SCH_CLK_JIFFIES=y
-# CONFIG_NET_SCH_DSMARK is not set
-CONFIG_NET_SCHED=y
-# CONFIG_NET_SCH_ESFQ is not set
-# CONFIG_NET_SCH_GRED is not set
-# CONFIG_NET_SCH_HFSC is not set
-# CONFIG_NET_SCH_HTB is not set
-# CONFIG_NET_SCH_INGRESS is not set
-# CONFIG_NET_SCH_NETEM is not set
-# CONFIG_NET_SCH_PRIO is not set
-# CONFIG_NET_SCH_RED is not set
-# CONFIG_NET_SCH_SFQ is not set
-# CONFIG_NET_SCH_TBF is not set
-# CONFIG_NET_SCH_TEQL is not set
-# CONFIG_NET_TULIP is not set
-CONFIG_NET_WIRELESS_RTNETLINK=y
-CONFIG_NET_WIRELESS=y
-# CONFIG_NETWORK_SECMARK is not set
-# CONFIG_NETXEN_NIC is not set
-CONFIG_NET=y
-CONFIG_NEW_LEDS=y
-# CONFIG_NF_CONNTRACK_AMANDA is not set
-CONFIG_NF_CONNTRACK_ENABLED=y
-# CONFIG_NF_CONNTRACK_EVENTS is not set
-# CONFIG_NF_CONNTRACK_FTP is not set
-# CONFIG_NF_CONNTRACK_H323 is not set
-CONFIG_NF_CONNTRACK_IPV4=y
-# CONFIG_NF_CONNTRACK_IPV6 is not set
-# CONFIG_NF_CONNTRACK_IRC is not set
-CONFIG_NF_CONNTRACK_MARK=y
-# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
-# CONFIG_NF_CONNTRACK_PPTP is not set
-CONFIG_NF_CONNTRACK_PROC_COMPAT=y
-# CONFIG_NF_CONNTRACK_SANE is not set
-# CONFIG_NF_CONNTRACK_SIP is not set
-CONFIG_NF_CONNTRACK_SUPPORT=y
-# CONFIG_NF_CONNTRACK_TFTP is not set
-CONFIG_NF_CONNTRACK=y
-CONFIG_NF_CT_ACCT=y
-# CONFIG_NF_CT_PROTO_SCTP is not set
-# CONFIG_NF_NAT_AMANDA is not set
-# CONFIG_NF_NAT_FTP is not set
-# CONFIG_NF_NAT_H323 is not set
-# CONFIG_NF_NAT_IRC is not set
-CONFIG_NF_NAT_NEEDED=y
-# CONFIG_NF_NAT_PPTP is not set
-# CONFIG_NF_NAT_SIP is not set
-# CONFIG_NF_NAT_SNMP_BASIC is not set
-# CONFIG_NF_NAT_TFTP is not set
-CONFIG_NF_NAT=y
-# CONFIG_NFS_ACL_SUPPORT is not set
-CONFIG_NFS_COMMON=y
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
-CONFIG_NFSD_TCP=y
-# CONFIG_NFSD_V2_ACL is not set
-# CONFIG_NFSD_V3_ACL is not set
-CONFIG_NFSD_V3=y
-CONFIG_NFSD_V4=y
-# CONFIG_NFS_FS is not set
-# CONFIG_NFS_V3_ACL is not set
-CONFIG_NFS_V3=y
-CONFIG_NFS_V4=y
-# CONFIG_NFTL is not set
-# CONFIG_NLS_ASCII is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# 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_874 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS 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_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_8 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-# CONFIG_NORTEL_HERMES is not set
-# CONFIG_NS83820 is not set
-# CONFIG_NTFS_DEBUG is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_RW is not set
-# CONFIG_NVRAM is not set
-# CONFIG_OCFS2_FS is not set
-# CONFIG_OSF_PARTITION is not set
-CONFIG_PACKET_MMAP=y
-CONFIG_PACKET=y
-# CONFIG_PAGE_SIZE_16KB is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_64KB is not set
-# CONFIG_PAGE_SIZE_8KB is not set
-# CONFIG_PARPORT is not set
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_PATA_ALI is not set
-# CONFIG_PATA_AMD is not set
-# CONFIG_PATA_ARTOP is not set
-# CONFIG_PATA_ATIIXP is not set
-# CONFIG_PATA_CMD64X is not set
-# CONFIG_PATA_CS5520 is not set
-# CONFIG_PATA_CS5530 is not set
-# CONFIG_PATA_CS5535 is not set
-# CONFIG_PATA_CYPRESS is not set
-# CONFIG_PATA_EFAR is not set
-# CONFIG_PATA_HPT366 is not set
-# CONFIG_PATA_HPT37X is not set
-# CONFIG_PATA_HPT3X2N is not set
-# CONFIG_PATA_HPT3X3 is not set
-# CONFIG_PATA_ISAPNP is not set
-# CONFIG_PATA_IT8213 is not set
-# CONFIG_PATA_IT821X is not set
-# CONFIG_PATA_JMICRON is not set
-# CONFIG_PATA_LEGACY is not set
-# CONFIG_PATA_MARVELL is not set
-# CONFIG_PATA_MPIIX is not set
-# CONFIG_PATA_NETCELL is not set
-# CONFIG_PATA_NS87410 is not set
-# CONFIG_PATA_OLDPIIX is not set
-# CONFIG_PATA_OPTIDMA is not set
-# CONFIG_PATA_OPTI is not set
-# CONFIG_PATA_PCMCIA is not set
-# CONFIG_PATA_PDC2027X is not set
-# CONFIG_PATA_PDC_OLD is not set
-# CONFIG_PATA_PLATFORM is not set
-# CONFIG_PATA_QDI is not set
-# CONFIG_PATA_RADISYS is not set
-# CONFIG_PATA_RZ1000 is not set
-# CONFIG_PATA_SC1200 is not set
-# CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_SIL680 is not set
-# CONFIG_PATA_SIS is not set
-# CONFIG_PATA_TRIFLEX is not set
-# CONFIG_PATA_VIA is not set
-# CONFIG_PATA_WINBOND is not set
-# CONFIG_PATA_WINBOND_VLB is not set
-# CONFIG_PC300TOO is not set
-# CONFIG_PCCARD is not set
-# CONFIG_PCI_ATMEL is not set
-# CONFIG_PCI_HERMES is not set
-CONFIG_PCI_SYSCALL=y
-CONFIG_PCI=y
-# CONFIG_PCMCIA_AHA152X is not set
-# CONFIG_PCMCIA_ATMEL is not set
-# CONFIG_PCMCIA_DEBUG is not set
-# CONFIG_PCMCIA_FDOMAIN is not set
-# CONFIG_PCMCIA_HERMES is not set
-# CONFIG_PCMCIA_IOCTL is not set
-# CONFIG_PCMCIA is not set
-# CONFIG_PCMCIA_LOAD_CIS is not set
-# CONFIG_PCMCIA_NETWAVE is not set
-# CONFIG_PCMCIA_NINJA_SCSI is not set
-# CONFIG_PCMCIA_QLOGIC is not set
-# CONFIG_PCMCIA_RAYCS is not set
-# CONFIG_PCMCIA_SPECTRUM is not set
-# CONFIG_PCMCIA_SYM53C500 is not set
-# CONFIG_PCMCIA_WAVELAN is not set
-# CONFIG_PCMCIA_WL3501 is not set
-# CONFIG_PCNET32 is not set
-# CONFIG_PCSPKR_PLATFORM is not set
-# CONFIG_PD6729 is not set
-# CONFIG_PHONE is not set
-# CONFIG_PHYLIB is not set
-CONFIG_PLIST=y
-# CONFIG_PLX_HERMES is not set
-# CONFIG_PM is not set
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_PPP_ASYNC is not set
-# CONFIG_PPP_BSDCOMP is not set
-# CONFIG_PPP_DEFLATE is not set
-CONFIG_PPP_FILTER=y
-# CONFIG_PPP is not set
-# CONFIG_PPP_MPPE is not set
-CONFIG_PPP_MULTILINK=y
-# CONFIG_PPPOATM is not set
-# CONFIG_PPPOE is not set
-# CONFIG_PPP_SYNC_TTY is not set
-# CONFIG_PREEMPT is not set
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_VOLUNTARY is not set
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_PRINTK_TIME is not set
-CONFIG_PRINTK=y
-# CONFIG_PRISM54 is not set
-CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_PROC_SYSCTL=y
-# CONFIG_PROFILING is not set
-# CONFIG_QEMU is not set
-# CONFIG_QLA3XXX is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_QUOTA is not set
-# CONFIG_R3964 is not set
-# CONFIG_R8169 is not set
-# CONFIG_RADIO_AZTECH is not set
-# CONFIG_RADIO_CADET is not set
-# CONFIG_RADIO_GEMTEK is not set
-# CONFIG_RADIO_GEMTEK_PCI is not set
-# CONFIG_RADIO_MAESTRO is not set
-# CONFIG_RADIO_MAXIRADIO is not set
-# CONFIG_RADIO_RTRACK2 is not set
-# CONFIG_RADIO_RTRACK is not set
-# CONFIG_RADIO_SF16FMI is not set
-# CONFIG_RADIO_SF16FMR2 is not set
-# CONFIG_RADIO_TERRATEC is not set
-# CONFIG_RADIO_TRUST is not set
-# CONFIG_RADIO_TYPHOON is not set
-# CONFIG_RADIO_ZOLTRIX is not set
-# CONFIG_RAID_ATTRS is not set
-CONFIG_RAMFS=y
-# CONFIG_RAW_DRIVER is not set
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_REISERFS_FS_XATTR is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_RELAY is not set
-# CONFIG_RESOURCES_64BIT is not set
-# CONFIG_RFD_FTL is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_ROSE is not set
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
-# CONFIG_RTC_CLASS is not set
-# CONFIG_RTC_DEBUG is not set
-CONFIG_RTC_DRV_CMOS=y
-# CONFIG_RTC_DRV_DS1307 is not set
-# CONFIG_RTC_DRV_DS1374 is not set
-# CONFIG_RTC_DRV_DS1553 is not set
-# CONFIG_RTC_DRV_DS1672 is not set
-# CONFIG_RTC_DRV_DS1742 is not set
-# CONFIG_RTC_DRV_ISL1208 is not set
-# CONFIG_RTC_DRV_M41T80 is not set
-# CONFIG_RTC_DRV_M48T59 is not set
-# CONFIG_RTC_DRV_M48T86 is not set
-# CONFIG_RTC_DRV_PCF50606 is not set
-# CONFIG_RTC_DRV_PCF8563 is not set
-# CONFIG_RTC_DRV_PCF8583 is not set
-# CONFIG_RTC_DRV_RS5C372 is not set
-# CONFIG_RTC_DRV_STK17TA8 is not set
-# CONFIG_RTC_DRV_TEST is not set
-# CONFIG_RTC_DRV_V3020 is not set
-# CONFIG_RTC_DRV_X1205 is not set
-CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
-CONFIG_RTC_HCTOSYS=y
-# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
-CONFIG_RTC_LIB=y
-CONFIG_RT_MUTEXES=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_S2IO is not set
-# CONFIG_SATA_INIC162X is not set
-# CONFIG_SATA_MV is not set
-# CONFIG_SATA_NV is not set
-# CONFIG_SATA_PROMISE is not set
-# CONFIG_SATA_QSTOR is not set
-# CONFIG_SATA_SIL24 is not set
-# CONFIG_SATA_SIL is not set
-# CONFIG_SATA_SIS is not set
-# CONFIG_SATA_SVW is not set
-# CONFIG_SATA_SX4 is not set
-# CONFIG_SATA_ULI is not set
-# CONFIG_SATA_VIA is not set
-# CONFIG_SATA_VITESSE is not set
-# CONFIG_SC92031 is not set
-# CONFIG_SCSI_3W_9XXX is not set
-# CONFIG_SCSI_7000FASST is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_AIC94XX is not set
-# CONFIG_SCSI_ARCMSR is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_DC395x is not set
-# CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_FC_ATTRS 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_GENERIC_NCR5380_MMIO is not set
-# CONFIG_SCSI_HPTIOP is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI is not set
-# CONFIG_SCSI_LOGGING is not set
-# CONFIG_SCSI_LPFC is not set
-CONFIG_SCSI_MULTI_LUN=y
-# CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NETLINK is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_PAS16 is not set
-CONFIG_SCSI_PROC_FS=y
-# CONFIG_SCSI_PSI240I is not set
-# CONFIG_SCSI_QLA_FC is not set
-# CONFIG_SCSI_QLA_ISCSI is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
-# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
-# CONFIG_SCSI_SAS_LIBSAS is not set
-# CONFIG_SCSI_SCAN_ASYNC is not set
-# CONFIG_SCSI_SEAGATE is not set
-# CONFIG_SCSI_SPI_ATTRS is not set
-# CONFIG_SCSI_SRP is not set
-# CONFIG_SCSI_STEX is not set
-# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_TGT is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_ULTRASTOR is not set
-# CONFIG_SECURITY is not set
-CONFIG_SELECT_MEMORY_MODEL=y
-# CONFIG_SENSORS_ABITUGURU is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1026 is not set
-# CONFIG_SENSORS_ADM1029 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ADM9240 is not set
-# CONFIG_SENSORS_ASB100 is not set
-# CONFIG_SENSORS_ATXP1 is not set
-# CONFIG_SENSORS_DS1337 is not set
-# CONFIG_SENSORS_DS1374 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_EEPROM is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_FSCPOS is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_GL520SM is not set
-# CONFIG_SENSORS_HDAPS is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_K8TEMP is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_LM92 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_MAX6875 is not set
-# CONFIG_SENSORS_PC87427 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_SIS5595 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_SMSC47M192 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_VIA686A is not set
-# CONFIG_SENSORS_VT1211 is not set
-# CONFIG_SENSORS_VT8231 is not set
-# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_SENSORS_W83627HF is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83791D is not set
-# CONFIG_SENSORS_W83792D is not set
-# CONFIG_SENSORS_W83793 is not set
-# CONFIG_SENSORS_W83L785TS is not set
-CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_SERIAL_8250_CS is not set
-CONFIG_SERIAL_8250_NR_UARTS=2
-# CONFIG_SERIAL_8250_PCI is not set
-CONFIG_SERIAL_8250_RUNTIME_UARTS=2
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_SERIAL_CORE=y
-# CONFIG_SERIAL_JSM is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_SERIAL_UARTLITE is not set
-# CONFIG_SERIO is not set
-# CONFIG_SGI_IOC4 is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_SHAPER is not set
-CONFIG_SHMEM=y
-# CONFIG_SIS190 is not set
-# CONFIG_SIS900 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_SKGE is not set
-# CONFIG_SKY2 is not set
-CONFIG_SLAB=y
-# CONFIG_SLHC is not set
-# CONFIG_SLIP is not set
-# CONFIG_SLOB is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_SMP is not set
-# CONFIG_SND_AC97_POWER_SAVE is not set
-# CONFIG_SND_AD1816A is not set
-# CONFIG_SND_AD1848 is not set
-# CONFIG_SND_AD1889 is not set
-# CONFIG_SND_ADLIB is not set
-# CONFIG_SND_ALI5451 is not set
-# CONFIG_SND_ALS100 is not set
-# CONFIG_SND_ALS300 is not set
-# CONFIG_SND_ALS4000 is not set
-# CONFIG_SND_ATIIXP is not set
-# CONFIG_SND_ATIIXP_MODEM is not set
-# CONFIG_SND_AU8810 is not set
-# CONFIG_SND_AU8820 is not set
-# CONFIG_SND_AU8830 is not set
-# CONFIG_SND_AZT2320 is not set
-# CONFIG_SND_AZT3328 is not set
-# CONFIG_SND_BT87X is not set
-# CONFIG_SND_CA0106 is not set
-# CONFIG_SND_CMI8330 is not set
-# CONFIG_SND_CMIPCI is not set
-# CONFIG_SND_CS4231 is not set
-# CONFIG_SND_CS4232 is not set
-# CONFIG_SND_CS4236 is not set
-# CONFIG_SND_CS4281 is not set
-# CONFIG_SND_CS46XX is not set
-# CONFIG_SND_CS5535AUDIO is not set
-# CONFIG_SND_DARLA20 is not set
-# CONFIG_SND_DARLA24 is not set
-# CONFIG_SND_DEBUG is not set
-# CONFIG_SND_DT019X is not set
-# CONFIG_SND_DUMMY is not set
-# CONFIG_SND_DYNAMIC_MINORS is not set
-# CONFIG_SND_ECHO3G is not set
-# CONFIG_SND_EMU10K1 is not set
-# CONFIG_SND_EMU10K1X is not set
-# CONFIG_SND_ENS1370 is not set
-# CONFIG_SND_ENS1371 is not set
-# CONFIG_SND_ES1688 is not set
-# CONFIG_SND_ES18XX is not set
-# CONFIG_SND_ES1938 is not set
-# CONFIG_SND_ES1968 is not set
-# CONFIG_SND_ES968 is not set
-# CONFIG_SND_FM801 is not set
-# CONFIG_SND_GINA20 is not set
-# CONFIG_SND_GINA24 is not set
-# CONFIG_SND_GUSCLASSIC is not set
-# CONFIG_SND_GUSEXTREME is not set
-# CONFIG_SND_GUSMAX is not set
-# CONFIG_SND_HDA_INTEL is not set
-# CONFIG_SND_HDSP is not set
-# CONFIG_SND_HDSPM is not set
-# CONFIG_SND_HWDEP is not set
-# CONFIG_SND_ICE1712 is not set
-# CONFIG_SND_ICE1724 is not set
-# CONFIG_SND_INDIGODJ is not set
-# CONFIG_SND_INDIGOIO is not set
-# CONFIG_SND_INDIGO is not set
-# CONFIG_SND_INTEL8X0 is not set
-# CONFIG_SND_INTEL8X0M is not set
-# CONFIG_SND_INTERWAVE is not set
-# CONFIG_SND_INTERWAVE_STB is not set
-# CONFIG_SND is not set
-# CONFIG_SND_KORG1212 is not set
-# CONFIG_SND_LAYLA20 is not set
-# CONFIG_SND_LAYLA24 is not set
-# CONFIG_SND_MAESTRO3 is not set
-# CONFIG_SND_MIA is not set
-# CONFIG_SND_MIRO is not set
-# CONFIG_SND_MIXART is not set
-# CONFIG_SND_MIXER_OSS is not set
-# CONFIG_SND_MONA is not set
-# CONFIG_SND_MPU401 is not set
-# CONFIG_SND_MTPAV is not set
-# CONFIG_SND_NM256 is not set
-# CONFIG_SND_OPL3SA2 is not set
-# CONFIG_SND_OPTI92X_AD1848 is not set
-# CONFIG_SND_OPTI92X_CS4231 is not set
-# CONFIG_SND_OPTI93X is not set
-CONFIG_SND_OSSEMUL=y
-# CONFIG_SND_PCM is not set
-# CONFIG_SND_PCM_OSS is not set
-CONFIG_SND_PCM_OSS_PLUGINS=y
-# CONFIG_SND_PCXHR is not set
-# CONFIG_SND_PDAUDIOCF is not set
-# CONFIG_SND_RAWMIDI is not set
-# CONFIG_SND_RIPTIDE is not set
-# CONFIG_SND_RME32 is not set
-# CONFIG_SND_RME9652 is not set
-# CONFIG_SND_RME96 is not set
-# CONFIG_SND_RTCTIMER is not set
-# CONFIG_SND_SB16 is not set
-# CONFIG_SND_SB8 is not set
-# CONFIG_SND_SBAWE is not set
-# CONFIG_SND_SEQUENCER is not set
-# CONFIG_SND_SERIAL_U16550 is not set
-# CONFIG_SND_SGALAXY is not set
-# CONFIG_SND_SOC is not set
-# CONFIG_SND_SONICVIBES is not set
-# CONFIG_SND_SSCAPE is not set
-# CONFIG_SND_SUPPORT_OLD_API is not set
-# CONFIG_SND_TIMER is not set
-# CONFIG_SND_TRIDENT is not set
-# CONFIG_SND_USB_AUDIO is not set
-# CONFIG_SND_USB_USX2Y is not set
-# CONFIG_SND_VERBOSE_PRINTK is not set
-CONFIG_SND_VERBOSE_PROCFS=y
-# CONFIG_SND_VIA82XX is not set
-# CONFIG_SND_VIA82XX_MODEM is not set
-# CONFIG_SND_VX222 is not set
-# CONFIG_SND_VXPOCKET is not set
-# CONFIG_SND_WAVEFRONT is not set
-# CONFIG_SND_YMFPCI is not set
-# CONFIG_SNI_RM is not set
-# CONFIG_SOFT_WATCHDOG is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_SOUND is not set
-# CONFIG_SOUND_PRIME is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
-CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_SQUASHFS_EMBEDDED is not set
-CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
-# CONFIG_SQUASHFS_VMALLOC is not set
-CONFIG_SQUASHFS=y
-# CONFIG_SSFDC is not set
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_STANDALONE=y
-# CONFIG_STRIP is not set
-# CONFIG_SUNDANCE is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_SUNRPC_GSS is not set
-# CONFIG_SUNRPC is not set
-CONFIG_SWAP=y
-# CONFIG_SYNCLINK_CS is not set
-CONFIG_SYN_COOKIES=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL=y
-# CONFIG_SYSFS_DEPRECATED is not set
-CONFIG_SYSFS=y
-# CONFIG_SYS_HYPERVISOR is not set
-# CONFIG_SYSV_FS is not set
-CONFIG_SYSVIPC_SYSCTL=y
-CONFIG_SYSVIPC=y
-# CONFIG_TASKSTATS is not set
-# CONFIG_TCG_TPM is not set
-CONFIG_TCP_CONG_ADVANCED=y
-# CONFIG_TCP_CONG_BIC is not set
-# CONFIG_TCP_CONG_CUBIC is not set
-# CONFIG_TCP_CONG_HSTCP is not set
-# CONFIG_TCP_CONG_HTCP is not set
-# CONFIG_TCP_CONG_HYBLA is not set
-# CONFIG_TCP_CONG_LP is not set
-# CONFIG_TCP_CONG_SCALABLE is not set
-# CONFIG_TCP_CONG_VEGAS is not set
-# CONFIG_TCP_CONG_VENO is not set
-CONFIG_TCP_CONG_WESTWOOD=y
-# CONFIG_TCP_MD5SIG is not set
-# CONFIG_TEXTSEARCH_BM is not set
-# CONFIG_TEXTSEARCH_FSM is not set
-# CONFIG_TEXTSEARCH_KMP is not set
-CONFIG_TEXTSEARCH=y
-CONFIG_TICK_ONESHOT=y
-# CONFIG_TIFM_CORE is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_TINY_SHMEM is not set
-# CONFIG_TIPC is not set
-# CONFIG_TLAN is not set
-# CONFIG_TMD_HERMES is not set
-# CONFIG_TMPFS_POSIX_ACL is not set
-CONFIG_TMPFS=y
-# CONFIG_TOUCHSCREEN_ELO is not set
-# CONFIG_TOUCHSCREEN_GUNZE is not set
-# CONFIG_TOUCHSCREEN_MK712 is not set
-# CONFIG_TOUCHSCREEN_MTOUCH is not set
-# CONFIG_TOUCHSCREEN_PENMOUNT is not set
-# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
-# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
-# CONFIG_TOUCHSCREEN_UCB1400 is not set
-CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-# CONFIG_TR is not set
-# CONFIG_TUNER_3036 is not set
-# CONFIG_TUN is not set
-# CONFIG_UDF_FS is not set
-CONFIG_UDF_NLS=y
-# CONFIG_UFS_FS is not set
-# CONFIG_ULTRIX_PARTITION is not set
-CONFIG_UNIX98_PTYS=y
-# CONFIG_UNIXWARE_DISKLABEL is not set
-CONFIG_UNIX=y
-# CONFIG_USB_ACECAD is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_AIPTEK is not set
-CONFIG_USB_ALI_M5632=y
-CONFIG_USB_AN2720=y
-# CONFIG_USB_APPLEDISPLAY is not set
-# CONFIG_USB_APPLETOUCH is not set
-CONFIG_USB_ARCH_HAS_EHCI=y
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
-CONFIG_USB_ARMLINUX=y
-# CONFIG_USB_ATI_REMOTE2 is not set
-# CONFIG_USB_ATI_REMOTE is not set
-# CONFIG_USB_ATM is not set
-# CONFIG_USB_AUERSWALD is not set
-# CONFIG_USB_BANDWIDTH is not set
-CONFIG_USB_BELKIN=y
-# CONFIG_USB_BERRY_CHARGE is not set
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_CXACRU is not set
-# CONFIG_USB_CYPRESS_CY7C63 is not set
-# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_DABUSB is not set
-# CONFIG_USB_DEBUG is not set
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_EMI62 is not set
-# CONFIG_USB_EPSON2888 is not set
-# CONFIG_USB_ET61X251 is not set
-CONFIG_USB_EZUSB=y
-# CONFIG_USB_FTDI_ELAN is not set
-# CONFIG_USB_GADGET is not set
-# CONFIG_USB_HIDDEV is not set
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-CONFIG_USB_HIDINPUT=y
-# CONFIG_USB_HID is not set
-# CONFIG_USB_IBMCAM is not set
-# CONFIG_USB_IDMOUSE is not set
-# CONFIG_USB_IOWARRIOR is not set
-# CONFIG_USB is not set
-# CONFIG_USB_ISP116X_HCD is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_KC2190 is not set
-# CONFIG_USB_KEYSPAN_REMOTE is not set
-# CONFIG_USB_KONICAWC is not set
-# CONFIG_USB_LCD is not set
-# CONFIG_USB_LD is not set
-# CONFIG_USB_LED is not set
-# CONFIG_USB_LEGOTOWER is not set
-# CONFIG_USB_LIBUSUAL is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_MON is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_NET_AX8817X is not set
-# CONFIG_USB_NET_CDCETHER is not set
-# CONFIG_USB_NET_CDC_SUBSET is not set
-# CONFIG_USB_NET_DM9601 is not set
-# CONFIG_USB_NET_GL620A is not set
-# CONFIG_USB_NET_MCS7830 is not set
-# CONFIG_USB_NET_NET1080 is not set
-# CONFIG_USB_NET_PLUSB is not set
-# CONFIG_USB_NET_RNDIS_HOST is not set
-# CONFIG_USB_NET_ZAURUS is not set
-# CONFIG_USB_OHCI_BIG_ENDIAN is not set
-# CONFIG_USB_OHCI_HCD is not set
-CONFIG_USB_OHCI_LITTLE_ENDIAN=y
-# CONFIG_USB_OTG is not set
-# CONFIG_USB_OV511 is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_PHIDGET is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_PRINTER is not set
-# CONFIG_USB_QUICKCAM_MESSENGER is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_SE401 is not set
-# CONFIG_USB_SERIAL_AIRCABLE is not set
-# CONFIG_USB_SERIAL_AIRPRIME is not set
-# CONFIG_USB_SERIAL_ARK3116 is not set
-# CONFIG_USB_SERIAL_BELKIN is not set
-# CONFIG_USB_SERIAL_CP2101 is not set
-# CONFIG_USB_SERIAL_CYBERJACK is not set
-# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
-# CONFIG_USB_SERIAL_DEBUG is not set
-# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_EDGEPORT is not set
-# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
-# CONFIG_USB_SERIAL_EMPEG is not set
-# CONFIG_USB_SERIAL_FTDI_SIO is not set
-# CONFIG_USB_SERIAL_FUNSOFT is not set
-# CONFIG_USB_SERIAL_GARMIN is not set
-CONFIG_USB_SERIAL_GENERIC=y
-# CONFIG_USB_SERIAL_HP4X is not set
-# CONFIG_USB_SERIAL_IPAQ is not set
-# CONFIG_USB_SERIAL_IPW is not set
-# CONFIG_USB_SERIAL_IR is not set
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_SERIAL_KEYSPAN is not set
-CONFIG_USB_SERIAL_KEYSPAN_MPR=y
-# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28=y
-CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
-CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
-# CONFIG_USB_SERIAL_KLSI is not set
-# CONFIG_USB_SERIAL_KOBIL_SCT is not set
-# CONFIG_USB_SERIAL_MCT_U232 is not set
-# CONFIG_USB_SERIAL_MOS7720 is not set
-# CONFIG_USB_SERIAL_MOS7840 is not set
-# CONFIG_USB_SERIAL_NAVMAN is not set
-# CONFIG_USB_SERIAL_OMNINET is not set
-# CONFIG_USB_SERIAL_OPTION is not set
-# CONFIG_USB_SERIAL_PL2303 is not set
-# CONFIG_USB_SERIAL_SAFE is not set
-CONFIG_USB_SERIAL_SAFE_PADDED=y
-# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
-# CONFIG_USB_SERIAL_TI is not set
-# CONFIG_USB_SERIAL_VISOR is not set
-# CONFIG_USB_SERIAL_WHITEHEAT is not set
-# CONFIG_USB_SERIAL_XIRCOM is not set
-# CONFIG_USB_SISUSBVGA is not set
-# CONFIG_USB_SL811_HCD is not set
-# CONFIG_USB_SN9C102 is not set
-# CONFIG_USB_SPEEDTOUCH is not set
-CONFIG_USB_STORAGE_ALAUDA=y
-CONFIG_USB_STORAGE_DATAFAB=y
-# CONFIG_USB_STORAGE_DEBUG is not set
-CONFIG_USB_STORAGE_DPCM=y
-CONFIG_USB_STORAGE_FREECOM=y
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE is not set
-CONFIG_USB_STORAGE_JUMPSHOT=y
-CONFIG_USB_STORAGE_KARMA=y
-# CONFIG_USB_STORAGE_ONETOUCH is not set
-CONFIG_USB_STORAGE_SDDR09=y
-CONFIG_USB_STORAGE_SDDR55=y
-CONFIG_USB_STORAGE_USBAT=y
-# CONFIG_USB_STV680 is not set
-# CONFIG_USB_SUSPEND is not set
-# CONFIG_USB_TEST is not set
-# CONFIG_USB_TOUCHSCREEN is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
-# CONFIG_USB_UEAGLEATM is not set
-# CONFIG_USB_USBNET is not set
-# CONFIG_USB_USBNET_MII is not set
-# CONFIG_USB_VICAM is not set
-# CONFIG_USB_W9968CF is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_XPAD is not set
-# CONFIG_USB_XUSBATM is not set
-# CONFIG_USB_YEALINK is not set
-# CONFIG_USB_ZC0301 is not set
-# CONFIG_USB_ZD1201 is not set
-# CONFIG_USB_ZR364XX is not set
-# CONFIG_UTS_NS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_VIA_VELOCITY is not set
-# CONFIG_VIDEO_ADV7170 is not set
-# CONFIG_VIDEO_ADV7175 is not set
-# CONFIG_VIDEO_ADV_DEBUG is not set
-# CONFIG_VIDEO_BT819 is not set
-# CONFIG_VIDEO_BT848 is not set
-# CONFIG_VIDEO_BT856 is not set
-# CONFIG_VIDEO_BT866 is not set
-# CONFIG_VIDEO_CAFE_CCIC is not set
-# CONFIG_VIDEO_CPIA is not set
-# CONFIG_VIDEO_CS53L32A is not set
-# CONFIG_VIDEO_CX2341X is not set
-# CONFIG_VIDEO_CX25840 is not set
-# CONFIG_VIDEO_CX88 is not set
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_VIDEO_DPC is not set
-# CONFIG_VIDEO_EM28XX is not set
-# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
-# CONFIG_VIDEO_HEXIUM_GEMINI is not set
-# CONFIG_VIDEO_HEXIUM_ORION is not set
-# CONFIG_VIDEO_IVTV is not set
-# CONFIG_VIDEO_KS0127 is not set
-# CONFIG_VIDEO_MSP3400 is not set
-# CONFIG_VIDEO_MXB is not set
-# CONFIG_VIDEO_OV7670 is not set
-# CONFIG_VIDEO_OVCAMCHIP is not set
-# CONFIG_VIDEO_PMS is not set
-# CONFIG_VIDEO_PVRUSB2 is not set
-# CONFIG_VIDEO_SAA5246A is not set
-# CONFIG_VIDEO_SAA5249 is not set
-# CONFIG_VIDEO_SAA7110 is not set
-# CONFIG_VIDEO_SAA7111 is not set
-# CONFIG_VIDEO_SAA7114 is not set
-# CONFIG_VIDEO_SAA711X is not set
-# CONFIG_VIDEO_SAA7127 is not set
-# CONFIG_VIDEO_SAA7134 is not set
-# CONFIG_VIDEO_SAA7185 is not set
-# CONFIG_VIDEO_SAA7191 is not set
-# CONFIG_VIDEO_STRADIS is not set
-# CONFIG_VIDEO_TDA7432 is not set
-# CONFIG_VIDEO_TDA9840 is not set
-# CONFIG_VIDEO_TDA9875 is not set
-# CONFIG_VIDEO_TEA6415C is not set
-# CONFIG_VIDEO_TEA6420 is not set
-# CONFIG_VIDEO_TLV320AIC23B is not set
-# CONFIG_VIDEO_TVAUDIO is not set
-# CONFIG_VIDEO_TVP5150 is not set
-# CONFIG_VIDEO_UPD64031A is not set
-# CONFIG_VIDEO_UPD64083 is not set
-# CONFIG_VIDEO_USBVISION is not set
-CONFIG_VIDEO_V4L1_COMPAT=y
-# CONFIG_VIDEO_V4L1 is not set
-CONFIG_VIDEO_V4L2=y
-# CONFIG_VIDEO_VIVI is not set
-# CONFIG_VIDEO_VPX3220 is not set
-# CONFIG_VIDEO_WM8739 is not set
-# CONFIG_VIDEO_WM8775 is not set
-# CONFIG_VIDEO_ZORAN is not set
-# CONFIG_VITESSE_PHY is not set
-CONFIG_VLAN_8021Q=y
-# CONFIG_VM_EVENT_COUNTERS is not set
-# CONFIG_VT is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_W1 is not set
-# CONFIG_WAN is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-CONFIG_WATCHDOG=y
-# CONFIG_WDTPCI is not set
-CONFIG_WIRELESS_EXT=y
-# CONFIG_WR_PPMC is not set
-# CONFIG_X25 is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_USER is not set
-CONFIG_XFRM=y
-# CONFIG_XFS_FS is not set
-# CONFIG_XFS_POSIX_ACL is not set
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_RT is not set
-# CONFIG_XFS_SECURITY is not set
-# CONFIG_YAFFS_FS is not set
-# CONFIG_YAM is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_YENTA is not set
-# CONFIG_YENTA_O2 is not set
-# CONFIG_YENTA_RICOH is not set
-# CONFIG_YENTA_TI is not set
-# CONFIG_YENTA_TOSHIBA is not set
-# CONFIG_ZD1211RW_DEBUG is not set
-# CONFIG_ZD1211RW is not set
-# CONFIG_ZISOFS_FS is not set
-CONFIG_ZISOFS=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZONE_DMA_FLAG=1
-CONFIG_ZONE_DMA=y

+ 0 - 4160
target/linux/generic-2.6/patches-2.6.21/001-squashfs.patch

@@ -1,4160 +0,0 @@
---- a/fs/Kconfig
-+++ b/fs/Kconfig
-@@ -1371,6 +1371,71 @@ config CRAMFS
- 
- 	  If unsure, say N.
- 
-+config SQUASHFS
-+	tristate "SquashFS 3.0 - Squashed file system support"
-+	select ZLIB_INFLATE
-+	help
-+	  Saying Y here includes support for SquashFS 3.0 (a Compressed Read-Only File
-+	  System).  Squashfs is a highly compressed read-only filesystem for Linux.
-+	  It uses zlib compression to compress both files, inodes and directories.
-+	  Inodes in the system are very small and all blocks are packed to minimise
-+	  data overhead. Block sizes greater than 4K are supported up to a maximum of 64K.
-+	  SquashFS 3.0 supports 64 bit filesystems and files (larger than 4GB), full
-+	  uid/gid information, hard links and timestamps.
-+
-+	  Squashfs is intended for general read-only filesystem use, for archival
-+	  use (i.e. in cases where a .tar.gz file may be used), and in embedded
-+	  systems where low overhead is needed.  Further information and filesystem tools
-+	  are available from http://squashfs.sourceforge.net.
-+
-+	  If you want to compile this as a module ( = code which can be
-+	  inserted in and removed from the running kernel whenever you want),
-+	  say M here and read <file:Documentation/modules.txt>.  The module
-+	  will be called squashfs.  Note that the root file system (the one
-+	  containing the directory /) cannot be compiled as a module.
-+
-+	  If unsure, say N.
-+
-+config SQUASHFS_EMBEDDED
-+
-+	bool "Additional options for memory-constrained systems"
-+	depends on SQUASHFS
-+	default n
-+	help
-+	  Saying Y here allows you to specify cache sizes and how Squashfs
-+	  allocates memory.  This is only intended for memory constrained
-+	  systems.
-+
-+	  If unsure, say N.
-+
-+config SQUASHFS_FRAGMENT_CACHE_SIZE
-+	int "Number of fragments cached" if SQUASHFS_EMBEDDED
-+	depends on SQUASHFS
-+	default "3"
-+	help
-+	  By default SquashFS caches the last 3 fragments read from
-+	  the filesystem.  Increasing this amount may mean SquashFS
-+	  has to re-read fragments less often from disk, at the expense
-+	  of extra system memory.  Decreasing this amount will mean
-+	  SquashFS uses less memory at the expense of extra reads from disk.
-+
-+	  Note there must be at least one cached fragment.  Anything
-+	  much more than three will probably not make much difference.
-+
-+config SQUASHFS_VMALLOC
-+	bool "Use Vmalloc rather than Kmalloc" if SQUASHFS_EMBEDDED
-+	depends on SQUASHFS
-+	default n
-+	help
-+	  By default SquashFS uses kmalloc to obtain fragment cache memory.
-+	  Kmalloc memory is the standard kernel allocator, but it can fail
-+	  on memory constrained systems.  Because of the way Vmalloc works,
-+	  Vmalloc can succeed when kmalloc fails.  Specifying this option
-+	  will make SquashFS always use Vmalloc to allocate the
-+	  fragment cache memory.
-+
-+	  If unsure, say N.
-+
- config VXFS_FS
- 	tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)"
- 	depends on BLOCK
---- a/fs/Makefile
-+++ b/fs/Makefile
-@@ -68,6 +68,7 @@ obj-$(CONFIG_JBD)		+= jbd/
- obj-$(CONFIG_JBD2)		+= jbd2/
- obj-$(CONFIG_EXT2_FS)		+= ext2/
- obj-$(CONFIG_CRAMFS)		+= cramfs/
-+obj-$(CONFIG_SQUASHFS)		+= squashfs/
- obj-$(CONFIG_RAMFS)		+= ramfs/
- obj-$(CONFIG_HUGETLBFS)		+= hugetlbfs/
- obj-$(CONFIG_CODA_FS)		+= coda/
---- /dev/null
-+++ b/fs/squashfs/inode.c
-@@ -0,0 +1,2124 @@
-+/*
-+ * Squashfs - a compressed read only filesystem for Linux
-+ *
-+ * Copyright (c) 2002, 2003, 2004, 2005, 2006
-+ * Phillip Lougher <[email protected]>
-+ *
-+ * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * inode.c
-+ */
-+
-+#include <linux/types.h>
-+#include <linux/squashfs_fs.h>
-+#include <linux/module.h>
-+#include <linux/errno.h>
-+#include <linux/slab.h>
-+#include <linux/fs.h>
-+#include <linux/smp_lock.h>
-+#include <linux/slab.h>
-+#include <linux/squashfs_fs_sb.h>
-+#include <linux/squashfs_fs_i.h>
-+#include <linux/buffer_head.h>
-+#include <linux/vfs.h>
-+#include <linux/init.h>
-+#include <linux/dcache.h>
-+#include <linux/wait.h>
-+#include <linux/zlib.h>
-+#include <linux/blkdev.h>
-+#include <linux/vmalloc.h>
-+#include <asm/uaccess.h>
-+#include <asm/semaphore.h>
-+
-+#include "squashfs.h"
-+
-+static void squashfs_put_super(struct super_block *);
-+static int squashfs_statfs(struct dentry *, struct kstatfs *);
-+static int squashfs_symlink_readpage(struct file *file, struct page *page);
-+static int squashfs_readpage(struct file *file, struct page *page);
-+static int squashfs_readpage4K(struct file *file, struct page *page);
-+static int squashfs_readdir(struct file *, void *, filldir_t);
-+static struct inode *squashfs_alloc_inode(struct super_block *sb);
-+static void squashfs_destroy_inode(struct inode *inode);
-+static int init_inodecache(void);
-+static void destroy_inodecache(void);
-+static struct dentry *squashfs_lookup(struct inode *, struct dentry *,
-+				struct nameidata *);
-+static struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode);
-+static long long read_blocklist(struct inode *inode, int index,
-+				int readahead_blks, char *block_list,
-+				unsigned short **block_p, unsigned int *bsize);
-+static int squashfs_get_sb(struct file_system_type *, int,
-+			const char *, void *, struct vfsmount *);
-+
-+
-+static z_stream stream;
-+
-+static struct file_system_type squashfs_fs_type = {
-+	.owner = THIS_MODULE,
-+	.name = "squashfs",
-+	.get_sb = squashfs_get_sb,
-+	.kill_sb = kill_block_super,
-+	.fs_flags = FS_REQUIRES_DEV
-+};
-+
-+static unsigned char squashfs_filetype_table[] = {
-+	DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK
-+};
-+
-+static struct super_operations squashfs_ops = {
-+	.alloc_inode = squashfs_alloc_inode,
-+	.destroy_inode = squashfs_destroy_inode,
-+	.statfs = squashfs_statfs,
-+	.put_super = squashfs_put_super,
-+};
-+
-+SQSH_EXTERN struct address_space_operations squashfs_symlink_aops = {
-+	.readpage = squashfs_symlink_readpage
-+};
-+
-+SQSH_EXTERN struct address_space_operations squashfs_aops = {
-+	.readpage = squashfs_readpage
-+};
-+
-+SQSH_EXTERN struct address_space_operations squashfs_aops_4K = {
-+	.readpage = squashfs_readpage4K
-+};
-+
-+static struct file_operations squashfs_dir_ops = {
-+	.read = generic_read_dir,
-+	.readdir = squashfs_readdir
-+};
-+
-+SQSH_EXTERN struct inode_operations squashfs_dir_inode_ops = {
-+	.lookup = squashfs_lookup
-+};
-+
-+
-+static struct buffer_head *get_block_length(struct super_block *s,
-+				int *cur_index, int *offset, int *c_byte)
-+{
-+	struct squashfs_sb_info *msblk = s->s_fs_info;
-+	unsigned short temp;
-+	struct buffer_head *bh;
-+
-+	if (!(bh = sb_bread(s, *cur_index)))
-+		goto out;
-+
-+	if (msblk->devblksize - *offset == 1) {
-+		if (msblk->swap)
-+			((unsigned char *) &temp)[1] = *((unsigned char *)
-+				(bh->b_data + *offset));
-+		else
-+			((unsigned char *) &temp)[0] = *((unsigned char *)
-+				(bh->b_data + *offset));
-+		brelse(bh);
-+		if (!(bh = sb_bread(s, ++(*cur_index))))
-+			goto out;
-+		if (msblk->swap)
-+			((unsigned char *) &temp)[0] = *((unsigned char *)
-+				bh->b_data);
-+		else
-+			((unsigned char *) &temp)[1] = *((unsigned char *)
-+				bh->b_data);
-+		*c_byte = temp;
-+		*offset = 1;
-+	} else {
-+		if (msblk->swap) {
-+			((unsigned char *) &temp)[1] = *((unsigned char *)
-+				(bh->b_data + *offset));
-+			((unsigned char *) &temp)[0] = *((unsigned char *)
-+				(bh->b_data + *offset + 1));
-+		} else {
-+			((unsigned char *) &temp)[0] = *((unsigned char *)
-+				(bh->b_data + *offset));
-+			((unsigned char *) &temp)[1] = *((unsigned char *)
-+				(bh->b_data + *offset + 1));
-+		}
-+		*c_byte = temp;
-+		*offset += 2;
-+	}
-+
-+	if (SQUASHFS_CHECK_DATA(msblk->sblk.flags)) {
-+		if (*offset == msblk->devblksize) {
-+			brelse(bh);
-+			if (!(bh = sb_bread(s, ++(*cur_index))))
-+				goto out;
-+			*offset = 0;
-+		}
-+		if (*((unsigned char *) (bh->b_data + *offset)) !=
-+						SQUASHFS_MARKER_BYTE) {
-+			ERROR("Metadata block marker corrupt @ %x\n",
-+						*cur_index);
-+			brelse(bh);
-+			goto out;
-+		}
-+		(*offset)++;
-+	}
-+	return bh;
-+
-+out:
-+	return NULL;
-+}
-+
-+
-+SQSH_EXTERN unsigned int squashfs_read_data(struct super_block *s, char *buffer,
-+			long long index, unsigned int length,
-+			long long *next_index)
-+{
-+	struct squashfs_sb_info *msblk = s->s_fs_info;
-+	struct buffer_head *bh[((SQUASHFS_FILE_MAX_SIZE - 1) >>
-+			msblk->devblksize_log2) + 2];
-+	unsigned int offset = index & ((1 << msblk->devblksize_log2) - 1);
-+	unsigned int cur_index = index >> msblk->devblksize_log2;
-+	int bytes, avail_bytes, b = 0, k;
-+	char *c_buffer;
-+	unsigned int compressed;
-+	unsigned int c_byte = length;
-+
-+	if (c_byte) {
-+		bytes = msblk->devblksize - offset;
-+		compressed = SQUASHFS_COMPRESSED_BLOCK(c_byte);
-+		c_buffer = compressed ? msblk->read_data : buffer;
-+		c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte);
-+
-+		TRACE("Block @ 0x%llx, %scompressed size %d\n", index, compressed
-+					? "" : "un", (unsigned int) c_byte);
-+
-+		if (!(bh[0] = sb_getblk(s, cur_index)))
-+			goto block_release;
-+
-+		for (b = 1; bytes < c_byte; b++) {
-+			if (!(bh[b] = sb_getblk(s, ++cur_index)))
-+				goto block_release;
-+			bytes += msblk->devblksize;
-+		}
-+		ll_rw_block(READ, b, bh);
-+	} else {
-+		if (!(bh[0] = get_block_length(s, &cur_index, &offset,
-+								&c_byte)))
-+			goto read_failure;
-+
-+		bytes = msblk->devblksize - offset;
-+		compressed = SQUASHFS_COMPRESSED(c_byte);
-+		c_buffer = compressed ? msblk->read_data : buffer;
-+		c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte);
-+
-+		TRACE("Block @ 0x%llx, %scompressed size %d\n", index, compressed
-+					? "" : "un", (unsigned int) c_byte);
-+
-+		for (b = 1; bytes < c_byte; b++) {
-+			if (!(bh[b] = sb_getblk(s, ++cur_index)))
-+				goto block_release;
-+			bytes += msblk->devblksize;
-+		}
-+		ll_rw_block(READ, b - 1, bh + 1);
-+	}
-+
-+	if (compressed)
-+		down(&msblk->read_data_mutex);
-+
-+	for (bytes = 0, k = 0; k < b; k++) {
-+		avail_bytes = (c_byte - bytes) > (msblk->devblksize - offset) ?
-+					msblk->devblksize - offset :
-+					c_byte - bytes;
-+		wait_on_buffer(bh[k]);
-+		if (!buffer_uptodate(bh[k]))
-+			goto block_release;
-+		memcpy(c_buffer + bytes, bh[k]->b_data + offset, avail_bytes);
-+		bytes += avail_bytes;
-+		offset = 0;
-+		brelse(bh[k]);
-+	}
-+
-+	/*
-+	 * uncompress block
-+	 */
-+	if (compressed) {
-+		int zlib_err;
-+
-+		stream.next_in = c_buffer;
-+		stream.avail_in = c_byte;
-+		stream.next_out = buffer;
-+		stream.avail_out = msblk->read_size;
-+
-+		if (((zlib_err = zlib_inflateInit(&stream)) != Z_OK) ||
-+				((zlib_err = zlib_inflate(&stream, Z_FINISH))
-+				 != Z_STREAM_END) || ((zlib_err =
-+				zlib_inflateEnd(&stream)) != Z_OK)) {
-+			ERROR("zlib_fs returned unexpected result 0x%x\n",
-+				zlib_err);
-+			bytes = 0;
-+		} else
-+			bytes = stream.total_out;
-+
-+		up(&msblk->read_data_mutex);
-+	}
-+
-+	if (next_index)
-+		*next_index = index + c_byte + (length ? 0 :
-+				(SQUASHFS_CHECK_DATA(msblk->sblk.flags)
-+				 ? 3 : 2));
-+	return bytes;
-+
-+block_release:
-+	while (--b >= 0)
-+		brelse(bh[b]);
-+
-+read_failure:
-+	ERROR("sb_bread failed reading block 0x%x\n", cur_index);
-+	return 0;
-+}
-+
-+
-+SQSH_EXTERN int squashfs_get_cached_block(struct super_block *s, char *buffer,
-+				long long block, unsigned int offset,
-+				int length, long long *next_block,
-+				unsigned int *next_offset)
-+{
-+	struct squashfs_sb_info *msblk = s->s_fs_info;
-+	int n, i, bytes, return_length = length;
-+	long long next_index;
-+
-+	TRACE("Entered squashfs_get_cached_block [%llx:%x]\n", block, offset);
-+
-+	while ( 1 ) {
-+		for (i = 0; i < SQUASHFS_CACHED_BLKS; i++)
-+			if (msblk->block_cache[i].block == block)
-+				break;
-+
-+		down(&msblk->block_cache_mutex);
-+
-+		if (i == SQUASHFS_CACHED_BLKS) {
-+			/* read inode header block */
-+			for (i = msblk->next_cache, n = SQUASHFS_CACHED_BLKS;
-+					n ; n --, i = (i + 1) %
-+					SQUASHFS_CACHED_BLKS)
-+				if (msblk->block_cache[i].block !=
-+							SQUASHFS_USED_BLK)
-+					break;
-+
-+			if (n == 0) {
-+				wait_queue_t wait;
-+
-+				init_waitqueue_entry(&wait, current);
-+				add_wait_queue(&msblk->waitq, &wait);
-+				set_current_state(TASK_UNINTERRUPTIBLE);
-+ 				up(&msblk->block_cache_mutex);
-+				schedule();
-+				set_current_state(TASK_RUNNING);
-+				remove_wait_queue(&msblk->waitq, &wait);
-+				continue;
-+			}
-+			msblk->next_cache = (i + 1) % SQUASHFS_CACHED_BLKS;
-+
-+			if (msblk->block_cache[i].block ==
-+							SQUASHFS_INVALID_BLK) {
-+				if (!(msblk->block_cache[i].data =
-+						kmalloc(SQUASHFS_METADATA_SIZE,
-+						GFP_KERNEL))) {
-+					ERROR("Failed to allocate cache"
-+							"block\n");
-+					up(&msblk->block_cache_mutex);
-+					goto out;
-+				}
-+			}
-+
-+			msblk->block_cache[i].block = SQUASHFS_USED_BLK;
-+			up(&msblk->block_cache_mutex);
-+
-+			if (!(msblk->block_cache[i].length =
-+						squashfs_read_data(s,
-+						msblk->block_cache[i].data,
-+						block, 0, &next_index))) {
-+				ERROR("Unable to read cache block [%llx:%x]\n",
-+						block, offset);
-+				goto out;
-+			}
-+
-+			down(&msblk->block_cache_mutex);
-+			wake_up(&msblk->waitq);
-+			msblk->block_cache[i].block = block;
-+			msblk->block_cache[i].next_index = next_index;
-+			TRACE("Read cache block [%llx:%x]\n", block, offset);
-+		}
-+
-+		if (msblk->block_cache[i].block != block) {
-+			up(&msblk->block_cache_mutex);
-+			continue;
-+		}
-+
-+		if ((bytes = msblk->block_cache[i].length - offset) >= length) {
-+			if (buffer)
-+				memcpy(buffer, msblk->block_cache[i].data +
-+						offset, length);
-+			if (msblk->block_cache[i].length - offset == length) {
-+				*next_block = msblk->block_cache[i].next_index;
-+				*next_offset = 0;
-+			} else {
-+				*next_block = block;
-+				*next_offset = offset + length;
-+			}
-+			up(&msblk->block_cache_mutex);
-+			goto finish;
-+		} else {
-+			if (buffer) {
-+				memcpy(buffer, msblk->block_cache[i].data +
-+						offset, bytes);
-+				buffer += bytes;
-+			}
-+			block = msblk->block_cache[i].next_index;
-+			up(&msblk->block_cache_mutex);
-+			length -= bytes;
-+			offset = 0;
-+		}
-+	}
-+
-+finish:
-+	return return_length;
-+out:
-+	return 0;
-+}
-+
-+
-+static int get_fragment_location(struct super_block *s, unsigned int fragment,
-+				long long *fragment_start_block,
-+				unsigned int *fragment_size)
-+{
-+	struct squashfs_sb_info *msblk = s->s_fs_info;
-+	long long start_block =
-+		msblk->fragment_index[SQUASHFS_FRAGMENT_INDEX(fragment)];
-+	int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET(fragment);
-+	struct squashfs_fragment_entry fragment_entry;
-+
-+	if (msblk->swap) {
-+		struct squashfs_fragment_entry sfragment_entry;
-+
-+		if (!squashfs_get_cached_block(s, (char *) &sfragment_entry,
-+					start_block, offset,
-+					sizeof(sfragment_entry), &start_block,
-+					&offset))
-+			goto out;
-+		SQUASHFS_SWAP_FRAGMENT_ENTRY(&fragment_entry, &sfragment_entry);
-+	} else
-+		if (!squashfs_get_cached_block(s, (char *) &fragment_entry,
-+					start_block, offset,
-+					sizeof(fragment_entry), &start_block,
-+					&offset))
-+			goto out;
-+
-+	*fragment_start_block = fragment_entry.start_block;
-+	*fragment_size = fragment_entry.size;
-+
-+	return 1;
-+
-+out:
-+	return 0;
-+}
-+
-+
-+SQSH_EXTERN void release_cached_fragment(struct squashfs_sb_info *msblk, struct
-+					squashfs_fragment_cache *fragment)
-+{
-+	down(&msblk->fragment_mutex);
-+	fragment->locked --;
-+	wake_up(&msblk->fragment_wait_queue);
-+	up(&msblk->fragment_mutex);
-+}
-+
-+
-+SQSH_EXTERN struct squashfs_fragment_cache *get_cached_fragment(struct super_block
-+					*s, long long start_block,
-+					int length)
-+{
-+	int i, n;
-+	struct squashfs_sb_info *msblk = s->s_fs_info;
-+
-+	while ( 1 ) {
-+		down(&msblk->fragment_mutex);
-+
-+		for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS &&
-+				msblk->fragment[i].block != start_block; i++);
-+
-+		if (i == SQUASHFS_CACHED_FRAGMENTS) {
-+			for (i = msblk->next_fragment, n =
-+				SQUASHFS_CACHED_FRAGMENTS; n &&
-+				msblk->fragment[i].locked; n--, i = (i + 1) %
-+				SQUASHFS_CACHED_FRAGMENTS);
-+
-+			if (n == 0) {
-+				wait_queue_t wait;
-+
-+				init_waitqueue_entry(&wait, current);
-+				add_wait_queue(&msblk->fragment_wait_queue,
-+									&wait);
-+				set_current_state(TASK_UNINTERRUPTIBLE);
-+				up(&msblk->fragment_mutex);
-+				schedule();
-+				set_current_state(TASK_RUNNING);
-+				remove_wait_queue(&msblk->fragment_wait_queue,
-+									&wait);
-+				continue;
-+			}
-+			msblk->next_fragment = (msblk->next_fragment + 1) %
-+				SQUASHFS_CACHED_FRAGMENTS;
-+
-+			if (msblk->fragment[i].data == NULL)
-+				if (!(msblk->fragment[i].data = SQUASHFS_ALLOC
-+						(SQUASHFS_FILE_MAX_SIZE))) {
-+					ERROR("Failed to allocate fragment "
-+							"cache block\n");
-+					up(&msblk->fragment_mutex);
-+					goto out;
-+				}
-+
-+			msblk->fragment[i].block = SQUASHFS_INVALID_BLK;
-+			msblk->fragment[i].locked = 1;
-+			up(&msblk->fragment_mutex);
-+
-+			if (!(msblk->fragment[i].length = squashfs_read_data(s,
-+						msblk->fragment[i].data,
-+						start_block, length, NULL))) {
-+				ERROR("Unable to read fragment cache block "
-+							"[%llx]\n", start_block);
-+				msblk->fragment[i].locked = 0;
-+				goto out;
-+			}
-+
-+			msblk->fragment[i].block = start_block;
-+			TRACE("New fragment %d, start block %lld, locked %d\n",
-+						i, msblk->fragment[i].block,
-+						msblk->fragment[i].locked);
-+			break;
-+		}
-+
-+		msblk->fragment[i].locked++;
-+		up(&msblk->fragment_mutex);
-+		TRACE("Got fragment %d, start block %lld, locked %d\n", i,
-+						msblk->fragment[i].block,
-+						msblk->fragment[i].locked);
-+		break;
-+	}
-+
-+	return &msblk->fragment[i];
-+
-+out:
-+	return NULL;
-+}
-+
-+
-+static struct inode *squashfs_new_inode(struct super_block *s,
-+		struct squashfs_base_inode_header *inodeb)
-+{
-+	struct squashfs_sb_info *msblk = s->s_fs_info;
-+	struct inode *i = new_inode(s);
-+
-+	if (i) {
-+		i->i_ino = inodeb->inode_number;
-+		i->i_mtime.tv_sec = inodeb->mtime;
-+		i->i_atime.tv_sec = inodeb->mtime;
-+		i->i_ctime.tv_sec = inodeb->mtime;
-+		i->i_uid = msblk->uid[inodeb->uid];
-+		i->i_mode = inodeb->mode;
-+		i->i_size = 0;
-+		if (inodeb->guid == SQUASHFS_GUIDS)
-+			i->i_gid = i->i_uid;
-+		else
-+			i->i_gid = msblk->guid[inodeb->guid];
-+	}
-+
-+	return i;
-+}
-+
-+
-+static struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode)
-+{
-+	struct inode *i;
-+	struct squashfs_sb_info *msblk = s->s_fs_info;
-+	struct squashfs_super_block *sblk = &msblk->sblk;
-+	long long block = SQUASHFS_INODE_BLK(inode) +
-+		sblk->inode_table_start;
-+	unsigned int offset = SQUASHFS_INODE_OFFSET(inode);
-+	long long next_block;
-+	unsigned int next_offset;
-+	union squashfs_inode_header id, sid;
-+	struct squashfs_base_inode_header *inodeb = &id.base,
-+					  *sinodeb = &sid.base;
-+
-+	TRACE("Entered squashfs_iget\n");
-+
-+	if (msblk->swap) {
-+		if (!squashfs_get_cached_block(s, (char *) sinodeb, block,
-+					offset, sizeof(*sinodeb), &next_block,
-+					&next_offset))
-+			goto failed_read;
-+		SQUASHFS_SWAP_BASE_INODE_HEADER(inodeb, sinodeb,
-+					sizeof(*sinodeb));
-+	} else
-+		if (!squashfs_get_cached_block(s, (char *) inodeb, block,
-+					offset, sizeof(*inodeb), &next_block,
-+					&next_offset))
-+			goto failed_read;
-+
-+	switch(inodeb->inode_type) {
-+		case SQUASHFS_FILE_TYPE: {
-+			unsigned int frag_size;
-+			long long frag_blk;
-+			struct squashfs_reg_inode_header *inodep = &id.reg;
-+			struct squashfs_reg_inode_header *sinodep = &sid.reg;
-+
-+			if (msblk->swap) {
-+				if (!squashfs_get_cached_block(s, (char *)
-+						sinodep, block, offset,
-+						sizeof(*sinodep), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+				SQUASHFS_SWAP_REG_INODE_HEADER(inodep, sinodep);
-+			} else
-+				if (!squashfs_get_cached_block(s, (char *)
-+						inodep, block, offset,
-+						sizeof(*inodep), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+
-+			frag_blk = SQUASHFS_INVALID_BLK;
-+			if (inodep->fragment != SQUASHFS_INVALID_FRAG &&
-+					!get_fragment_location(s,
-+					inodep->fragment, &frag_blk, &frag_size))
-+				goto failed_read;
-+
-+			if((i = squashfs_new_inode(s, inodeb)) == NULL)
-+				goto failed_read1;
-+
-+			i->i_nlink = 1;
-+			i->i_size = inodep->file_size;
-+			i->i_fop = &generic_ro_fops;
-+			i->i_mode |= S_IFREG;
-+			i->i_blocks = ((i->i_size - 1) >> 9) + 1;
-+			SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk;
-+			SQUASHFS_I(i)->u.s1.fragment_size = frag_size;
-+			SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset;
-+			SQUASHFS_I(i)->start_block = inodep->start_block;
-+			SQUASHFS_I(i)->u.s1.block_list_start = next_block;
-+			SQUASHFS_I(i)->offset = next_offset;
-+			if (sblk->block_size > 4096)
-+				i->i_data.a_ops = &squashfs_aops;
-+			else
-+				i->i_data.a_ops = &squashfs_aops_4K;
-+
-+			TRACE("File inode %x:%x, start_block %llx, "
-+					"block_list_start %llx, offset %x\n",
-+					SQUASHFS_INODE_BLK(inode), offset,
-+					inodep->start_block, next_block,
-+					next_offset);
-+			break;
-+		}
-+		case SQUASHFS_LREG_TYPE: {
-+			unsigned int frag_size;
-+			long long frag_blk;
-+			struct squashfs_lreg_inode_header *inodep = &id.lreg;
-+			struct squashfs_lreg_inode_header *sinodep = &sid.lreg;
-+
-+			if (msblk->swap) {
-+				if (!squashfs_get_cached_block(s, (char *)
-+						sinodep, block, offset,
-+						sizeof(*sinodep), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+				SQUASHFS_SWAP_LREG_INODE_HEADER(inodep, sinodep);
-+			} else
-+				if (!squashfs_get_cached_block(s, (char *)
-+						inodep, block, offset,
-+						sizeof(*inodep), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+
-+			frag_blk = SQUASHFS_INVALID_BLK;
-+			if (inodep->fragment != SQUASHFS_INVALID_FRAG &&
-+					!get_fragment_location(s,
-+					inodep->fragment, &frag_blk, &frag_size))
-+				goto failed_read;
-+
-+			if((i = squashfs_new_inode(s, inodeb)) == NULL)
-+				goto failed_read1;
-+
-+			i->i_nlink = inodep->nlink;
-+			i->i_size = inodep->file_size;
-+			i->i_fop = &generic_ro_fops;
-+			i->i_mode |= S_IFREG;
-+			i->i_blocks = ((i->i_size - 1) >> 9) + 1;
-+			SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk;
-+			SQUASHFS_I(i)->u.s1.fragment_size = frag_size;
-+			SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset;
-+			SQUASHFS_I(i)->start_block = inodep->start_block;
-+			SQUASHFS_I(i)->u.s1.block_list_start = next_block;
-+			SQUASHFS_I(i)->offset = next_offset;
-+			if (sblk->block_size > 4096)
-+				i->i_data.a_ops = &squashfs_aops;
-+			else
-+				i->i_data.a_ops = &squashfs_aops_4K;
-+
-+			TRACE("File inode %x:%x, start_block %llx, "
-+					"block_list_start %llx, offset %x\n",
-+					SQUASHFS_INODE_BLK(inode), offset,
-+					inodep->start_block, next_block,
-+					next_offset);
-+			break;
-+		}
-+		case SQUASHFS_DIR_TYPE: {
-+			struct squashfs_dir_inode_header *inodep = &id.dir;
-+			struct squashfs_dir_inode_header *sinodep = &sid.dir;
-+
-+			if (msblk->swap) {
-+				if (!squashfs_get_cached_block(s, (char *)
-+						sinodep, block, offset,
-+						sizeof(*sinodep), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+				SQUASHFS_SWAP_DIR_INODE_HEADER(inodep, sinodep);
-+			} else
-+				if (!squashfs_get_cached_block(s, (char *)
-+						inodep, block, offset,
-+						sizeof(*inodep), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+
-+			if((i = squashfs_new_inode(s, inodeb)) == NULL)
-+				goto failed_read1;
-+
-+			i->i_nlink = inodep->nlink;
-+			i->i_size = inodep->file_size;
-+			i->i_op = &squashfs_dir_inode_ops;
-+			i->i_fop = &squashfs_dir_ops;
-+			i->i_mode |= S_IFDIR;
-+			SQUASHFS_I(i)->start_block = inodep->start_block;
-+			SQUASHFS_I(i)->offset = inodep->offset;
-+			SQUASHFS_I(i)->u.s2.directory_index_count = 0;
-+			SQUASHFS_I(i)->u.s2.parent_inode = inodep->parent_inode;
-+
-+			TRACE("Directory inode %x:%x, start_block %x, offset "
-+					"%x\n", SQUASHFS_INODE_BLK(inode),
-+					offset, inodep->start_block,
-+					inodep->offset);
-+			break;
-+		}
-+		case SQUASHFS_LDIR_TYPE: {
-+			struct squashfs_ldir_inode_header *inodep = &id.ldir;
-+			struct squashfs_ldir_inode_header *sinodep = &sid.ldir;
-+
-+			if (msblk->swap) {
-+				if (!squashfs_get_cached_block(s, (char *)
-+						sinodep, block, offset,
-+						sizeof(*sinodep), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+				SQUASHFS_SWAP_LDIR_INODE_HEADER(inodep,
-+						sinodep);
-+			} else
-+				if (!squashfs_get_cached_block(s, (char *)
-+						inodep, block, offset,
-+						sizeof(*inodep), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+
-+			if((i = squashfs_new_inode(s, inodeb)) == NULL)
-+				goto failed_read1;
-+
-+			i->i_nlink = inodep->nlink;
-+			i->i_size = inodep->file_size;
-+			i->i_op = &squashfs_dir_inode_ops;
-+			i->i_fop = &squashfs_dir_ops;
-+			i->i_mode |= S_IFDIR;
-+			SQUASHFS_I(i)->start_block = inodep->start_block;
-+			SQUASHFS_I(i)->offset = inodep->offset;
-+			SQUASHFS_I(i)->u.s2.directory_index_start = next_block;
-+			SQUASHFS_I(i)->u.s2.directory_index_offset =
-+								next_offset;
-+			SQUASHFS_I(i)->u.s2.directory_index_count =
-+								inodep->i_count;
-+			SQUASHFS_I(i)->u.s2.parent_inode = inodep->parent_inode;
-+
-+			TRACE("Long directory inode %x:%x, start_block %x, "
-+					"offset %x\n",
-+					SQUASHFS_INODE_BLK(inode), offset,
-+					inodep->start_block, inodep->offset);
-+			break;
-+		}
-+		case SQUASHFS_SYMLINK_TYPE: {
-+			struct squashfs_symlink_inode_header *inodep =
-+								&id.symlink;
-+			struct squashfs_symlink_inode_header *sinodep =
-+								&sid.symlink;
-+
-+			if (msblk->swap) {
-+				if (!squashfs_get_cached_block(s, (char *)
-+						sinodep, block, offset,
-+						sizeof(*sinodep), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+				SQUASHFS_SWAP_SYMLINK_INODE_HEADER(inodep,
-+								sinodep);
-+			} else
-+				if (!squashfs_get_cached_block(s, (char *)
-+						inodep, block, offset,
-+						sizeof(*inodep), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+
-+			if((i = squashfs_new_inode(s, inodeb)) == NULL)
-+				goto failed_read1;
-+
-+			i->i_nlink = inodep->nlink;
-+			i->i_size = inodep->symlink_size;
-+			i->i_op = &page_symlink_inode_operations;
-+			i->i_data.a_ops = &squashfs_symlink_aops;
-+			i->i_mode |= S_IFLNK;
-+			SQUASHFS_I(i)->start_block = next_block;
-+			SQUASHFS_I(i)->offset = next_offset;
-+
-+			TRACE("Symbolic link inode %x:%x, start_block %llx, "
-+					"offset %x\n",
-+					SQUASHFS_INODE_BLK(inode), offset,
-+					next_block, next_offset);
-+			break;
-+		 }
-+		 case SQUASHFS_BLKDEV_TYPE:
-+		 case SQUASHFS_CHRDEV_TYPE: {
-+			struct squashfs_dev_inode_header *inodep = &id.dev;
-+			struct squashfs_dev_inode_header *sinodep = &sid.dev;
-+
-+			if (msblk->swap) {
-+				if (!squashfs_get_cached_block(s, (char *)
-+						sinodep, block, offset,
-+						sizeof(*sinodep), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+				SQUASHFS_SWAP_DEV_INODE_HEADER(inodep, sinodep);
-+			} else
-+				if (!squashfs_get_cached_block(s, (char *)
-+						inodep, block, offset,
-+						sizeof(*inodep), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+
-+			if ((i = squashfs_new_inode(s, inodeb)) == NULL)
-+				goto failed_read1;
-+
-+			i->i_nlink = inodep->nlink;
-+			i->i_mode |= (inodeb->inode_type ==
-+					SQUASHFS_CHRDEV_TYPE) ?  S_IFCHR :
-+					S_IFBLK;
-+			init_special_inode(i, i->i_mode,
-+					old_decode_dev(inodep->rdev));
-+
-+			TRACE("Device inode %x:%x, rdev %x\n",
-+					SQUASHFS_INODE_BLK(inode), offset,
-+					inodep->rdev);
-+			break;
-+		 }
-+		 case SQUASHFS_FIFO_TYPE:
-+		 case SQUASHFS_SOCKET_TYPE: {
-+			struct squashfs_ipc_inode_header *inodep = &id.ipc;
-+			struct squashfs_ipc_inode_header *sinodep = &sid.ipc;
-+
-+			if (msblk->swap) {
-+				if (!squashfs_get_cached_block(s, (char *)
-+						sinodep, block, offset,
-+						sizeof(*sinodep), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+				SQUASHFS_SWAP_IPC_INODE_HEADER(inodep, sinodep);
-+			} else
-+				if (!squashfs_get_cached_block(s, (char *)
-+						inodep, block, offset,
-+						sizeof(*inodep), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+
-+			if ((i = squashfs_new_inode(s, inodeb)) == NULL)
-+				goto failed_read1;
-+
-+			i->i_nlink = inodep->nlink;
-+			i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE)
-+							? S_IFIFO : S_IFSOCK;
-+			init_special_inode(i, i->i_mode, 0);
-+			break;
-+		 }
-+		 default:
-+			ERROR("Unknown inode type %d in squashfs_iget!\n",
-+					inodeb->inode_type);
-+			goto failed_read1;
-+	}
-+
-+	insert_inode_hash(i);
-+	return i;
-+
-+failed_read:
-+	ERROR("Unable to read inode [%llx:%x]\n", block, offset);
-+
-+failed_read1:
-+	return NULL;
-+}
-+
-+
-+static int read_fragment_index_table(struct super_block *s)
-+{
-+	struct squashfs_sb_info *msblk = s->s_fs_info;
-+	struct squashfs_super_block *sblk = &msblk->sblk;
-+
-+	/* Allocate fragment index table */
-+	if (!(msblk->fragment_index = kmalloc(SQUASHFS_FRAGMENT_INDEX_BYTES
-+					(sblk->fragments), GFP_KERNEL))) {
-+		ERROR("Failed to allocate uid/gid table\n");
-+		return 0;
-+	}
-+
-+	if (SQUASHFS_FRAGMENT_INDEX_BYTES(sblk->fragments) &&
-+					!squashfs_read_data(s, (char *)
-+					msblk->fragment_index,
-+					sblk->fragment_table_start,
-+					SQUASHFS_FRAGMENT_INDEX_BYTES
-+					(sblk->fragments) |
-+					SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {
-+		ERROR("unable to read fragment index table\n");
-+		return 0;
-+	}
-+
-+	if (msblk->swap) {
-+		int i;
-+		long long fragment;
-+
-+		for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES(sblk->fragments);
-+									i++) {
-+			SQUASHFS_SWAP_FRAGMENT_INDEXES((&fragment),
-+						&msblk->fragment_index[i], 1);
-+			msblk->fragment_index[i] = fragment;
-+		}
-+	}
-+
-+	return 1;
-+}
-+
-+
-+static int supported_squashfs_filesystem(struct squashfs_sb_info *msblk, int silent)
-+{
-+	struct squashfs_super_block *sblk = &msblk->sblk;
-+
-+	msblk->iget = squashfs_iget;
-+	msblk->read_blocklist = read_blocklist;
-+	msblk->read_fragment_index_table = read_fragment_index_table;
-+
-+	if (sblk->s_major == 1) {
-+		if (!squashfs_1_0_supported(msblk)) {
-+			SERROR("Major/Minor mismatch, Squashfs 1.0 filesystems "
-+				"are unsupported\n");
-+			SERROR("Please recompile with "
-+				"Squashfs 1.0 support enabled\n");
-+			return 0;
-+		}
-+	} else if (sblk->s_major == 2) {
-+		if (!squashfs_2_0_supported(msblk)) {
-+			SERROR("Major/Minor mismatch, Squashfs 2.0 filesystems "
-+				"are unsupported\n");
-+			SERROR("Please recompile with "
-+				"Squashfs 2.0 support enabled\n");
-+			return 0;
-+		}
-+	} else if(sblk->s_major != SQUASHFS_MAJOR || sblk->s_minor >
-+			SQUASHFS_MINOR) {
-+		SERROR("Major/Minor mismatch, trying to mount newer %d.%d "
-+				"filesystem\n", sblk->s_major, sblk->s_minor);
-+		SERROR("Please update your kernel\n");
-+		return 0;
-+	}
-+
-+	return 1;
-+}
-+
-+
-+static int squashfs_fill_super(struct super_block *s, void *data, int silent)
-+{
-+	struct squashfs_sb_info *msblk;
-+	struct squashfs_super_block *sblk;
-+	int i;
-+	char b[BDEVNAME_SIZE];
-+	struct inode *root;
-+
-+	TRACE("Entered squashfs_read_superblock\n");
-+
-+	if (!(s->s_fs_info = kmalloc(sizeof(struct squashfs_sb_info),
-+						GFP_KERNEL))) {
-+		ERROR("Failed to allocate superblock\n");
-+		goto failure;
-+	}
-+	memset(s->s_fs_info, 0, sizeof(struct squashfs_sb_info));
-+	msblk = s->s_fs_info;
-+	sblk = &msblk->sblk;
-+
-+	msblk->devblksize = sb_min_blocksize(s, BLOCK_SIZE);
-+	msblk->devblksize_log2 = ffz(~msblk->devblksize);
-+
-+	init_MUTEX(&msblk->read_data_mutex);
-+	init_MUTEX(&msblk->read_page_mutex);
-+	init_MUTEX(&msblk->block_cache_mutex);
-+	init_MUTEX(&msblk->fragment_mutex);
-+	init_MUTEX(&msblk->meta_index_mutex);
-+
-+	init_waitqueue_head(&msblk->waitq);
-+	init_waitqueue_head(&msblk->fragment_wait_queue);
-+
-+	if (!squashfs_read_data(s, (char *) sblk, SQUASHFS_START,
-+					sizeof(struct squashfs_super_block) |
-+					SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {
-+		SERROR("unable to read superblock\n");
-+		goto failed_mount;
-+	}
-+
-+	/* Check it is a SQUASHFS superblock */
-+	msblk->swap = 0;
-+	if ((s->s_magic = sblk->s_magic) != SQUASHFS_MAGIC) {
-+		if (sblk->s_magic == SQUASHFS_MAGIC_SWAP) {
-+			struct squashfs_super_block ssblk;
-+
-+			WARNING("Mounting a different endian SQUASHFS "
-+				"filesystem on %s\n", bdevname(s->s_bdev, b));
-+
-+			SQUASHFS_SWAP_SUPER_BLOCK(&ssblk, sblk);
-+			memcpy(sblk, &ssblk, sizeof(struct squashfs_super_block));
-+			msblk->swap = 1;
-+		} else  {
-+			SERROR("Can't find a SQUASHFS superblock on %s\n",
-+							bdevname(s->s_bdev, b));
-+			goto failed_mount;
-+		}
-+	}
-+
-+	/* Check the MAJOR & MINOR versions */
-+	if(!supported_squashfs_filesystem(msblk, silent))
-+		goto failed_mount;
-+
-+	TRACE("Found valid superblock on %s\n", bdevname(s->s_bdev, b));
-+	TRACE("Inodes are %scompressed\n",
-+					SQUASHFS_UNCOMPRESSED_INODES
-+					(sblk->flags) ? "un" : "");
-+	TRACE("Data is %scompressed\n",
-+					SQUASHFS_UNCOMPRESSED_DATA(sblk->flags)
-+					? "un" : "");
-+	TRACE("Check data is %s present in the filesystem\n",
-+					SQUASHFS_CHECK_DATA(sblk->flags) ?
-+					"" : "not");
-+	TRACE("Filesystem size %lld bytes\n", sblk->bytes_used);
-+	TRACE("Block size %d\n", sblk->block_size);
-+	TRACE("Number of inodes %d\n", sblk->inodes);
-+	if (sblk->s_major > 1)
-+		TRACE("Number of fragments %d\n", sblk->fragments);
-+	TRACE("Number of uids %d\n", sblk->no_uids);
-+	TRACE("Number of gids %d\n", sblk->no_guids);
-+	TRACE("sblk->inode_table_start %llx\n", sblk->inode_table_start);
-+	TRACE("sblk->directory_table_start %llx\n", sblk->directory_table_start);
-+	if (sblk->s_major > 1)
-+		TRACE("sblk->fragment_table_start %llx\n",
-+					sblk->fragment_table_start);
-+	TRACE("sblk->uid_start %llx\n", sblk->uid_start);
-+
-+	s->s_flags |= MS_RDONLY;
-+	s->s_op = &squashfs_ops;
-+
-+	/* Init inode_table block pointer array */
-+	if (!(msblk->block_cache = kmalloc(sizeof(struct squashfs_cache) *
-+					SQUASHFS_CACHED_BLKS, GFP_KERNEL))) {
-+		ERROR("Failed to allocate block cache\n");
-+		goto failed_mount;
-+	}
-+
-+	for (i = 0; i < SQUASHFS_CACHED_BLKS; i++)
-+		msblk->block_cache[i].block = SQUASHFS_INVALID_BLK;
-+
-+	msblk->next_cache = 0;
-+
-+	/* Allocate read_data block */
-+	msblk->read_size = (sblk->block_size < SQUASHFS_METADATA_SIZE) ?
-+					SQUASHFS_METADATA_SIZE :
-+					sblk->block_size;
-+
-+	if (!(msblk->read_data = kmalloc(msblk->read_size, GFP_KERNEL))) {
-+		ERROR("Failed to allocate read_data block\n");
-+		goto failed_mount;
-+	}
-+
-+	/* Allocate read_page block */
-+	if (!(msblk->read_page = kmalloc(sblk->block_size, GFP_KERNEL))) {
-+		ERROR("Failed to allocate read_page block\n");
-+		goto failed_mount;
-+	}
-+
-+	/* Allocate uid and gid tables */
-+	if (!(msblk->uid = kmalloc((sblk->no_uids + sblk->no_guids) *
-+					sizeof(unsigned int), GFP_KERNEL))) {
-+		ERROR("Failed to allocate uid/gid table\n");
-+		goto failed_mount;
-+	}
-+	msblk->guid = msblk->uid + sblk->no_uids;
-+
-+	if (msblk->swap) {
-+		unsigned int suid[sblk->no_uids + sblk->no_guids];
-+
-+		if (!squashfs_read_data(s, (char *) &suid, sblk->uid_start,
-+					((sblk->no_uids + sblk->no_guids) *
-+					 sizeof(unsigned int)) |
-+					SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {
-+			ERROR("unable to read uid/gid table\n");
-+			goto failed_mount;
-+		}
-+
-+		SQUASHFS_SWAP_DATA(msblk->uid, suid, (sblk->no_uids +
-+			sblk->no_guids), (sizeof(unsigned int) * 8));
-+	} else
-+		if (!squashfs_read_data(s, (char *) msblk->uid, sblk->uid_start,
-+					((sblk->no_uids + sblk->no_guids) *
-+					 sizeof(unsigned int)) |
-+					SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {
-+			ERROR("unable to read uid/gid table\n");
-+			goto failed_mount;
-+		}
-+
-+
-+	if (sblk->s_major == 1 && squashfs_1_0_supported(msblk))
-+		goto allocate_root;
-+
-+	if (!(msblk->fragment = kmalloc(sizeof(struct squashfs_fragment_cache) *
-+				SQUASHFS_CACHED_FRAGMENTS, GFP_KERNEL))) {
-+		ERROR("Failed to allocate fragment block cache\n");
-+		goto failed_mount;
-+	}
-+
-+	for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS; i++) {
-+		msblk->fragment[i].locked = 0;
-+		msblk->fragment[i].block = SQUASHFS_INVALID_BLK;
-+		msblk->fragment[i].data = NULL;
-+	}
-+
-+	msblk->next_fragment = 0;
-+
-+	/* Allocate fragment index table */
-+	if (msblk->read_fragment_index_table(s) == 0)
-+		goto failed_mount;
-+
-+allocate_root:
-+	if ((root = (msblk->iget)(s, sblk->root_inode)) == NULL)
-+		goto failed_mount;
-+
-+	if ((s->s_root = d_alloc_root(root)) == NULL) {
-+		ERROR("Root inode create failed\n");
-+		iput(root);
-+		goto failed_mount;
-+	}
-+
-+	TRACE("Leaving squashfs_read_super\n");
-+	return 0;
-+
-+failed_mount:
-+	kfree(msblk->fragment_index);
-+	kfree(msblk->fragment);
-+	kfree(msblk->uid);
-+	kfree(msblk->read_page);
-+	kfree(msblk->read_data);
-+	kfree(msblk->block_cache);
-+	kfree(msblk->fragment_index_2);
-+	kfree(s->s_fs_info);
-+	s->s_fs_info = NULL;
-+	return -EINVAL;
-+
-+failure:
-+	return -ENOMEM;
-+}
-+
-+
-+static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf)
-+{
-+	struct squashfs_sb_info *msblk = dentry->d_inode->i_sb->s_fs_info;
-+	struct squashfs_super_block *sblk = &msblk->sblk;
-+
-+	TRACE("Entered squashfs_statfs\n");
-+
-+	buf->f_type = SQUASHFS_MAGIC;
-+	buf->f_bsize = sblk->block_size;
-+	buf->f_blocks = ((sblk->bytes_used - 1) >> sblk->block_log) + 1;
-+	buf->f_bfree = buf->f_bavail = 0;
-+	buf->f_files = sblk->inodes;
-+	buf->f_ffree = 0;
-+	buf->f_namelen = SQUASHFS_NAME_LEN;
-+
-+	return 0;
-+}
-+
-+
-+static int squashfs_symlink_readpage(struct file *file, struct page *page)
-+{
-+	struct inode *inode = page->mapping->host;
-+	int index = page->index << PAGE_CACHE_SHIFT, length, bytes;
-+	long long block = SQUASHFS_I(inode)->start_block;
-+	int offset = SQUASHFS_I(inode)->offset;
-+	void *pageaddr = kmap(page);
-+
-+	TRACE("Entered squashfs_symlink_readpage, page index %ld, start block "
-+				"%llx, offset %x\n", page->index,
-+				SQUASHFS_I(inode)->start_block,
-+				SQUASHFS_I(inode)->offset);
-+
-+	for (length = 0; length < index; length += bytes) {
-+		if (!(bytes = squashfs_get_cached_block(inode->i_sb, NULL,
-+				block, offset, PAGE_CACHE_SIZE, &block,
-+				&offset))) {
-+			ERROR("Unable to read symbolic link [%llx:%x]\n", block,
-+					offset);
-+			goto skip_read;
-+		}
-+	}
-+
-+	if (length != index) {
-+		ERROR("(squashfs_symlink_readpage) length != index\n");
-+		bytes = 0;
-+		goto skip_read;
-+	}
-+
-+	bytes = (i_size_read(inode) - length) > PAGE_CACHE_SIZE ? PAGE_CACHE_SIZE :
-+					i_size_read(inode) - length;
-+
-+	if (!(bytes = squashfs_get_cached_block(inode->i_sb, pageaddr, block,
-+					offset, bytes, &block, &offset)))
-+		ERROR("Unable to read symbolic link [%llx:%x]\n", block, offset);
-+
-+skip_read:
-+	memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes);
-+	kunmap(page);
-+	SetPageUptodate(page);
-+	unlock_page(page);
-+
-+	return 0;
-+}
-+
-+
-+struct meta_index *locate_meta_index(struct inode *inode, int index, int offset)
-+{
-+	struct meta_index *meta = NULL;
-+	struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
-+	int i;
-+
-+	down(&msblk->meta_index_mutex);
-+
-+	TRACE("locate_meta_index: index %d, offset %d\n", index, offset);
-+
-+	if(msblk->meta_index == NULL)
-+		goto not_allocated;
-+
-+	for (i = 0; i < SQUASHFS_META_NUMBER; i ++)
-+		if (msblk->meta_index[i].inode_number == inode->i_ino &&
-+				msblk->meta_index[i].offset >= offset &&
-+				msblk->meta_index[i].offset <= index &&
-+				msblk->meta_index[i].locked == 0) {
-+			TRACE("locate_meta_index: entry %d, offset %d\n", i,
-+					msblk->meta_index[i].offset);
-+			meta = &msblk->meta_index[i];
-+			offset = meta->offset;
-+		}
-+
-+	if (meta)
-+		meta->locked = 1;
-+
-+not_allocated:
-+	up(&msblk->meta_index_mutex);
-+
-+	return meta;
-+}
-+
-+
-+struct meta_index *empty_meta_index(struct inode *inode, int offset, int skip)
-+{
-+	struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
-+	struct meta_index *meta = NULL;
-+	int i;
-+
-+	down(&msblk->meta_index_mutex);
-+
-+	TRACE("empty_meta_index: offset %d, skip %d\n", offset, skip);
-+
-+	if(msblk->meta_index == NULL) {
-+		if (!(msblk->meta_index = kmalloc(sizeof(struct meta_index) *
-+					SQUASHFS_META_NUMBER, GFP_KERNEL))) {
-+			ERROR("Failed to allocate meta_index\n");
-+			goto failed;
-+		}
-+		for(i = 0; i < SQUASHFS_META_NUMBER; i++) {
-+			msblk->meta_index[i].inode_number = 0;
-+			msblk->meta_index[i].locked = 0;
-+		}
-+		msblk->next_meta_index = 0;
-+	}
-+
-+	for(i = SQUASHFS_META_NUMBER; i &&
-+			msblk->meta_index[msblk->next_meta_index].locked; i --)
-+		msblk->next_meta_index = (msblk->next_meta_index + 1) %
-+			SQUASHFS_META_NUMBER;
-+
-+	if(i == 0) {
-+		TRACE("empty_meta_index: failed!\n");
-+		goto failed;
-+	}
-+
-+	TRACE("empty_meta_index: returned meta entry %d, %p\n",
-+			msblk->next_meta_index,
-+			&msblk->meta_index[msblk->next_meta_index]);
-+
-+	meta = &msblk->meta_index[msblk->next_meta_index];
-+	msblk->next_meta_index = (msblk->next_meta_index + 1) %
-+			SQUASHFS_META_NUMBER;
-+
-+	meta->inode_number = inode->i_ino;
-+	meta->offset = offset;
-+	meta->skip = skip;
-+	meta->entries = 0;
-+	meta->locked = 1;
-+
-+failed:
-+	up(&msblk->meta_index_mutex);
-+	return meta;
-+}
-+
-+
-+void release_meta_index(struct inode *inode, struct meta_index *meta)
-+{
-+	meta->locked = 0;
-+}
-+
-+
-+static int read_block_index(struct super_block *s, int blocks, char *block_list,
-+		long long *start_block, int *offset)
-+{
-+	struct squashfs_sb_info *msblk = s->s_fs_info;
-+	unsigned int *block_listp;
-+	int block = 0;
-+
-+	if (msblk->swap) {
-+		char sblock_list[blocks << 2];
-+
-+		if (!squashfs_get_cached_block(s, sblock_list, *start_block,
-+				*offset, blocks << 2, start_block, offset)) {
-+			ERROR("Unable to read block list [%llx:%x]\n",
-+				*start_block, *offset);
-+			goto failure;
-+		}
-+		SQUASHFS_SWAP_INTS(((unsigned int *)block_list),
-+				((unsigned int *)sblock_list), blocks);
-+	} else
-+		if (!squashfs_get_cached_block(s, block_list, *start_block,
-+				*offset, blocks << 2, start_block, offset)) {
-+			ERROR("Unable to read block list [%llx:%x]\n",
-+				*start_block, *offset);
-+			goto failure;
-+		}
-+
-+	for (block_listp = (unsigned int *) block_list; blocks;
-+				block_listp++, blocks --)
-+		block += SQUASHFS_COMPRESSED_SIZE_BLOCK(*block_listp);
-+
-+	return block;
-+
-+failure:
-+	return -1;
-+}
-+
-+
-+#define SIZE 256
-+
-+static inline int calculate_skip(int blocks) {
-+	int skip = (blocks - 1) / ((SQUASHFS_SLOTS * SQUASHFS_META_ENTRIES + 1) * SQUASHFS_META_INDEXES);
-+	return skip >= 7 ? 7 : skip + 1;
-+}
-+
-+
-+static int get_meta_index(struct inode *inode, int index,
-+		long long *index_block, int *index_offset,
-+		long long *data_block, char *block_list)
-+{
-+	struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
-+	struct squashfs_super_block *sblk = &msblk->sblk;
-+	int skip = calculate_skip(i_size_read(inode) >> sblk->block_log);
-+	int offset = 0;
-+	struct meta_index *meta;
-+	struct meta_entry *meta_entry;
-+	long long cur_index_block = SQUASHFS_I(inode)->u.s1.block_list_start;
-+	int cur_offset = SQUASHFS_I(inode)->offset;
-+	long long cur_data_block = SQUASHFS_I(inode)->start_block;
-+	int i;
-+
-+	index /= SQUASHFS_META_INDEXES * skip;
-+
-+	while ( offset < index ) {
-+		meta = locate_meta_index(inode, index, offset + 1);
-+
-+		if (meta == NULL) {
-+			if ((meta = empty_meta_index(inode, offset + 1,
-+							skip)) == NULL)
-+				goto all_done;
-+		} else {
-+			offset = index < meta->offset + meta->entries ? index :
-+				meta->offset + meta->entries - 1;
-+			meta_entry = &meta->meta_entry[offset - meta->offset];
-+			cur_index_block = meta_entry->index_block + sblk->inode_table_start;
-+			cur_offset = meta_entry->offset;
-+			cur_data_block = meta_entry->data_block;
-+			TRACE("get_meta_index: offset %d, meta->offset %d, "
-+				"meta->entries %d\n", offset, meta->offset,
-+				meta->entries);
-+			TRACE("get_meta_index: index_block 0x%llx, offset 0x%x"
-+				" data_block 0x%llx\n", cur_index_block,
-+				cur_offset, cur_data_block);
-+		}
-+
-+		for (i = meta->offset + meta->entries; i <= index &&
-+				i < meta->offset + SQUASHFS_META_ENTRIES; i++) {
-+			int blocks = skip * SQUASHFS_META_INDEXES;
-+
-+			while (blocks) {
-+				int block = blocks > (SIZE >> 2) ? (SIZE >> 2) :
-+					blocks;
-+				int res = read_block_index(inode->i_sb, block,
-+					block_list, &cur_index_block,
-+					&cur_offset);
-+
-+				if (res == -1)
-+					goto failed;
-+
-+				cur_data_block += res;
-+				blocks -= block;
-+			}
-+
-+			meta_entry = &meta->meta_entry[i - meta->offset];
-+			meta_entry->index_block = cur_index_block - sblk->inode_table_start;
-+			meta_entry->offset = cur_offset;
-+			meta_entry->data_block = cur_data_block;
-+			meta->entries ++;
-+			offset ++;
-+		}
-+
-+		TRACE("get_meta_index: meta->offset %d, meta->entries %d\n",
-+				meta->offset, meta->entries);
-+
-+		release_meta_index(inode, meta);
-+	}
-+
-+all_done:
-+	*index_block = cur_index_block;
-+	*index_offset = cur_offset;
-+	*data_block = cur_data_block;
-+
-+	return offset * SQUASHFS_META_INDEXES * skip;
-+
-+failed:
-+	release_meta_index(inode, meta);
-+	return -1;
-+}
-+
-+
-+static long long read_blocklist(struct inode *inode, int index,
-+				int readahead_blks, char *block_list,
-+				unsigned short **block_p, unsigned int *bsize)
-+{
-+	long long block_ptr;
-+	int offset;
-+	long long block;
-+	int res = get_meta_index(inode, index, &block_ptr, &offset, &block,
-+		block_list);
-+
-+	TRACE("read_blocklist: res %d, index %d, block_ptr 0x%llx, offset"
-+		       " 0x%x, block 0x%llx\n", res, index, block_ptr, offset,
-+		       block);
-+
-+	if(res == -1)
-+		goto failure;
-+
-+	index -= res;
-+
-+	while ( index ) {
-+		int blocks = index > (SIZE >> 2) ? (SIZE >> 2) : index;
-+		int res = read_block_index(inode->i_sb, blocks, block_list,
-+			&block_ptr, &offset);
-+		if (res == -1)
-+			goto failure;
-+		block += res;
-+		index -= blocks;
-+	}
-+
-+	if (read_block_index(inode->i_sb, 1, block_list,
-+			&block_ptr, &offset) == -1)
-+		goto failure;
-+	*bsize = *((unsigned int *) block_list);
-+
-+	return block;
-+
-+failure:
-+	return 0;
-+}
-+
-+
-+static int squashfs_readpage(struct file *file, struct page *page)
-+{
-+	struct inode *inode = page->mapping->host;
-+	struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
-+	struct squashfs_super_block *sblk = &msblk->sblk;
-+	unsigned char block_list[SIZE];
-+	long long block;
-+	unsigned int bsize, i = 0, bytes = 0, byte_offset = 0;
-+	int index = page->index >> (sblk->block_log - PAGE_CACHE_SHIFT);
-+ 	void *pageaddr;
-+	struct squashfs_fragment_cache *fragment = NULL;
-+	char *data_ptr = msblk->read_page;
-+
-+	int mask = (1 << (sblk->block_log - PAGE_CACHE_SHIFT)) - 1;
-+	int start_index = page->index & ~mask;
-+	int end_index = start_index | mask;
-+
-+	TRACE("Entered squashfs_readpage, page index %lx, start block %llx\n",
-+					page->index,
-+					SQUASHFS_I(inode)->start_block);
-+
-+	if (page->index >= ((i_size_read(inode) + PAGE_CACHE_SIZE - 1) >>
-+					PAGE_CACHE_SHIFT))
-+		goto skip_read;
-+
-+	if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK
-+					|| index < (i_size_read(inode) >>
-+					sblk->block_log)) {
-+		if ((block = (msblk->read_blocklist)(inode, index, 1,
-+					block_list, NULL, &bsize)) == 0)
-+			goto skip_read;
-+
-+		down(&msblk->read_page_mutex);
-+
-+		if (!(bytes = squashfs_read_data(inode->i_sb, msblk->read_page,
-+					block, bsize, NULL))) {
-+			ERROR("Unable to read page, block %llx, size %x\n", block,
-+					bsize);
-+			up(&msblk->read_page_mutex);
-+			goto skip_read;
-+		}
-+	} else {
-+		if ((fragment = get_cached_fragment(inode->i_sb,
-+					SQUASHFS_I(inode)->
-+					u.s1.fragment_start_block,
-+					SQUASHFS_I(inode)->u.s1.fragment_size))
-+					== NULL) {
-+			ERROR("Unable to read page, block %llx, size %x\n",
-+					SQUASHFS_I(inode)->
-+					u.s1.fragment_start_block,
-+					(int) SQUASHFS_I(inode)->
-+					u.s1.fragment_size);
-+			goto skip_read;
-+		}
-+		bytes = SQUASHFS_I(inode)->u.s1.fragment_offset +
-+					(i_size_read(inode) & (sblk->block_size
-+					- 1));
-+		byte_offset = SQUASHFS_I(inode)->u.s1.fragment_offset;
-+		data_ptr = fragment->data;
-+	}
-+
-+	for (i = start_index; i <= end_index && byte_offset < bytes;
-+					i++, byte_offset += PAGE_CACHE_SIZE) {
-+		struct page *push_page;
-+		int available_bytes = (bytes - byte_offset) > PAGE_CACHE_SIZE ?
-+					PAGE_CACHE_SIZE : bytes - byte_offset;
-+
-+		TRACE("bytes %d, i %d, byte_offset %d, available_bytes %d\n",
-+					bytes, i, byte_offset, available_bytes);
-+
-+		if (i == page->index)  {
-+			pageaddr = kmap_atomic(page, KM_USER0);
-+			memcpy(pageaddr, data_ptr + byte_offset,
-+					available_bytes);
-+			memset(pageaddr + available_bytes, 0,
-+					PAGE_CACHE_SIZE - available_bytes);
-+			kunmap_atomic(pageaddr, KM_USER0);
-+			flush_dcache_page(page);
-+			SetPageUptodate(page);
-+			unlock_page(page);
-+		} else if ((push_page =
-+				grab_cache_page_nowait(page->mapping, i))) {
-+ 			pageaddr = kmap_atomic(push_page, KM_USER0);
-+
-+			memcpy(pageaddr, data_ptr + byte_offset,
-+					available_bytes);
-+			memset(pageaddr + available_bytes, 0,
-+					PAGE_CACHE_SIZE - available_bytes);
-+			kunmap_atomic(pageaddr, KM_USER0);
-+			flush_dcache_page(push_page);
-+			SetPageUptodate(push_page);
-+			unlock_page(push_page);
-+			page_cache_release(push_page);
-+		}
-+	}
-+
-+	if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK
-+					|| index < (i_size_read(inode) >>
-+					sblk->block_log))
-+		up(&msblk->read_page_mutex);
-+	else
-+		release_cached_fragment(msblk, fragment);
-+
-+	return 0;
-+
-+skip_read:
-+	pageaddr = kmap_atomic(page, KM_USER0);
-+	memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes);
-+	kunmap_atomic(pageaddr, KM_USER0);
-+	flush_dcache_page(page);
-+	SetPageUptodate(page);
-+	unlock_page(page);
-+
-+	return 0;
-+}
-+
-+
-+static int squashfs_readpage4K(struct file *file, struct page *page)
-+{
-+	struct inode *inode = page->mapping->host;
-+	struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
-+	struct squashfs_super_block *sblk = &msblk->sblk;
-+	unsigned char block_list[SIZE];
-+	long long block;
-+	unsigned int bsize, bytes = 0;
-+ 	void *pageaddr;
-+
-+	TRACE("Entered squashfs_readpage4K, page index %lx, start block %llx\n",
-+					page->index,
-+					SQUASHFS_I(inode)->start_block);
-+
-+	if (page->index >= ((i_size_read(inode) + PAGE_CACHE_SIZE - 1) >>
-+					PAGE_CACHE_SHIFT)) {
-+		pageaddr = kmap_atomic(page, KM_USER0);
-+		goto skip_read;
-+	}
-+
-+	if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK
-+					|| page->index < (i_size_read(inode) >>
-+					sblk->block_log)) {
-+		block = (msblk->read_blocklist)(inode, page->index, 1,
-+					block_list, NULL, &bsize);
-+
-+		down(&msblk->read_page_mutex);
-+		bytes = squashfs_read_data(inode->i_sb, msblk->read_page, block,
-+					bsize, NULL);
-+		pageaddr = kmap_atomic(page, KM_USER0);
-+		if (bytes)
-+			memcpy(pageaddr, msblk->read_page, bytes);
-+		else
-+			ERROR("Unable to read page, block %llx, size %x\n",
-+					block, bsize);
-+		up(&msblk->read_page_mutex);
-+	} else {
-+		struct squashfs_fragment_cache *fragment =
-+			get_cached_fragment(inode->i_sb,
-+					SQUASHFS_I(inode)->
-+					u.s1.fragment_start_block,
-+					SQUASHFS_I(inode)-> u.s1.fragment_size);
-+		pageaddr = kmap_atomic(page, KM_USER0);
-+		if (fragment) {
-+			bytes = i_size_read(inode) & (sblk->block_size - 1);
-+			memcpy(pageaddr, fragment->data + SQUASHFS_I(inode)->
-+					u.s1.fragment_offset, bytes);
-+			release_cached_fragment(msblk, fragment);
-+		} else
-+			ERROR("Unable to read page, block %llx, size %x\n",
-+					SQUASHFS_I(inode)->
-+					u.s1.fragment_start_block, (int)
-+					SQUASHFS_I(inode)-> u.s1.fragment_size);
-+	}
-+
-+skip_read:
-+	memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes);
-+	kunmap_atomic(pageaddr, KM_USER0);
-+	flush_dcache_page(page);
-+	SetPageUptodate(page);
-+	unlock_page(page);
-+
-+	return 0;
-+}
-+
-+
-+static int get_dir_index_using_offset(struct super_block *s, long long
-+				*next_block, unsigned int *next_offset,
-+				long long index_start,
-+				unsigned int index_offset, int i_count,
-+				long long f_pos)
-+{
-+	struct squashfs_sb_info *msblk = s->s_fs_info;
-+	struct squashfs_super_block *sblk = &msblk->sblk;
-+	int i, length = 0;
-+	struct squashfs_dir_index index;
-+
-+	TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n",
-+					i_count, (unsigned int) f_pos);
-+
-+	f_pos =- 3;
-+	if (f_pos == 0)
-+		goto finish;
-+
-+	for (i = 0; i < i_count; i++) {
-+		if (msblk->swap) {
-+			struct squashfs_dir_index sindex;
-+			squashfs_get_cached_block(s, (char *) &sindex,
-+					index_start, index_offset,
-+					sizeof(sindex), &index_start,
-+					&index_offset);
-+			SQUASHFS_SWAP_DIR_INDEX(&index, &sindex);
-+		} else
-+			squashfs_get_cached_block(s, (char *) &index,
-+					index_start, index_offset,
-+					sizeof(index), &index_start,
-+					&index_offset);
-+
-+		if (index.index > f_pos)
-+			break;
-+
-+		squashfs_get_cached_block(s, NULL, index_start, index_offset,
-+					index.size + 1, &index_start,
-+					&index_offset);
-+
-+		length = index.index;
-+		*next_block = index.start_block + sblk->directory_table_start;
-+	}
-+
-+	*next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
-+
-+finish:
-+	return length + 3;
-+}
-+
-+
-+static int get_dir_index_using_name(struct super_block *s, long long
-+				*next_block, unsigned int *next_offset,
-+				long long index_start,
-+				unsigned int index_offset, int i_count,
-+				const char *name, int size)
-+{
-+	struct squashfs_sb_info *msblk = s->s_fs_info;
-+	struct squashfs_super_block *sblk = &msblk->sblk;
-+	int i, length = 0;
-+	char buffer[sizeof(struct squashfs_dir_index) + SQUASHFS_NAME_LEN + 1];
-+	struct squashfs_dir_index *index = (struct squashfs_dir_index *) buffer;
-+	char str[SQUASHFS_NAME_LEN + 1];
-+
-+	TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count);
-+
-+	strncpy(str, name, size);
-+	str[size] = '\0';
-+
-+	for (i = 0; i < i_count; i++) {
-+		if (msblk->swap) {
-+			struct squashfs_dir_index sindex;
-+			squashfs_get_cached_block(s, (char *) &sindex,
-+					index_start, index_offset,
-+					sizeof(sindex), &index_start,
-+					&index_offset);
-+			SQUASHFS_SWAP_DIR_INDEX(index, &sindex);
-+		} else
-+			squashfs_get_cached_block(s, (char *) index,
-+					index_start, index_offset,
-+					sizeof(struct squashfs_dir_index),
-+					&index_start, &index_offset);
-+
-+		squashfs_get_cached_block(s, index->name, index_start,
-+					index_offset, index->size + 1,
-+					&index_start, &index_offset);
-+
-+		index->name[index->size + 1] = '\0';
-+
-+		if (strcmp(index->name, str) > 0)
-+			break;
-+
-+		length = index->index;
-+		*next_block = index->start_block + sblk->directory_table_start;
-+	}
-+
-+	*next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
-+	return length + 3;
-+}
-+
-+
-+static int squashfs_readdir(struct file *file, void *dirent, filldir_t filldir)
-+{
-+	struct inode *i = file->f_dentry->d_inode;
-+	struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
-+	struct squashfs_super_block *sblk = &msblk->sblk;
-+	long long next_block = SQUASHFS_I(i)->start_block +
-+		sblk->directory_table_start;
-+	int next_offset = SQUASHFS_I(i)->offset, length = 0, dirs_read = 0,
-+		dir_count;
-+	struct squashfs_dir_header dirh;
-+	char buffer[sizeof(struct squashfs_dir_entry) + SQUASHFS_NAME_LEN + 1];
-+	struct squashfs_dir_entry *dire = (struct squashfs_dir_entry *) buffer;
-+
-+	TRACE("Entered squashfs_readdir [%llx:%x]\n", next_block, next_offset);
-+
-+	while(file->f_pos < 3) {
-+		char *name;
-+		int size, i_ino;
-+
-+		if(file->f_pos == 0) {
-+			name = ".";
-+			size = 1;
-+			i_ino = i->i_ino;
-+		} else {
-+			name = "..";
-+			size = 2;
-+			i_ino = SQUASHFS_I(i)->u.s2.parent_inode;
-+		}
-+		TRACE("Calling filldir(%x, %s, %d, %d, %d, %d)\n",
-+				(unsigned int) dirent, name, size, (int)
-+				file->f_pos, i_ino,
-+				squashfs_filetype_table[1]);
-+
-+		if (filldir(dirent, name, size,
-+				file->f_pos, i_ino,
-+				squashfs_filetype_table[1]) < 0) {
-+				TRACE("Filldir returned less than 0\n");
-+				goto finish;
-+		}
-+		file->f_pos += size;
-+		dirs_read++;
-+	}
-+
-+	length = get_dir_index_using_offset(i->i_sb, &next_block, &next_offset,
-+				SQUASHFS_I(i)->u.s2.directory_index_start,
-+				SQUASHFS_I(i)->u.s2.directory_index_offset,
-+				SQUASHFS_I(i)->u.s2.directory_index_count,
-+				file->f_pos);
-+
-+	while (length < i_size_read(i)) {
-+		/* read directory header */
-+		if (msblk->swap) {
-+			struct squashfs_dir_header sdirh;
-+
-+			if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh,
-+					next_block, next_offset, sizeof(sdirh),
-+					&next_block, &next_offset))
-+				goto failed_read;
-+
-+			length += sizeof(sdirh);
-+			SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh);
-+		} else {
-+			if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh,
-+					next_block, next_offset, sizeof(dirh),
-+					&next_block, &next_offset))
-+				goto failed_read;
-+
-+			length += sizeof(dirh);
-+		}
-+
-+		dir_count = dirh.count + 1;
-+		while (dir_count--) {
-+			if (msblk->swap) {
-+				struct squashfs_dir_entry sdire;
-+				if (!squashfs_get_cached_block(i->i_sb, (char *)
-+						&sdire, next_block, next_offset,
-+						sizeof(sdire), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+
-+				length += sizeof(sdire);
-+				SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire);
-+			} else {
-+				if (!squashfs_get_cached_block(i->i_sb, (char *)
-+						dire, next_block, next_offset,
-+						sizeof(*dire), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+
-+				length += sizeof(*dire);
-+			}
-+
-+			if (!squashfs_get_cached_block(i->i_sb, dire->name,
-+						next_block, next_offset,
-+						dire->size + 1, &next_block,
-+						&next_offset))
-+				goto failed_read;
-+
-+			length += dire->size + 1;
-+
-+			if (file->f_pos >= length)
-+				continue;
-+
-+			dire->name[dire->size + 1] = '\0';
-+
-+			TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d, %d)\n",
-+					(unsigned int) dirent, dire->name,
-+					dire->size + 1, (int) file->f_pos,
-+					dirh.start_block, dire->offset,
-+					dirh.inode_number + dire->inode_number,
-+					squashfs_filetype_table[dire->type]);
-+
-+			if (filldir(dirent, dire->name, dire->size + 1,
-+					file->f_pos,
-+					dirh.inode_number + dire->inode_number,
-+					squashfs_filetype_table[dire->type])
-+					< 0) {
-+				TRACE("Filldir returned less than 0\n");
-+				goto finish;
-+			}
-+			file->f_pos = length;
-+			dirs_read++;
-+		}
-+	}
-+
-+finish:
-+	return dirs_read;
-+
-+failed_read:
-+	ERROR("Unable to read directory block [%llx:%x]\n", next_block,
-+		next_offset);
-+	return 0;
-+}
-+
-+
-+static struct dentry *squashfs_lookup(struct inode *i, struct dentry *dentry,
-+				struct nameidata *nd)
-+{
-+	const unsigned char *name = dentry->d_name.name;
-+	int len = dentry->d_name.len;
-+	struct inode *inode = NULL;
-+	struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
-+	struct squashfs_super_block *sblk = &msblk->sblk;
-+	long long next_block = SQUASHFS_I(i)->start_block +
-+				sblk->directory_table_start;
-+	int next_offset = SQUASHFS_I(i)->offset, length = 0,
-+				dir_count;
-+	struct squashfs_dir_header dirh;
-+	char buffer[sizeof(struct squashfs_dir_entry) + SQUASHFS_NAME_LEN];
-+	struct squashfs_dir_entry *dire = (struct squashfs_dir_entry *) buffer;
-+
-+	TRACE("Entered squashfs_lookup [%llx:%x]\n", next_block, next_offset);
-+
-+	if (len > SQUASHFS_NAME_LEN)
-+		goto exit_loop;
-+
-+	length = get_dir_index_using_name(i->i_sb, &next_block, &next_offset,
-+				SQUASHFS_I(i)->u.s2.directory_index_start,
-+				SQUASHFS_I(i)->u.s2.directory_index_offset,
-+				SQUASHFS_I(i)->u.s2.directory_index_count, name,
-+				len);
-+
-+	while (length < i_size_read(i)) {
-+		/* read directory header */
-+		if (msblk->swap) {
-+			struct squashfs_dir_header sdirh;
-+			if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh,
-+					next_block, next_offset, sizeof(sdirh),
-+					&next_block, &next_offset))
-+				goto failed_read;
-+
-+			length += sizeof(sdirh);
-+			SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh);
-+		} else {
-+			if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh,
-+					next_block, next_offset, sizeof(dirh),
-+					&next_block, &next_offset))
-+				goto failed_read;
-+
-+			length += sizeof(dirh);
-+		}
-+
-+		dir_count = dirh.count + 1;
-+		while (dir_count--) {
-+			if (msblk->swap) {
-+				struct squashfs_dir_entry sdire;
-+				if (!squashfs_get_cached_block(i->i_sb, (char *)
-+						&sdire, next_block,next_offset,
-+						sizeof(sdire), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+
-+				length += sizeof(sdire);
-+				SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire);
-+			} else {
-+				if (!squashfs_get_cached_block(i->i_sb, (char *)
-+						dire, next_block,next_offset,
-+						sizeof(*dire), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+
-+				length += sizeof(*dire);
-+			}
-+
-+			if (!squashfs_get_cached_block(i->i_sb, dire->name,
-+					next_block, next_offset, dire->size + 1,
-+					&next_block, &next_offset))
-+				goto failed_read;
-+
-+			length += dire->size + 1;
-+
-+			if (name[0] < dire->name[0])
-+				goto exit_loop;
-+
-+			if ((len == dire->size + 1) && !strncmp(name,
-+						dire->name, len)) {
-+				squashfs_inode_t ino =
-+					SQUASHFS_MKINODE(dirh.start_block,
-+					dire->offset);
-+
-+				TRACE("calling squashfs_iget for directory "
-+					"entry %s, inode %x:%x, %d\n", name,
-+					dirh.start_block, dire->offset,
-+					dirh.inode_number + dire->inode_number);
-+
-+				inode = (msblk->iget)(i->i_sb, ino);
-+
-+				goto exit_loop;
-+			}
-+		}
-+	}
-+
-+exit_loop:
-+	d_add(dentry, inode);
-+	return ERR_PTR(0);
-+
-+failed_read:
-+	ERROR("Unable to read directory block [%llx:%x]\n", next_block,
-+		next_offset);
-+	goto exit_loop;
-+}
-+
-+
-+static void squashfs_put_super(struct super_block *s)
-+{
-+	int i;
-+
-+	if (s->s_fs_info) {
-+		struct squashfs_sb_info *sbi = s->s_fs_info;
-+		if (sbi->block_cache)
-+			for (i = 0; i < SQUASHFS_CACHED_BLKS; i++)
-+				if (sbi->block_cache[i].block !=
-+							SQUASHFS_INVALID_BLK)
-+					kfree(sbi->block_cache[i].data);
-+		if (sbi->fragment)
-+			for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS; i++)
-+				SQUASHFS_FREE(sbi->fragment[i].data);
-+		kfree(sbi->fragment);
-+		kfree(sbi->block_cache);
-+		kfree(sbi->read_data);
-+		kfree(sbi->read_page);
-+		kfree(sbi->uid);
-+		kfree(sbi->fragment_index);
-+		kfree(sbi->fragment_index_2);
-+		kfree(sbi->meta_index);
-+		kfree(s->s_fs_info);
-+		s->s_fs_info = NULL;
-+	}
-+}
-+
-+
-+static int squashfs_get_sb(struct file_system_type *fs_type,
-+			int flags, const char *dev_name, void *data,
-+			struct vfsmount *mnt)
-+{
-+	return get_sb_bdev(fs_type, flags, dev_name, data, squashfs_fill_super, mnt);
-+}
-+
-+
-+static int __init init_squashfs_fs(void)
-+{
-+	int err = init_inodecache();
-+	if (err)
-+		goto out;
-+
-+	printk(KERN_INFO "squashfs: version 3.0 (2006/03/15) "
-+		"Phillip Lougher\n");
-+
-+	if (!(stream.workspace = vmalloc(zlib_inflate_workspacesize()))) {
-+		ERROR("Failed to allocate zlib workspace\n");
-+		destroy_inodecache();
-+		err = -ENOMEM;
-+		goto out;
-+	}
-+
-+	if ((err = register_filesystem(&squashfs_fs_type))) {
-+		vfree(stream.workspace);
-+		destroy_inodecache();
-+	}
-+
-+out:
-+	return err;
-+}
-+
-+
-+static void __exit exit_squashfs_fs(void)
-+{
-+	vfree(stream.workspace);
-+	unregister_filesystem(&squashfs_fs_type);
-+	destroy_inodecache();
-+}
-+
-+
-+static struct kmem_cache * squashfs_inode_cachep;
-+
-+
-+static struct inode *squashfs_alloc_inode(struct super_block *sb)
-+{
-+	struct squashfs_inode_info *ei;
-+	ei = kmem_cache_alloc(squashfs_inode_cachep, GFP_KERNEL);
-+	if (!ei)
-+		return NULL;
-+	return &ei->vfs_inode;
-+}
-+
-+
-+static void squashfs_destroy_inode(struct inode *inode)
-+{
-+	kmem_cache_free(squashfs_inode_cachep, SQUASHFS_I(inode));
-+}
-+
-+
-+static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
-+{
-+	struct squashfs_inode_info *ei = foo;
-+
-+	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
-+							SLAB_CTOR_CONSTRUCTOR)
-+		inode_init_once(&ei->vfs_inode);
-+}
-+
-+
-+static int __init init_inodecache(void)
-+{
-+	squashfs_inode_cachep = kmem_cache_create("squashfs_inode_cache",
-+	     sizeof(struct squashfs_inode_info),
-+	     0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
-+	     init_once, NULL);
-+	if (squashfs_inode_cachep == NULL)
-+		return -ENOMEM;
-+	return 0;
-+}
-+
-+
-+static void destroy_inodecache(void)
-+{
-+	kmem_cache_destroy(squashfs_inode_cachep);
-+}
-+
-+
-+module_init(init_squashfs_fs);
-+module_exit(exit_squashfs_fs);
-+MODULE_DESCRIPTION("squashfs, a compressed read-only filesystem");
-+MODULE_AUTHOR("Phillip Lougher <[email protected]>");
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/fs/squashfs/Makefile
-@@ -0,0 +1,7 @@
-+#
-+# Makefile for the linux squashfs routines.
-+#
-+
-+obj-$(CONFIG_SQUASHFS) += squashfs.o
-+squashfs-y += inode.o
-+squashfs-y += squashfs2_0.o
---- /dev/null
-+++ b/fs/squashfs/squashfs2_0.c
-@@ -0,0 +1,758 @@
-+/*
-+ * Squashfs - a compressed read only filesystem for Linux
-+ *
-+ * Copyright (c) 2002, 2003, 2004, 2005, 2006
-+ * Phillip Lougher <[email protected]>
-+ *
-+ * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * squashfs2_0.c
-+ */
-+
-+#include <linux/types.h>
-+#include <linux/squashfs_fs.h>
-+#include <linux/module.h>
-+#include <linux/errno.h>
-+#include <linux/slab.h>
-+#include <linux/fs.h>
-+#include <linux/smp_lock.h>
-+#include <linux/slab.h>
-+#include <linux/squashfs_fs_sb.h>
-+#include <linux/squashfs_fs_i.h>
-+#include <linux/buffer_head.h>
-+#include <linux/vfs.h>
-+#include <linux/init.h>
-+#include <linux/dcache.h>
-+#include <linux/wait.h>
-+#include <linux/zlib.h>
-+#include <linux/blkdev.h>
-+#include <linux/vmalloc.h>
-+#include <asm/uaccess.h>
-+#include <asm/semaphore.h>
-+
-+#include "squashfs.h"
-+static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir);
-+static struct dentry *squashfs_lookup_2(struct inode *, struct dentry *,
-+				struct nameidata *);
-+
-+static struct file_operations squashfs_dir_ops_2 = {
-+	.read = generic_read_dir,
-+	.readdir = squashfs_readdir_2
-+};
-+
-+static struct inode_operations squashfs_dir_inode_ops_2 = {
-+	.lookup = squashfs_lookup_2
-+};
-+
-+static unsigned char squashfs_filetype_table[] = {
-+	DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK
-+};
-+
-+static int read_fragment_index_table_2(struct super_block *s)
-+{
-+	struct squashfs_sb_info *msblk = s->s_fs_info;
-+	struct squashfs_super_block *sblk = &msblk->sblk;
-+
-+	if (!(msblk->fragment_index_2 = kmalloc(SQUASHFS_FRAGMENT_INDEX_BYTES_2
-+					(sblk->fragments), GFP_KERNEL))) {
-+		ERROR("Failed to allocate uid/gid table\n");
-+		return 0;
-+	}
-+
-+	if (SQUASHFS_FRAGMENT_INDEX_BYTES_2(sblk->fragments) &&
-+					!squashfs_read_data(s, (char *)
-+					msblk->fragment_index_2,
-+					sblk->fragment_table_start,
-+					SQUASHFS_FRAGMENT_INDEX_BYTES_2
-+					(sblk->fragments) |
-+					SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {
-+		ERROR("unable to read fragment index table\n");
-+		return 0;
-+	}
-+
-+	if (msblk->swap) {
-+		int i;
-+		unsigned int fragment;
-+
-+		for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES_2(sblk->fragments);
-+									i++) {
-+			SQUASHFS_SWAP_FRAGMENT_INDEXES_2((&fragment),
-+						&msblk->fragment_index_2[i], 1);
-+			msblk->fragment_index_2[i] = fragment;
-+		}
-+	}
-+
-+	return 1;
-+}
-+
-+
-+static int get_fragment_location_2(struct super_block *s, unsigned int fragment,
-+				long long *fragment_start_block,
-+				unsigned int *fragment_size)
-+{
-+	struct squashfs_sb_info *msblk = s->s_fs_info;
-+	long long start_block =
-+		msblk->fragment_index_2[SQUASHFS_FRAGMENT_INDEX_2(fragment)];
-+	int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET_2(fragment);
-+	struct squashfs_fragment_entry_2 fragment_entry;
-+
-+	if (msblk->swap) {
-+		struct squashfs_fragment_entry_2 sfragment_entry;
-+
-+		if (!squashfs_get_cached_block(s, (char *) &sfragment_entry,
-+					start_block, offset,
-+					sizeof(sfragment_entry), &start_block,
-+					&offset))
-+			goto out;
-+		SQUASHFS_SWAP_FRAGMENT_ENTRY_2(&fragment_entry, &sfragment_entry);
-+	} else
-+		if (!squashfs_get_cached_block(s, (char *) &fragment_entry,
-+					start_block, offset,
-+					sizeof(fragment_entry), &start_block,
-+					&offset))
-+			goto out;
-+
-+	*fragment_start_block = fragment_entry.start_block;
-+	*fragment_size = fragment_entry.size;
-+
-+	return 1;
-+
-+out:
-+	return 0;
-+}
-+
-+
-+static struct inode *squashfs_new_inode(struct super_block *s,
-+		struct squashfs_base_inode_header_2 *inodeb, unsigned int ino)
-+{
-+	struct squashfs_sb_info *msblk = s->s_fs_info;
-+	struct squashfs_super_block *sblk = &msblk->sblk;
-+	struct inode *i = new_inode(s);
-+
-+	if (i) {
-+		i->i_ino = ino;
-+		i->i_mtime.tv_sec = sblk->mkfs_time;
-+		i->i_atime.tv_sec = sblk->mkfs_time;
-+		i->i_ctime.tv_sec = sblk->mkfs_time;
-+		i->i_uid = msblk->uid[inodeb->uid];
-+		i->i_mode = inodeb->mode;
-+		i->i_nlink = 1;
-+		i->i_size = 0;
-+		if (inodeb->guid == SQUASHFS_GUIDS)
-+			i->i_gid = i->i_uid;
-+		else
-+			i->i_gid = msblk->guid[inodeb->guid];
-+	}
-+
-+	return i;
-+}
-+
-+
-+static struct inode *squashfs_iget_2(struct super_block *s, squashfs_inode_t inode)
-+{
-+	struct inode *i;
-+	struct squashfs_sb_info *msblk = s->s_fs_info;
-+	struct squashfs_super_block *sblk = &msblk->sblk;
-+	unsigned int block = SQUASHFS_INODE_BLK(inode) +
-+		sblk->inode_table_start;
-+	unsigned int offset = SQUASHFS_INODE_OFFSET(inode);
-+	unsigned int ino = SQUASHFS_MK_VFS_INODE(block
-+		- sblk->inode_table_start, offset);
-+	long long next_block;
-+	unsigned int next_offset;
-+	union squashfs_inode_header_2 id, sid;
-+	struct squashfs_base_inode_header_2 *inodeb = &id.base,
-+					  *sinodeb = &sid.base;
-+
-+	TRACE("Entered squashfs_iget\n");
-+
-+	if (msblk->swap) {
-+		if (!squashfs_get_cached_block(s, (char *) sinodeb, block,
-+					offset, sizeof(*sinodeb), &next_block,
-+					&next_offset))
-+			goto failed_read;
-+		SQUASHFS_SWAP_BASE_INODE_HEADER_2(inodeb, sinodeb,
-+					sizeof(*sinodeb));
-+	} else
-+		if (!squashfs_get_cached_block(s, (char *) inodeb, block,
-+					offset, sizeof(*inodeb), &next_block,
-+					&next_offset))
-+			goto failed_read;
-+
-+	switch(inodeb->inode_type) {
-+		case SQUASHFS_FILE_TYPE: {
-+			struct squashfs_reg_inode_header_2 *inodep = &id.reg;
-+			struct squashfs_reg_inode_header_2 *sinodep = &sid.reg;
-+			long long frag_blk;
-+			unsigned int frag_size;
-+
-+			if (msblk->swap) {
-+				if (!squashfs_get_cached_block(s, (char *)
-+						sinodep, block, offset,
-+						sizeof(*sinodep), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+				SQUASHFS_SWAP_REG_INODE_HEADER_2(inodep, sinodep);
-+			} else
-+				if (!squashfs_get_cached_block(s, (char *)
-+						inodep, block, offset,
-+						sizeof(*inodep), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+
-+			frag_blk = SQUASHFS_INVALID_BLK;
-+			if (inodep->fragment != SQUASHFS_INVALID_FRAG &&
-+					!get_fragment_location_2(s,
-+					inodep->fragment, &frag_blk, &frag_size))
-+				goto failed_read;
-+
-+			if((i = squashfs_new_inode(s, inodeb, ino)) == NULL)
-+				goto failed_read1;
-+
-+			i->i_size = inodep->file_size;
-+			i->i_fop = &generic_ro_fops;
-+			i->i_mode |= S_IFREG;
-+			i->i_mtime.tv_sec = inodep->mtime;
-+			i->i_atime.tv_sec = inodep->mtime;
-+			i->i_ctime.tv_sec = inodep->mtime;
-+			i->i_blocks = ((i->i_size - 1) >> 9) + 1;
-+			i->i_blksize = PAGE_CACHE_SIZE;
-+			SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk;
-+			SQUASHFS_I(i)->u.s1.fragment_size = frag_size;
-+			SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset;
-+			SQUASHFS_I(i)->start_block = inodep->start_block;
-+			SQUASHFS_I(i)->u.s1.block_list_start = next_block;
-+			SQUASHFS_I(i)->offset = next_offset;
-+			if (sblk->block_size > 4096)
-+				i->i_data.a_ops = &squashfs_aops;
-+			else
-+				i->i_data.a_ops = &squashfs_aops_4K;
-+
-+			TRACE("File inode %x:%x, start_block %x, "
-+					"block_list_start %llx, offset %x\n",
-+					SQUASHFS_INODE_BLK(inode), offset,
-+					inodep->start_block, next_block,
-+					next_offset);
-+			break;
-+		}
-+		case SQUASHFS_DIR_TYPE: {
-+			struct squashfs_dir_inode_header_2 *inodep = &id.dir;
-+			struct squashfs_dir_inode_header_2 *sinodep = &sid.dir;
-+
-+			if (msblk->swap) {
-+				if (!squashfs_get_cached_block(s, (char *)
-+						sinodep, block, offset,
-+						sizeof(*sinodep), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+				SQUASHFS_SWAP_DIR_INODE_HEADER_2(inodep, sinodep);
-+			} else
-+				if (!squashfs_get_cached_block(s, (char *)
-+						inodep, block, offset,
-+						sizeof(*inodep), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+
-+			if((i = squashfs_new_inode(s, inodeb, ino)) == NULL)
-+				goto failed_read1;
-+
-+			i->i_size = inodep->file_size;
-+			i->i_op = &squashfs_dir_inode_ops_2;
-+			i->i_fop = &squashfs_dir_ops_2;
-+			i->i_mode |= S_IFDIR;
-+			i->i_mtime.tv_sec = inodep->mtime;
-+			i->i_atime.tv_sec = inodep->mtime;
-+			i->i_ctime.tv_sec = inodep->mtime;
-+			SQUASHFS_I(i)->start_block = inodep->start_block;
-+			SQUASHFS_I(i)->offset = inodep->offset;
-+			SQUASHFS_I(i)->u.s2.directory_index_count = 0;
-+			SQUASHFS_I(i)->u.s2.parent_inode = 0;
-+
-+			TRACE("Directory inode %x:%x, start_block %x, offset "
-+					"%x\n", SQUASHFS_INODE_BLK(inode),
-+					offset, inodep->start_block,
-+					inodep->offset);
-+			break;
-+		}
-+		case SQUASHFS_LDIR_TYPE: {
-+			struct squashfs_ldir_inode_header_2 *inodep = &id.ldir;
-+			struct squashfs_ldir_inode_header_2 *sinodep = &sid.ldir;
-+
-+			if (msblk->swap) {
-+				if (!squashfs_get_cached_block(s, (char *)
-+						sinodep, block, offset,
-+						sizeof(*sinodep), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+				SQUASHFS_SWAP_LDIR_INODE_HEADER_2(inodep,
-+						sinodep);
-+			} else
-+				if (!squashfs_get_cached_block(s, (char *)
-+						inodep, block, offset,
-+						sizeof(*inodep), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+
-+			if((i = squashfs_new_inode(s, inodeb, ino)) == NULL)
-+				goto failed_read1;
-+
-+			i->i_size = inodep->file_size;
-+			i->i_op = &squashfs_dir_inode_ops_2;
-+			i->i_fop = &squashfs_dir_ops_2;
-+			i->i_mode |= S_IFDIR;
-+			i->i_mtime.tv_sec = inodep->mtime;
-+			i->i_atime.tv_sec = inodep->mtime;
-+			i->i_ctime.tv_sec = inodep->mtime;
-+			SQUASHFS_I(i)->start_block = inodep->start_block;
-+			SQUASHFS_I(i)->offset = inodep->offset;
-+			SQUASHFS_I(i)->u.s2.directory_index_start = next_block;
-+			SQUASHFS_I(i)->u.s2.directory_index_offset =
-+								next_offset;
-+			SQUASHFS_I(i)->u.s2.directory_index_count =
-+								inodep->i_count;
-+			SQUASHFS_I(i)->u.s2.parent_inode = 0;
-+
-+			TRACE("Long directory inode %x:%x, start_block %x, "
-+					"offset %x\n",
-+					SQUASHFS_INODE_BLK(inode), offset,
-+					inodep->start_block, inodep->offset);
-+			break;
-+		}
-+		case SQUASHFS_SYMLINK_TYPE: {
-+			struct squashfs_symlink_inode_header_2 *inodep =
-+								&id.symlink;
-+			struct squashfs_symlink_inode_header_2 *sinodep =
-+								&sid.symlink;
-+
-+			if (msblk->swap) {
-+				if (!squashfs_get_cached_block(s, (char *)
-+						sinodep, block, offset,
-+						sizeof(*sinodep), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+				SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(inodep,
-+								sinodep);
-+			} else
-+				if (!squashfs_get_cached_block(s, (char *)
-+						inodep, block, offset,
-+						sizeof(*inodep), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+
-+			if((i = squashfs_new_inode(s, inodeb, ino)) == NULL)
-+				goto failed_read1;
-+
-+			i->i_size = inodep->symlink_size;
-+			i->i_op = &page_symlink_inode_operations;
-+			i->i_data.a_ops = &squashfs_symlink_aops;
-+			i->i_mode |= S_IFLNK;
-+			SQUASHFS_I(i)->start_block = next_block;
-+			SQUASHFS_I(i)->offset = next_offset;
-+
-+			TRACE("Symbolic link inode %x:%x, start_block %llx, "
-+					"offset %x\n",
-+					SQUASHFS_INODE_BLK(inode), offset,
-+					next_block, next_offset);
-+			break;
-+		 }
-+		 case SQUASHFS_BLKDEV_TYPE:
-+		 case SQUASHFS_CHRDEV_TYPE: {
-+			struct squashfs_dev_inode_header_2 *inodep = &id.dev;
-+			struct squashfs_dev_inode_header_2 *sinodep = &sid.dev;
-+
-+			if (msblk->swap) {
-+				if (!squashfs_get_cached_block(s, (char *)
-+						sinodep, block, offset,
-+						sizeof(*sinodep), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+				SQUASHFS_SWAP_DEV_INODE_HEADER_2(inodep, sinodep);
-+			} else
-+				if (!squashfs_get_cached_block(s, (char *)
-+						inodep, block, offset,
-+						sizeof(*inodep), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+
-+			if ((i = squashfs_new_inode(s, inodeb, ino)) == NULL)
-+				goto failed_read1;
-+
-+			i->i_mode |= (inodeb->inode_type ==
-+					SQUASHFS_CHRDEV_TYPE) ?  S_IFCHR :
-+					S_IFBLK;
-+			init_special_inode(i, i->i_mode,
-+					old_decode_dev(inodep->rdev));
-+
-+			TRACE("Device inode %x:%x, rdev %x\n",
-+					SQUASHFS_INODE_BLK(inode), offset,
-+					inodep->rdev);
-+			break;
-+		 }
-+		 case SQUASHFS_FIFO_TYPE:
-+		 case SQUASHFS_SOCKET_TYPE: {
-+			if ((i = squashfs_new_inode(s, inodeb, ino)) == NULL)
-+				goto failed_read1;
-+
-+			i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE)
-+							? S_IFIFO : S_IFSOCK;
-+			init_special_inode(i, i->i_mode, 0);
-+			break;
-+		 }
-+		 default:
-+			ERROR("Unknown inode type %d in squashfs_iget!\n",
-+					inodeb->inode_type);
-+			goto failed_read1;
-+	}
-+
-+	insert_inode_hash(i);
-+	return i;
-+
-+failed_read:
-+	ERROR("Unable to read inode [%x:%x]\n", block, offset);
-+
-+failed_read1:
-+	return NULL;
-+}
-+
-+
-+static int get_dir_index_using_offset(struct super_block *s, long long
-+				*next_block, unsigned int *next_offset,
-+				long long index_start,
-+				unsigned int index_offset, int i_count,
-+				long long f_pos)
-+{
-+	struct squashfs_sb_info *msblk = s->s_fs_info;
-+	struct squashfs_super_block *sblk = &msblk->sblk;
-+	int i, length = 0;
-+	struct squashfs_dir_index_2 index;
-+
-+	TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n",
-+					i_count, (unsigned int) f_pos);
-+
-+	if (f_pos == 0)
-+		goto finish;
-+
-+	for (i = 0; i < i_count; i++) {
-+		if (msblk->swap) {
-+			struct squashfs_dir_index_2 sindex;
-+			squashfs_get_cached_block(s, (char *) &sindex,
-+					index_start, index_offset,
-+					sizeof(sindex), &index_start,
-+					&index_offset);
-+			SQUASHFS_SWAP_DIR_INDEX_2(&index, &sindex);
-+		} else
-+			squashfs_get_cached_block(s, (char *) &index,
-+					index_start, index_offset,
-+					sizeof(index), &index_start,
-+					&index_offset);
-+
-+		if (index.index > f_pos)
-+			break;
-+
-+		squashfs_get_cached_block(s, NULL, index_start, index_offset,
-+					index.size + 1, &index_start,
-+					&index_offset);
-+
-+		length = index.index;
-+		*next_block = index.start_block + sblk->directory_table_start;
-+	}
-+
-+	*next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
-+
-+finish:
-+	return length;
-+}
-+
-+
-+static int get_dir_index_using_name(struct super_block *s, long long
-+				*next_block, unsigned int *next_offset,
-+				long long index_start,
-+				unsigned int index_offset, int i_count,
-+				const char *name, int size)
-+{
-+	struct squashfs_sb_info *msblk = s->s_fs_info;
-+	struct squashfs_super_block *sblk = &msblk->sblk;
-+	int i, length = 0;
-+	char buffer[sizeof(struct squashfs_dir_index_2) + SQUASHFS_NAME_LEN + 1];
-+	struct squashfs_dir_index_2 *index = (struct squashfs_dir_index_2 *) buffer;
-+	char str[SQUASHFS_NAME_LEN + 1];
-+
-+	TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count);
-+
-+	strncpy(str, name, size);
-+	str[size] = '\0';
-+
-+	for (i = 0; i < i_count; i++) {
-+		if (msblk->swap) {
-+			struct squashfs_dir_index_2 sindex;
-+			squashfs_get_cached_block(s, (char *) &sindex,
-+					index_start, index_offset,
-+					sizeof(sindex), &index_start,
-+					&index_offset);
-+			SQUASHFS_SWAP_DIR_INDEX_2(index, &sindex);
-+		} else
-+			squashfs_get_cached_block(s, (char *) index,
-+					index_start, index_offset,
-+					sizeof(struct squashfs_dir_index_2),
-+					&index_start, &index_offset);
-+
-+		squashfs_get_cached_block(s, index->name, index_start,
-+					index_offset, index->size + 1,
-+					&index_start, &index_offset);
-+
-+		index->name[index->size + 1] = '\0';
-+
-+		if (strcmp(index->name, str) > 0)
-+			break;
-+
-+		length = index->index;
-+		*next_block = index->start_block + sblk->directory_table_start;
-+	}
-+
-+	*next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
-+	return length;
-+}
-+
-+
-+static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir)
-+{
-+	struct inode *i = file->f_dentry->d_inode;
-+	struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
-+	struct squashfs_super_block *sblk = &msblk->sblk;
-+	long long next_block = SQUASHFS_I(i)->start_block +
-+		sblk->directory_table_start;
-+	int next_offset = SQUASHFS_I(i)->offset, length = 0, dirs_read = 0,
-+		dir_count;
-+	struct squashfs_dir_header_2 dirh;
-+	char buffer[sizeof(struct squashfs_dir_entry_2) + SQUASHFS_NAME_LEN + 1];
-+	struct squashfs_dir_entry_2 *dire = (struct squashfs_dir_entry_2 *) buffer;
-+
-+	TRACE("Entered squashfs_readdir_2 [%llx:%x]\n", next_block, next_offset);
-+
-+	length = get_dir_index_using_offset(i->i_sb, &next_block, &next_offset,
-+				SQUASHFS_I(i)->u.s2.directory_index_start,
-+				SQUASHFS_I(i)->u.s2.directory_index_offset,
-+				SQUASHFS_I(i)->u.s2.directory_index_count,
-+				file->f_pos);
-+
-+	while (length < i_size_read(i)) {
-+		/* read directory header */
-+		if (msblk->swap) {
-+			struct squashfs_dir_header_2 sdirh;
-+
-+			if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh,
-+					next_block, next_offset, sizeof(sdirh),
-+					&next_block, &next_offset))
-+				goto failed_read;
-+
-+			length += sizeof(sdirh);
-+			SQUASHFS_SWAP_DIR_HEADER_2(&dirh, &sdirh);
-+		} else {
-+			if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh,
-+					next_block, next_offset, sizeof(dirh),
-+					&next_block, &next_offset))
-+				goto failed_read;
-+
-+			length += sizeof(dirh);
-+		}
-+
-+		dir_count = dirh.count + 1;
-+		while (dir_count--) {
-+			if (msblk->swap) {
-+				struct squashfs_dir_entry_2 sdire;
-+				if (!squashfs_get_cached_block(i->i_sb, (char *)
-+						&sdire, next_block, next_offset,
-+						sizeof(sdire), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+
-+				length += sizeof(sdire);
-+				SQUASHFS_SWAP_DIR_ENTRY_2(dire, &sdire);
-+			} else {
-+				if (!squashfs_get_cached_block(i->i_sb, (char *)
-+						dire, next_block, next_offset,
-+						sizeof(*dire), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+
-+				length += sizeof(*dire);
-+			}
-+
-+			if (!squashfs_get_cached_block(i->i_sb, dire->name,
-+						next_block, next_offset,
-+						dire->size + 1, &next_block,
-+						&next_offset))
-+				goto failed_read;
-+
-+			length += dire->size + 1;
-+
-+			if (file->f_pos >= length)
-+				continue;
-+
-+			dire->name[dire->size + 1] = '\0';
-+
-+			TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d)\n",
-+					(unsigned int) dirent, dire->name,
-+					dire->size + 1, (int) file->f_pos,
-+					dirh.start_block, dire->offset,
-+					squashfs_filetype_table[dire->type]);
-+
-+			if (filldir(dirent, dire->name, dire->size + 1,
-+					file->f_pos, SQUASHFS_MK_VFS_INODE(
-+					dirh.start_block, dire->offset),
-+					squashfs_filetype_table[dire->type])
-+					< 0) {
-+				TRACE("Filldir returned less than 0\n");
-+				goto finish;
-+			}
-+			file->f_pos = length;
-+			dirs_read++;
-+		}
-+	}
-+
-+finish:
-+	return dirs_read;
-+
-+failed_read:
-+	ERROR("Unable to read directory block [%llx:%x]\n", next_block,
-+		next_offset);
-+	return 0;
-+}
-+
-+
-+static struct dentry *squashfs_lookup_2(struct inode *i, struct dentry *dentry,
-+				struct nameidata *nd)
-+{
-+	const unsigned char *name = dentry->d_name.name;
-+	int len = dentry->d_name.len;
-+	struct inode *inode = NULL;
-+	struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
-+	struct squashfs_super_block *sblk = &msblk->sblk;
-+	long long next_block = SQUASHFS_I(i)->start_block +
-+				sblk->directory_table_start;
-+	int next_offset = SQUASHFS_I(i)->offset, length = 0,
-+				dir_count;
-+	struct squashfs_dir_header_2 dirh;
-+	char buffer[sizeof(struct squashfs_dir_entry_2) + SQUASHFS_NAME_LEN];
-+	struct squashfs_dir_entry_2 *dire = (struct squashfs_dir_entry_2 *) buffer;
-+	int sorted = sblk->s_major == 2 && sblk->s_minor >= 1;
-+
-+	TRACE("Entered squashfs_lookup [%llx:%x]\n", next_block, next_offset);
-+
-+	if (len > SQUASHFS_NAME_LEN)
-+		goto exit_loop;
-+
-+	length = get_dir_index_using_name(i->i_sb, &next_block, &next_offset,
-+				SQUASHFS_I(i)->u.s2.directory_index_start,
-+				SQUASHFS_I(i)->u.s2.directory_index_offset,
-+				SQUASHFS_I(i)->u.s2.directory_index_count, name,
-+				len);
-+
-+	while (length < i_size_read(i)) {
-+		/* read directory header */
-+		if (msblk->swap) {
-+			struct squashfs_dir_header_2 sdirh;
-+			if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh,
-+					next_block, next_offset, sizeof(sdirh),
-+					&next_block, &next_offset))
-+				goto failed_read;
-+
-+			length += sizeof(sdirh);
-+			SQUASHFS_SWAP_DIR_HEADER_2(&dirh, &sdirh);
-+		} else {
-+			if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh,
-+					next_block, next_offset, sizeof(dirh),
-+					&next_block, &next_offset))
-+				goto failed_read;
-+
-+			length += sizeof(dirh);
-+		}
-+
-+		dir_count = dirh.count + 1;
-+		while (dir_count--) {
-+			if (msblk->swap) {
-+				struct squashfs_dir_entry_2 sdire;
-+				if (!squashfs_get_cached_block(i->i_sb, (char *)
-+						&sdire, next_block,next_offset,
-+						sizeof(sdire), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+
-+				length += sizeof(sdire);
-+				SQUASHFS_SWAP_DIR_ENTRY_2(dire, &sdire);
-+			} else {
-+				if (!squashfs_get_cached_block(i->i_sb, (char *)
-+						dire, next_block,next_offset,
-+						sizeof(*dire), &next_block,
-+						&next_offset))
-+					goto failed_read;
-+
-+				length += sizeof(*dire);
-+			}
-+
-+			if (!squashfs_get_cached_block(i->i_sb, dire->name,
-+					next_block, next_offset, dire->size + 1,
-+					&next_block, &next_offset))
-+				goto failed_read;
-+
-+			length += dire->size + 1;
-+
-+			if (sorted && name[0] < dire->name[0])
-+				goto exit_loop;
-+
-+			if ((len == dire->size + 1) && !strncmp(name,
-+						dire->name, len)) {
-+				squashfs_inode_t ino =
-+					SQUASHFS_MKINODE(dirh.start_block,
-+					dire->offset);
-+
-+				TRACE("calling squashfs_iget for directory "
-+					"entry %s, inode %x:%x, %lld\n", name,
-+					dirh.start_block, dire->offset, ino);
-+
-+				inode = (msblk->iget)(i->i_sb, ino);
-+
-+				goto exit_loop;
-+			}
-+		}
-+	}
-+
-+exit_loop:
-+	d_add(dentry, inode);
-+	return ERR_PTR(0);
-+
-+failed_read:
-+	ERROR("Unable to read directory block [%llx:%x]\n", next_block,
-+		next_offset);
-+	goto exit_loop;
-+}
-+
-+
-+int squashfs_2_0_supported(struct squashfs_sb_info *msblk)
-+{
-+	struct squashfs_super_block *sblk = &msblk->sblk;
-+
-+	msblk->iget = squashfs_iget_2;
-+	msblk->read_fragment_index_table = read_fragment_index_table_2;
-+
-+	sblk->bytes_used = sblk->bytes_used_2;
-+	sblk->uid_start = sblk->uid_start_2;
-+	sblk->guid_start = sblk->guid_start_2;
-+	sblk->inode_table_start = sblk->inode_table_start_2;
-+	sblk->directory_table_start = sblk->directory_table_start_2;
-+	sblk->fragment_table_start = sblk->fragment_table_start_2;
-+
-+	return 1;
-+}
---- /dev/null
-+++ b/fs/squashfs/squashfs.h
-@@ -0,0 +1,86 @@
-+/*
-+ * Squashfs - a compressed read only filesystem for Linux
-+ *
-+ * Copyright (c) 2002, 2003, 2004, 2005, 2006
-+ * Phillip Lougher <[email protected]>
-+ *
-+ * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * squashfs.h
-+ */
-+
-+#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
-+#undef CONFIG_SQUASHFS_1_0_COMPATIBILITY
-+#endif
-+
-+#ifdef SQUASHFS_TRACE
-+#define TRACE(s, args...)	printk(KERN_NOTICE "SQUASHFS: "s, ## args)
-+#else
-+#define TRACE(s, args...)	{}
-+#endif
-+
-+#define ERROR(s, args...)	printk(KERN_ERR "SQUASHFS error: "s, ## args)
-+
-+#define SERROR(s, args...)	do { \
-+				if (!silent) \
-+				printk(KERN_ERR "SQUASHFS error: "s, ## args);\
-+				} while(0)
-+
-+#define WARNING(s, args...)	printk(KERN_WARNING "SQUASHFS: "s, ## args)
-+
-+static inline struct squashfs_inode_info *SQUASHFS_I(struct inode *inode)
-+{
-+	return list_entry(inode, struct squashfs_inode_info, vfs_inode);
-+}
-+
-+#if defined(CONFIG_SQUASHFS_1_0_COMPATIBILITY ) || defined(CONFIG_SQUASHFS_2_0_COMPATIBILITY)
-+#define SQSH_EXTERN
-+extern unsigned int squashfs_read_data(struct super_block *s, char *buffer,
-+				long long index, unsigned int length,
-+				long long *next_index);
-+extern int squashfs_get_cached_block(struct super_block *s, char *buffer,
-+				long long block, unsigned int offset,
-+				int length, long long *next_block,
-+				unsigned int *next_offset);
-+extern void release_cached_fragment(struct squashfs_sb_info *msblk, struct
-+					squashfs_fragment_cache *fragment);
-+extern struct squashfs_fragment_cache *get_cached_fragment(struct super_block
-+					*s, long long start_block,
-+					int length);
-+extern struct address_space_operations squashfs_symlink_aops;
-+extern struct address_space_operations squashfs_aops;
-+extern struct address_space_operations squashfs_aops_4K;
-+extern struct inode_operations squashfs_dir_inode_ops;
-+#else
-+#define SQSH_EXTERN static
-+#endif
-+
-+#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
-+extern int squashfs_1_0_supported(struct squashfs_sb_info *msblk);
-+#else
-+static inline int squashfs_1_0_supported(struct squashfs_sb_info *msblk)
-+{
-+	return 0;
-+}
-+#endif
-+
-+#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY
-+extern int squashfs_2_0_supported(struct squashfs_sb_info *msblk);
-+#else
-+static inline int squashfs_2_0_supported(struct squashfs_sb_info *msblk)
-+{
-+	return 0;
-+}
-+#endif
---- /dev/null
-+++ b/include/linux/squashfs_fs.h
-@@ -0,0 +1,911 @@
-+#ifndef SQUASHFS_FS
-+#define SQUASHFS_FS
-+
-+/*
-+ * Squashfs
-+ *
-+ * Copyright (c) 2002, 2003, 2004, 2005, 2006
-+ * Phillip Lougher <[email protected]>
-+ *
-+ * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * squashfs_fs.h
-+ */
-+
-+#ifndef CONFIG_SQUASHFS_2_0_COMPATIBILITY
-+#define CONFIG_SQUASHFS_2_0_COMPATIBILITY
-+#endif
-+
-+#ifdef	CONFIG_SQUASHFS_VMALLOC
-+#define SQUASHFS_ALLOC(a)		vmalloc(a)
-+#define SQUASHFS_FREE(a)		vfree(a)
-+#else
-+#define SQUASHFS_ALLOC(a)		kmalloc(a, GFP_KERNEL)
-+#define SQUASHFS_FREE(a)		kfree(a)
-+#endif
-+#define SQUASHFS_CACHED_FRAGMENTS	CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE
-+#define SQUASHFS_MAJOR			3
-+#define SQUASHFS_MINOR			0
-+#define SQUASHFS_MAGIC			0x73717368
-+#define SQUASHFS_MAGIC_SWAP		0x68737173
-+#define SQUASHFS_START			0
-+
-+/* size of metadata (inode and directory) blocks */
-+#define SQUASHFS_METADATA_SIZE		8192
-+#define SQUASHFS_METADATA_LOG		13
-+
-+/* default size of data blocks */
-+#define SQUASHFS_FILE_SIZE		65536
-+#define SQUASHFS_FILE_LOG		16
-+
-+#define SQUASHFS_FILE_MAX_SIZE		65536
-+
-+/* Max number of uids and gids */
-+#define SQUASHFS_UIDS			256
-+#define SQUASHFS_GUIDS			255
-+
-+/* Max length of filename (not 255) */
-+#define SQUASHFS_NAME_LEN		256
-+
-+#define SQUASHFS_INVALID		((long long) 0xffffffffffff)
-+#define SQUASHFS_INVALID_FRAG		((unsigned int) 0xffffffff)
-+#define SQUASHFS_INVALID_BLK		((long long) -1)
-+#define SQUASHFS_USED_BLK		((long long) -2)
-+
-+/* Filesystem flags */
-+#define SQUASHFS_NOI			0
-+#define SQUASHFS_NOD			1
-+#define SQUASHFS_CHECK			2
-+#define SQUASHFS_NOF			3
-+#define SQUASHFS_NO_FRAG		4
-+#define SQUASHFS_ALWAYS_FRAG		5
-+#define SQUASHFS_DUPLICATE		6
-+
-+#define SQUASHFS_BIT(flag, bit)		((flag >> bit) & 1)
-+
-+#define SQUASHFS_UNCOMPRESSED_INODES(flags)	SQUASHFS_BIT(flags, \
-+						SQUASHFS_NOI)
-+
-+#define SQUASHFS_UNCOMPRESSED_DATA(flags)	SQUASHFS_BIT(flags, \
-+						SQUASHFS_NOD)
-+
-+#define SQUASHFS_UNCOMPRESSED_FRAGMENTS(flags)	SQUASHFS_BIT(flags, \
-+						SQUASHFS_NOF)
-+
-+#define SQUASHFS_NO_FRAGMENTS(flags)		SQUASHFS_BIT(flags, \
-+						SQUASHFS_NO_FRAG)
-+
-+#define SQUASHFS_ALWAYS_FRAGMENTS(flags)	SQUASHFS_BIT(flags, \
-+						SQUASHFS_ALWAYS_FRAG)
-+
-+#define SQUASHFS_DUPLICATES(flags)		SQUASHFS_BIT(flags, \
-+						SQUASHFS_DUPLICATE)
-+
-+#define SQUASHFS_CHECK_DATA(flags)		SQUASHFS_BIT(flags, \
-+						SQUASHFS_CHECK)
-+
-+#define SQUASHFS_MKFLAGS(noi, nod, check_data, nof, no_frag, always_frag, \
-+		duplicate_checking)	(noi | (nod << 1) | (check_data << 2) \
-+		| (nof << 3) | (no_frag << 4) | (always_frag << 5) | \
-+		(duplicate_checking << 6))
-+
-+/* Max number of types and file types */
-+#define SQUASHFS_DIR_TYPE		1
-+#define SQUASHFS_FILE_TYPE		2
-+#define SQUASHFS_SYMLINK_TYPE		3
-+#define SQUASHFS_BLKDEV_TYPE		4
-+#define SQUASHFS_CHRDEV_TYPE		5
-+#define SQUASHFS_FIFO_TYPE		6
-+#define SQUASHFS_SOCKET_TYPE		7
-+#define SQUASHFS_LDIR_TYPE		8
-+#define SQUASHFS_LREG_TYPE		9
-+
-+/* 1.0 filesystem type definitions */
-+#define SQUASHFS_TYPES			5
-+#define SQUASHFS_IPC_TYPE		0
-+
-+/* Flag whether block is compressed or uncompressed, bit is set if block is
-+ * uncompressed */
-+#define SQUASHFS_COMPRESSED_BIT		(1 << 15)
-+
-+#define SQUASHFS_COMPRESSED_SIZE(B)	(((B) & ~SQUASHFS_COMPRESSED_BIT) ? \
-+		(B) & ~SQUASHFS_COMPRESSED_BIT :  SQUASHFS_COMPRESSED_BIT)
-+
-+#define SQUASHFS_COMPRESSED(B)		(!((B) & SQUASHFS_COMPRESSED_BIT))
-+
-+#define SQUASHFS_COMPRESSED_BIT_BLOCK		(1 << 24)
-+
-+#define SQUASHFS_COMPRESSED_SIZE_BLOCK(B)	(((B) & \
-+	~SQUASHFS_COMPRESSED_BIT_BLOCK) ? (B) & \
-+	~SQUASHFS_COMPRESSED_BIT_BLOCK : SQUASHFS_COMPRESSED_BIT_BLOCK)
-+
-+#define SQUASHFS_COMPRESSED_BLOCK(B)	(!((B) & SQUASHFS_COMPRESSED_BIT_BLOCK))
-+
-+/*
-+ * Inode number ops.  Inodes consist of a compressed block number, and an
-+ * uncompressed  offset within that block
-+ */
-+#define SQUASHFS_INODE_BLK(a)		((unsigned int) ((a) >> 16))
-+
-+#define SQUASHFS_INODE_OFFSET(a)	((unsigned int) ((a) & 0xffff))
-+
-+#define SQUASHFS_MKINODE(A, B)		((squashfs_inode_t)(((squashfs_inode_t) (A)\
-+					<< 16) + (B)))
-+
-+/* Compute 32 bit VFS inode number from squashfs inode number */
-+#define SQUASHFS_MK_VFS_INODE(a, b)	((unsigned int) (((a) << 8) + \
-+					((b) >> 2) + 1))
-+/* XXX */
-+
-+/* Translate between VFS mode and squashfs mode */
-+#define SQUASHFS_MODE(a)		((a) & 0xfff)
-+
-+/* fragment and fragment table defines */
-+#define SQUASHFS_FRAGMENT_BYTES(A)	(A * sizeof(struct squashfs_fragment_entry))
-+
-+#define SQUASHFS_FRAGMENT_INDEX(A)	(SQUASHFS_FRAGMENT_BYTES(A) / \
-+					SQUASHFS_METADATA_SIZE)
-+
-+#define SQUASHFS_FRAGMENT_INDEX_OFFSET(A)	(SQUASHFS_FRAGMENT_BYTES(A) % \
-+						SQUASHFS_METADATA_SIZE)
-+
-+#define SQUASHFS_FRAGMENT_INDEXES(A)	((SQUASHFS_FRAGMENT_BYTES(A) + \
-+					SQUASHFS_METADATA_SIZE - 1) / \
-+					SQUASHFS_METADATA_SIZE)
-+
-+#define SQUASHFS_FRAGMENT_INDEX_BYTES(A)	(SQUASHFS_FRAGMENT_INDEXES(A) *\
-+						sizeof(long long))
-+
-+/* cached data constants for filesystem */
-+#define SQUASHFS_CACHED_BLKS		8
-+
-+#define SQUASHFS_MAX_FILE_SIZE_LOG	64
-+
-+#define SQUASHFS_MAX_FILE_SIZE		((long long) 1 << \
-+					(SQUASHFS_MAX_FILE_SIZE_LOG - 2))
-+
-+#define SQUASHFS_MARKER_BYTE		0xff
-+
-+/* meta index cache */
-+#define SQUASHFS_META_INDEXES	(SQUASHFS_METADATA_SIZE / sizeof(unsigned int))
-+#define SQUASHFS_META_ENTRIES	31
-+#define SQUASHFS_META_NUMBER	8
-+#define SQUASHFS_SLOTS		4
-+
-+struct meta_entry {
-+	long long		data_block;
-+	unsigned int		index_block;
-+	unsigned short		offset;
-+	unsigned short		pad;
-+};
-+
-+struct meta_index {
-+	unsigned int		inode_number;
-+	unsigned int		offset;
-+	unsigned short		entries;
-+	unsigned short		skip;
-+	unsigned short		locked;
-+	unsigned short		pad;
-+	struct meta_entry	meta_entry[SQUASHFS_META_ENTRIES];
-+};
-+
-+
-+/*
-+ * definitions for structures on disk
-+ */
-+
-+typedef long long		squashfs_block_t;
-+typedef long long		squashfs_inode_t;
-+
-+struct squashfs_super_block {
-+	unsigned int		s_magic;
-+	unsigned int		inodes;
-+	unsigned int		bytes_used_2;
-+	unsigned int		uid_start_2;
-+	unsigned int		guid_start_2;
-+	unsigned int		inode_table_start_2;
-+	unsigned int		directory_table_start_2;
-+	unsigned int		s_major:16;
-+	unsigned int		s_minor:16;
-+	unsigned int		block_size_1:16;
-+	unsigned int		block_log:16;
-+	unsigned int		flags:8;
-+	unsigned int		no_uids:8;
-+	unsigned int		no_guids:8;
-+	unsigned int		mkfs_time /* time of filesystem creation */;
-+	squashfs_inode_t	root_inode;
-+	unsigned int		block_size;
-+	unsigned int		fragments;
-+	unsigned int		fragment_table_start_2;
-+	long long		bytes_used;
-+	long long		uid_start;
-+	long long		guid_start;
-+	long long		inode_table_start;
-+	long long		directory_table_start;
-+	long long		fragment_table_start;
-+	long long		unused;
-+} __attribute__ ((packed));
-+
-+struct squashfs_dir_index {
-+	unsigned int		index;
-+	unsigned int		start_block;
-+	unsigned char		size;
-+	unsigned char		name[0];
-+} __attribute__ ((packed));
-+
-+#define SQUASHFS_BASE_INODE_HEADER		\
-+	unsigned int		inode_type:4;	\
-+	unsigned int		mode:12;	\
-+	unsigned int		uid:8;		\
-+	unsigned int		guid:8;		\
-+	unsigned int		mtime;		\
-+	unsigned int 		inode_number;
-+
-+struct squashfs_base_inode_header {
-+	SQUASHFS_BASE_INODE_HEADER;
-+} __attribute__ ((packed));
-+
-+struct squashfs_ipc_inode_header {
-+	SQUASHFS_BASE_INODE_HEADER;
-+	unsigned int		nlink;
-+} __attribute__ ((packed));
-+
-+struct squashfs_dev_inode_header {
-+	SQUASHFS_BASE_INODE_HEADER;
-+	unsigned int		nlink;
-+	unsigned short		rdev;
-+} __attribute__ ((packed));
-+
-+struct squashfs_symlink_inode_header {
-+	SQUASHFS_BASE_INODE_HEADER;
-+	unsigned int		nlink;
-+	unsigned short		symlink_size;
-+	char			symlink[0];
-+} __attribute__ ((packed));
-+
-+struct squashfs_reg_inode_header {
-+	SQUASHFS_BASE_INODE_HEADER;
-+	squashfs_block_t	start_block;
-+	unsigned int		fragment;
-+	unsigned int		offset;
-+	unsigned int		file_size;
-+	unsigned short		block_list[0];
-+} __attribute__ ((packed));
-+
-+struct squashfs_lreg_inode_header {
-+	SQUASHFS_BASE_INODE_HEADER;
-+	unsigned int		nlink;
-+	squashfs_block_t	start_block;
-+	unsigned int		fragment;
-+	unsigned int		offset;
-+	long long		file_size;
-+	unsigned short		block_list[0];
-+} __attribute__ ((packed));
-+
-+struct squashfs_dir_inode_header {
-+	SQUASHFS_BASE_INODE_HEADER;
-+	unsigned int		nlink;
-+	unsigned int		file_size:19;
-+	unsigned int		offset:13;
-+	unsigned int		start_block;
-+	unsigned int		parent_inode;
-+} __attribute__  ((packed));
-+
-+struct squashfs_ldir_inode_header {
-+	SQUASHFS_BASE_INODE_HEADER;
-+	unsigned int		nlink;
-+	unsigned int		file_size:27;
-+	unsigned int		offset:13;
-+	unsigned int		start_block;
-+	unsigned int		i_count:16;
-+	unsigned int		parent_inode;
-+	struct squashfs_dir_index	index[0];
-+} __attribute__  ((packed));
-+
-+union squashfs_inode_header {
-+	struct squashfs_base_inode_header	base;
-+	struct squashfs_dev_inode_header	dev;
-+	struct squashfs_symlink_inode_header	symlink;
-+	struct squashfs_reg_inode_header	reg;
-+	struct squashfs_lreg_inode_header	lreg;
-+	struct squashfs_dir_inode_header	dir;
-+	struct squashfs_ldir_inode_header	ldir;
-+	struct squashfs_ipc_inode_header	ipc;
-+};
-+
-+struct squashfs_dir_entry {
-+	unsigned int		offset:13;
-+	unsigned int		type:3;
-+	unsigned int		size:8;
-+	int			inode_number:16;
-+	char			name[0];
-+} __attribute__ ((packed));
-+
-+struct squashfs_dir_header {
-+	unsigned int		count:8;
-+	unsigned int		start_block;
-+	unsigned int		inode_number;
-+} __attribute__ ((packed));
-+
-+struct squashfs_fragment_entry {
-+	long long		start_block;
-+	unsigned int		size;
-+	unsigned int		unused;
-+} __attribute__ ((packed));
-+
-+extern int squashfs_uncompress_block(void *d, int dstlen, void *s, int srclen);
-+extern int squashfs_uncompress_init(void);
-+extern int squashfs_uncompress_exit(void);
-+
-+/*
-+ * macros to convert each packed bitfield structure from little endian to big
-+ * endian and vice versa.  These are needed when creating or using a filesystem
-+ * on a machine with different byte ordering to the target architecture.
-+ *
-+ */
-+
-+#define SQUASHFS_SWAP_START \
-+	int bits;\
-+	int b_pos;\
-+	unsigned long long val;\
-+	unsigned char *s;\
-+	unsigned char *d;
-+
-+#define SQUASHFS_SWAP_SUPER_BLOCK(s, d) {\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_super_block));\
-+	SQUASHFS_SWAP((s)->s_magic, d, 0, 32);\
-+	SQUASHFS_SWAP((s)->inodes, d, 32, 32);\
-+	SQUASHFS_SWAP((s)->bytes_used_2, d, 64, 32);\
-+	SQUASHFS_SWAP((s)->uid_start_2, d, 96, 32);\
-+	SQUASHFS_SWAP((s)->guid_start_2, d, 128, 32);\
-+	SQUASHFS_SWAP((s)->inode_table_start_2, d, 160, 32);\
-+	SQUASHFS_SWAP((s)->directory_table_start_2, d, 192, 32);\
-+	SQUASHFS_SWAP((s)->s_major, d, 224, 16);\
-+	SQUASHFS_SWAP((s)->s_minor, d, 240, 16);\
-+	SQUASHFS_SWAP((s)->block_size_1, d, 256, 16);\
-+	SQUASHFS_SWAP((s)->block_log, d, 272, 16);\
-+	SQUASHFS_SWAP((s)->flags, d, 288, 8);\
-+	SQUASHFS_SWAP((s)->no_uids, d, 296, 8);\
-+	SQUASHFS_SWAP((s)->no_guids, d, 304, 8);\
-+	SQUASHFS_SWAP((s)->mkfs_time, d, 312, 32);\
-+	SQUASHFS_SWAP((s)->root_inode, d, 344, 64);\
-+	SQUASHFS_SWAP((s)->block_size, d, 408, 32);\
-+	SQUASHFS_SWAP((s)->fragments, d, 440, 32);\
-+	SQUASHFS_SWAP((s)->fragment_table_start_2, d, 472, 32);\
-+	SQUASHFS_SWAP((s)->bytes_used, d, 504, 64);\
-+	SQUASHFS_SWAP((s)->uid_start, d, 568, 64);\
-+	SQUASHFS_SWAP((s)->guid_start, d, 632, 64);\
-+	SQUASHFS_SWAP((s)->inode_table_start, d, 696, 64);\
-+	SQUASHFS_SWAP((s)->directory_table_start, d, 760, 64);\
-+	SQUASHFS_SWAP((s)->fragment_table_start, d, 824, 64);\
-+	SQUASHFS_SWAP((s)->unused, d, 888, 64);\
-+}
-+
-+#define SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\
-+	SQUASHFS_MEMSET(s, d, n);\
-+	SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
-+	SQUASHFS_SWAP((s)->mode, d, 4, 12);\
-+	SQUASHFS_SWAP((s)->uid, d, 16, 8);\
-+	SQUASHFS_SWAP((s)->guid, d, 24, 8);\
-+	SQUASHFS_SWAP((s)->mtime, d, 32, 32);\
-+	SQUASHFS_SWAP((s)->inode_number, d, 64, 32);
-+
-+#define SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, n) {\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\
-+}
-+
-+#define SQUASHFS_SWAP_IPC_INODE_HEADER(s, d) {\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
-+			sizeof(struct squashfs_ipc_inode_header))\
-+	SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
-+}
-+
-+#define SQUASHFS_SWAP_DEV_INODE_HEADER(s, d) {\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
-+			sizeof(struct squashfs_dev_inode_header)); \
-+	SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
-+	SQUASHFS_SWAP((s)->rdev, d, 128, 16);\
-+}
-+
-+#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER(s, d) {\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
-+			sizeof(struct squashfs_symlink_inode_header));\
-+	SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
-+	SQUASHFS_SWAP((s)->symlink_size, d, 128, 16);\
-+}
-+
-+#define SQUASHFS_SWAP_REG_INODE_HEADER(s, d) {\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
-+			sizeof(struct squashfs_reg_inode_header));\
-+	SQUASHFS_SWAP((s)->start_block, d, 96, 64);\
-+	SQUASHFS_SWAP((s)->fragment, d, 160, 32);\
-+	SQUASHFS_SWAP((s)->offset, d, 192, 32);\
-+	SQUASHFS_SWAP((s)->file_size, d, 224, 32);\
-+}
-+
-+#define SQUASHFS_SWAP_LREG_INODE_HEADER(s, d) {\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
-+			sizeof(struct squashfs_lreg_inode_header));\
-+	SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
-+	SQUASHFS_SWAP((s)->start_block, d, 128, 64);\
-+	SQUASHFS_SWAP((s)->fragment, d, 192, 32);\
-+	SQUASHFS_SWAP((s)->offset, d, 224, 32);\
-+	SQUASHFS_SWAP((s)->file_size, d, 256, 64);\
-+}
-+
-+#define SQUASHFS_SWAP_DIR_INODE_HEADER(s, d) {\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
-+			sizeof(struct squashfs_dir_inode_header));\
-+	SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
-+	SQUASHFS_SWAP((s)->file_size, d, 128, 19);\
-+	SQUASHFS_SWAP((s)->offset, d, 147, 13);\
-+	SQUASHFS_SWAP((s)->start_block, d, 160, 32);\
-+	SQUASHFS_SWAP((s)->parent_inode, d, 192, 32);\
-+}
-+
-+#define SQUASHFS_SWAP_LDIR_INODE_HEADER(s, d) {\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
-+			sizeof(struct squashfs_ldir_inode_header));\
-+	SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
-+	SQUASHFS_SWAP((s)->file_size, d, 128, 27);\
-+	SQUASHFS_SWAP((s)->offset, d, 155, 13);\
-+	SQUASHFS_SWAP((s)->start_block, d, 168, 32);\
-+	SQUASHFS_SWAP((s)->i_count, d, 200, 16);\
-+	SQUASHFS_SWAP((s)->parent_inode, d, 216, 32);\
-+}
-+
-+#define SQUASHFS_SWAP_DIR_INDEX(s, d) {\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index));\
-+	SQUASHFS_SWAP((s)->index, d, 0, 32);\
-+	SQUASHFS_SWAP((s)->start_block, d, 32, 32);\
-+	SQUASHFS_SWAP((s)->size, d, 64, 8);\
-+}
-+
-+#define SQUASHFS_SWAP_DIR_HEADER(s, d) {\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header));\
-+	SQUASHFS_SWAP((s)->count, d, 0, 8);\
-+	SQUASHFS_SWAP((s)->start_block, d, 8, 32);\
-+	SQUASHFS_SWAP((s)->inode_number, d, 40, 32);\
-+}
-+
-+#define SQUASHFS_SWAP_DIR_ENTRY(s, d) {\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry));\
-+	SQUASHFS_SWAP((s)->offset, d, 0, 13);\
-+	SQUASHFS_SWAP((s)->type, d, 13, 3);\
-+	SQUASHFS_SWAP((s)->size, d, 16, 8);\
-+	SQUASHFS_SWAP((s)->inode_number, d, 24, 16);\
-+}
-+
-+#define SQUASHFS_SWAP_FRAGMENT_ENTRY(s, d) {\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry));\
-+	SQUASHFS_SWAP((s)->start_block, d, 0, 64);\
-+	SQUASHFS_SWAP((s)->size, d, 64, 32);\
-+}
-+
-+#define SQUASHFS_SWAP_SHORTS(s, d, n) {\
-+	int entry;\
-+	int bit_position;\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_MEMSET(s, d, n * 2);\
-+	for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
-+			16)\
-+		SQUASHFS_SWAP(s[entry], d, bit_position, 16);\
-+}
-+
-+#define SQUASHFS_SWAP_INTS(s, d, n) {\
-+	int entry;\
-+	int bit_position;\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_MEMSET(s, d, n * 4);\
-+	for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
-+			32)\
-+		SQUASHFS_SWAP(s[entry], d, bit_position, 32);\
-+}
-+
-+#define SQUASHFS_SWAP_LONG_LONGS(s, d, n) {\
-+	int entry;\
-+	int bit_position;\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_MEMSET(s, d, n * 8);\
-+	for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
-+			64)\
-+		SQUASHFS_SWAP(s[entry], d, bit_position, 64);\
-+}
-+
-+#define SQUASHFS_SWAP_DATA(s, d, n, bits) {\
-+	int entry;\
-+	int bit_position;\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_MEMSET(s, d, n * bits / 8);\
-+	for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
-+			bits)\
-+		SQUASHFS_SWAP(s[entry], d, bit_position, bits);\
-+}
-+
-+#define SQUASHFS_SWAP_FRAGMENT_INDEXES(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n)
-+
-+#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
-+
-+struct squashfs_base_inode_header_1 {
-+	unsigned int		inode_type:4;
-+	unsigned int		mode:12; /* protection */
-+	unsigned int		uid:4; /* index into uid table */
-+	unsigned int		guid:4; /* index into guid table */
-+} __attribute__ ((packed));
-+
-+struct squashfs_ipc_inode_header_1 {
-+	unsigned int		inode_type:4;
-+	unsigned int		mode:12; /* protection */
-+	unsigned int		uid:4; /* index into uid table */
-+	unsigned int		guid:4; /* index into guid table */
-+	unsigned int		type:4;
-+	unsigned int		offset:4;
-+} __attribute__ ((packed));
-+
-+struct squashfs_dev_inode_header_1 {
-+	unsigned int		inode_type:4;
-+	unsigned int		mode:12; /* protection */
-+	unsigned int		uid:4; /* index into uid table */
-+	unsigned int		guid:4; /* index into guid table */
-+	unsigned short		rdev;
-+} __attribute__ ((packed));
-+
-+struct squashfs_symlink_inode_header_1 {
-+	unsigned int		inode_type:4;
-+	unsigned int		mode:12; /* protection */
-+	unsigned int		uid:4; /* index into uid table */
-+	unsigned int		guid:4; /* index into guid table */
-+	unsigned short		symlink_size;
-+	char			symlink[0];
-+} __attribute__ ((packed));
-+
-+struct squashfs_reg_inode_header_1 {
-+	unsigned int		inode_type:4;
-+	unsigned int		mode:12; /* protection */
-+	unsigned int		uid:4; /* index into uid table */
-+	unsigned int		guid:4; /* index into guid table */
-+	unsigned int		mtime;
-+	unsigned int		start_block;
-+	unsigned int		file_size:32;
-+	unsigned short		block_list[0];
-+} __attribute__ ((packed));
-+
-+struct squashfs_dir_inode_header_1 {
-+	unsigned int		inode_type:4;
-+	unsigned int		mode:12; /* protection */
-+	unsigned int		uid:4; /* index into uid table */
-+	unsigned int		guid:4; /* index into guid table */
-+	unsigned int		file_size:19;
-+	unsigned int		offset:13;
-+	unsigned int		mtime;
-+	unsigned int		start_block:24;
-+} __attribute__  ((packed));
-+
-+#define SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n) \
-+	SQUASHFS_MEMSET(s, d, n);\
-+	SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
-+	SQUASHFS_SWAP((s)->mode, d, 4, 12);\
-+	SQUASHFS_SWAP((s)->uid, d, 16, 4);\
-+	SQUASHFS_SWAP((s)->guid, d, 20, 4);
-+
-+#define SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, n) {\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n)\
-+}
-+
-+#define SQUASHFS_SWAP_IPC_INODE_HEADER_1(s, d) {\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
-+			sizeof(struct squashfs_ipc_inode_header_1));\
-+	SQUASHFS_SWAP((s)->type, d, 24, 4);\
-+	SQUASHFS_SWAP((s)->offset, d, 28, 4);\
-+}
-+
-+#define SQUASHFS_SWAP_DEV_INODE_HEADER_1(s, d) {\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
-+			sizeof(struct squashfs_dev_inode_header_1));\
-+	SQUASHFS_SWAP((s)->rdev, d, 24, 16);\
-+}
-+
-+#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_1(s, d) {\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
-+			sizeof(struct squashfs_symlink_inode_header_1));\
-+	SQUASHFS_SWAP((s)->symlink_size, d, 24, 16);\
-+}
-+
-+#define SQUASHFS_SWAP_REG_INODE_HEADER_1(s, d) {\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
-+			sizeof(struct squashfs_reg_inode_header_1));\
-+	SQUASHFS_SWAP((s)->mtime, d, 24, 32);\
-+	SQUASHFS_SWAP((s)->start_block, d, 56, 32);\
-+	SQUASHFS_SWAP((s)->file_size, d, 88, 32);\
-+}
-+
-+#define SQUASHFS_SWAP_DIR_INODE_HEADER_1(s, d) {\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
-+			sizeof(struct squashfs_dir_inode_header_1));\
-+	SQUASHFS_SWAP((s)->file_size, d, 24, 19);\
-+	SQUASHFS_SWAP((s)->offset, d, 43, 13);\
-+	SQUASHFS_SWAP((s)->mtime, d, 56, 32);\
-+	SQUASHFS_SWAP((s)->start_block, d, 88, 24);\
-+}
-+
-+#endif
-+
-+#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY
-+
-+struct squashfs_dir_index_2 {
-+	unsigned int		index:27;
-+	unsigned int		start_block:29;
-+	unsigned char		size;
-+	unsigned char		name[0];
-+} __attribute__ ((packed));
-+
-+struct squashfs_base_inode_header_2 {
-+	unsigned int		inode_type:4;
-+	unsigned int		mode:12; /* protection */
-+	unsigned int		uid:8; /* index into uid table */
-+	unsigned int		guid:8; /* index into guid table */
-+} __attribute__ ((packed));
-+
-+struct squashfs_ipc_inode_header_2 {
-+	unsigned int		inode_type:4;
-+	unsigned int		mode:12; /* protection */
-+	unsigned int		uid:8; /* index into uid table */
-+	unsigned int		guid:8; /* index into guid table */
-+} __attribute__ ((packed));
-+
-+struct squashfs_dev_inode_header_2 {
-+	unsigned int		inode_type:4;
-+	unsigned int		mode:12; /* protection */
-+	unsigned int		uid:8; /* index into uid table */
-+	unsigned int		guid:8; /* index into guid table */
-+	unsigned short		rdev;
-+} __attribute__ ((packed));
-+
-+struct squashfs_symlink_inode_header_2 {
-+	unsigned int		inode_type:4;
-+	unsigned int		mode:12; /* protection */
-+	unsigned int		uid:8; /* index into uid table */
-+	unsigned int		guid:8; /* index into guid table */
-+	unsigned short		symlink_size;
-+	char			symlink[0];
-+} __attribute__ ((packed));
-+
-+struct squashfs_reg_inode_header_2 {
-+	unsigned int		inode_type:4;
-+	unsigned int		mode:12; /* protection */
-+	unsigned int		uid:8; /* index into uid table */
-+	unsigned int		guid:8; /* index into guid table */
-+	unsigned int		mtime;
-+	unsigned int		start_block;
-+	unsigned int		fragment;
-+	unsigned int		offset;
-+	unsigned int		file_size:32;
-+	unsigned short		block_list[0];
-+} __attribute__ ((packed));
-+
-+struct squashfs_dir_inode_header_2 {
-+	unsigned int		inode_type:4;
-+	unsigned int		mode:12; /* protection */
-+	unsigned int		uid:8; /* index into uid table */
-+	unsigned int		guid:8; /* index into guid table */
-+	unsigned int		file_size:19;
-+	unsigned int		offset:13;
-+	unsigned int		mtime;
-+	unsigned int		start_block:24;
-+} __attribute__  ((packed));
-+
-+struct squashfs_ldir_inode_header_2 {
-+	unsigned int		inode_type:4;
-+	unsigned int		mode:12; /* protection */
-+	unsigned int		uid:8; /* index into uid table */
-+	unsigned int		guid:8; /* index into guid table */
-+	unsigned int		file_size:27;
-+	unsigned int		offset:13;
-+	unsigned int		mtime;
-+	unsigned int		start_block:24;
-+	unsigned int		i_count:16;
-+	struct squashfs_dir_index_2	index[0];
-+} __attribute__  ((packed));
-+
-+union squashfs_inode_header_2 {
-+	struct squashfs_base_inode_header_2	base;
-+	struct squashfs_dev_inode_header_2	dev;
-+	struct squashfs_symlink_inode_header_2	symlink;
-+	struct squashfs_reg_inode_header_2	reg;
-+	struct squashfs_dir_inode_header_2	dir;
-+	struct squashfs_ldir_inode_header_2	ldir;
-+	struct squashfs_ipc_inode_header_2	ipc;
-+};
-+
-+struct squashfs_dir_header_2 {
-+	unsigned int		count:8;
-+	unsigned int		start_block:24;
-+} __attribute__ ((packed));
-+
-+struct squashfs_dir_entry_2 {
-+	unsigned int		offset:13;
-+	unsigned int		type:3;
-+	unsigned int		size:8;
-+	char			name[0];
-+} __attribute__ ((packed));
-+
-+struct squashfs_fragment_entry_2 {
-+	unsigned int		start_block;
-+	unsigned int		size;
-+} __attribute__ ((packed));
-+
-+#define SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\
-+	SQUASHFS_MEMSET(s, d, n);\
-+	SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
-+	SQUASHFS_SWAP((s)->mode, d, 4, 12);\
-+	SQUASHFS_SWAP((s)->uid, d, 16, 8);\
-+	SQUASHFS_SWAP((s)->guid, d, 24, 8);\
-+
-+#define SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, n) {\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\
-+}
-+
-+#define SQUASHFS_SWAP_IPC_INODE_HEADER_2(s, d) \
-+	SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, sizeof(struct squashfs_ipc_inode_header_2))
-+
-+#define SQUASHFS_SWAP_DEV_INODE_HEADER_2(s, d) {\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
-+			sizeof(struct squashfs_dev_inode_header_2)); \
-+	SQUASHFS_SWAP((s)->rdev, d, 32, 16);\
-+}
-+
-+#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(s, d) {\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
-+			sizeof(struct squashfs_symlink_inode_header_2));\
-+	SQUASHFS_SWAP((s)->symlink_size, d, 32, 16);\
-+}
-+
-+#define SQUASHFS_SWAP_REG_INODE_HEADER_2(s, d) {\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
-+			sizeof(struct squashfs_reg_inode_header_2));\
-+	SQUASHFS_SWAP((s)->mtime, d, 32, 32);\
-+	SQUASHFS_SWAP((s)->start_block, d, 64, 32);\
-+	SQUASHFS_SWAP((s)->fragment, d, 96, 32);\
-+	SQUASHFS_SWAP((s)->offset, d, 128, 32);\
-+	SQUASHFS_SWAP((s)->file_size, d, 160, 32);\
-+}
-+
-+#define SQUASHFS_SWAP_DIR_INODE_HEADER_2(s, d) {\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
-+			sizeof(struct squashfs_dir_inode_header_2));\
-+	SQUASHFS_SWAP((s)->file_size, d, 32, 19);\
-+	SQUASHFS_SWAP((s)->offset, d, 51, 13);\
-+	SQUASHFS_SWAP((s)->mtime, d, 64, 32);\
-+	SQUASHFS_SWAP((s)->start_block, d, 96, 24);\
-+}
-+
-+#define SQUASHFS_SWAP_LDIR_INODE_HEADER_2(s, d) {\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
-+			sizeof(struct squashfs_ldir_inode_header_2));\
-+	SQUASHFS_SWAP((s)->file_size, d, 32, 27);\
-+	SQUASHFS_SWAP((s)->offset, d, 59, 13);\
-+	SQUASHFS_SWAP((s)->mtime, d, 72, 32);\
-+	SQUASHFS_SWAP((s)->start_block, d, 104, 24);\
-+	SQUASHFS_SWAP((s)->i_count, d, 128, 16);\
-+}
-+
-+#define SQUASHFS_SWAP_DIR_INDEX_2(s, d) {\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index_2));\
-+	SQUASHFS_SWAP((s)->index, d, 0, 27);\
-+	SQUASHFS_SWAP((s)->start_block, d, 27, 29);\
-+	SQUASHFS_SWAP((s)->size, d, 56, 8);\
-+}
-+#define SQUASHFS_SWAP_DIR_HEADER_2(s, d) {\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header_2));\
-+	SQUASHFS_SWAP((s)->count, d, 0, 8);\
-+	SQUASHFS_SWAP((s)->start_block, d, 8, 24);\
-+}
-+
-+#define SQUASHFS_SWAP_DIR_ENTRY_2(s, d) {\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry_2));\
-+	SQUASHFS_SWAP((s)->offset, d, 0, 13);\
-+	SQUASHFS_SWAP((s)->type, d, 13, 3);\
-+	SQUASHFS_SWAP((s)->size, d, 16, 8);\
-+}
-+
-+#define SQUASHFS_SWAP_FRAGMENT_ENTRY_2(s, d) {\
-+	SQUASHFS_SWAP_START\
-+	SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry_2));\
-+	SQUASHFS_SWAP((s)->start_block, d, 0, 32);\
-+	SQUASHFS_SWAP((s)->size, d, 32, 32);\
-+}
-+
-+#define SQUASHFS_SWAP_FRAGMENT_INDEXES_2(s, d, n) SQUASHFS_SWAP_INTS(s, d, n)
-+
-+/* fragment and fragment table defines */
-+#define SQUASHFS_FRAGMENT_BYTES_2(A)	(A * sizeof(struct squashfs_fragment_entry_2))
-+
-+#define SQUASHFS_FRAGMENT_INDEX_2(A)	(SQUASHFS_FRAGMENT_BYTES_2(A) / \
-+					SQUASHFS_METADATA_SIZE)
-+
-+#define SQUASHFS_FRAGMENT_INDEX_OFFSET_2(A)	(SQUASHFS_FRAGMENT_BYTES_2(A) % \
-+						SQUASHFS_METADATA_SIZE)
-+
-+#define SQUASHFS_FRAGMENT_INDEXES_2(A)	((SQUASHFS_FRAGMENT_BYTES_2(A) + \
-+					SQUASHFS_METADATA_SIZE - 1) / \
-+					SQUASHFS_METADATA_SIZE)
-+
-+#define SQUASHFS_FRAGMENT_INDEX_BYTES_2(A)	(SQUASHFS_FRAGMENT_INDEXES_2(A) *\
-+						sizeof(int))
-+
-+#endif
-+
-+#ifdef __KERNEL__
-+
-+/*
-+ * macros used to swap each structure entry, taking into account
-+ * bitfields and different bitfield placing conventions on differing
-+ * architectures
-+ */
-+
-+#include <asm/byteorder.h>
-+
-+#ifdef __BIG_ENDIAN
-+	/* convert from little endian to big endian */
-+#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \
-+		tbits, b_pos)
-+#else
-+	/* convert from big endian to little endian */
-+#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \
-+		tbits, 64 - tbits - b_pos)
-+#endif
-+
-+#define _SQUASHFS_SWAP(value, p, pos, tbits, SHIFT) {\
-+	b_pos = pos % 8;\
-+	val = 0;\
-+	s = (unsigned char *)p + (pos / 8);\
-+	d = ((unsigned char *) &val) + 7;\
-+	for(bits = 0; bits < (tbits + b_pos); bits += 8) \
-+		*d-- = *s++;\
-+	value = (val >> (SHIFT))/* & ((1 << tbits) - 1)*/;\
-+}
-+
-+#define SQUASHFS_MEMSET(s, d, n)	memset(s, 0, n);
-+
-+#endif
-+#endif
---- /dev/null
-+++ b/include/linux/squashfs_fs_i.h
-@@ -0,0 +1,45 @@
-+#ifndef SQUASHFS_FS_I
-+#define SQUASHFS_FS_I
-+/*
-+ * Squashfs
-+ *
-+ * Copyright (c) 2002, 2003, 2004, 2005, 2006
-+ * Phillip Lougher <[email protected]>
-+ *
-+ * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * squashfs_fs_i.h
-+ */
-+
-+struct squashfs_inode_info {
-+	long long	start_block;
-+	unsigned int	offset;
-+	union {
-+		struct {
-+			long long	fragment_start_block;
-+			unsigned int	fragment_size;
-+			unsigned int	fragment_offset;
-+			long long	block_list_start;
-+		} s1;
-+		struct {
-+			long long	directory_index_start;
-+			unsigned int	directory_index_offset;
-+			unsigned int	directory_index_count;
-+			unsigned int	parent_inode;
-+		} s2;
-+	} u;
-+	struct inode	vfs_inode;
-+};
-+#endif
---- /dev/null
-+++ b/include/linux/squashfs_fs_sb.h
-@@ -0,0 +1,74 @@
-+#ifndef SQUASHFS_FS_SB
-+#define SQUASHFS_FS_SB
-+/*
-+ * Squashfs
-+ *
-+ * Copyright (c) 2002, 2003, 2004, 2005, 2006
-+ * Phillip Lougher <[email protected]>
-+ *
-+ * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * squashfs_fs_sb.h
-+ */
-+
-+#include <linux/squashfs_fs.h>
-+
-+struct squashfs_cache {
-+	long long	block;
-+	int		length;
-+	long long	next_index;
-+	char		*data;
-+};
-+
-+struct squashfs_fragment_cache {
-+	long long	block;
-+	int		length;
-+	unsigned int	locked;
-+	char		*data;
-+};
-+
-+struct squashfs_sb_info {
-+	struct squashfs_super_block	sblk;
-+	int			devblksize;
-+	int			devblksize_log2;
-+	int			swap;
-+	struct squashfs_cache	*block_cache;
-+	struct squashfs_fragment_cache	*fragment;
-+	int			next_cache;
-+	int			next_fragment;
-+	int			next_meta_index;
-+	unsigned int		*uid;
-+	unsigned int		*guid;
-+	long long		*fragment_index;
-+	unsigned int		*fragment_index_2;
-+	unsigned int		read_size;
-+	char			*read_data;
-+	char			*read_page;
-+	struct semaphore	read_data_mutex;
-+	struct semaphore	read_page_mutex;
-+	struct semaphore	block_cache_mutex;
-+	struct semaphore	fragment_mutex;
-+	struct semaphore	meta_index_mutex;
-+	wait_queue_head_t	waitq;
-+	wait_queue_head_t	fragment_wait_queue;
-+	struct meta_index	*meta_index;
-+	struct inode		*(*iget)(struct super_block *s,  squashfs_inode_t \
-+				inode);
-+	long long		(*read_blocklist)(struct inode *inode, int \
-+				index, int readahead_blks, char *block_list, \
-+				unsigned short **block_p, unsigned int *bsize);
-+	int			(*read_fragment_index_table)(struct super_block *s);
-+};
-+#endif
---- a/init/do_mounts_rd.c
-+++ b/init/do_mounts_rd.c
-@@ -5,6 +5,7 @@
- #include <linux/ext2_fs.h>
- #include <linux/romfs_fs.h>
- #include <linux/cramfs_fs.h>
-+#include <linux/squashfs_fs.h>
- #include <linux/initrd.h>
- #include <linux/string.h>
- 
-@@ -39,6 +40,7 @@ static int __init crd_load(int in_fd, in
-  * numbers could not be found.
-  *
-  * We currently check for the following magic numbers:
-+ *      squashfs
-  * 	minix
-  * 	ext2
-  *	romfs
-@@ -53,6 +55,7 @@ identify_ramdisk_image(int fd, int start
- 	struct ext2_super_block *ext2sb;
- 	struct romfs_super_block *romfsb;
- 	struct cramfs_super *cramfsb;
-+	struct squashfs_super_block *squashfsb;
- 	int nblocks = -1;
- 	unsigned char *buf;
- 
-@@ -64,6 +67,7 @@ identify_ramdisk_image(int fd, int start
- 	ext2sb = (struct ext2_super_block *) buf;
- 	romfsb = (struct romfs_super_block *) buf;
- 	cramfsb = (struct cramfs_super *) buf;
-+	squashfsb = (struct squashfs_super_block *) buf;
- 	memset(buf, 0xe5, size);
- 
- 	/*
-@@ -101,6 +105,15 @@ identify_ramdisk_image(int fd, int start
- 		goto done;
- 	}
- 
-+	/* squashfs is at block zero too */
-+	if (squashfsb->s_magic == SQUASHFS_MAGIC) {
-+		printk(KERN_NOTICE
-+		       "RAMDISK: squashfs filesystem found at block %d\n",
-+		       start_block);
-+		nblocks = (squashfsb->bytes_used+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
-+		goto done;
-+	}
-+
- 	/*
- 	 * Read block 1 to test for minix and ext2 superblock
- 	 */

+ 0 - 788
target/linux/generic-2.6/patches-2.6.21/002-lzma_decompress.patch

@@ -1,788 +0,0 @@
---- /dev/null
-+++ b/include/linux/LzmaDecode.h
-@@ -0,0 +1,100 @@
-+/*
-+  LzmaDecode.h
-+  LZMA Decoder interface
-+
-+  LZMA SDK 4.05 Copyright (c) 1999-2004 Igor Pavlov (2004-08-25)
-+  http://www.7-zip.org/
-+
-+  LZMA SDK is licensed under two licenses:
-+  1) GNU Lesser General Public License (GNU LGPL)
-+  2) Common Public License (CPL)
-+  It means that you can select one of these two licenses and
-+  follow rules of that license.
-+
-+  SPECIAL EXCEPTION:
-+  Igor Pavlov, as the author of this code, expressly permits you to
-+  statically or dynamically link your code (or bind by name) to the
-+  interfaces of this file without subjecting your linked code to the
-+  terms of the CPL or GNU LGPL. Any modifications or additions
-+  to this file, however, are subject to the LGPL or CPL terms.
-+*/
-+
-+#ifndef __LZMADECODE_H
-+#define __LZMADECODE_H
-+
-+/* #define _LZMA_IN_CB */
-+/* Use callback for input data */
-+
-+/* #define _LZMA_OUT_READ */
-+/* Use read function for output data */
-+
-+/* #define _LZMA_PROB32 */
-+/* It can increase speed on some 32-bit CPUs,
-+   but memory usage will be doubled in that case */
-+
-+/* #define _LZMA_LOC_OPT */
-+/* Enable local speed optimizations inside code */
-+
-+#ifndef UInt32
-+#ifdef _LZMA_UINT32_IS_ULONG
-+#define UInt32 unsigned long
-+#else
-+#define UInt32 unsigned int
-+#endif
-+#endif
-+
-+#ifdef _LZMA_PROB32
-+#define CProb UInt32
-+#else
-+#define CProb unsigned short
-+#endif
-+
-+#define LZMA_RESULT_OK 0
-+#define LZMA_RESULT_DATA_ERROR 1
-+#define LZMA_RESULT_NOT_ENOUGH_MEM 2
-+
-+#ifdef _LZMA_IN_CB
-+typedef struct _ILzmaInCallback
-+{
-+  int (*Read)(void *object, unsigned char **buffer, UInt32 *bufferSize);
-+} ILzmaInCallback;
-+#endif
-+
-+#define LZMA_BASE_SIZE 1846
-+#define LZMA_LIT_SIZE 768
-+
-+/*
-+bufferSize = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp)))* sizeof(CProb)
-+bufferSize += 100 in case of _LZMA_OUT_READ
-+by default CProb is unsigned short,
-+but if specify _LZMA_PROB_32, CProb will be UInt32(unsigned int)
-+*/
-+
-+#ifdef _LZMA_OUT_READ
-+int LzmaDecoderInit(
-+    unsigned char *buffer, UInt32 bufferSize,
-+    int lc, int lp, int pb,
-+    unsigned char *dictionary, UInt32 dictionarySize,
-+  #ifdef _LZMA_IN_CB
-+    ILzmaInCallback *inCallback
-+  #else
-+    unsigned char *inStream, UInt32 inSize
-+  #endif
-+);
-+#endif
-+
-+int LzmaDecode(
-+    unsigned char *buffer,
-+  #ifndef _LZMA_OUT_READ
-+    UInt32 bufferSize,
-+    int lc, int lp, int pb,
-+  #ifdef _LZMA_IN_CB
-+    ILzmaInCallback *inCallback,
-+  #else
-+    unsigned char *inStream, UInt32 inSize,
-+  #endif
-+  #endif
-+    unsigned char *outStream, UInt32 outSize,
-+    UInt32 *outSizeProcessed);
-+
-+#endif
---- /dev/null
-+++ b/lib/LzmaDecode.c
-@@ -0,0 +1,663 @@
-+/*
-+  LzmaDecode.c
-+  LZMA Decoder
-+
-+  LZMA SDK 4.05 Copyright (c) 1999-2004 Igor Pavlov (2004-08-25)
-+  http://www.7-zip.org/
-+
-+  LZMA SDK is licensed under two licenses:
-+  1) GNU Lesser General Public License (GNU LGPL)
-+  2) Common Public License (CPL)
-+  It means that you can select one of these two licenses and
-+  follow rules of that license.
-+
-+  SPECIAL EXCEPTION:
-+  Igor Pavlov, as the author of this code, expressly permits you to
-+  statically or dynamically link your code (or bind by name) to the
-+  interfaces of this file without subjecting your linked code to the
-+  terms of the CPL or GNU LGPL. Any modifications or additions
-+  to this file, however, are subject to the LGPL or CPL terms.
-+*/
-+
-+#include <linux/LzmaDecode.h>
-+
-+#ifndef Byte
-+#define Byte unsigned char
-+#endif
-+
-+#define kNumTopBits 24
-+#define kTopValue ((UInt32)1 << kNumTopBits)
-+
-+#define kNumBitModelTotalBits 11
-+#define kBitModelTotal (1 << kNumBitModelTotalBits)
-+#define kNumMoveBits 5
-+
-+typedef struct _CRangeDecoder
-+{
-+  Byte *Buffer;
-+  Byte *BufferLim;
-+  UInt32 Range;
-+  UInt32 Code;
-+  #ifdef _LZMA_IN_CB
-+  ILzmaInCallback *InCallback;
-+  int Result;
-+  #endif
-+  int ExtraBytes;
-+} CRangeDecoder;
-+
-+Byte RangeDecoderReadByte(CRangeDecoder *rd)
-+{
-+  if (rd->Buffer == rd->BufferLim)
-+  {
-+    #ifdef _LZMA_IN_CB
-+    UInt32 size;
-+    rd->Result = rd->InCallback->Read(rd->InCallback, &rd->Buffer, &size);
-+    rd->BufferLim = rd->Buffer + size;
-+    if (size == 0)
-+    #endif
-+    {
-+      rd->ExtraBytes = 1;
-+      return 0xFF;
-+    }
-+  }
-+  return (*rd->Buffer++);
-+}
-+
-+/* #define ReadByte (*rd->Buffer++) */
-+#define ReadByte (RangeDecoderReadByte(rd))
-+
-+void RangeDecoderInit(CRangeDecoder *rd,
-+  #ifdef _LZMA_IN_CB
-+    ILzmaInCallback *inCallback
-+  #else
-+    Byte *stream, UInt32 bufferSize
-+  #endif
-+    )
-+{
-+  int i;
-+  #ifdef _LZMA_IN_CB
-+  rd->InCallback = inCallback;
-+  rd->Buffer = rd->BufferLim = 0;
-+  #else
-+  rd->Buffer = stream;
-+  rd->BufferLim = stream + bufferSize;
-+  #endif
-+  rd->ExtraBytes = 0;
-+  rd->Code = 0;
-+  rd->Range = (0xFFFFFFFF);
-+  for(i = 0; i < 5; i++)
-+    rd->Code = (rd->Code << 8) | ReadByte;
-+}
-+
-+#define RC_INIT_VAR UInt32 range = rd->Range; UInt32 code = rd->Code;
-+#define RC_FLUSH_VAR rd->Range = range; rd->Code = code;
-+#define RC_NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | ReadByte; }
-+
-+UInt32 RangeDecoderDecodeDirectBits(CRangeDecoder *rd, int numTotalBits)
-+{
-+  RC_INIT_VAR
-+  UInt32 result = 0;
-+  int i;
-+  for (i = numTotalBits; i > 0; i--)
-+  {
-+    /* UInt32 t; */
-+    range >>= 1;
-+
-+    result <<= 1;
-+    if (code >= range)
-+    {
-+      code -= range;
-+      result |= 1;
-+    }
-+    /*
-+    t = (code - range) >> 31;
-+    t &= 1;
-+    code -= range & (t - 1);
-+    result = (result + result) | (1 - t);
-+    */
-+    RC_NORMALIZE
-+  }
-+  RC_FLUSH_VAR
-+  return result;
-+}
-+
-+int RangeDecoderBitDecode(CProb *prob, CRangeDecoder *rd)
-+{
-+  UInt32 bound = (rd->Range >> kNumBitModelTotalBits) * *prob;
-+  if (rd->Code < bound)
-+  {
-+    rd->Range = bound;
-+    *prob += (kBitModelTotal - *prob) >> kNumMoveBits;
-+    if (rd->Range < kTopValue)
-+    {
-+      rd->Code = (rd->Code << 8) | ReadByte;
-+      rd->Range <<= 8;
-+    }
-+    return 0;
-+  }
-+  else
-+  {
-+    rd->Range -= bound;
-+    rd->Code -= bound;
-+    *prob -= (*prob) >> kNumMoveBits;
-+    if (rd->Range < kTopValue)
-+    {
-+      rd->Code = (rd->Code << 8) | ReadByte;
-+      rd->Range <<= 8;
-+    }
-+    return 1;
-+  }
-+}
-+
-+#define RC_GET_BIT2(prob, mi, A0, A1) \
-+  UInt32 bound = (range >> kNumBitModelTotalBits) * *prob; \
-+  if (code < bound) \
-+    { A0; range = bound; *prob += (kBitModelTotal - *prob) >> kNumMoveBits; mi <<= 1; } \
-+  else \
-+    { A1; range -= bound; code -= bound; *prob -= (*prob) >> kNumMoveBits; mi = (mi + mi) + 1; } \
-+  RC_NORMALIZE
-+
-+#define RC_GET_BIT(prob, mi) RC_GET_BIT2(prob, mi, ; , ;)
-+
-+int RangeDecoderBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd)
-+{
-+  int mi = 1;
-+  int i;
-+  #ifdef _LZMA_LOC_OPT
-+  RC_INIT_VAR
-+  #endif
-+  for(i = numLevels; i > 0; i--)
-+  {
-+    #ifdef _LZMA_LOC_OPT
-+    CProb *prob = probs + mi;
-+    RC_GET_BIT(prob, mi)
-+    #else
-+    mi = (mi + mi) + RangeDecoderBitDecode(probs + mi, rd);
-+    #endif
-+  }
-+  #ifdef _LZMA_LOC_OPT
-+  RC_FLUSH_VAR
-+  #endif
-+  return mi - (1 << numLevels);
-+}
-+
-+int RangeDecoderReverseBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd)
-+{
-+  int mi = 1;
-+  int i;
-+  int symbol = 0;
-+  #ifdef _LZMA_LOC_OPT
-+  RC_INIT_VAR
-+  #endif
-+  for(i = 0; i < numLevels; i++)
-+  {
-+    #ifdef _LZMA_LOC_OPT
-+    CProb *prob = probs + mi;
-+    RC_GET_BIT2(prob, mi, ; , symbol |= (1 << i))
-+    #else
-+    int bit = RangeDecoderBitDecode(probs + mi, rd);
-+    mi = mi + mi + bit;
-+    symbol |= (bit << i);
-+    #endif
-+  }
-+  #ifdef _LZMA_LOC_OPT
-+  RC_FLUSH_VAR
-+  #endif
-+  return symbol;
-+}
-+
-+Byte LzmaLiteralDecode(CProb *probs, CRangeDecoder *rd)
-+{
-+  int symbol = 1;
-+  #ifdef _LZMA_LOC_OPT
-+  RC_INIT_VAR
-+  #endif
-+  do
-+  {
-+    #ifdef _LZMA_LOC_OPT
-+    CProb *prob = probs + symbol;
-+    RC_GET_BIT(prob, symbol)
-+    #else
-+    symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd);
-+    #endif
-+  }
-+  while (symbol < 0x100);
-+  #ifdef _LZMA_LOC_OPT
-+  RC_FLUSH_VAR
-+  #endif
-+  return symbol;
-+}
-+
-+Byte LzmaLiteralDecodeMatch(CProb *probs, CRangeDecoder *rd, Byte matchByte)
-+{
-+  int symbol = 1;
-+  #ifdef _LZMA_LOC_OPT
-+  RC_INIT_VAR
-+  #endif
-+  do
-+  {
-+    int bit;
-+    int matchBit = (matchByte >> 7) & 1;
-+    matchByte <<= 1;
-+    #ifdef _LZMA_LOC_OPT
-+    {
-+      CProb *prob = probs + ((1 + matchBit) << 8) + symbol;
-+      RC_GET_BIT2(prob, symbol, bit = 0, bit = 1)
-+    }
-+    #else
-+    bit = RangeDecoderBitDecode(probs + ((1 + matchBit) << 8) + symbol, rd);
-+    symbol = (symbol << 1) | bit;
-+    #endif
-+    if (matchBit != bit)
-+    {
-+      while (symbol < 0x100)
-+      {
-+        #ifdef _LZMA_LOC_OPT
-+        CProb *prob = probs + symbol;
-+        RC_GET_BIT(prob, symbol)
-+        #else
-+        symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd);
-+        #endif
-+      }
-+      break;
-+    }
-+  }
-+  while (symbol < 0x100);
-+  #ifdef _LZMA_LOC_OPT
-+  RC_FLUSH_VAR
-+  #endif
-+  return symbol;
-+}
-+
-+#define kNumPosBitsMax 4
-+#define kNumPosStatesMax (1 << kNumPosBitsMax)
-+
-+#define kLenNumLowBits 3
-+#define kLenNumLowSymbols (1 << kLenNumLowBits)
-+#define kLenNumMidBits 3
-+#define kLenNumMidSymbols (1 << kLenNumMidBits)
-+#define kLenNumHighBits 8
-+#define kLenNumHighSymbols (1 << kLenNumHighBits)
-+
-+#define LenChoice 0
-+#define LenChoice2 (LenChoice + 1)
-+#define LenLow (LenChoice2 + 1)
-+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
-+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
-+#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
-+
-+int LzmaLenDecode(CProb *p, CRangeDecoder *rd, int posState)
-+{
-+  if(RangeDecoderBitDecode(p + LenChoice, rd) == 0)
-+    return RangeDecoderBitTreeDecode(p + LenLow +
-+        (posState << kLenNumLowBits), kLenNumLowBits, rd);
-+  if(RangeDecoderBitDecode(p + LenChoice2, rd) == 0)
-+    return kLenNumLowSymbols + RangeDecoderBitTreeDecode(p + LenMid +
-+        (posState << kLenNumMidBits), kLenNumMidBits, rd);
-+  return kLenNumLowSymbols + kLenNumMidSymbols +
-+      RangeDecoderBitTreeDecode(p + LenHigh, kLenNumHighBits, rd);
-+}
-+
-+#define kNumStates 12
-+
-+#define kStartPosModelIndex 4
-+#define kEndPosModelIndex 14
-+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
-+
-+#define kNumPosSlotBits 6
-+#define kNumLenToPosStates 4
-+
-+#define kNumAlignBits 4
-+#define kAlignTableSize (1 << kNumAlignBits)
-+
-+#define kMatchMinLen 2
-+
-+#define IsMatch 0
-+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
-+#define IsRepG0 (IsRep + kNumStates)
-+#define IsRepG1 (IsRepG0 + kNumStates)
-+#define IsRepG2 (IsRepG1 + kNumStates)
-+#define IsRep0Long (IsRepG2 + kNumStates)
-+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
-+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
-+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
-+#define LenCoder (Align + kAlignTableSize)
-+#define RepLenCoder (LenCoder + kNumLenProbs)
-+#define Literal (RepLenCoder + kNumLenProbs)
-+
-+#if Literal != LZMA_BASE_SIZE
-+StopCompilingDueBUG
-+#endif
-+
-+#ifdef _LZMA_OUT_READ
-+
-+typedef struct _LzmaVarState
-+{
-+  CRangeDecoder RangeDecoder;
-+  Byte *Dictionary;
-+  UInt32 DictionarySize;
-+  UInt32 DictionaryPos;
-+  UInt32 GlobalPos;
-+  UInt32 Reps[4];
-+  int lc;
-+  int lp;
-+  int pb;
-+  int State;
-+  int PreviousIsMatch;
-+  int RemainLen;
-+} LzmaVarState;
-+
-+int LzmaDecoderInit(
-+    unsigned char *buffer, UInt32 bufferSize,
-+    int lc, int lp, int pb,
-+    unsigned char *dictionary, UInt32 dictionarySize,
-+    #ifdef _LZMA_IN_CB
-+    ILzmaInCallback *inCallback
-+    #else
-+    unsigned char *inStream, UInt32 inSize
-+    #endif
-+    )
-+{
-+  LzmaVarState *vs = (LzmaVarState *)buffer;
-+  CProb *p = (CProb *)(buffer + sizeof(LzmaVarState));
-+  UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + lp));
-+  UInt32 i;
-+  if (bufferSize < numProbs * sizeof(CProb) + sizeof(LzmaVarState))
-+    return LZMA_RESULT_NOT_ENOUGH_MEM;
-+  vs->Dictionary = dictionary;
-+  vs->DictionarySize = dictionarySize;
-+  vs->DictionaryPos = 0;
-+  vs->GlobalPos = 0;
-+  vs->Reps[0] = vs->Reps[1] = vs->Reps[2] = vs->Reps[3] = 1;
-+  vs->lc = lc;
-+  vs->lp = lp;
-+  vs->pb = pb;
-+  vs->State = 0;
-+  vs->PreviousIsMatch = 0;
-+  vs->RemainLen = 0;
-+  dictionary[dictionarySize - 1] = 0;
-+  for (i = 0; i < numProbs; i++)
-+    p[i] = kBitModelTotal >> 1;
-+  RangeDecoderInit(&vs->RangeDecoder,
-+      #ifdef _LZMA_IN_CB
-+      inCallback
-+      #else
-+      inStream, inSize
-+      #endif
-+  );
-+  return LZMA_RESULT_OK;
-+}
-+
-+int LzmaDecode(unsigned char *buffer,
-+    unsigned char *outStream, UInt32 outSize,
-+    UInt32 *outSizeProcessed)
-+{
-+  LzmaVarState *vs = (LzmaVarState *)buffer;
-+  CProb *p = (CProb *)(buffer + sizeof(LzmaVarState));
-+  CRangeDecoder rd = vs->RangeDecoder;
-+  int state = vs->State;
-+  int previousIsMatch = vs->PreviousIsMatch;
-+  Byte previousByte;
-+  UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
-+  UInt32 nowPos = 0;
-+  UInt32 posStateMask = (1 << (vs->pb)) - 1;
-+  UInt32 literalPosMask = (1 << (vs->lp)) - 1;
-+  int lc = vs->lc;
-+  int len = vs->RemainLen;
-+  UInt32 globalPos = vs->GlobalPos;
-+
-+  Byte *dictionary = vs->Dictionary;
-+  UInt32 dictionarySize = vs->DictionarySize;
-+  UInt32 dictionaryPos = vs->DictionaryPos;
-+
-+  if (len == -1)
-+  {
-+    *outSizeProcessed = 0;
-+    return LZMA_RESULT_OK;
-+  }
-+
-+  while(len > 0 && nowPos < outSize)
-+  {
-+    UInt32 pos = dictionaryPos - rep0;
-+    if (pos >= dictionarySize)
-+      pos += dictionarySize;
-+    outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
-+    if (++dictionaryPos == dictionarySize)
-+      dictionaryPos = 0;
-+    len--;
-+  }
-+  if (dictionaryPos == 0)
-+    previousByte = dictionary[dictionarySize - 1];
-+  else
-+    previousByte = dictionary[dictionaryPos - 1];
-+#else
-+
-+int LzmaDecode(
-+    Byte *buffer, UInt32 bufferSize,
-+    int lc, int lp, int pb,
-+    #ifdef _LZMA_IN_CB
-+    ILzmaInCallback *inCallback,
-+    #else
-+    unsigned char *inStream, UInt32 inSize,
-+    #endif
-+    unsigned char *outStream, UInt32 outSize,
-+    UInt32 *outSizeProcessed)
-+{
-+  UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + lp));
-+  CProb *p = (CProb *)buffer;
-+  CRangeDecoder rd;
-+  UInt32 i;
-+  int state = 0;
-+  int previousIsMatch = 0;
-+  Byte previousByte = 0;
-+  UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
-+  UInt32 nowPos = 0;
-+  UInt32 posStateMask = (1 << pb) - 1;
-+  UInt32 literalPosMask = (1 << lp) - 1;
-+  int len = 0;
-+  if (bufferSize < numProbs * sizeof(CProb))
-+    return LZMA_RESULT_NOT_ENOUGH_MEM;
-+  for (i = 0; i < numProbs; i++)
-+    p[i] = kBitModelTotal >> 1;
-+  RangeDecoderInit(&rd,
-+      #ifdef _LZMA_IN_CB
-+      inCallback
-+      #else
-+      inStream, inSize
-+      #endif
-+      );
-+#endif
-+
-+  *outSizeProcessed = 0;
-+  while(nowPos < outSize)
-+  {
-+    int posState = (int)(
-+        (nowPos
-+        #ifdef _LZMA_OUT_READ
-+        + globalPos
-+        #endif
-+        )
-+        & posStateMask);
-+    #ifdef _LZMA_IN_CB
-+    if (rd.Result != LZMA_RESULT_OK)
-+      return rd.Result;
-+    #endif
-+    if (rd.ExtraBytes != 0)
-+      return LZMA_RESULT_DATA_ERROR;
-+    if (RangeDecoderBitDecode(p + IsMatch + (state << kNumPosBitsMax) + posState, &rd) == 0)
-+    {
-+      CProb *probs = p + Literal + (LZMA_LIT_SIZE *
-+        (((
-+        (nowPos
-+        #ifdef _LZMA_OUT_READ
-+        + globalPos
-+        #endif
-+        )
-+        & literalPosMask) << lc) + (previousByte >> (8 - lc))));
-+
-+      if (state < 4) state = 0;
-+      else if (state < 10) state -= 3;
-+      else state -= 6;
-+      if (previousIsMatch)
-+      {
-+        Byte matchByte;
-+        #ifdef _LZMA_OUT_READ
-+        UInt32 pos = dictionaryPos - rep0;
-+        if (pos >= dictionarySize)
-+          pos += dictionarySize;
-+        matchByte = dictionary[pos];
-+        #else
-+        matchByte = outStream[nowPos - rep0];
-+        #endif
-+        previousByte = LzmaLiteralDecodeMatch(probs, &rd, matchByte);
-+        previousIsMatch = 0;
-+      }
-+      else
-+        previousByte = LzmaLiteralDecode(probs, &rd);
-+      outStream[nowPos++] = previousByte;
-+      #ifdef _LZMA_OUT_READ
-+      dictionary[dictionaryPos] = previousByte;
-+      if (++dictionaryPos == dictionarySize)
-+        dictionaryPos = 0;
-+      #endif
-+    }
-+    else
-+    {
-+      previousIsMatch = 1;
-+      if (RangeDecoderBitDecode(p + IsRep + state, &rd) == 1)
-+      {
-+        if (RangeDecoderBitDecode(p + IsRepG0 + state, &rd) == 0)
-+        {
-+          if (RangeDecoderBitDecode(p + IsRep0Long + (state << kNumPosBitsMax) + posState, &rd) == 0)
-+          {
-+            #ifdef _LZMA_OUT_READ
-+            UInt32 pos;
-+            #endif
-+            if (
-+               (nowPos
-+                #ifdef _LZMA_OUT_READ
-+                + globalPos
-+                #endif
-+               )
-+               == 0)
-+              return LZMA_RESULT_DATA_ERROR;
-+            state = state < 7 ? 9 : 11;
-+            #ifdef _LZMA_OUT_READ
-+            pos = dictionaryPos - rep0;
-+            if (pos >= dictionarySize)
-+              pos += dictionarySize;
-+            previousByte = dictionary[pos];
-+            dictionary[dictionaryPos] = previousByte;
-+            if (++dictionaryPos == dictionarySize)
-+              dictionaryPos = 0;
-+            #else
-+            previousByte = outStream[nowPos - rep0];
-+            #endif
-+            outStream[nowPos++] = previousByte;
-+            continue;
-+          }
-+        }
-+        else
-+        {
-+          UInt32 distance;
-+          if(RangeDecoderBitDecode(p + IsRepG1 + state, &rd) == 0)
-+            distance = rep1;
-+          else
-+          {
-+            if(RangeDecoderBitDecode(p + IsRepG2 + state, &rd) == 0)
-+              distance = rep2;
-+            else
-+            {
-+              distance = rep3;
-+              rep3 = rep2;
-+            }
-+            rep2 = rep1;
-+          }
-+          rep1 = rep0;
-+          rep0 = distance;
-+        }
-+        len = LzmaLenDecode(p + RepLenCoder, &rd, posState);
-+        state = state < 7 ? 8 : 11;
-+      }
-+      else
-+      {
-+        int posSlot;
-+        rep3 = rep2;
-+        rep2 = rep1;
-+        rep1 = rep0;
-+        state = state < 7 ? 7 : 10;
-+        len = LzmaLenDecode(p + LenCoder, &rd, posState);
-+        posSlot = RangeDecoderBitTreeDecode(p + PosSlot +
-+            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
-+            kNumPosSlotBits), kNumPosSlotBits, &rd);
-+        if (posSlot >= kStartPosModelIndex)
-+        {
-+          int numDirectBits = ((posSlot >> 1) - 1);
-+          rep0 = ((2 | ((UInt32)posSlot & 1)) << numDirectBits);
-+          if (posSlot < kEndPosModelIndex)
-+          {
-+            rep0 += RangeDecoderReverseBitTreeDecode(
-+                p + SpecPos + rep0 - posSlot - 1, numDirectBits, &rd);
-+          }
-+          else
-+          {
-+            rep0 += RangeDecoderDecodeDirectBits(&rd,
-+                numDirectBits - kNumAlignBits) << kNumAlignBits;
-+            rep0 += RangeDecoderReverseBitTreeDecode(p + Align, kNumAlignBits, &rd);
-+          }
-+        }
-+        else
-+          rep0 = posSlot;
-+        rep0++;
-+      }
-+      if (rep0 == (UInt32)(0))
-+      {
-+        /* it's for stream version */
-+        len = -1;
-+        break;
-+      }
-+      if (rep0 > nowPos
-+        #ifdef _LZMA_OUT_READ
-+        + globalPos
-+        #endif
-+        )
-+      {
-+        return LZMA_RESULT_DATA_ERROR;
-+      }
-+      len += kMatchMinLen;
-+      do
-+      {
-+        #ifdef _LZMA_OUT_READ
-+        UInt32 pos = dictionaryPos - rep0;
-+        if (pos >= dictionarySize)
-+          pos += dictionarySize;
-+        previousByte = dictionary[pos];
-+        dictionary[dictionaryPos] = previousByte;
-+        if (++dictionaryPos == dictionarySize)
-+          dictionaryPos = 0;
-+        #else
-+        previousByte = outStream[nowPos - rep0];
-+        #endif
-+        outStream[nowPos++] = previousByte;
-+        len--;
-+      }
-+      while(len > 0 && nowPos < outSize);
-+    }
-+  }
-+
-+  #ifdef _LZMA_OUT_READ
-+  vs->RangeDecoder = rd;
-+  vs->DictionaryPos = dictionaryPos;
-+  vs->GlobalPos = globalPos + nowPos;
-+  vs->Reps[0] = rep0;
-+  vs->Reps[1] = rep1;
-+  vs->Reps[2] = rep2;
-+  vs->Reps[3] = rep3;
-+  vs->State = state;
-+  vs->PreviousIsMatch = previousIsMatch;
-+  vs->RemainLen = len;
-+  #endif
-+
-+  *outSizeProcessed = nowPos;
-+  return LZMA_RESULT_OK;
-+}
---- a/lib/Makefile
-+++ b/lib/Makefile
-@@ -12,7 +12,7 @@ lib-$(CONFIG_SMP) += cpumask.o
- 
- lib-y	+= kobject.o kref.o kobject_uevent.o klist.o
- 
--obj-y += sort.o parser.o halfmd4.o debug_locks.o random32.o bust_spinlocks.o
-+obj-y += sort.o parser.o halfmd4.o debug_locks.o random32.o bust_spinlocks.o LzmaDecode.o
- 
- ifeq ($(CONFIG_DEBUG_KOBJECT),y)
- CFLAGS_kobject.o += -DDEBUG
-@@ -56,6 +56,7 @@ obj-$(CONFIG_SMP) += percpu_counter.o
- obj-$(CONFIG_AUDIT_GENERIC) += audit.o
- 
- obj-$(CONFIG_SWIOTLB) += swiotlb.o
-+
- obj-$(CONFIG_FAULT_INJECTION) += fault-inject.o
- 
- lib-$(CONFIG_GENERIC_BUG) += bug.o

+ 0 - 107
target/linux/generic-2.6/patches-2.6.21/003-squashfs_lzma.patch

@@ -1,107 +0,0 @@
---- a/fs/squashfs/inode.c
-+++ b/fs/squashfs/inode.c
-@@ -4,6 +4,9 @@
-  * Copyright (c) 2002, 2003, 2004, 2005, 2006
-  * Phillip Lougher <[email protected]>
-  *
-+ * LZMA decompressor support added by Oleg I. Vdovikin
-+ * Copyright (c) 2005 Oleg I.Vdovikin <[email protected]>
-+ *
-  * 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,
-@@ -21,6 +24,7 @@
-  * inode.c
-  */
- 
-+#define SQUASHFS_LZMA
- #include <linux/types.h>
- #include <linux/squashfs_fs.h>
- #include <linux/module.h>
-@@ -44,6 +48,19 @@
- 
- #include "squashfs.h"
- 
-+#ifdef SQUASHFS_LZMA
-+#include <linux/LzmaDecode.h>
-+
-+/* default LZMA settings, should be in sync with mksquashfs */
-+#define LZMA_LC 3
-+#define LZMA_LP 0
-+#define LZMA_PB 2
-+
-+#define LZMA_WORKSPACE_SIZE ((LZMA_BASE_SIZE + \
-+      (LZMA_LIT_SIZE << (LZMA_LC + LZMA_LP))) * sizeof(CProb))
-+
-+#endif
-+
- static void squashfs_put_super(struct super_block *);
- static int squashfs_statfs(struct dentry *, struct kstatfs *);
- static int squashfs_symlink_readpage(struct file *file, struct page *page);
-@@ -64,7 +81,11 @@ static int squashfs_get_sb(struct file_s
- 			const char *, void *, struct vfsmount *);
- 
- 
-+#ifdef SQUASHFS_LZMA
-+static unsigned char lzma_workspace[LZMA_WORKSPACE_SIZE];
-+#else
- static z_stream stream;
-+#endif
- 
- static struct file_system_type squashfs_fs_type = {
- 	.owner = THIS_MODULE,
-@@ -249,6 +270,15 @@ SQSH_EXTERN unsigned int squashfs_read_d
- 	if (compressed) {
- 		int zlib_err;
- 
-+#ifdef SQUASHFS_LZMA
-+		if ((zlib_err = LzmaDecode(lzma_workspace,
-+			LZMA_WORKSPACE_SIZE, LZMA_LC, LZMA_LP, LZMA_PB,
-+			c_buffer, c_byte, buffer, msblk->read_size, &bytes)) != LZMA_RESULT_OK)
-+		{
-+			ERROR("lzma returned unexpected result 0x%x\n", zlib_err);
-+			bytes = 0;
-+		}
-+#else
- 		stream.next_in = c_buffer;
- 		stream.avail_in = c_byte;
- 		stream.next_out = buffer;
-@@ -263,7 +293,7 @@ SQSH_EXTERN unsigned int squashfs_read_d
- 			bytes = 0;
- 		} else
- 			bytes = stream.total_out;
--
-+#endif
- 		up(&msblk->read_data_mutex);
- 	}
- 
-@@ -2045,15 +2075,19 @@ static int __init init_squashfs_fs(void)
- 	printk(KERN_INFO "squashfs: version 3.0 (2006/03/15) "
- 		"Phillip Lougher\n");
- 
-+#ifndef SQUASHFS_LZMA
- 	if (!(stream.workspace = vmalloc(zlib_inflate_workspacesize()))) {
- 		ERROR("Failed to allocate zlib workspace\n");
- 		destroy_inodecache();
- 		err = -ENOMEM;
- 		goto out;
- 	}
-+#endif
- 
- 	if ((err = register_filesystem(&squashfs_fs_type))) {
-+#ifndef SQUASHFS_LZMA
- 		vfree(stream.workspace);
-+#endif
- 		destroy_inodecache();
- 	}
- 
-@@ -2064,7 +2098,9 @@ out:
- 
- static void __exit exit_squashfs_fs(void)
- {
-+#ifndef SQUASHFS_LZMA
- 	vfree(stream.workspace);
-+#endif
- 	unregister_filesystem(&squashfs_fs_type);
- 	destroy_inodecache();
- }

+ 0 - 12
target/linux/generic-2.6/patches-2.6.21/004-extra_optimization.patch

@@ -1,12 +0,0 @@
---- a/Makefile
-+++ b/Makefile
-@@ -507,6 +507,9 @@ CFLAGS          += $(call cc-option, -fn
- NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
- CHECKFLAGS     += $(NOSTDINC_FLAGS)
- 
-+# improve gcc optimization
-+CFLAGS += $(call cc-option,-funit-at-a-time,)
-+
- # warn about C99 declaration after statement
- CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
- 

+ 0 - 11
target/linux/generic-2.6/patches-2.6.21/006-gcc4_inline_fix.patch

@@ -1,11 +0,0 @@
---- a/include/asm-mips/system.h
-+++ b/include/asm-mips/system.h
-@@ -188,7 +188,7 @@ extern __u64 __xchg_u64_unsupported_on_3
-    if something tries to do an invalid xchg().  */
- extern void __xchg_called_with_bad_pointer(void);
- 
--static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
-+static __always_inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
- {
- 	switch (size) {
- 	case 4:

+ 0 - 36
target/linux/generic-2.6/patches-2.6.21/007-samsung_flash.patch

@@ -1,36 +0,0 @@
---- a/drivers/mtd/chips/cfi_cmdset_0002.c
-+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
-@@ -51,6 +51,7 @@
- #define SST49LF040B	        0x0050
- #define SST49LF008A		0x005a
- #define AT49BV6416		0x00d6
-+#define MANUFACTURER_SAMSUNG	0x00ec
- 
- static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
- static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
-@@ -294,12 +295,19 @@ struct mtd_info *cfi_cmdset_0002(struct 
- 
- 		if (extp->MajorVersion != '1' ||
- 		    (extp->MinorVersion < '0' || extp->MinorVersion > '4')) {
--			printk(KERN_ERR "  Unknown Amd/Fujitsu Extended Query "
--			       "version %c.%c.\n",  extp->MajorVersion,
--			       extp->MinorVersion);
--			kfree(extp);
--			kfree(mtd);
--			return NULL;
-+		        if (cfi->mfr == MANUFACTURER_SAMSUNG &&
-+			    (extp->MajorVersion == '3' && extp->MinorVersion == '3')) {
-+			    printk(KERN_NOTICE "  Newer Samsung flash detected, "
-+			           "should be compatibile with Amd/Fujitsu.\n");
-+		        }
-+		        else {
-+			    printk(KERN_ERR "  Unknown Amd/Fujitsu Extended Query "
-+			           "version %c.%c.\n",  extp->MajorVersion,
-+			           extp->MinorVersion);
-+			    kfree(extp);
-+			    kfree(mtd);
-+			    return NULL;
-+		        }
- 		}
- 
- 		/* Install our own private info structure */

+ 0 - 169
target/linux/generic-2.6/patches-2.6.21/009-revert_intel_flash_breakage.patch

@@ -1,169 +0,0 @@
---- a/drivers/mtd/chips/cfi_cmdset_0001.c
-+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
-@@ -919,7 +919,7 @@ static void __xipram xip_enable(struct m
- 
- static int __xipram xip_wait_for_operation(
- 		struct map_info *map, struct flchip *chip,
--		unsigned long adr, unsigned int chip_op_time )
-+		unsigned long adr, int *chip_op_time )
- {
- 	struct cfi_private *cfi = map->fldrv_priv;
- 	struct cfi_pri_intelext *cfip = cfi->cmdset_priv;
-@@ -928,7 +928,7 @@ static int __xipram xip_wait_for_operati
- 	flstate_t oldstate, newstate;
- 
-        	start = xip_currtime();
--	usec = chip_op_time * 8;
-+	usec = *chip_op_time * 8;
- 	if (usec == 0)
- 		usec = 500000;
- 	done = 0;
-@@ -1038,8 +1038,8 @@ static int __xipram xip_wait_for_operati
- #define XIP_INVAL_CACHED_RANGE(map, from, size)  \
- 	INVALIDATE_CACHED_RANGE(map, from, size)
- 
--#define INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, inval_adr, inval_len, usec) \
--	xip_wait_for_operation(map, chip, cmd_adr, usec)
-+#define INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, inval_adr, inval_len, p_usec) \
-+	xip_wait_for_operation(map, chip, cmd_adr, p_usec)
- 
- #else
- 
-@@ -1051,65 +1051,65 @@ static int __xipram xip_wait_for_operati
- static int inval_cache_and_wait_for_operation(
- 		struct map_info *map, struct flchip *chip,
- 		unsigned long cmd_adr, unsigned long inval_adr, int inval_len,
--		unsigned int chip_op_time)
-+		int *chip_op_time )
- {
- 	struct cfi_private *cfi = map->fldrv_priv;
- 	map_word status, status_OK = CMD(0x80);
--	int chip_state = chip->state;
--	unsigned int timeo, sleep_time;
-+	int z, chip_state = chip->state;
-+	unsigned long timeo;
- 
- 	spin_unlock(chip->mutex);
- 	if (inval_len)
- 		INVALIDATE_CACHED_RANGE(map, inval_adr, inval_len);
-+	if (*chip_op_time)
-+		cfi_udelay(*chip_op_time);
- 	spin_lock(chip->mutex);
- 
--	/* set our timeout to 8 times the expected delay */
--	timeo = chip_op_time * 8;
--	if (!timeo)
--		timeo = 500000;
--	sleep_time = chip_op_time / 2;
-+	timeo = *chip_op_time * 8 * HZ / 1000000;
-+	if (timeo < HZ/2)
-+		timeo = HZ/2;
-+	timeo += jiffies;
- 
-+	z = 0;
- 	for (;;) {
-+		if (chip->state != chip_state) {
-+			/* Someone's suspended the operation: sleep */
-+			DECLARE_WAITQUEUE(wait, current);
-+
-+			set_current_state(TASK_UNINTERRUPTIBLE);
-+			add_wait_queue(&chip->wq, &wait);
-+			spin_unlock(chip->mutex);
-+			schedule();
-+			remove_wait_queue(&chip->wq, &wait);
-+			timeo = jiffies + (HZ / 2); /* FIXME */
-+			spin_lock(chip->mutex);
-+			continue;
-+		}
-+
- 		status = map_read(map, cmd_adr);
- 		if (map_word_andequal(map, status, status_OK, status_OK))
- 			break;
- 
--		if (!timeo) {
-+		/* OK Still waiting */
-+		if (time_after(jiffies, timeo)) {
- 			map_write(map, CMD(0x70), cmd_adr);
- 			chip->state = FL_STATUS;
- 			return -ETIME;
- 		}
- 
--		/* OK Still waiting. Drop the lock, wait a while and retry. */
-+		/* Latency issues. Drop the lock, wait a while and retry */
-+		z++;
- 		spin_unlock(chip->mutex);
--		if (sleep_time >= 1000000/HZ) {
--			/*
--			 * Half of the normal delay still remaining
--			 * can be performed with a sleeping delay instead
--			 * of busy waiting.
--			 */
--			msleep(sleep_time/1000);
--			timeo -= sleep_time;
--			sleep_time = 1000000/HZ;
--		} else {
--			udelay(1);
--			cond_resched();
--			timeo--;
--		}
-+		cfi_udelay(1);
- 		spin_lock(chip->mutex);
--
--		while (chip->state != chip_state) {
--			/* Someone's suspended the operation: sleep */
--			DECLARE_WAITQUEUE(wait, current);
--			set_current_state(TASK_UNINTERRUPTIBLE);
--			add_wait_queue(&chip->wq, &wait);
--			spin_unlock(chip->mutex);
--			schedule();
--			remove_wait_queue(&chip->wq, &wait);
--			spin_lock(chip->mutex);
--		}
- 	}
- 
-+	if (!z) {
-+		if (!--(*chip_op_time))
-+			*chip_op_time = 1;
-+	} else if (z > 1)
-+		++(*chip_op_time);
-+
- 	/* Done and happy. */
-  	chip->state = FL_STATUS;
- 	return 0;
-@@ -1118,7 +1118,8 @@ static int inval_cache_and_wait_for_oper
- #endif
- 
- #define WAIT_TIMEOUT(map, chip, adr, udelay) \
--	INVAL_CACHE_AND_WAIT(map, chip, adr, 0, 0, udelay);
-+	({ int __udelay = (udelay); \
-+	   INVAL_CACHE_AND_WAIT(map, chip, adr, 0, 0, &__udelay); })
- 
- 
- static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len)
-@@ -1342,7 +1343,7 @@ static int __xipram do_write_oneword(str
- 
- 	ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
- 				   adr, map_bankwidth(map),
--				   chip->word_write_time);
-+				   &chip->word_write_time);
- 	if (ret) {
- 		xip_enable(map, chip, adr);
- 		printk(KERN_ERR "%s: word write error (status timeout)\n", map->name);
-@@ -1579,7 +1580,7 @@ static int __xipram do_write_buffer(stru
- 
- 	ret = INVAL_CACHE_AND_WAIT(map, chip, cmd_adr,
- 				   adr, len,
--				   chip->buffer_write_time);
-+				   &chip->buffer_write_time);
- 	if (ret) {
- 		map_write(map, CMD(0x70), cmd_adr);
- 		chip->state = FL_STATUS;
-@@ -1714,7 +1715,7 @@ static int __xipram do_erase_oneblock(st
- 
- 	ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
- 				   adr, len,
--				   chip->erase_time);
-+				   &chip->erase_time);
- 	if (ret) {
- 		map_write(map, CMD(0x70), adr);
- 		chip->state = FL_STATUS;

+ 0 - 19
target/linux/generic-2.6/patches-2.6.21/010-disable_old_squashfs_compatibility.patch

@@ -1,19 +0,0 @@
---- a/fs/squashfs/Makefile
-+++ b/fs/squashfs/Makefile
-@@ -4,4 +4,3 @@
- 
- obj-$(CONFIG_SQUASHFS) += squashfs.o
- squashfs-y += inode.o
--squashfs-y += squashfs2_0.o
---- a/fs/squashfs/squashfs.h
-+++ b/fs/squashfs/squashfs.h
-@@ -24,6 +24,9 @@
- #ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
- #undef CONFIG_SQUASHFS_1_0_COMPATIBILITY
- #endif
-+#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY
-+#undef CONFIG_SQUASHFS_2_0_COMPATIBILITY
-+#endif
- 
- #ifdef SQUASHFS_TRACE
- #define TRACE(s, args...)	printk(KERN_NOTICE "SQUASHFS: "s, ## args)

+ 0 - 19
target/linux/generic-2.6/patches-2.6.21/011-mips_boot.patch

@@ -1,19 +0,0 @@
---- a/arch/mips/kernel/head.S
-+++ b/arch/mips/kernel/head.S
-@@ -129,11 +129,15 @@
- #endif
- 	.endm
- 
-+
-+	j kernel_entry
-+	nop
-+
- 	/*
- 	 * Reserved space for exception handlers.
- 	 * Necessary for machines which link their kernels at KSEG0.
- 	 */
--	.fill	0x400
-+	.align 10
- 
- EXPORT(stext)					# used for profiling
- EXPORT(_stext)

+ 0 - 18
target/linux/generic-2.6/patches-2.6.21/012-mips_cpu_tlb.patch

@@ -1,18 +0,0 @@
---- a/arch/mips/mm/tlbex.c
-+++ b/arch/mips/mm/tlbex.c
-@@ -887,7 +887,6 @@ static __init void build_tlb_write_entry
- 	case CPU_R10000:
- 	case CPU_R12000:
- 	case CPU_R14000:
--	case CPU_4KC:
- 	case CPU_SB1:
- 	case CPU_SB1A:
- 	case CPU_4KSC:
-@@ -915,6 +914,7 @@ static __init void build_tlb_write_entry
- 		tlbw(p);
- 		break;
- 
-+	case CPU_4KC:
- 	case CPU_4KEC:
- 	case CPU_24K:
- 	case CPU_34K:

+ 0 - 32
target/linux/generic-2.6/patches-2.6.21/013-mips_generic_gpio_support.patch

@@ -1,32 +0,0 @@
---- a/arch/mips/defconfig
-+++ b/arch/mips/defconfig
-@@ -69,6 +69,7 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
- CONFIG_GENERIC_HWEIGHT=y
- CONFIG_GENERIC_CALIBRATE_DELAY=y
- CONFIG_GENERIC_TIME=y
-+CONFIG_GENERIC_GPIO=n
- CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
- # CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
- CONFIG_ARC=y
---- a/arch/mips/Kconfig
-+++ b/arch/mips/Kconfig
-@@ -869,6 +869,10 @@ config GENERIC_TIME
- 	bool
- 	default y
- 
-+config GENERIC_GPIO
-+	bool
-+	default n
-+
- config SCHED_NO_NO_OMIT_FRAME_POINTER
- 	bool
- 	default y
---- /dev/null
-+++ b/include/asm-mips/gpio.h
-@@ -0,0 +1,6 @@
-+#ifndef _ASM_MIPS_GPIO_H
-+#define _ASM_MIPS_GPIO_H
-+
-+#include <gpio.h>
-+
-+#endif /* _ASM_MIPS_GPIO_H */

+ 0 - 150
target/linux/generic-2.6/patches-2.6.21/024-mips_disable_fpu.patch

@@ -1,150 +0,0 @@
-MIPS: allow disabling the kernel FPU emulator
-
-This patch allows turning off the in-kernel Algorithmics
-FPU emulator support, which allows one to save a couple of
-precious blocks on an embedded system.
-
-Signed-off-by: Florian Fainelli <[email protected]>
-
---- a/arch/mips/Kconfig
-+++ b/arch/mips/Kconfig
-@@ -938,6 +938,17 @@ config LIMITED_DMA
- config MIPS_BONITO64
- 	bool
- 
-+config MIPS_FPU_EMU
-+	bool "Enable FPU emulation"
-+	default y
-+	help
-+	   This option allows building a kernel with or without the Algorithmics
-+	   FPU emulator enabled. Turning off this option results in a kernel which
-+	   does not catch floating operations exceptions. Make sure that your toolchain
-+	   is configured to enable software floating point emulation in that case.
-+		
-+	   If unsure say Y here.
-+
- config MIPS_MSC
- 	bool
- 
---- a/arch/mips/math-emu/Makefile
-+++ b/arch/mips/math-emu/Makefile
-@@ -1,11 +1,12 @@
- #
- # Makefile for the Linux/MIPS kernel FPU emulation.
- #
-+obj-y	:=	kernel_linkage.o dsemul.o cp1emu.o
- 
--obj-y	:= cp1emu.o ieee754m.o ieee754d.o ieee754dp.o ieee754sp.o ieee754.o \
-+obj-$(CONFIG_MIPS_FPU_EMU)	+= ieee754m.o ieee754d.o ieee754dp.o ieee754sp.o ieee754.o \
- 	   ieee754xcpt.o dp_frexp.o dp_modf.o dp_div.o dp_mul.o dp_sub.o \
- 	   dp_add.o dp_fsp.o dp_cmp.o dp_logb.o dp_scalb.o dp_simple.o \
- 	   dp_tint.o dp_fint.o dp_tlong.o dp_flong.o sp_frexp.o sp_modf.o \
- 	   sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_logb.o \
- 	   sp_scalb.o sp_simple.o sp_tint.o sp_fint.o sp_tlong.o sp_flong.o \
--	   dp_sqrt.o sp_sqrt.o kernel_linkage.o dsemul.o
-+	   dp_sqrt.o sp_sqrt.o
---- a/arch/mips/math-emu/cp1emu.c
-+++ b/arch/mips/math-emu/cp1emu.c
-@@ -56,6 +56,12 @@
- #endif
- #define __mips 4
- 
-+/* Further private data for which no space exists in mips_fpu_struct */
-+
-+struct mips_fpu_emulator_stats fpuemustats;
-+
-+#ifdef CONFIG_MIPS_FPU_EMU
-+
- /* Function which emulates a floating point instruction. */
- 
- static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *,
-@@ -66,10 +72,6 @@ static int fpux_emu(struct pt_regs *,
- 	struct mips_fpu_struct *, mips_instruction);
- #endif
- 
--/* Further private data for which no space exists in mips_fpu_struct */
--
--struct mips_fpu_emulator_stats fpuemustats;
--
- /* Control registers */
- 
- #define FPCREG_RID	0	/* $0  = revision id */
-@@ -1277,3 +1279,10 @@ int fpu_emulator_cop1Handler(struct pt_r
- 
- 	return sig;
- }
-+#else
-+int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
-+        int has_fpu)
-+{
-+	return 0;
-+}
-+#endif /* CONFIG_MIPS_FPU_EMU */
---- a/arch/mips/math-emu/dsemul.c
-+++ b/arch/mips/math-emu/dsemul.c
-@@ -112,6 +112,7 @@ int mips_dsemul(struct pt_regs *regs, mi
- 	return SIGILL;		/* force out of emulation loop */
- }
- 
-+#ifdef CONFIG_MIPS_FPU_EMU
- int do_dsemulret(struct pt_regs *xcp)
- {
- 	struct emuframe *fr;
-@@ -167,3 +168,9 @@ int do_dsemulret(struct pt_regs *xcp)
- 
- 	return 1;
- }
-+#else
-+int do_dsemulret(struct pt_regs *xcp)
-+{
-+	return 0;
-+}
-+#endif /* CONFIG_MIPS_FPU_EMU */
---- a/arch/mips/math-emu/kernel_linkage.c
-+++ b/arch/mips/math-emu/kernel_linkage.c
-@@ -28,6 +28,7 @@
- 
- #define SIGNALLING_NAN 0x7ff800007ff80000LL
- 
-+#ifdef CONFIG_MIPS_FPU_EMU
- void fpu_emulator_init_fpu(void)
- {
- 	static int first = 1;
-@@ -111,4 +112,36 @@ int fpu_emulator_restore_context32(struc
- 
- 	return err;
- }
--#endif
-+#endif	/* CONFIG_64BIT */
-+#else
-+
-+void fpu_emulator_init_fpu(void)
-+{
-+	printk(KERN_INFO "FPU emulator disabled, make sure your toolchain"
-+		"was compiled with software floating point support (soft-float)\n");
-+	return;
-+}
-+
-+int fpu_emulator_save_context(struct sigcontext __user *sc)
-+{
-+	return 0;
-+}
-+
-+int fpu_emulator_restore_context(struct sigcontext __user *sc)
-+{
-+	return 0;
-+}
-+
-+#ifdef CONFIG_64BIT
-+int fpu_emulator_save_context32(struct sigcontext32 __user *sc)
-+{
-+	return 0;
-+}
-+
-+int fpu_emulator_restore_context32(struct sigcontext32 __user *sc)
-+{
-+	return 0;
-+}
-+
-+#endif	/* CONFIG_64BIT */
-+#endif /* CONFIG_MIPS_FPU_EMU */

+ 0 - 488
target/linux/generic-2.6/patches-2.6.21/060-rootfs_split.patch

@@ -1,488 +0,0 @@
---- a/drivers/mtd/Kconfig
-+++ b/drivers/mtd/Kconfig
-@@ -49,6 +49,16 @@ config MTD_PARTITIONS
- 	  devices. Partitioning on NFTL 'devices' is a different - that's the
- 	  'normal' form of partitioning used on a block device.
- 
-+config MTD_ROOTFS_ROOT_DEV
-+	bool "Automatically set 'rootfs' partition to be root filesystem"
-+	depends on MTD_PARTITIONS
-+	default y
-+
-+config MTD_ROOTFS_SPLIT
-+	bool "Automatically split 'rootfs' partition for squashfs"
-+	depends on MTD_PARTITIONS
-+	default y
-+
- config MTD_REDBOOT_PARTS
- 	tristate "RedBoot partition table parsing"
- 	depends on MTD_PARTITIONS
---- a/drivers/mtd/mtdpart.c
-+++ b/drivers/mtd/mtdpart.c
-@@ -20,6 +20,8 @@
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/partitions.h>
- #include <linux/mtd/compatmac.h>
-+#include <linux/squashfs_fs.h>
-+#include <linux/root_dev.h>
- 
- /* Our partition linked list */
- static LIST_HEAD(mtd_partitions);
-@@ -308,6 +310,266 @@ int del_mtd_partitions(struct mtd_info *
- 	return 0;
- }
- 
-+static u_int32_t cur_offset = 0;
-+static int add_one_partition(struct mtd_info *master, const struct mtd_partition *part,
-+		int i, struct mtd_part **slp)
-+{
-+	struct mtd_part *slave;
-+
-+	/* allocate the partition structure */
-+	slave = kzalloc (sizeof(*slave), GFP_KERNEL);
-+	if (!slave) {
-+		printk ("memory allocation error while creating partitions for \"%s\"\n",
-+			master->name);
-+		del_mtd_partitions(master);
-+		return -ENOMEM;
-+	}
-+	list_add(&slave->list, &mtd_partitions);
-+
-+	/* set up the MTD object for this partition */
-+	slave->mtd.type = master->type;
-+	slave->mtd.flags = master->flags & ~part->mask_flags;
-+	slave->mtd.size = part->size;
-+	slave->mtd.writesize = master->writesize;
-+	slave->mtd.oobsize = master->oobsize;
-+	slave->mtd.oobavail = master->oobavail;
-+	slave->mtd.subpage_sft = master->subpage_sft;
-+
-+	slave->mtd.name = part->name;
-+	slave->mtd.bank_size = master->bank_size;
-+	slave->mtd.owner = master->owner;
-+
-+	slave->mtd.read = part_read;
-+	slave->mtd.write = part_write;
-+
-+	if(master->point && master->unpoint){
-+		slave->mtd.point = part_point;
-+		slave->mtd.unpoint = part_unpoint;
-+	}
-+
-+	if (master->read_oob)
-+		slave->mtd.read_oob = part_read_oob;
-+	if (master->write_oob)
-+		slave->mtd.write_oob = part_write_oob;
-+	if(master->read_user_prot_reg)
-+		slave->mtd.read_user_prot_reg = part_read_user_prot_reg;
-+	if(master->read_fact_prot_reg)
-+		slave->mtd.read_fact_prot_reg = part_read_fact_prot_reg;
-+	if(master->write_user_prot_reg)
-+		slave->mtd.write_user_prot_reg = part_write_user_prot_reg;
-+	if(master->lock_user_prot_reg)
-+		slave->mtd.lock_user_prot_reg = part_lock_user_prot_reg;
-+	if(master->get_user_prot_info)
-+		slave->mtd.get_user_prot_info = part_get_user_prot_info;
-+	if(master->get_fact_prot_info)
-+		slave->mtd.get_fact_prot_info = part_get_fact_prot_info;
-+	if (master->sync)
-+		slave->mtd.sync = part_sync;
-+	if (!i && master->suspend && master->resume) {
-+			slave->mtd.suspend = part_suspend;
-+			slave->mtd.resume = part_resume;
-+	}
-+	if (master->writev)
-+		slave->mtd.writev = part_writev;
-+	if (master->lock)
-+		slave->mtd.lock = part_lock;
-+	if (master->unlock)
-+		slave->mtd.unlock = part_unlock;
-+	if (master->block_isbad)
-+		slave->mtd.block_isbad = part_block_isbad;
-+	if (master->block_markbad)
-+		slave->mtd.block_markbad = part_block_markbad;
-+	slave->mtd.erase = part_erase;
-+	slave->master = master;
-+	slave->offset = part->offset;
-+	slave->index = i;
-+
-+	if (slave->offset == MTDPART_OFS_APPEND)
-+		slave->offset = cur_offset;
-+	if (slave->offset == MTDPART_OFS_NXTBLK) {
-+		slave->offset = cur_offset;
-+		if ((cur_offset % master->erasesize) != 0) {
-+			/* Round up to next erasesize */
-+			slave->offset = ((cur_offset / master->erasesize) + 1) * master->erasesize;
-+			printk(KERN_NOTICE "Moving partition %d: "
-+			       "0x%08x -> 0x%08x\n", i,
-+			       cur_offset, slave->offset);
-+		}
-+	}
-+	if (slave->mtd.size == MTDPART_SIZ_FULL)
-+		slave->mtd.size = master->size - slave->offset;
-+	cur_offset = slave->offset + slave->mtd.size;
-+
-+	printk (KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset,
-+		slave->offset + slave->mtd.size, slave->mtd.name);
-+
-+	/* let's do some sanity checks */
-+	if (slave->offset >= master->size) {
-+			/* let's register it anyway to preserve ordering */
-+		slave->offset = 0;
-+		slave->mtd.size = 0;
-+		printk ("mtd: partition \"%s\" is out of reach -- disabled\n",
-+			part->name);
-+	}
-+	if (slave->offset + slave->mtd.size > master->size) {
-+		slave->mtd.size = master->size - slave->offset;
-+		printk ("mtd: partition \"%s\" extends beyond the end of device \"%s\" -- size truncated to %#x\n",
-+			part->name, master->name, slave->mtd.size);
-+	}
-+	if (master->numeraseregions>1) {
-+		/* Deal with variable erase size stuff */
-+		int i;
-+		struct mtd_erase_region_info *regions = master->eraseregions;
-+
-+		/* Find the first erase regions which is part of this partition. */
-+		for (i=0; i < master->numeraseregions && slave->offset >= regions[i].offset; i++)
-+			;
-+
-+		for (i--; i < master->numeraseregions && slave->offset + slave->mtd.size > regions[i].offset; i++) {
-+			if (slave->mtd.erasesize < regions[i].erasesize) {
-+				slave->mtd.erasesize = regions[i].erasesize;
-+			}
-+		}
-+	} else {
-+		/* Single erase size */
-+		slave->mtd.erasesize = master->erasesize;
-+	}
-+
-+	if ((slave->mtd.flags & MTD_WRITEABLE) &&
-+	    (slave->offset % slave->mtd.erasesize)) {
-+		/* Doesn't start on a boundary of major erase size */
-+		/* FIXME: Let it be writable if it is on a boundary of _minor_ erase size though */
-+		slave->mtd.flags &= ~MTD_WRITEABLE;
-+		printk ("mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n",
-+			part->name);
-+	}
-+	if ((slave->mtd.flags & MTD_WRITEABLE) &&
-+	    (slave->mtd.size % slave->mtd.erasesize)) {
-+		slave->mtd.flags &= ~MTD_WRITEABLE;
-+		printk ("mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n",
-+			part->name);
-+	}
-+
-+	slave->mtd.ecclayout = master->ecclayout;
-+	if (master->block_isbad) {
-+		uint32_t offs = 0;
-+
-+		while(offs < slave->mtd.size) {
-+			if (master->block_isbad(master,
-+						offs + slave->offset))
-+				slave->mtd.ecc_stats.badblocks++;
-+			offs += slave->mtd.erasesize;
-+		}
-+	}
-+
-+	if(part->mtdp)
-+	{	/* store the object pointer (caller may or may not register it */
-+		*part->mtdp = &slave->mtd;
-+		slave->registered = 0;
-+	}
-+	else
-+	{
-+		/* register our partition */
-+		add_mtd_device(&slave->mtd);
-+		slave->registered = 1;
-+	}
-+
-+	if (slp)
-+		*slp = slave;
-+
-+	return 0;
-+}
-+
-+#ifdef CONFIG_MTD_ROOTFS_SPLIT
-+#define ROOTFS_SPLIT_NAME "rootfs_data"
-+static int split_squashfs(struct mtd_info *master, struct mtd_partition *old,
-+		struct mtd_partition **new)
-+{
-+	struct mtd_partition *part = NULL;
-+	int len;
-+	char buf[512];
-+	struct squashfs_super_block *sb = (struct squashfs_super_block *) buf;
-+	int ret;
-+
-+	ret = master->read(master, old->offset, sizeof(*sb), &len, buf);
-+	if (ret) {
-+		printk(KERN_ALERT "split_squashfs: error occured while reading "
-+			"from \"%s\"\n", master->name);
-+		goto out;
-+	}
-+
-+	if (len != sizeof(*sb)) {
-+		printk(KERN_ALERT "split_squashfs: unable to read superblock "
-+			"from \"%s\"\n", master->name);
-+		ret=-1;
-+		goto out;
-+	}
-+
-+	if (*((u32 *) buf) != SQUASHFS_MAGIC) {
-+		printk(KERN_ALERT "split_squasfs: no squashfs found in \"%s\"\n",
-+			master->name);
-+		ret=0;
-+		goto out;
-+	}
-+
-+	if (sb->bytes_used <= 0) {
-+		printk(KERN_ALERT "split_squashfs: squashfs is empty in \"%s\"\n",
-+			master->name);
-+		ret=0;
-+		goto out;
-+	}
-+
-+	part = kmalloc(sizeof(*part)+sizeof(ROOTFS_SPLIT_NAME)+1, GFP_KERNEL);
-+	if (part == NULL) {
-+		printk(KERN_INFO "split_squashfs: no memory for partition \"%s\"\n",
-+			ROOTFS_SPLIT_NAME);
-+		ret = -ENOMEM;
-+		goto out;
-+	}
-+
-+	memcpy(part, old, sizeof(*part));
-+	part->name = (unsigned char *)&part[1];
-+	strcpy(part->name, ROOTFS_SPLIT_NAME);
-+
-+	len = (u32) sb->bytes_used;
-+	len += (part->offset & 0x000fffff);
-+	len +=  (master->erasesize - 1);
-+	len &= ~(master->erasesize - 1);
-+	len -= (part->offset & 0x000fffff);
-+	part->offset += len;
-+	part->size -= len;
-+
-+	ret = 0;
-+
-+out:
-+	*new = part;
-+	return ret;
-+}
-+
-+static int split_rootfs_data(struct mtd_info *master, struct mtd_partition *part,
-+		int index)
-+{
-+	struct mtd_partition *dpart;
-+	int ret;
-+
-+	ret = split_squashfs(master, part, &dpart);
-+	if (ret)
-+		return ret;
-+
-+	if (dpart == NULL)
-+		return 1;
-+
-+	printk(KERN_INFO "mtd: partition \"%s\" created automatically, ofs=%X, len=%X \n",
-+		ROOTFS_SPLIT_NAME, dpart->offset, dpart->size);
-+
-+	ret = add_one_partition(master, dpart, index, NULL);
-+	if (ret)
-+		kfree(dpart);
-+
-+	return ret;
-+}
-+#endif /* CONFIG_MTD_ROOTFS_SPLIT */
-+
- /*
-  * This function, given a master MTD object and a partition table, creates
-  * and registers slave MTD objects which are bound to the master according to
-@@ -320,169 +582,31 @@ int add_mtd_partitions(struct mtd_info *
- 		       int nbparts)
- {
- 	struct mtd_part *slave;
--	u_int32_t cur_offset = 0;
--	int i;
-+	struct mtd_partition *part;
-+	int i, j, ret = 0;
- 
- 	printk (KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name);
- 
--	for (i = 0; i < nbparts; i++) {
--
--		/* allocate the partition structure */
--		slave = kzalloc (sizeof(*slave), GFP_KERNEL);
--		if (!slave) {
--			printk ("memory allocation error while creating partitions for \"%s\"\n",
--				master->name);
--			del_mtd_partitions(master);
--			return -ENOMEM;
--		}
--		list_add(&slave->list, &mtd_partitions);
--
--		/* set up the MTD object for this partition */
--		slave->mtd.type = master->type;
--		slave->mtd.flags = master->flags & ~parts[i].mask_flags;
--		slave->mtd.size = parts[i].size;
--		slave->mtd.writesize = master->writesize;
--		slave->mtd.oobsize = master->oobsize;
--		slave->mtd.oobavail = master->oobavail;
--		slave->mtd.subpage_sft = master->subpage_sft;
--
--		slave->mtd.name = parts[i].name;
--		slave->mtd.bank_size = master->bank_size;
--		slave->mtd.owner = master->owner;
--
--		slave->mtd.read = part_read;
--		slave->mtd.write = part_write;
--
--		if(master->point && master->unpoint){
--			slave->mtd.point = part_point;
--			slave->mtd.unpoint = part_unpoint;
--		}
--
--		if (master->read_oob)
--			slave->mtd.read_oob = part_read_oob;
--		if (master->write_oob)
--			slave->mtd.write_oob = part_write_oob;
--		if(master->read_user_prot_reg)
--			slave->mtd.read_user_prot_reg = part_read_user_prot_reg;
--		if(master->read_fact_prot_reg)
--			slave->mtd.read_fact_prot_reg = part_read_fact_prot_reg;
--		if(master->write_user_prot_reg)
--			slave->mtd.write_user_prot_reg = part_write_user_prot_reg;
--		if(master->lock_user_prot_reg)
--			slave->mtd.lock_user_prot_reg = part_lock_user_prot_reg;
--		if(master->get_user_prot_info)
--			slave->mtd.get_user_prot_info = part_get_user_prot_info;
--		if(master->get_fact_prot_info)
--			slave->mtd.get_fact_prot_info = part_get_fact_prot_info;
--		if (master->sync)
--			slave->mtd.sync = part_sync;
--		if (!i && master->suspend && master->resume) {
--				slave->mtd.suspend = part_suspend;
--				slave->mtd.resume = part_resume;
--		}
--		if (master->writev)
--			slave->mtd.writev = part_writev;
--		if (master->lock)
--			slave->mtd.lock = part_lock;
--		if (master->unlock)
--			slave->mtd.unlock = part_unlock;
--		if (master->block_isbad)
--			slave->mtd.block_isbad = part_block_isbad;
--		if (master->block_markbad)
--			slave->mtd.block_markbad = part_block_markbad;
--		slave->mtd.erase = part_erase;
--		slave->master = master;
--		slave->offset = parts[i].offset;
--		slave->index = i;
--
--		if (slave->offset == MTDPART_OFS_APPEND)
--			slave->offset = cur_offset;
--		if (slave->offset == MTDPART_OFS_NXTBLK) {
--			slave->offset = cur_offset;
--			if ((cur_offset % master->erasesize) != 0) {
--				/* Round up to next erasesize */
--				slave->offset = ((cur_offset / master->erasesize) + 1) * master->erasesize;
--				printk(KERN_NOTICE "Moving partition %d: "
--				       "0x%08x -> 0x%08x\n", i,
--				       cur_offset, slave->offset);
--			}
--		}
--		if (slave->mtd.size == MTDPART_SIZ_FULL)
--			slave->mtd.size = master->size - slave->offset;
--		cur_offset = slave->offset + slave->mtd.size;
--
--		printk (KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset,
--			slave->offset + slave->mtd.size, slave->mtd.name);
--
--		/* let's do some sanity checks */
--		if (slave->offset >= master->size) {
--				/* let's register it anyway to preserve ordering */
--			slave->offset = 0;
--			slave->mtd.size = 0;
--			printk ("mtd: partition \"%s\" is out of reach -- disabled\n",
--				parts[i].name);
--		}
--		if (slave->offset + slave->mtd.size > master->size) {
--			slave->mtd.size = master->size - slave->offset;
--			printk ("mtd: partition \"%s\" extends beyond the end of device \"%s\" -- size truncated to %#x\n",
--				parts[i].name, master->name, slave->mtd.size);
--		}
--		if (master->numeraseregions>1) {
--			/* Deal with variable erase size stuff */
--			int i;
--			struct mtd_erase_region_info *regions = master->eraseregions;
--
--			/* Find the first erase regions which is part of this partition. */
--			for (i=0; i < master->numeraseregions && slave->offset >= regions[i].offset; i++)
--				;
--
--			for (i--; i < master->numeraseregions && slave->offset + slave->mtd.size > regions[i].offset; i++) {
--				if (slave->mtd.erasesize < regions[i].erasesize) {
--					slave->mtd.erasesize = regions[i].erasesize;
--				}
--			}
--		} else {
--			/* Single erase size */
--			slave->mtd.erasesize = master->erasesize;
--		}
--
--		if ((slave->mtd.flags & MTD_WRITEABLE) &&
--		    (slave->offset % slave->mtd.erasesize)) {
--			/* Doesn't start on a boundary of major erase size */
--			/* FIXME: Let it be writable if it is on a boundary of _minor_ erase size though */
--			slave->mtd.flags &= ~MTD_WRITEABLE;
--			printk ("mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n",
--				parts[i].name);
--		}
--		if ((slave->mtd.flags & MTD_WRITEABLE) &&
--		    (slave->mtd.size % slave->mtd.erasesize)) {
--			slave->mtd.flags &= ~MTD_WRITEABLE;
--			printk ("mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n",
--				parts[i].name);
--		}
--
--		slave->mtd.ecclayout = master->ecclayout;
--		if (master->block_isbad) {
--			uint32_t offs = 0;
--
--			while(offs < slave->mtd.size) {
--				if (master->block_isbad(master,
--							offs + slave->offset))
--					slave->mtd.ecc_stats.badblocks++;
--				offs += slave->mtd.erasesize;
-+	for (i = 0, j = 0; i < nbparts; i++) {
-+		part = (struct mtd_partition *) &parts[i];
-+		ret = add_one_partition(master, part, j, &slave);
-+		if (ret)
-+			return ret;
-+		j++;
-+
-+		if (strcmp(part->name, "rootfs") == 0 && slave->registered) {
-+#ifdef CONFIG_MTD_ROOTFS_ROOT_DEV
-+			if (ROOT_DEV == 0) {
-+				printk(KERN_NOTICE "mtd: partition \"rootfs\" "
-+					"set to be root filesystem\n");
-+				ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, slave->mtd.index);
- 			}
--		}
--
--		if(parts[i].mtdp)
--		{	/* store the object pointer (caller may or may not register it */
--			*parts[i].mtdp = &slave->mtd;
--			slave->registered = 0;
--		}
--		else
--		{
--			/* register our partition */
--			add_mtd_device(&slave->mtd);
--			slave->registered = 1;
-+#endif
-+#ifdef CONFIG_MTD_ROOTFS_SPLIT
-+			ret = split_rootfs_data(master, part, j);
-+			if (ret == 0)
-+				j++;
-+#endif
- 		}
- 	}
- 

+ 0 - 112
target/linux/generic-2.6/patches-2.6.21/065-block2mtd_init.patch

@@ -1,112 +0,0 @@
---- a/drivers/mtd/devices/block2mtd.c
-+++ b/drivers/mtd/devices/block2mtd.c
-@@ -16,6 +16,7 @@
- #include <linux/list.h>
- #include <linux/init.h>
- #include <linux/mtd/mtd.h>
-+#include <linux/mtd/partitions.h>
- #include <linux/buffer_head.h>
- #include <linux/mutex.h>
- #include <linux/mount.h>
-@@ -288,10 +289,11 @@ static void block2mtd_free_device(struct
- 
- 
- /* FIXME: ensure that mtd->size % erase_size == 0 */
--static struct block2mtd_dev *add_device(char *devname, int erase_size)
-+static struct block2mtd_dev *add_device(char *devname, int erase_size, char *mtdname)
- {
- 	struct block_device *bdev;
- 	struct block2mtd_dev *dev;
-+	struct mtd_partition *part;
- 
- 	if (!devname)
- 		return NULL;
-@@ -330,14 +332,18 @@ static struct block2mtd_dev *add_device(
- 
- 	/* Setup the MTD structure */
- 	/* make the name contain the block device in */
--	dev->mtd.name = kmalloc(sizeof("block2mtd: ") + strlen(devname),
--			GFP_KERNEL);
-+
-+	if (!mtdname)
-+		mtdname = devname;
-+
-+	dev->mtd.name = kmalloc(strlen(mtdname) + 1, GFP_KERNEL);
-+
- 	if (!dev->mtd.name)
- 		goto devinit_err;
-+	
-+	strcpy(dev->mtd.name, mtdname);
- 
--	sprintf(dev->mtd.name, "block2mtd: %s", devname);
--
--	dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK;
-+	dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK & ~(erase_size - 1);
- 	dev->mtd.erasesize = erase_size;
- 	dev->mtd.writesize = 1;
- 	dev->mtd.type = MTD_RAM;
-@@ -349,15 +355,18 @@ static struct block2mtd_dev *add_device(
- 	dev->mtd.read = block2mtd_read;
- 	dev->mtd.priv = dev;
- 	dev->mtd.owner = THIS_MODULE;
--
--	if (add_mtd_device(&dev->mtd)) {
-+	
-+	part = kzalloc(sizeof(struct mtd_partition), GFP_KERNEL);
-+	part->name = dev->mtd.name;
-+	part->offset = 0;
-+	part->size = dev->mtd.size;
-+	if (add_mtd_partitions(&dev->mtd, part, 1)) {
- 		/* Device didnt get added, so free the entry */
- 		goto devinit_err;
- 	}
- 	list_add(&dev->list, &blkmtd_device_list);
- 	INFO("mtd%d: [%s] erase_size = %dKiB [%d]", dev->mtd.index,
--			dev->mtd.name + strlen("blkmtd: "),
--			dev->mtd.erasesize >> 10, dev->mtd.erasesize);
-+			mtdname, dev->mtd.erasesize >> 10, dev->mtd.erasesize);
- 	return dev;
- 
- devinit_err:
-@@ -430,9 +439,9 @@ static __initdata char block2mtd_paramli
- 
- static int block2mtd_setup2(const char *val)
- {
--	char buf[80 + 12]; /* 80 for device, 12 for erase size */
-+	char buf[80 + 12 + 80]; /* 80 for device, 12 for erase size, 80 for name */
- 	char *str = buf;
--	char *token[2];
-+	char *token[3];
- 	char *name;
- 	size_t erase_size = PAGE_SIZE;
- 	int i, ret;
-@@ -443,7 +452,7 @@ static int block2mtd_setup2(const char *
- 	strcpy(str, val);
- 	kill_final_newline(str);
- 
--	for (i = 0; i < 2; i++)
-+	for (i = 0; i < 3; i++)
- 		token[i] = strsep(&str, ",");
- 
- 	if (str)
-@@ -463,8 +472,10 @@ static int block2mtd_setup2(const char *
- 			parse_err("illegal erase size");
- 		}
- 	}
-+	if (token[2] && (strlen(token[2]) + 1 > 80))
-+		parse_err("mtd device name too long");
- 
--	add_device(name, erase_size);
-+	add_device(name, erase_size, token[2]);
- 
- 	return 0;
- }
-@@ -498,7 +509,7 @@ static int block2mtd_setup(const char *v
- 
- 
- module_param_call(block2mtd, block2mtd_setup, NULL, NULL, 0200);
--MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>]\"");
-+MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>[,<name>]]\"");
- 
- static int __init block2mtd_init(void)
- {

+ 0 - 2106
target/linux/generic-2.6/patches-2.6.21/100-netfilter_layer7_2.21.patch

@@ -1,2106 +0,0 @@
---- /dev/null
-+++ b/include/linux/netfilter/xt_layer7.h
-@@ -0,0 +1,13 @@
-+#ifndef _XT_LAYER7_H
-+#define _XT_LAYER7_H
-+
-+#define MAX_PATTERN_LEN 8192
-+#define MAX_PROTOCOL_LEN 256
-+
-+struct xt_layer7_info {
-+    char protocol[MAX_PROTOCOL_LEN];
-+    char invert:1;
-+    char pattern[MAX_PATTERN_LEN];
-+};
-+
-+#endif /* _XT_LAYER7_H */
---- a/include/net/netfilter/nf_conntrack.h
-+++ b/include/net/netfilter/nf_conntrack.h
-@@ -128,6 +128,22 @@ struct nf_conn
- 	u_int32_t secmark;
- #endif
- 
-+#if defined(CONFIG_NETFILTER_XT_MATCH_LAYER7) || \
-+    defined(CONFIG_NETFILTER_XT_MATCH_LAYER7_MODULE)
-+	struct {
-+		/*
-+		 * e.g. "http". NULL before decision. "unknown" after decision
-+		 * if no match.
-+		 */
-+		char *app_proto;
-+		/*
-+		 * application layer data so far. NULL after match decision.
-+		 */
-+		char *app_data;
-+		unsigned int app_data_len;
-+	} layer7;
-+#endif
-+
- 	/* Storage reserved for other modules: */
- 	union nf_conntrack_proto proto;
- 
---- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
-+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
-@@ -163,6 +163,12 @@ static int ct_seq_show(struct seq_file *
- 		return -ENOSPC;
- #endif
- 
-+#if defined(CONFIG_NETFILTER_XT_MATCH_LAYER7) || defined(CONFIG_NETFILTER_XT_MATCH_LAYER7_MODULE)
-+	if(ct->layer7.app_proto)
-+		if(seq_printf(s, "l7proto=%s ", ct->layer7.app_proto))
-+			return -ENOSPC;
-+#endif
-+
- 	if (seq_printf(s, "use=%u\n", atomic_read(&ct->ct_general.use)))
- 		return -ENOSPC;
- 
---- a/net/netfilter/Kconfig
-+++ b/net/netfilter/Kconfig
-@@ -640,6 +640,27 @@ config NETFILTER_XT_MATCH_STATE
- 
- 	  To compile it as a module, choose M here.  If unsure, say N.
- 
-+config NETFILTER_XT_MATCH_LAYER7
-+	tristate '"layer7" match support'
-+	depends on NETFILTER_XTABLES
-+	depends on IP_NF_CONNTRACK || NF_CONNTRACK
-+       depends on NF_CT_ACCT
-+	help
-+	  Say Y if you want to be able to classify connections (and their
-+	  packets) based on regular expression matching of their application
-+	  layer data.   This is one way to classify applications such as
-+	  peer-to-peer filesharing systems that do not always use the same
-+	  port.
-+
-+	  To compile it as a module, choose M here.  If unsure, say N.
-+
-+config NETFILTER_XT_MATCH_LAYER7_DEBUG
-+        bool 'layer7 debugging output'
-+        depends on NETFILTER_XT_MATCH_LAYER7
-+        help
-+          Say Y to get lots of debugging output.
-+
-+
- config NETFILTER_XT_MATCH_STATISTIC
- 	tristate '"statistic" match support'
- 	depends on NETFILTER_XTABLES
---- a/net/netfilter/Makefile
-+++ b/net/netfilter/Makefile
-@@ -68,6 +68,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) +
- obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o
- obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o
- obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o
-+obj-$(CONFIG_NETFILTER_XT_MATCH_LAYER7) += xt_layer7.o
- obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o
- obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o
- obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o
---- a/net/netfilter/nf_conntrack_core.c
-+++ b/net/netfilter/nf_conntrack_core.c
-@@ -352,6 +352,14 @@ destroy_conntrack(struct nf_conntrack *n
- 	 * too. */
- 	nf_ct_remove_expectations(ct);
- 
-+	#if defined(CONFIG_NETFILTER_XT_MATCH_LAYER7) || defined(CONFIG_NETFILTER_XT_MATCH_LAYER7_MODULE)
-+	if(ct->layer7.app_proto)
-+		kfree(ct->layer7.app_proto);
-+	if(ct->layer7.app_data)
-+	kfree(ct->layer7.app_data);
-+	#endif
-+
-+
- 	/* We overload first tuple to link into unconfirmed list. */
- 	if (!nf_ct_is_confirmed(ct)) {
- 		BUG_ON(list_empty(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list));
---- a/net/netfilter/nf_conntrack_standalone.c
-+++ b/net/netfilter/nf_conntrack_standalone.c
-@@ -195,6 +195,11 @@ static int ct_seq_show(struct seq_file *
- 		return -ENOSPC;
- #endif
- 
-+#if defined(CONFIG_NETFILTER_XT_MATCH_LAYER7) || defined(CONFIG_NETFILTER_XT_MATCH_LAYER7_MODULE)
-+	if(conntrack->layer7.app_proto)
-+		if(seq_printf(s, "l7proto=%s ",conntrack->layer7.app_proto))
-+			return -ENOSPC;
-+#endif
- 	if (seq_printf(s, "use=%u\n", atomic_read(&conntrack->ct_general.use)))
- 		return -ENOSPC;
- 	
---- /dev/null
-+++ b/net/netfilter/regexp/regexp.c
-@@ -0,0 +1,1197 @@
-+/*
-+ * regcomp and regexec -- regsub and regerror are elsewhere
-+ * @(#)regexp.c	1.3 of 18 April 87
-+ *
-+ *	Copyright (c) 1986 by University of Toronto.
-+ *	Written by Henry Spencer.  Not derived from licensed software.
-+ *
-+ *	Permission is granted to anyone to use this software for any
-+ *	purpose on any computer system, and to redistribute it freely,
-+ *	subject to the following restrictions:
-+ *
-+ *	1. The author is not responsible for the consequences of use of
-+ *		this software, no matter how awful, even if they arise
-+ *		from defects in it.
-+ *
-+ *	2. The origin of this software must not be misrepresented, either
-+ *		by explicit claim or by omission.
-+ *
-+ *	3. Altered versions must be plainly marked as such, and must not
-+ *		be misrepresented as being the original software.
-+ *
-+ * Beware that some of this code is subtly aware of the way operator
-+ * precedence is structured in regular expressions.  Serious changes in
-+ * regular-expression syntax might require a total rethink.
-+ *
-+ * This code was modified by Ethan Sommer to work within the kernel
-+ * (it now uses kmalloc etc..)
-+ *
-+ * Modified slightly by Matthew Strait to use more modern C.
-+ */
-+
-+#include "regexp.h"
-+#include "regmagic.h"
-+
-+/* added by ethan and matt.  Lets it work in both kernel and user space.
-+(So iptables can use it, for instance.)  Yea, it goes both ways... */
-+#if __KERNEL__
-+  #define malloc(foo) kmalloc(foo,GFP_ATOMIC)
-+#else
-+  #define printk(format,args...) printf(format,##args)
-+#endif
-+
-+void regerror(char * s)
-+{
-+        printk("<3>Regexp: %s\n", s);
-+        /* NOTREACHED */
-+}
-+
-+/*
-+ * The "internal use only" fields in regexp.h are present to pass info from
-+ * compile to execute that permits the execute phase to run lots faster on
-+ * simple cases.  They are:
-+ *
-+ * regstart	char that must begin a match; '\0' if none obvious
-+ * reganch	is the match anchored (at beginning-of-line only)?
-+ * regmust	string (pointer into program) that match must include, or NULL
-+ * regmlen	length of regmust string
-+ *
-+ * Regstart and reganch permit very fast decisions on suitable starting points
-+ * for a match, cutting down the work a lot.  Regmust permits fast rejection
-+ * of lines that cannot possibly match.  The regmust tests are costly enough
-+ * that regcomp() supplies a regmust only if the r.e. contains something
-+ * potentially expensive (at present, the only such thing detected is * or +
-+ * at the start of the r.e., which can involve a lot of backup).  Regmlen is
-+ * supplied because the test in regexec() needs it and regcomp() is computing
-+ * it anyway.
-+ */
-+
-+/*
-+ * Structure for regexp "program".  This is essentially a linear encoding
-+ * of a nondeterministic finite-state machine (aka syntax charts or
-+ * "railroad normal form" in parsing technology).  Each node is an opcode
-+ * plus a "next" pointer, possibly plus an operand.  "Next" pointers of
-+ * all nodes except BRANCH implement concatenation; a "next" pointer with
-+ * a BRANCH on both ends of it is connecting two alternatives.  (Here we
-+ * have one of the subtle syntax dependencies:  an individual BRANCH (as
-+ * opposed to a collection of them) is never concatenated with anything
-+ * because of operator precedence.)  The operand of some types of node is
-+ * a literal string; for others, it is a node leading into a sub-FSM.  In
-+ * particular, the operand of a BRANCH node is the first node of the branch.
-+ * (NB this is *not* a tree structure:  the tail of the branch connects
-+ * to the thing following the set of BRANCHes.)  The opcodes are:
-+ */
-+
-+/* definition	number	opnd?	meaning */
-+#define	END	0	/* no	End of program. */
-+#define	BOL	1	/* no	Match "" at beginning of line. */
-+#define	EOL	2	/* no	Match "" at end of line. */
-+#define	ANY	3	/* no	Match any one character. */
-+#define	ANYOF	4	/* str	Match any character in this string. */
-+#define	ANYBUT	5	/* str	Match any character not in this string. */
-+#define	BRANCH	6	/* node	Match this alternative, or the next... */
-+#define	BACK	7	/* no	Match "", "next" ptr points backward. */
-+#define	EXACTLY	8	/* str	Match this string. */
-+#define	NOTHING	9	/* no	Match empty string. */
-+#define	STAR	10	/* node	Match this (simple) thing 0 or more times. */
-+#define	PLUS	11	/* node	Match this (simple) thing 1 or more times. */
-+#define	OPEN	20	/* no	Mark this point in input as start of #n. */
-+			/*	OPEN+1 is number 1, etc. */
-+#define	CLOSE	30	/* no	Analogous to OPEN. */
-+
-+/*
-+ * Opcode notes:
-+ *
-+ * BRANCH	The set of branches constituting a single choice are hooked
-+ *		together with their "next" pointers, since precedence prevents
-+ *		anything being concatenated to any individual branch.  The
-+ *		"next" pointer of the last BRANCH in a choice points to the
-+ *		thing following the whole choice.  This is also where the
-+ *		final "next" pointer of each individual branch points; each
-+ *		branch starts with the operand node of a BRANCH node.
-+ *
-+ * BACK		Normal "next" pointers all implicitly point forward; BACK
-+ *		exists to make loop structures possible.
-+ *
-+ * STAR,PLUS	'?', and complex '*' and '+', are implemented as circular
-+ *		BRANCH structures using BACK.  Simple cases (one character
-+ *		per match) are implemented with STAR and PLUS for speed
-+ *		and to minimize recursive plunges.
-+ *
-+ * OPEN,CLOSE	...are numbered at compile time.
-+ */
-+
-+/*
-+ * A node is one char of opcode followed by two chars of "next" pointer.
-+ * "Next" pointers are stored as two 8-bit pieces, high order first.  The
-+ * value is a positive offset from the opcode of the node containing it.
-+ * An operand, if any, simply follows the node.  (Note that much of the
-+ * code generation knows about this implicit relationship.)
-+ *
-+ * Using two bytes for the "next" pointer is vast overkill for most things,
-+ * but allows patterns to get big without disasters.
-+ */
-+#define	OP(p)	(*(p))
-+#define	NEXT(p)	(((*((p)+1)&0377)<<8) + (*((p)+2)&0377))
-+#define	OPERAND(p)	((p) + 3)
-+
-+/*
-+ * See regmagic.h for one further detail of program structure.
-+ */
-+
-+
-+/*
-+ * Utility definitions.
-+ */
-+#ifndef CHARBITS
-+#define	UCHARAT(p)	((int)*(unsigned char *)(p))
-+#else
-+#define	UCHARAT(p)	((int)*(p)&CHARBITS)
-+#endif
-+
-+#define	FAIL(m)	{ regerror(m); return(NULL); }
-+#define	ISMULT(c)	((c) == '*' || (c) == '+' || (c) == '?')
-+#define	META	"^$.[()|?+*\\"
-+
-+/*
-+ * Flags to be passed up and down.
-+ */
-+#define	HASWIDTH	01	/* Known never to match null string. */
-+#define	SIMPLE		02	/* Simple enough to be STAR/PLUS operand. */
-+#define	SPSTART		04	/* Starts with * or +. */
-+#define	WORST		0	/* Worst case. */
-+
-+/*
-+ * Global work variables for regcomp().
-+ */
-+struct match_globals {
-+char *reginput;		/* String-input pointer. */
-+char *regbol;		/* Beginning of input, for ^ check. */
-+char **regstartp;	/* Pointer to startp array. */
-+char **regendp;		/* Ditto for endp. */
-+char *regparse;		/* Input-scan pointer. */
-+int regnpar;		/* () count. */
-+char regdummy;
-+char *regcode;		/* Code-emit pointer; &regdummy = don't. */
-+long regsize;		/* Code size. */
-+};
-+
-+/*
-+ * Forward declarations for regcomp()'s friends.
-+ */
-+#ifndef STATIC
-+#define	STATIC	static
-+#endif
-+STATIC char *reg(struct match_globals *g, int paren,int *flagp);
-+STATIC char *regbranch(struct match_globals *g, int *flagp);
-+STATIC char *regpiece(struct match_globals *g, int *flagp);
-+STATIC char *regatom(struct match_globals *g, int *flagp);
-+STATIC char *regnode(struct match_globals *g, char op);
-+STATIC char *regnext(struct match_globals *g, char *p);
-+STATIC void regc(struct match_globals *g, char b);
-+STATIC void reginsert(struct match_globals *g, char op, char *opnd);
-+STATIC void regtail(struct match_globals *g, char *p, char *val);
-+STATIC void regoptail(struct match_globals *g, char *p, char *val);
-+
-+
-+__kernel_size_t my_strcspn(const char *s1,const char *s2)
-+{
-+        char *scan1;
-+        char *scan2;
-+        int count;
-+
-+        count = 0;
-+        for (scan1 = (char *)s1; *scan1 != '\0'; scan1++) {
-+                for (scan2 = (char *)s2; *scan2 != '\0';)       /* ++ moved down. */
-+                        if (*scan1 == *scan2++)
-+                                return(count);
-+                count++;
-+        }
-+        return(count);
-+}
-+
-+/*
-+ - regcomp - compile a regular expression into internal code
-+ *
-+ * We can't allocate space until we know how big the compiled form will be,
-+ * but we can't compile it (and thus know how big it is) until we've got a
-+ * place to put the code.  So we cheat:  we compile it twice, once with code
-+ * generation turned off and size counting turned on, and once "for real".
-+ * This also means that we don't allocate space until we are sure that the
-+ * thing really will compile successfully, and we never have to move the
-+ * code and thus invalidate pointers into it.  (Note that it has to be in
-+ * one piece because free() must be able to free it all.)
-+ *
-+ * Beware that the optimization-preparation code in here knows about some
-+ * of the structure of the compiled regexp.
-+ */
-+regexp *
-+regcomp(char *exp,int *patternsize)
-+{
-+	register regexp *r;
-+	register char *scan;
-+	register char *longest;
-+	register int len;
-+	int flags;
-+	struct match_globals g;
-+	
-+	/* commented out by ethan
-+	   extern char *malloc();
-+	*/
-+
-+	if (exp == NULL)
-+		FAIL("NULL argument");
-+
-+	/* First pass: determine size, legality. */
-+	g.regparse = exp;
-+	g.regnpar = 1;
-+	g.regsize = 0L;
-+	g.regcode = &g.regdummy;
-+	regc(&g, MAGIC);
-+	if (reg(&g, 0, &flags) == NULL)
-+		return(NULL);
-+
-+	/* Small enough for pointer-storage convention? */
-+	if (g.regsize >= 32767L)		/* Probably could be 65535L. */
-+		FAIL("regexp too big");
-+
-+	/* Allocate space. */
-+	*patternsize=sizeof(regexp) + (unsigned)g.regsize;
-+	r = (regexp *)malloc(sizeof(regexp) + (unsigned)g.regsize);
-+	if (r == NULL)
-+		FAIL("out of space");
-+
-+	/* Second pass: emit code. */
-+	g.regparse = exp;
-+	g.regnpar = 1;
-+	g.regcode = r->program;
-+	regc(&g, MAGIC);
-+	if (reg(&g, 0, &flags) == NULL)
-+		return(NULL);
-+
-+	/* Dig out information for optimizations. */
-+	r->regstart = '\0';	/* Worst-case defaults. */
-+	r->reganch = 0;
-+	r->regmust = NULL;
-+	r->regmlen = 0;
-+	scan = r->program+1;			/* First BRANCH. */
-+	if (OP(regnext(&g, scan)) == END) {		/* Only one top-level choice. */
-+		scan = OPERAND(scan);
-+
-+		/* Starting-point info. */
-+		if (OP(scan) == EXACTLY)
-+			r->regstart = *OPERAND(scan);
-+		else if (OP(scan) == BOL)
-+			r->reganch++;
-+
-+		/*
-+		 * If there's something expensive in the r.e., find the
-+		 * longest literal string that must appear and make it the
-+		 * regmust.  Resolve ties in favor of later strings, since
-+		 * the regstart check works with the beginning of the r.e.
-+		 * and avoiding duplication strengthens checking.  Not a
-+		 * strong reason, but sufficient in the absence of others.
-+		 */
-+		if (flags&SPSTART) {
-+			longest = NULL;
-+			len = 0;
-+			for (; scan != NULL; scan = regnext(&g, scan))
-+				if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) {
-+					longest = OPERAND(scan);
-+					len = strlen(OPERAND(scan));
-+				}
-+			r->regmust = longest;
-+			r->regmlen = len;
-+		}
-+	}
-+
-+	return(r);
-+}
-+
-+/*
-+ - reg - regular expression, i.e. main body or parenthesized thing
-+ *
-+ * Caller must absorb opening parenthesis.
-+ *
-+ * Combining parenthesis handling with the base level of regular expression
-+ * is a trifle forced, but the need to tie the tails of the branches to what
-+ * follows makes it hard to avoid.
-+ */
-+static char *
-+reg(struct match_globals *g, int paren, int *flagp /* Parenthesized? */ )
-+{
-+	register char *ret;
-+	register char *br;
-+	register char *ender;
-+	register int parno = 0; /* 0 makes gcc happy */
-+	int flags;
-+
-+	*flagp = HASWIDTH;	/* Tentatively. */
-+
-+	/* Make an OPEN node, if parenthesized. */
-+	if (paren) {
-+		if (g->regnpar >= NSUBEXP)
-+			FAIL("too many ()");
-+		parno = g->regnpar;
-+		g->regnpar++;
-+		ret = regnode(g, OPEN+parno);
-+	} else
-+		ret = NULL;
-+
-+	/* Pick up the branches, linking them together. */
-+	br = regbranch(g, &flags);
-+	if (br == NULL)
-+		return(NULL);
-+	if (ret != NULL)
-+		regtail(g, ret, br);	/* OPEN -> first. */
-+	else
-+		ret = br;
-+	if (!(flags&HASWIDTH))
-+		*flagp &= ~HASWIDTH;
-+	*flagp |= flags&SPSTART;
-+	while (*g->regparse == '|') {
-+		g->regparse++;
-+		br = regbranch(g, &flags);
-+		if (br == NULL)
-+			return(NULL);
-+		regtail(g, ret, br);	/* BRANCH -> BRANCH. */
-+		if (!(flags&HASWIDTH))
-+			*flagp &= ~HASWIDTH;
-+		*flagp |= flags&SPSTART;
-+	}
-+
-+	/* Make a closing node, and hook it on the end. */
-+	ender = regnode(g, (paren) ? CLOSE+parno : END);	
-+	regtail(g, ret, ender);
-+
-+	/* Hook the tails of the branches to the closing node. */
-+	for (br = ret; br != NULL; br = regnext(g, br))
-+		regoptail(g, br, ender);
-+
-+	/* Check for proper termination. */
-+	if (paren && *g->regparse++ != ')') {
-+		FAIL("unmatched ()");
-+	} else if (!paren && *g->regparse != '\0') {
-+		if (*g->regparse == ')') {
-+			FAIL("unmatched ()");
-+		} else
-+			FAIL("junk on end");	/* "Can't happen". */
-+		/* NOTREACHED */
-+	}
-+
-+	return(ret);
-+}
-+
-+/*
-+ - regbranch - one alternative of an | operator
-+ *
-+ * Implements the concatenation operator.
-+ */
-+static char *
-+regbranch(struct match_globals *g, int *flagp)
-+{
-+	register char *ret;
-+	register char *chain;
-+	register char *latest;
-+	int flags;
-+
-+	*flagp = WORST;		/* Tentatively. */
-+
-+	ret = regnode(g, BRANCH);
-+	chain = NULL;
-+	while (*g->regparse != '\0' && *g->regparse != '|' && *g->regparse != ')') {
-+		latest = regpiece(g, &flags);
-+		if (latest == NULL)
-+			return(NULL);
-+		*flagp |= flags&HASWIDTH;
-+		if (chain == NULL)	/* First piece. */
-+			*flagp |= flags&SPSTART;
-+		else
-+			regtail(g, chain, latest);
-+		chain = latest;
-+	}
-+	if (chain == NULL)	/* Loop ran zero times. */
-+		(void) regnode(g, NOTHING);
-+
-+	return(ret);
-+}
-+
-+/*
-+ - regpiece - something followed by possible [*+?]
-+ *
-+ * Note that the branching code sequences used for ? and the general cases
-+ * of * and + are somewhat optimized:  they use the same NOTHING node as
-+ * both the endmarker for their branch list and the body of the last branch.
-+ * It might seem that this node could be dispensed with entirely, but the
-+ * endmarker role is not redundant.
-+ */
-+static char *
-+regpiece(struct match_globals *g, int *flagp)
-+{
-+	register char *ret;
-+	register char op;
-+	register char *next;
-+	int flags;
-+
-+	ret = regatom(g, &flags);
-+	if (ret == NULL)
-+		return(NULL);
-+
-+	op = *g->regparse;
-+	if (!ISMULT(op)) {
-+		*flagp = flags;
-+		return(ret);
-+	}
-+
-+	if (!(flags&HASWIDTH) && op != '?')
-+		FAIL("*+ operand could be empty");
-+	*flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH);
-+
-+	if (op == '*' && (flags&SIMPLE))
-+		reginsert(g, STAR, ret);
-+	else if (op == '*') {
-+		/* Emit x* as (x&|), where & means "self". */
-+		reginsert(g, BRANCH, ret);			/* Either x */
-+		regoptail(g, ret, regnode(g, BACK));		/* and loop */
-+		regoptail(g, ret, ret);			/* back */
-+		regtail(g, ret, regnode(g, BRANCH));		/* or */
-+		regtail(g, ret, regnode(g, NOTHING));		/* null. */
-+	} else if (op == '+' && (flags&SIMPLE))
-+		reginsert(g, PLUS, ret);
-+	else if (op == '+') {
-+		/* Emit x+ as x(&|), where & means "self". */
-+		next = regnode(g, BRANCH);			/* Either */
-+		regtail(g, ret, next);
-+		regtail(g, regnode(g, BACK), ret);		/* loop back */
-+		regtail(g, next, regnode(g, BRANCH));		/* or */
-+		regtail(g, ret, regnode(g, NOTHING));		/* null. */
-+	} else if (op == '?') {
-+		/* Emit x? as (x|) */
-+		reginsert(g, BRANCH, ret);			/* Either x */
-+		regtail(g, ret, regnode(g, BRANCH));		/* or */
-+		next = regnode(g, NOTHING);		/* null. */
-+		regtail(g, ret, next);
-+		regoptail(g, ret, next);
-+	}
-+	g->regparse++;
-+	if (ISMULT(*g->regparse))
-+		FAIL("nested *?+");
-+
-+	return(ret);
-+}
-+
-+/*
-+ - regatom - the lowest level
-+ *
-+ * Optimization:  gobbles an entire sequence of ordinary characters so that
-+ * it can turn them into a single node, which is smaller to store and
-+ * faster to run.  Backslashed characters are exceptions, each becoming a
-+ * separate node; the code is simpler that way and it's not worth fixing.
-+ */
-+static char *
-+regatom(struct match_globals *g, int *flagp)
-+{
-+	register char *ret;
-+	int flags;
-+
-+	*flagp = WORST;		/* Tentatively. */
-+
-+	switch (*g->regparse++) {
-+	case '^':
-+		ret = regnode(g, BOL);
-+		break;
-+	case '$':
-+		ret = regnode(g, EOL);
-+		break;
-+	case '.':
-+		ret = regnode(g, ANY);
-+		*flagp |= HASWIDTH|SIMPLE;
-+		break;
-+	case '[': {
-+			register int class;
-+			register int classend;
-+
-+			if (*g->regparse == '^') {	/* Complement of range. */
-+				ret = regnode(g, ANYBUT);
-+				g->regparse++;
-+			} else
-+				ret = regnode(g, ANYOF);
-+			if (*g->regparse == ']' || *g->regparse == '-')
-+				regc(g, *g->regparse++);
-+			while (*g->regparse != '\0' && *g->regparse != ']') {
-+				if (*g->regparse == '-') {
-+					g->regparse++;
-+					if (*g->regparse == ']' || *g->regparse == '\0')
-+						regc(g, '-');
-+					else {
-+						class = UCHARAT(g->regparse-2)+1;
-+						classend = UCHARAT(g->regparse);
-+						if (class > classend+1)
-+							FAIL("invalid [] range");
-+						for (; class <= classend; class++)
-+							regc(g, class);
-+						g->regparse++;
-+					}
-+				} else
-+					regc(g, *g->regparse++);
-+			}
-+			regc(g, '\0');
-+			if (*g->regparse != ']')
-+				FAIL("unmatched []");
-+			g->regparse++;
-+			*flagp |= HASWIDTH|SIMPLE;
-+		}
-+		break;
-+	case '(':
-+		ret = reg(g, 1, &flags);
-+		if (ret == NULL)
-+			return(NULL);
-+		*flagp |= flags&(HASWIDTH|SPSTART);
-+		break;
-+	case '\0':
-+	case '|':
-+	case ')':
-+		FAIL("internal urp");	/* Supposed to be caught earlier. */
-+		break;
-+	case '?':
-+	case '+':
-+	case '*':
-+		FAIL("?+* follows nothing");
-+		break;
-+	case '\\':
-+		if (*g->regparse == '\0')
-+			FAIL("trailing \\");
-+		ret = regnode(g, EXACTLY);
-+		regc(g, *g->regparse++);
-+		regc(g, '\0');
-+		*flagp |= HASWIDTH|SIMPLE;
-+		break;
-+	default: {
-+			register int len;
-+			register char ender;
-+
-+			g->regparse--;
-+			len = my_strcspn((const char *)g->regparse, (const char *)META);
-+			if (len <= 0)
-+				FAIL("internal disaster");
-+			ender = *(g->regparse+len);
-+			if (len > 1 && ISMULT(ender))
-+				len--;		/* Back off clear of ?+* operand. */
-+			*flagp |= HASWIDTH;
-+			if (len == 1)
-+				*flagp |= SIMPLE;
-+			ret = regnode(g, EXACTLY);
-+			while (len > 0) {
-+				regc(g, *g->regparse++);
-+				len--;
-+			}
-+			regc(g, '\0');
-+		}
-+		break;
-+	}
-+
-+	return(ret);
-+}
-+
-+/*
-+ - regnode - emit a node
-+ */
-+static char *			/* Location. */
-+regnode(struct match_globals *g, char op)
-+{
-+	register char *ret;
-+	register char *ptr;
-+
-+	ret = g->regcode;
-+	if (ret == &g->regdummy) {
-+		g->regsize += 3;
-+		return(ret);
-+	}
-+
-+	ptr = ret;
-+	*ptr++ = op;
-+	*ptr++ = '\0';		/* Null "next" pointer. */
-+	*ptr++ = '\0';
-+	g->regcode = ptr;
-+
-+	return(ret);
-+}
-+
-+/*
-+ - regc - emit (if appropriate) a byte of code
-+ */
-+static void
-+regc(struct match_globals *g, char b)
-+{
-+	if (g->regcode != &g->regdummy)
-+		*g->regcode++ = b;
-+	else
-+		g->regsize++;
-+}
-+
-+/*
-+ - reginsert - insert an operator in front of already-emitted operand
-+ *
-+ * Means relocating the operand.
-+ */
-+static void
-+reginsert(struct match_globals *g, char op, char* opnd)
-+{
-+	register char *src;
-+	register char *dst;
-+	register char *place;
-+
-+	if (g->regcode == &g->regdummy) {
-+		g->regsize += 3;
-+		return;
-+	}
-+
-+	src = g->regcode;
-+	g->regcode += 3;
-+	dst = g->regcode;
-+	while (src > opnd)
-+		*--dst = *--src;
-+
-+	place = opnd;		/* Op node, where operand used to be. */
-+	*place++ = op;
-+	*place++ = '\0';
-+	*place++ = '\0';
-+}
-+
-+/*
-+ - regtail - set the next-pointer at the end of a node chain
-+ */
-+static void
-+regtail(struct match_globals *g, char *p, char *val)
-+{
-+	register char *scan;
-+	register char *temp;
-+	register int offset;
-+
-+	if (p == &g->regdummy)
-+		return;
-+
-+	/* Find last node. */
-+	scan = p;
-+	for (;;) {
-+		temp = regnext(g, scan);
-+		if (temp == NULL)
-+			break;
-+		scan = temp;
-+	}
-+
-+	if (OP(scan) == BACK)
-+		offset = scan - val;
-+	else
-+		offset = val - scan;
-+	*(scan+1) = (offset>>8)&0377;
-+	*(scan+2) = offset&0377;
-+}
-+
-+/*
-+ - regoptail - regtail on operand of first argument; nop if operandless
-+ */
-+static void
-+regoptail(struct match_globals *g, char *p, char *val)
-+{
-+	/* "Operandless" and "op != BRANCH" are synonymous in practice. */
-+	if (p == NULL || p == &g->regdummy || OP(p) != BRANCH)
-+		return;
-+	regtail(g, OPERAND(p), val);
-+}
-+
-+/*
-+ * regexec and friends
-+ */
-+
-+
-+/*
-+ * Forwards.
-+ */
-+STATIC int regtry(struct match_globals *g, regexp *prog, char *string);
-+STATIC int regmatch(struct match_globals *g, char *prog);
-+STATIC int regrepeat(struct match_globals *g, char *p);
-+
-+#ifdef DEBUG
-+int regnarrate = 0;
-+void regdump();
-+STATIC char *regprop(char *op);
-+#endif
-+
-+/*
-+ - regexec - match a regexp against a string
-+ */
-+int
-+regexec(regexp *prog, char *string)
-+{
-+	register char *s;
-+	struct match_globals g;
-+
-+	/* Be paranoid... */
-+	if (prog == NULL || string == NULL) {
-+		printk("<3>Regexp: NULL parameter\n");
-+		return(0);
-+	}
-+
-+	/* Check validity of program. */
-+	if (UCHARAT(prog->program) != MAGIC) {
-+		printk("<3>Regexp: corrupted program\n");
-+		return(0);
-+	}
-+
-+	/* If there is a "must appear" string, look for it. */
-+	if (prog->regmust != NULL) {
-+		s = string;
-+		while ((s = strchr(s, prog->regmust[0])) != NULL) {
-+			if (strncmp(s, prog->regmust, prog->regmlen) == 0)
-+				break;	/* Found it. */
-+			s++;
-+		}
-+		if (s == NULL)	/* Not present. */
-+			return(0);
-+	}
-+
-+	/* Mark beginning of line for ^ . */
-+	g.regbol = string;
-+
-+	/* Simplest case:  anchored match need be tried only once. */
-+	if (prog->reganch)
-+		return(regtry(&g, prog, string));
-+
-+	/* Messy cases:  unanchored match. */
-+	s = string;
-+	if (prog->regstart != '\0')
-+		/* We know what char it must start with. */
-+		while ((s = strchr(s, prog->regstart)) != NULL) {
-+			if (regtry(&g, prog, s))
-+				return(1);
-+			s++;
-+		}
-+	else
-+		/* We don't -- general case. */
-+		do {
-+			if (regtry(&g, prog, s))
-+				return(1);
-+		} while (*s++ != '\0');
-+
-+	/* Failure. */
-+	return(0);
-+}
-+
-+/*
-+ - regtry - try match at specific point
-+ */
-+static int			/* 0 failure, 1 success */
-+regtry(struct match_globals *g, regexp *prog, char *string)
-+{
-+	register int i;
-+	register char **sp;
-+	register char **ep;
-+
-+	g->reginput = string;
-+	g->regstartp = prog->startp;
-+	g->regendp = prog->endp;
-+
-+	sp = prog->startp;
-+	ep = prog->endp;
-+	for (i = NSUBEXP; i > 0; i--) {
-+		*sp++ = NULL;
-+		*ep++ = NULL;
-+	}
-+	if (regmatch(g, prog->program + 1)) {
-+		prog->startp[0] = string;
-+		prog->endp[0] = g->reginput;
-+		return(1);
-+	} else
-+		return(0);
-+}
-+
-+/*
-+ - regmatch - main matching routine
-+ *
-+ * Conceptually the strategy is simple:  check to see whether the current
-+ * node matches, call self recursively to see whether the rest matches,
-+ * and then act accordingly.  In practice we make some effort to avoid
-+ * recursion, in particular by going through "ordinary" nodes (that don't
-+ * need to know whether the rest of the match failed) by a loop instead of
-+ * by recursion.
-+ */
-+static int			/* 0 failure, 1 success */
-+regmatch(struct match_globals *g, char *prog)
-+{
-+	register char *scan = prog; /* Current node. */
-+	char *next;		    /* Next node. */
-+
-+#ifdef DEBUG
-+	if (scan != NULL && regnarrate)
-+		fprintf(stderr, "%s(\n", regprop(scan));
-+#endif
-+	while (scan != NULL) {
-+#ifdef DEBUG
-+		if (regnarrate)
-+			fprintf(stderr, "%s...\n", regprop(scan));
-+#endif
-+		next = regnext(g, scan);
-+
-+		switch (OP(scan)) {
-+		case BOL:
-+			if (g->reginput != g->regbol)
-+				return(0);
-+			break;
-+		case EOL:
-+			if (*g->reginput != '\0')
-+				return(0);
-+			break;
-+		case ANY:
-+			if (*g->reginput == '\0')
-+				return(0);
-+			g->reginput++;
-+			break;
-+		case EXACTLY: {
-+				register int len;
-+				register char *opnd;
-+
-+				opnd = OPERAND(scan);
-+				/* Inline the first character, for speed. */
-+				if (*opnd != *g->reginput)
-+					return(0);
-+				len = strlen(opnd);
-+				if (len > 1 && strncmp(opnd, g->reginput, len) != 0)
-+					return(0);
-+				g->reginput += len;
-+			}
-+			break;
-+		case ANYOF:
-+			if (*g->reginput == '\0' || strchr(OPERAND(scan), *g->reginput) == NULL)
-+				return(0);
-+			g->reginput++;
-+			break;
-+		case ANYBUT:
-+			if (*g->reginput == '\0' || strchr(OPERAND(scan), *g->reginput) != NULL)
-+				return(0);
-+			g->reginput++;
-+			break;
-+		case NOTHING:
-+		case BACK:
-+			break;
-+		case OPEN+1:
-+		case OPEN+2:
-+		case OPEN+3:
-+		case OPEN+4:
-+		case OPEN+5:
-+		case OPEN+6:
-+		case OPEN+7:
-+		case OPEN+8:
-+		case OPEN+9: {
-+				register int no;
-+				register char *save;
-+
-+				no = OP(scan) - OPEN;
-+				save = g->reginput;
-+
-+				if (regmatch(g, next)) {
-+					/*
-+					 * Don't set startp if some later
-+					 * invocation of the same parentheses
-+					 * already has.
-+					 */
-+					if (g->regstartp[no] == NULL)
-+						g->regstartp[no] = save;
-+					return(1);
-+				} else
-+					return(0);
-+			}
-+			break;
-+		case CLOSE+1:
-+		case CLOSE+2:
-+		case CLOSE+3:
-+		case CLOSE+4:
-+		case CLOSE+5:
-+		case CLOSE+6:
-+		case CLOSE+7:
-+		case CLOSE+8:
-+		case CLOSE+9:
-+			{
-+				register int no;
-+				register char *save;
-+
-+				no = OP(scan) - CLOSE;
-+				save = g->reginput;
-+
-+				if (regmatch(g, next)) {
-+					/*
-+					 * Don't set endp if some later
-+					 * invocation of the same parentheses
-+					 * already has.
-+					 */
-+					if (g->regendp[no] == NULL)
-+						g->regendp[no] = save;
-+					return(1);
-+				} else
-+					return(0);
-+			}
-+			break;
-+		case BRANCH: {
-+				register char *save;
-+
-+				if (OP(next) != BRANCH)		/* No choice. */
-+					next = OPERAND(scan);	/* Avoid recursion. */
-+				else {
-+					do {
-+						save = g->reginput;
-+						if (regmatch(g, OPERAND(scan)))
-+							return(1);
-+						g->reginput = save;
-+						scan = regnext(g, scan);
-+					} while (scan != NULL && OP(scan) == BRANCH);
-+					return(0);
-+					/* NOTREACHED */
-+				}
-+			}
-+			break;
-+		case STAR:
-+		case PLUS: {
-+				register char nextch;
-+				register int no;
-+				register char *save;
-+				register int min;
-+
-+				/*
-+				 * Lookahead to avoid useless match attempts
-+				 * when we know what character comes next.
-+				 */
-+				nextch = '\0';
-+				if (OP(next) == EXACTLY)
-+					nextch = *OPERAND(next);
-+				min = (OP(scan) == STAR) ? 0 : 1;
-+				save = g->reginput;
-+				no = regrepeat(g, OPERAND(scan));
-+				while (no >= min) {
-+					/* If it could work, try it. */
-+					if (nextch == '\0' || *g->reginput == nextch)
-+						if (regmatch(g, next))
-+							return(1);
-+					/* Couldn't or didn't -- back up. */
-+					no--;
-+					g->reginput = save + no;
-+				}
-+				return(0);
-+			}
-+			break;
-+		case END:
-+			return(1);	/* Success! */
-+			break;
-+		default:
-+			printk("<3>Regexp: memory corruption\n");
-+			return(0);
-+			break;
-+		}
-+
-+		scan = next;
-+	}
-+
-+	/*
-+	 * We get here only if there's trouble -- normally "case END" is
-+	 * the terminating point.
-+	 */
-+	printk("<3>Regexp: corrupted pointers\n");
-+	return(0);
-+}
-+
-+/*
-+ - regrepeat - repeatedly match something simple, report how many
-+ */
-+static int
-+regrepeat(struct match_globals *g, char *p)
-+{
-+	register int count = 0;
-+	register char *scan;
-+	register char *opnd;
-+
-+	scan = g->reginput;
-+	opnd = OPERAND(p);
-+	switch (OP(p)) {
-+	case ANY:
-+		count = strlen(scan);
-+		scan += count;
-+		break;
-+	case EXACTLY:
-+		while (*opnd == *scan) {
-+			count++;
-+			scan++;
-+		}
-+		break;
-+	case ANYOF:
-+		while (*scan != '\0' && strchr(opnd, *scan) != NULL) {
-+			count++;
-+			scan++;
-+		}
-+		break;
-+	case ANYBUT:
-+		while (*scan != '\0' && strchr(opnd, *scan) == NULL) {
-+			count++;
-+			scan++;
-+		}
-+		break;
-+	default:		/* Oh dear.  Called inappropriately. */
-+		printk("<3>Regexp: internal foulup\n");
-+		count = 0;	/* Best compromise. */
-+		break;
-+	}
-+	g->reginput = scan;
-+
-+	return(count);
-+}
-+
-+/*
-+ - regnext - dig the "next" pointer out of a node
-+ */
-+static char*
-+regnext(struct match_globals *g, char *p)
-+{
-+	register int offset;
-+
-+	if (p == &g->regdummy)
-+		return(NULL);
-+
-+	offset = NEXT(p);
-+	if (offset == 0)
-+		return(NULL);
-+
-+	if (OP(p) == BACK)
-+		return(p-offset);
-+	else
-+		return(p+offset);
-+}
-+
-+#ifdef DEBUG
-+
-+STATIC char *regprop();
-+
-+/*
-+ - regdump - dump a regexp onto stdout in vaguely comprehensible form
-+ */
-+void
-+regdump(regexp *r)
-+{
-+	register char *s;
-+	register char op = EXACTLY;	/* Arbitrary non-END op. */
-+	register char *next;
-+	/* extern char *strchr(); */
-+
-+
-+	s = r->program + 1;
-+	while (op != END) {	/* While that wasn't END last time... */
-+		op = OP(s);
-+		printf("%2d%s", s-r->program, regprop(s));	/* Where, what. */
-+		next = regnext(s);
-+		if (next == NULL)		/* Next ptr. */
-+			printf("(0)");
-+		else
-+			printf("(%d)", (s-r->program)+(next-s));
-+		s += 3;
-+		if (op == ANYOF || op == ANYBUT || op == EXACTLY) {
-+			/* Literal string, where present. */
-+			while (*s != '\0') {
-+				putchar(*s);
-+				s++;
-+			}
-+			s++;
-+		}
-+		putchar('\n');
-+	}
-+
-+	/* Header fields of interest. */
-+	if (r->regstart != '\0')
-+		printf("start `%c' ", r->regstart);
-+	if (r->reganch)
-+		printf("anchored ");
-+	if (r->regmust != NULL)
-+		printf("must have \"%s\"", r->regmust);
-+	printf("\n");
-+}
-+
-+/*
-+ - regprop - printable representation of opcode
-+ */
-+static char *
-+regprop(char *op)
-+{
-+#define BUFLEN 50
-+	register char *p;
-+	static char buf[BUFLEN];
-+
-+	strcpy(buf, ":");
-+
-+	switch (OP(op)) {
-+	case BOL:
-+		p = "BOL";
-+		break;
-+	case EOL:
-+		p = "EOL";
-+		break;
-+	case ANY:
-+		p = "ANY";
-+		break;
-+	case ANYOF:
-+		p = "ANYOF";
-+		break;
-+	case ANYBUT:
-+		p = "ANYBUT";
-+		break;
-+	case BRANCH:
-+		p = "BRANCH";
-+		break;
-+	case EXACTLY:
-+		p = "EXACTLY";
-+		break;
-+	case NOTHING:
-+		p = "NOTHING";
-+		break;
-+	case BACK:
-+		p = "BACK";
-+		break;
-+	case END:
-+		p = "END";
-+		break;
-+	case OPEN+1:
-+	case OPEN+2:
-+	case OPEN+3:
-+	case OPEN+4:
-+	case OPEN+5:
-+	case OPEN+6:
-+	case OPEN+7:
-+	case OPEN+8:
-+	case OPEN+9:
-+		snprintf(buf+strlen(buf),BUFLEN-strlen(buf), "OPEN%d", OP(op)-OPEN);
-+		p = NULL;
-+		break;
-+	case CLOSE+1:
-+	case CLOSE+2:
-+	case CLOSE+3:
-+	case CLOSE+4:
-+	case CLOSE+5:
-+	case CLOSE+6:
-+	case CLOSE+7:
-+	case CLOSE+8:
-+	case CLOSE+9:
-+		snprintf(buf+strlen(buf),BUFLEN-strlen(buf), "CLOSE%d", OP(op)-CLOSE);
-+		p = NULL;
-+		break;
-+	case STAR:
-+		p = "STAR";
-+		break;
-+	case PLUS:
-+		p = "PLUS";
-+		break;
-+	default:
-+		printk("<3>Regexp: corrupted opcode\n");
-+		break;
-+	}
-+	if (p != NULL)
-+		strncat(buf, p, BUFLEN-strlen(buf));
-+	return(buf);
-+}
-+#endif
-+
-+
---- /dev/null
-+++ b/net/netfilter/regexp/regexp.h
-@@ -0,0 +1,41 @@
-+/*
-+ * Definitions etc. for regexp(3) routines.
-+ *
-+ * Caveat:  this is V8 regexp(3) [actually, a reimplementation thereof],
-+ * not the System V one.
-+ */
-+
-+#ifndef REGEXP_H
-+#define REGEXP_H
-+
-+
-+/*
-+http://www.opensource.apple.com/darwinsource/10.3/expect-1/expect/expect.h ,
-+which contains a version of this library, says:
-+
-+ *
-+ * NSUBEXP must be at least 10, and no greater than 117 or the parser
-+ * will not work properly.
-+ *
-+
-+However, it looks rather like this library is limited to 10.  If you think
-+otherwise, let us know.
-+*/
-+
-+#define NSUBEXP  10
-+typedef struct regexp {
-+	char *startp[NSUBEXP];
-+	char *endp[NSUBEXP];
-+	char regstart;		/* Internal use only. */
-+	char reganch;		/* Internal use only. */
-+	char *regmust;		/* Internal use only. */
-+	int regmlen;		/* Internal use only. */
-+	char program[1];	/* Unwarranted chumminess with compiler. */
-+} regexp;
-+
-+regexp * regcomp(char *exp, int *patternsize);
-+int regexec(regexp *prog, char *string);
-+void regsub(regexp *prog, char *source, char *dest);
-+void regerror(char *s);
-+
-+#endif
---- /dev/null
-+++ b/net/netfilter/regexp/regmagic.h
-@@ -0,0 +1,5 @@
-+/*
-+ * The first byte of the regexp internal "program" is actually this magic
-+ * number; the start node begins in the second byte.
-+ */
-+#define	MAGIC	0234
---- /dev/null
-+++ b/net/netfilter/regexp/regsub.c
-@@ -0,0 +1,95 @@
-+/*
-+ * regsub
-+ * @(#)regsub.c	1.3 of 2 April 86
-+ *
-+ *	Copyright (c) 1986 by University of Toronto.
-+ *	Written by Henry Spencer.  Not derived from licensed software.
-+ *
-+ *	Permission is granted to anyone to use this software for any
-+ *	purpose on any computer system, and to redistribute it freely,
-+ *	subject to the following restrictions:
-+ *
-+ *	1. The author is not responsible for the consequences of use of
-+ *		this software, no matter how awful, even if they arise
-+ *		from defects in it.
-+ *
-+ *	2. The origin of this software must not be misrepresented, either
-+ *		by explicit claim or by omission.
-+ *
-+ *	3. Altered versions must be plainly marked as such, and must not
-+ *		be misrepresented as being the original software.
-+ *
-+ *
-+ * This code was modified by Ethan Sommer to work within the kernel
-+ * (it now uses kmalloc etc..)
-+ *
-+ */
-+#include "regexp.h"
-+#include "regmagic.h"
-+#include <linux/string.h>
-+
-+
-+#ifndef CHARBITS
-+#define	UCHARAT(p)	((int)*(unsigned char *)(p))
-+#else
-+#define	UCHARAT(p)	((int)*(p)&CHARBITS)
-+#endif
-+
-+#if 0
-+//void regerror(char * s)
-+//{
-+//        printk("regexp(3): %s", s);
-+//        /* NOTREACHED */
-+//}
-+#endif
-+
-+/*
-+ - regsub - perform substitutions after a regexp match
-+ */
-+void
-+regsub(regexp * prog, char * source, char * dest)
-+{
-+	register char *src;
-+	register char *dst;
-+	register char c;
-+	register int no;
-+	register int len;
-+	
-+	/* Not necessary and gcc doesn't like it -MLS */
-+	/*extern char *strncpy();*/
-+
-+	if (prog == NULL || source == NULL || dest == NULL) {
-+		regerror("NULL parm to regsub");
-+		return;
-+	}
-+	if (UCHARAT(prog->program) != MAGIC) {
-+		regerror("damaged regexp fed to regsub");
-+		return;
-+	}
-+
-+	src = source;
-+	dst = dest;
-+	while ((c = *src++) != '\0') {
-+		if (c == '&')
-+			no = 0;
-+		else if (c == '\\' && '0' <= *src && *src <= '9')
-+			no = *src++ - '0';
-+		else
-+			no = -1;
-+
-+		if (no < 0) {	/* Ordinary character. */
-+			if (c == '\\' && (*src == '\\' || *src == '&'))
-+				c = *src++;
-+			*dst++ = c;
-+		} else if (prog->startp[no] != NULL && prog->endp[no] != NULL) {
-+			len = prog->endp[no] - prog->startp[no];
-+			(void) strncpy(dst, prog->startp[no], len);
-+			dst += len;
-+			if (len != 0 && *(dst-1) == '\0') {	/* strncpy hit NUL. */
-+				regerror("damaged match string");
-+				return;
-+			}
-+		}
-+	}
-+	*dst++ = '\0';
-+}
---- /dev/null
-+++ b/net/netfilter/xt_layer7.c
-@@ -0,0 +1,626 @@
-+/*
-+  Kernel module to match application layer (OSI layer 7) data in connections.
-+
-+  http://l7-filter.sf.net
-+
-+  (C) 2003, 2004, 2005, 2006, 2007 Matthew Strait and Ethan Sommer.
-+
-+  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.
-+  http://www.gnu.org/licenses/gpl.txt
-+
-+  Based on ipt_string.c (C) 2000 Emmanuel Roger <[email protected]>,
-+  xt_helper.c (C) 2002 Harald Welte and cls_layer7.c (C) 2003 Matthew Strait,
-+  Ethan Sommer, Justin Levandoski.
-+*/
-+
-+#include <linux/spinlock.h>
-+#include <net/ip.h>
-+#include <net/tcp.h>
-+#include <linux/module.h>
-+#include <linux/skbuff.h>
-+#include <linux/netfilter.h>
-+#include <net/netfilter/nf_conntrack.h>
-+#include <net/netfilter/nf_conntrack_core.h>
-+#include <linux/netfilter/x_tables.h>
-+#include <linux/netfilter/xt_layer7.h>
-+#include <net/netfilter/nf_conntrack_compat.h>
-+#include <linux/ctype.h>
-+#include <linux/proc_fs.h>
-+
-+#include "regexp/regexp.c"
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Matthew Strait <[email protected]>, Ethan Sommer <[email protected]>");
-+MODULE_DESCRIPTION("iptables application layer match module");
-+MODULE_ALIAS("ipt_layer7");
-+MODULE_VERSION("2.16.1");
-+
-+static int maxdatalen = 2048; // this is the default
-+module_param(maxdatalen, int, 0444);
-+MODULE_PARM_DESC(maxdatalen, "maximum bytes of data looked at by l7-filter");
-+#ifdef CONFIG_NETFILTER_XT_MATCH_LAYER7_DEBUG
-+	#define DPRINTK(format,args...) printk(format,##args)
-+#else
-+	#define DPRINTK(format,args...)
-+#endif
-+
-+#define TOTAL_PACKETS master_conntrack->counters[IP_CT_DIR_ORIGINAL].packets + \
-+		      master_conntrack->counters[IP_CT_DIR_REPLY].packets
-+
-+/* Number of packets whose data we look at.
-+This can be modified through /proc/net/layer7_numpackets */
-+static int num_packets = 10;
-+
-+static struct pattern_cache {
-+	char * regex_string;
-+	regexp * pattern;
-+	struct pattern_cache * next;
-+} * first_pattern_cache = NULL;
-+
-+DEFINE_SPINLOCK(l7_lock);
-+
-+#ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG
-+/* Converts an unfriendly string into a friendly one by
-+replacing unprintables with periods and all whitespace with " ". */
-+static char * friendly_print(unsigned char * s)
-+{
-+	char * f = kmalloc(strlen(s) + 1, GFP_ATOMIC);
-+	int i;
-+
-+	if(!f) {
-+		if (net_ratelimit())
-+			printk(KERN_ERR "layer7: out of memory in "
-+					"friendly_print, bailing.\n");
-+		return NULL;
-+	}
-+
-+	for(i = 0; i < strlen(s); i++){
-+		if(isprint(s[i]) && s[i] < 128)	f[i] = s[i];
-+		else if(isspace(s[i]))		f[i] = ' ';
-+		else 				f[i] = '.';
-+	}
-+	f[i] = '\0';
-+	return f;
-+}
-+
-+static char dec2hex(int i)
-+{
-+	switch (i) {
-+		case 0 ... 9:
-+			return (char)(i + '0');
-+			break;
-+		case 10 ... 15:
-+			return (char)(i - 10 + 'a');
-+			break;
-+		default:
-+			if (net_ratelimit())
-+				printk("Problem in dec2hex\n");
-+			return '\0';
-+	}
-+}
-+
-+static char * hex_print(unsigned char * s)
-+{
-+	char * g = kmalloc(strlen(s)*3 + 1, GFP_ATOMIC);
-+	int i;
-+
-+	if(!g) {
-+	       if (net_ratelimit())
-+			printk(KERN_ERR "layer7: out of memory in hex_print, "
-+					"bailing.\n");
-+	       return NULL;
-+	}
-+
-+	for(i = 0; i < strlen(s); i++) {
-+		g[i*3    ] = dec2hex(s[i]/16);
-+		g[i*3 + 1] = dec2hex(s[i]%16);
-+		g[i*3 + 2] = ' ';
-+	}
-+	g[i*3] = '\0';
-+
-+	return g;
-+}
-+#endif // DEBUG
-+
-+/* Use instead of regcomp.  As we expect to be seeing the same regexps over and
-+over again, it make sense to cache the results. */
-+static regexp * compile_and_cache(char * regex_string, char * protocol)
-+{
-+	struct pattern_cache * node               = first_pattern_cache;
-+	struct pattern_cache * last_pattern_cache = first_pattern_cache;
-+	struct pattern_cache * tmp;
-+	unsigned int len;
-+
-+	while (node != NULL) {
-+		if (!strcmp(node->regex_string, regex_string))
-+		return node->pattern;
-+
-+		last_pattern_cache = node;/* points at the last non-NULL node */
-+		node = node->next;
-+	}
-+
-+	/* If we reach the end of the list, then we have not yet cached
-+	   the pattern for this regex. Let's do that now.
-+	   Be paranoid about running out of memory to avoid list corruption. */
-+	tmp = kmalloc(sizeof(struct pattern_cache), GFP_ATOMIC);
-+
-+	if(!tmp) {
-+		if (net_ratelimit())
-+			printk(KERN_ERR "layer7: out of memory in "
-+					"compile_and_cache, bailing.\n");
-+		return NULL;
-+	}
-+
-+	tmp->regex_string  = kmalloc(strlen(regex_string) + 1, GFP_ATOMIC);
-+	tmp->pattern       = kmalloc(sizeof(struct regexp),    GFP_ATOMIC);
-+	tmp->next = NULL;
-+
-+	if(!tmp->regex_string || !tmp->pattern) {
-+		if (net_ratelimit())
-+			printk(KERN_ERR "layer7: out of memory in "
-+					"compile_and_cache, bailing.\n");
-+		kfree(tmp->regex_string);
-+		kfree(tmp->pattern);
-+		kfree(tmp);
-+		return NULL;
-+	}
-+
-+	/* Ok.  The new node is all ready now. */
-+	node = tmp;
-+
-+	if(first_pattern_cache == NULL) /* list is empty */
-+		first_pattern_cache = node; /* make node the beginning */
-+	else
-+		last_pattern_cache->next = node; /* attach node to the end */
-+
-+	/* copy the string and compile the regex */
-+	len = strlen(regex_string);
-+	DPRINTK("About to compile this: \"%s\"\n", regex_string);
-+	node->pattern = regcomp(regex_string, &len);
-+	if ( !node->pattern ) {
-+		if (net_ratelimit())
-+			printk(KERN_ERR "layer7: Error compiling regexp "
-+					"\"%s\" (%s)\n", 
-+					regex_string, protocol);
-+		/* pattern is now cached as NULL, so we won't try again. */
-+	}
-+
-+	strcpy(node->regex_string, regex_string);
-+	return node->pattern;
-+}
-+
-+static int can_handle(const struct sk_buff *skb)
-+{
-+	if(!skb->nh.iph) /* not IP */
-+		return 0;
-+	if(skb->nh.iph->protocol != IPPROTO_TCP &&
-+	   skb->nh.iph->protocol != IPPROTO_UDP &&
-+	   skb->nh.iph->protocol != IPPROTO_ICMP)
-+		return 0;
-+	return 1;
-+}
-+
-+/* Returns offset the into the skb->data that the application data starts */
-+static int app_data_offset(const struct sk_buff *skb)
-+{
-+	/* In case we are ported somewhere (ebtables?) where skb->nh.iph
-+	isn't set, this can be gotten from 4*(skb->data[0] & 0x0f) as well. */
-+	int ip_hl = 4*skb->nh.iph->ihl;
-+
-+	if( skb->nh.iph->protocol == IPPROTO_TCP ) {
-+		/* 12 == offset into TCP header for the header length field.
-+		Can't get this with skb->h.th->doff because the tcphdr
-+		struct doesn't get set when routing (this is confirmed to be
-+		true in Netfilter as well as QoS.) */
-+		int tcp_hl = 4*(skb->data[ip_hl + 12] >> 4);
-+
-+		return ip_hl + tcp_hl;
-+	} else if( skb->nh.iph->protocol == IPPROTO_UDP  ) {
-+		return ip_hl + 8; /* UDP header is always 8 bytes */
-+	} else if( skb->nh.iph->protocol == IPPROTO_ICMP ) {
-+		return ip_hl + 8; /* ICMP header is 8 bytes */
-+	} else {
-+		if (net_ratelimit())
-+			printk(KERN_ERR "layer7: tried to handle unknown "
-+					"protocol!\n");
-+		return ip_hl + 8; /* something reasonable */
-+	}
-+}
-+
-+/* handles whether there's a match when we aren't appending data anymore */
-+static int match_no_append(struct nf_conn * conntrack, 
-+                           struct nf_conn * master_conntrack, 
-+                           enum ip_conntrack_info ctinfo,
-+                           enum ip_conntrack_info master_ctinfo,
-+                           struct xt_layer7_info * info)
-+{
-+	/* If we're in here, throw the app data away */
-+	if(master_conntrack->layer7.app_data != NULL) {
-+
-+	#ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG
-+		if(!master_conntrack->layer7.app_proto) {
-+			char * f = 
-+			  friendly_print(master_conntrack->layer7.app_data);
-+			char * g = 
-+			  hex_print(master_conntrack->layer7.app_data);
-+			DPRINTK("\nl7-filter gave up after %d bytes "
-+				"(%d packets):\n%s\n",
-+				strlen(f), TOTAL_PACKETS, f);
-+			kfree(f);
-+			DPRINTK("In hex: %s\n", g);
-+			kfree(g);
-+		}
-+	#endif
-+
-+		kfree(master_conntrack->layer7.app_data);
-+		master_conntrack->layer7.app_data = NULL; /* don't free again */
-+	}
-+
-+	if(master_conntrack->layer7.app_proto){
-+		/* Here child connections set their .app_proto (for /proc) */
-+		if(!conntrack->layer7.app_proto) {
-+			conntrack->layer7.app_proto = 
-+			  kmalloc(strlen(master_conntrack->layer7.app_proto)+1, 
-+			    GFP_ATOMIC);
-+			if(!conntrack->layer7.app_proto){
-+				if (net_ratelimit())
-+					printk(KERN_ERR "layer7: out of memory "
-+							"in match_no_append, "
-+							"bailing.\n");
-+				return 1;
-+			}
-+			strcpy(conntrack->layer7.app_proto, 
-+				master_conntrack->layer7.app_proto);
-+		}
-+
-+		return (!strcmp(master_conntrack->layer7.app_proto, 
-+				info->protocol));
-+	}
-+	else {
-+		/* If not classified, set to "unknown" to distinguish from
-+		connections that are still being tested. */
-+		master_conntrack->layer7.app_proto = 
-+			kmalloc(strlen("unknown")+1, GFP_ATOMIC);
-+		if(!master_conntrack->layer7.app_proto){
-+			if (net_ratelimit())
-+				printk(KERN_ERR "layer7: out of memory in "
-+						"match_no_append, bailing.\n");
-+			return 1;
-+		}
-+		strcpy(master_conntrack->layer7.app_proto, "unknown");
-+		return 0;
-+	}
-+}
-+
-+/* add the new app data to the conntrack.  Return number of bytes added. */
-+static int add_data(struct nf_conn * master_conntrack,
-+                    char * app_data, int appdatalen)
-+{
-+	int length = 0, i;
-+	int oldlength = master_conntrack->layer7.app_data_len;
-+
-+	/* This is a fix for a race condition by Deti Fliegl. However, I'm not 
-+	   clear on whether the race condition exists or whether this really 
-+	   fixes it.  I might just be being dense... Anyway, if it's not really 
-+	   a fix, all it does is waste a very small amount of time. */
-+	if(!master_conntrack->layer7.app_data) return 0;
-+
-+	/* Strip nulls. Make everything lower case (our regex lib doesn't
-+	do case insensitivity).  Add it to the end of the current data. */
-+	for(i = 0; i < maxdatalen-oldlength-1 &&
-+		   i < appdatalen; i++) {
-+		if(app_data[i] != '\0') {
-+			/* the kernel version of tolower mungs 'upper ascii' */
-+			master_conntrack->layer7.app_data[length+oldlength] =
-+				isascii(app_data[i])? 
-+					tolower(app_data[i]) : app_data[i];
-+			length++;
-+		}
-+	}
-+
-+	master_conntrack->layer7.app_data[length+oldlength] = '\0';
-+	master_conntrack->layer7.app_data_len = length + oldlength;
-+
-+	return length;
-+}
-+
-+/* taken from drivers/video/modedb.c */
-+static int my_atoi(const char *s)
-+{
-+	int val = 0;
-+
-+	for (;; s++) {
-+		switch (*s) {
-+			case '0'...'9':
-+			val = 10*val+(*s-'0');
-+			break;
-+		default:
-+			return val;
-+		}
-+	}
-+}
-+
-+/* write out num_packets to userland. */
-+static int layer7_read_proc(char* page, char ** start, off_t off, int count,
-+                            int* eof, void * data)
-+{
-+	if(num_packets > 99 && net_ratelimit())
-+		printk(KERN_ERR "layer7: NOT REACHED. num_packets too big\n");
-+
-+	page[0] = num_packets/10 + '0';
-+	page[1] = num_packets%10 + '0';
-+	page[2] = '\n';
-+	page[3] = '\0';
-+
-+	*eof=1;
-+
-+	return 3;
-+}
-+
-+/* Read in num_packets from userland */
-+static int layer7_write_proc(struct file* file, const char* buffer,
-+                             unsigned long count, void *data)
-+{
-+	char * foo = kmalloc(count, GFP_ATOMIC);
-+
-+	if(!foo){
-+		if (net_ratelimit())
-+			printk(KERN_ERR "layer7: out of memory, bailing. "
-+					"num_packets unchanged.\n");
-+		return count;
-+	}
-+
-+	if(copy_from_user(foo, buffer, count)) {
-+		return -EFAULT;
-+	}
-+
-+
-+	num_packets = my_atoi(foo);
-+	kfree (foo);
-+
-+	/* This has an arbitrary limit to make the math easier. I'm lazy.
-+	But anyway, 99 is a LOT! If you want more, you're doing it wrong! */
-+	if(num_packets > 99) {
-+		printk(KERN_WARNING "layer7: num_packets can't be > 99.\n");
-+		num_packets = 99;
-+	} else if(num_packets < 1) {
-+		printk(KERN_WARNING "layer7: num_packets can't be < 1.\n");
-+		num_packets = 1;
-+	}
-+
-+	return count;
-+}
-+
-+static int
-+match(const struct sk_buff *skbin,
-+      const struct net_device *in,
-+      const struct net_device *out,
-+      const struct xt_match *match,
-+      const void *matchinfo,
-+      int offset,
-+      unsigned int protoff,
-+      int *hotdrop)
-+{
-+	/* sidestep const without getting a compiler warning... */
-+	struct sk_buff * skb = (struct sk_buff *)skbin; 
-+
-+	struct xt_layer7_info * info = (struct xt_layer7_info *)matchinfo;
-+	enum ip_conntrack_info master_ctinfo, ctinfo;
-+	struct nf_conn *master_conntrack, *conntrack;
-+	unsigned char * app_data;
-+	unsigned int pattern_result, appdatalen;
-+	regexp * comppattern;
-+
-+	/* Be paranoid/incompetent - lock the entire match function. */
-+	spin_lock_bh(&l7_lock);
-+
-+	if(!can_handle(skb)){
-+		DPRINTK("layer7: This is some protocol I can't handle.\n");
-+		spin_unlock_bh(&l7_lock);
-+		return info->invert;
-+	}
-+
-+	/* Treat parent & all its children together as one connection, except
-+	for the purpose of setting conntrack->layer7.app_proto in the actual
-+	connection. This makes /proc/net/ip_conntrack more satisfying. */
-+	if(!(conntrack = nf_ct_get((struct sk_buff *)skb, &ctinfo)) ||
-+	   !(master_conntrack=nf_ct_get((struct sk_buff *)skb,&master_ctinfo))){
-+		DPRINTK("layer7: couldn't get conntrack.\n");
-+		spin_unlock_bh(&l7_lock);
-+		return info->invert;
-+	}
-+
-+	/* Try to get a master conntrack (and its master etc) for FTP, etc. */
-+	while (master_ct(master_conntrack) != NULL)
-+		master_conntrack = master_ct(master_conntrack);
-+
-+	/* if we've classified it or seen too many packets */
-+	if(TOTAL_PACKETS > num_packets ||
-+	   master_conntrack->layer7.app_proto) {
-+
-+		pattern_result = match_no_append(conntrack, master_conntrack, 
-+						 ctinfo, master_ctinfo, info);
-+
-+		/* skb->cb[0] == seen. Don't do things twice if there are 
-+		multiple l7 rules. I'm not sure that using cb for this purpose 
-+		is correct, even though it says "put your private variables 
-+		there". But it doesn't look like it is being used for anything
-+		else in the skbs that make it here. */
-+		skb->cb[0] = 1; /* marking it seen here's probably irrelevant */
-+
-+		spin_unlock_bh(&l7_lock);
-+		return (pattern_result ^ info->invert);
-+	}
-+
-+	if(skb_is_nonlinear(skb)){
-+		if(skb_linearize(skb) != 0){
-+			if (net_ratelimit())
-+				printk(KERN_ERR "layer7: failed to linearize "
-+						"packet, bailing.\n");
-+			spin_unlock_bh(&l7_lock);
-+			return info->invert;
-+		}
-+	}
-+
-+	/* now that the skb is linearized, it's safe to set these. */
-+	app_data = skb->data + app_data_offset(skb);
-+	appdatalen = skb->tail - app_data;
-+
-+	/* the return value gets checked later, when we're ready to use it */
-+	comppattern = compile_and_cache(info->pattern, info->protocol);
-+
-+	/* On the first packet of a connection, allocate space for app data */
-+	if(TOTAL_PACKETS == 1 && !skb->cb[0] && 
-+	   !master_conntrack->layer7.app_data){
-+		master_conntrack->layer7.app_data = 
-+			kmalloc(maxdatalen, GFP_ATOMIC);
-+		if(!master_conntrack->layer7.app_data){
-+			if (net_ratelimit())
-+				printk(KERN_ERR "layer7: out of memory in "
-+						"match, bailing.\n");
-+			spin_unlock_bh(&l7_lock);
-+			return info->invert;
-+		}
-+
-+		master_conntrack->layer7.app_data[0] = '\0';
-+	}
-+
-+	/* Can be here, but unallocated, if numpackets is increased near
-+	the beginning of a connection */
-+	if(master_conntrack->layer7.app_data == NULL){
-+		spin_unlock_bh(&l7_lock);
-+		return (info->invert); /* unmatched */
-+	}
-+
-+	if(!skb->cb[0]){
-+		int newbytes;
-+		newbytes = add_data(master_conntrack, app_data, appdatalen);
-+
-+		if(newbytes == 0) { /* didn't add any data */
-+			skb->cb[0] = 1;
-+			/* Didn't match before, not going to match now */
-+			spin_unlock_bh(&l7_lock);
-+			return info->invert;
-+		}
-+	}
-+
-+	/* If looking for "unknown", then never match.  "Unknown" means that
-+	we've given up; we're still trying with these packets. */
-+	if(!strcmp(info->protocol, "unknown")) {
-+		pattern_result = 0;
-+	/* If looking for "unset", then always match. "Unset" means that we
-+	haven't yet classified the connection. */
-+	} else if(!strcmp(info->protocol, "unset")) {
-+		pattern_result = 2;
-+		DPRINTK("layer7: matched unset: not yet classified "
-+			"(%d/%d packets)\n", TOTAL_PACKETS, num_packets);
-+	/* If the regexp failed to compile, don't bother running it */
-+	} else if(comppattern && 
-+		  regexec(comppattern, master_conntrack->layer7.app_data)){
-+		DPRINTK("layer7: matched %s\n", info->protocol);
-+		pattern_result = 1;
-+	} else pattern_result = 0;
-+
-+	if(pattern_result == 1) {
-+		master_conntrack->layer7.app_proto = 
-+			kmalloc(strlen(info->protocol)+1, GFP_ATOMIC);
-+		if(!master_conntrack->layer7.app_proto){
-+			if (net_ratelimit())
-+				printk(KERN_ERR "layer7: out of memory in "
-+						"match, bailing.\n");
-+			spin_unlock_bh(&l7_lock);
-+			return (pattern_result ^ info->invert);
-+		}
-+		strcpy(master_conntrack->layer7.app_proto, info->protocol);
-+	} else if(pattern_result > 1) { /* cleanup from "unset" */
-+		pattern_result = 1;
-+	}
-+
-+	/* mark the packet seen */
-+	skb->cb[0] = 1;
-+
-+	spin_unlock_bh(&l7_lock);
-+	return (pattern_result ^ info->invert);
-+}
-+
-+static int check(const char *tablename,
-+		 const void *inf,
-+		 const struct xt_match *match,
-+		 void *matchinfo,
-+		 unsigned int hook_mask)
-+
-+{
-+	// load nf_conntrack_ipv4
-+        if (nf_ct_l3proto_try_module_get(match->family) < 0) {
-+                printk(KERN_WARNING "can't load conntrack support for "
-+                                    "proto=%d\n", match->family);
-+                return 0;
-+        }
-+	return 1;
-+}
-+
-+static void
-+destroy(const struct xt_match *match, void *matchinfo)
-+{
-+	nf_ct_l3proto_module_put(match->family);
-+}
-+
-+static struct xt_match xt_layer7_match[] = {
-+{
-+	.name		= "layer7",
-+	.family		= AF_INET,
-+	.checkentry	= check,
-+	.match		= match,
-+	.destroy	= destroy,
-+	.matchsize	= sizeof(struct xt_layer7_info),
-+	.me		= THIS_MODULE
-+}
-+};
-+
-+static void layer7_cleanup_proc(void)
-+{
-+	remove_proc_entry("layer7_numpackets", proc_net);
-+}
-+
-+/* register the proc file */
-+static void layer7_init_proc(void)
-+{
-+	struct proc_dir_entry* entry;
-+	entry = create_proc_entry("layer7_numpackets", 0644, proc_net);
-+	entry->read_proc = layer7_read_proc;
-+	entry->write_proc = layer7_write_proc;
-+}
-+
-+static int __init xt_layer7_init(void)
-+{
-+	need_conntrack();
-+
-+	layer7_init_proc();
-+	if(maxdatalen < 1) {
-+		printk(KERN_WARNING "layer7: maxdatalen can't be < 1, "
-+			"using 1\n");
-+		maxdatalen = 1;
-+	}
-+	/* This is not a hard limit.  It's just here to prevent people from
-+	bringing their slow machines to a grinding halt. */
-+	else if(maxdatalen > 65536) {
-+		printk(KERN_WARNING "layer7: maxdatalen can't be > 65536, "
-+			"using 65536\n");
-+		maxdatalen = 65536;
-+	}
-+	return xt_register_matches(xt_layer7_match,
-+				   ARRAY_SIZE(xt_layer7_match));
-+}
-+
-+static void __exit xt_layer7_fini(void)
-+{
-+	layer7_cleanup_proc();
-+	xt_unregister_matches(xt_layer7_match, ARRAY_SIZE(xt_layer7_match));
-+}
-+
-+module_init(xt_layer7_init);
-+module_exit(xt_layer7_fini);
-+

+ 0 - 109
target/linux/generic-2.6/patches-2.6.21/101-netfilter_layer7_pktmatch.patch

@@ -1,109 +0,0 @@
---- a/include/linux/netfilter/xt_layer7.h
-+++ b/include/linux/netfilter/xt_layer7.h
-@@ -8,6 +8,7 @@ struct xt_layer7_info {
-     char protocol[MAX_PROTOCOL_LEN];
-     char invert:1;
-     char pattern[MAX_PATTERN_LEN];
-+    u_int8_t pkt;
- };
- 
- #endif /* _XT_LAYER7_H */
---- a/net/netfilter/xt_layer7.c
-+++ b/net/netfilter/xt_layer7.c
-@@ -296,34 +296,36 @@ static int match_no_append(struct nf_con
- }
- 
- /* add the new app data to the conntrack.  Return number of bytes added. */
--static int add_data(struct nf_conn * master_conntrack,
--                    char * app_data, int appdatalen)
-+static int add_datastr(char *target, int offset, char *app_data, int len)
- {
- 	int length = 0, i;
--	int oldlength = master_conntrack->layer7.app_data_len;
--
--	/* This is a fix for a race condition by Deti Fliegl. However, I'm not 
--	   clear on whether the race condition exists or whether this really 
--	   fixes it.  I might just be being dense... Anyway, if it's not really 
--	   a fix, all it does is waste a very small amount of time. */
--	if(!master_conntrack->layer7.app_data) return 0;
-+	
-+	if (!target) return 0;
- 
- 	/* Strip nulls. Make everything lower case (our regex lib doesn't
- 	do case insensitivity).  Add it to the end of the current data. */
--	for(i = 0; i < maxdatalen-oldlength-1 &&
--		   i < appdatalen; i++) {
-+	for(i = 0; i < maxdatalen-offset-1 && i < len; i++) {
- 		if(app_data[i] != '\0') {
- 			/* the kernel version of tolower mungs 'upper ascii' */
--			master_conntrack->layer7.app_data[length+oldlength] =
-+			target[length+offset] =
- 				isascii(app_data[i])? 
- 					tolower(app_data[i]) : app_data[i];
- 			length++;
- 		}
- 	}
-+	target[length+offset] = '\0';
-+	
-+	return length;
-+}
- 
--	master_conntrack->layer7.app_data[length+oldlength] = '\0';
--	master_conntrack->layer7.app_data_len = length + oldlength;
-+/* add the new app data to the conntrack.  Return number of bytes added. */
-+static int add_data(struct nf_conn * master_conntrack,
-+                    char * app_data, int appdatalen)
-+{
-+	int length;
- 
-+	length = add_datastr(master_conntrack->layer7.app_data, master_conntrack->layer7.app_data_len, app_data, appdatalen);
-+	master_conntrack->layer7.app_data_len += length;
- 	return length;
- }
- 
-@@ -410,7 +412,7 @@ match(const struct sk_buff *skbin,
- 	struct xt_layer7_info * info = (struct xt_layer7_info *)matchinfo;
- 	enum ip_conntrack_info master_ctinfo, ctinfo;
- 	struct nf_conn *master_conntrack, *conntrack;
--	unsigned char * app_data;
-+	unsigned char *app_data, *tmp_data;
- 	unsigned int pattern_result, appdatalen;
- 	regexp * comppattern;
- 
-@@ -438,8 +440,8 @@ match(const struct sk_buff *skbin,
- 		master_conntrack = master_ct(master_conntrack);
- 
- 	/* if we've classified it or seen too many packets */
--	if(TOTAL_PACKETS > num_packets ||
--	   master_conntrack->layer7.app_proto) {
-+	if(!info->pkt && (TOTAL_PACKETS > num_packets ||
-+	   master_conntrack->layer7.app_proto)) {
- 
- 		pattern_result = match_no_append(conntrack, master_conntrack, 
- 						 ctinfo, master_ctinfo, info);
-@@ -472,6 +474,25 @@ match(const struct sk_buff *skbin,
- 	/* the return value gets checked later, when we're ready to use it */
- 	comppattern = compile_and_cache(info->pattern, info->protocol);
- 
-+	if (info->pkt) {
-+		tmp_data = kmalloc(maxdatalen, GFP_ATOMIC);
-+		if(!tmp_data){
-+			if (net_ratelimit())
-+				printk(KERN_ERR "layer7: out of memory in match, bailing.\n");
-+			return info->invert;
-+		}
-+
-+		tmp_data[0] = '\0';
-+		add_datastr(tmp_data, 0, app_data, appdatalen);
-+		pattern_result = ((comppattern && regexec(comppattern, tmp_data)) ? 1 : 0);
-+
-+		kfree(tmp_data);
-+		tmp_data = NULL;
-+		spin_unlock_bh(&l7_lock);
-+
-+		return (pattern_result ^ info->invert);
-+	}
-+
- 	/* On the first packet of a connection, allocate space for app data */
- 	if(TOTAL_PACKETS == 1 && !skb->cb[0] && 
- 	   !master_conntrack->layer7.app_data){

+ 0 - 166
target/linux/generic-2.6/patches-2.6.21/120-openswan-2.4.0.kernel-2.6-natt.patch

@@ -1,166 +0,0 @@
---- /dev/null
-+++ b/include/net/xfrmudp.h
-@@ -0,0 +1,10 @@
-+/*
-+ * pointer to function for type that xfrm4_input wants, to permit
-+ * decoupling of XFRM from udp.c
-+ */
-+#define HAVE_XFRM4_UDP_REGISTER
-+
-+typedef int (*xfrm4_rcv_encap_t)(struct sk_buff *skb, __u16 encap_type);
-+extern int udp4_register_esp_rcvencap(xfrm4_rcv_encap_t func
-+				      , xfrm4_rcv_encap_t *oldfunc);
-+extern int udp4_unregister_esp_rcvencap(xfrm4_rcv_encap_t func);
---- a/net/ipv4/Kconfig
-+++ b/net/ipv4/Kconfig
-@@ -266,6 +266,12 @@ config NET_IPGRE_BROADCAST
- 	  Network), but can be distributed all over the Internet. If you want
- 	  to do that, say Y here and to "IP multicast routing" below.
- 
-+config IPSEC_NAT_TRAVERSAL
-+	bool "IPSEC NAT-Traversal (KLIPS compatible)"
-+	depends on INET
-+	---help---
-+          Includes support for RFC3947/RFC3948 NAT-Traversal of ESP over UDP.
-+
- config IP_MROUTE
- 	bool "IP: multicast routing"
- 	depends on IP_MULTICAST
---- a/net/ipv4/udp.c
-+++ b/net/ipv4/udp.c
-@@ -101,12 +101,15 @@
- #include <net/route.h>
- #include <net/checksum.h>
- #include <net/xfrm.h>
-+#include <net/xfrmudp.h>
- #include "udp_impl.h"
- 
- /*
-  *	Snmp MIB for the UDP layer
-  */
- 
-+static xfrm4_rcv_encap_t xfrm4_rcv_encap_func;
-+
- DEFINE_SNMP_STAT(struct udp_mib, udp_statistics) __read_mostly;
- 
- struct hlist_head udp_hash[UDP_HTABLE_SIZE];
-@@ -915,6 +918,42 @@ int udp_disconnect(struct sock *sk, int 
- 	return 0;
- }
- 
-+#if defined(CONFIG_XFRM) || defined(CONFIG_IPSEC_NAT_TRAVERSAL)
-+
-+/* if XFRM isn't a module, then register it directly. */
-+#if 0 && !defined(CONFIG_XFRM_MODULE) && !defined(CONFIG_IPSEC_NAT_TRAVERSAL)
-+static xfrm4_rcv_encap_t xfrm4_rcv_encap_func = xfrm4_rcv_encap;
-+#else
-+static xfrm4_rcv_encap_t xfrm4_rcv_encap_func = NULL;
-+#endif
-+
-+int udp4_register_esp_rcvencap(xfrm4_rcv_encap_t func
-+			       , xfrm4_rcv_encap_t *oldfunc)
-+{
-+  if(oldfunc != NULL) {
-+    *oldfunc = xfrm4_rcv_encap_func;
-+  }
-+
-+#if 0
-+  if(xfrm4_rcv_encap_func != NULL)
-+    return -1;
-+#endif
-+
-+  xfrm4_rcv_encap_func = func;
-+  return 0;
-+}
-+
-+int udp4_unregister_esp_rcvencap(xfrm4_rcv_encap_t func)
-+{
-+  if(xfrm4_rcv_encap_func != func)
-+    return -1;
-+
-+  xfrm4_rcv_encap_func = NULL;
-+  return 0;
-+}
-+#endif /* CONFIG_XFRM_MODULE || CONFIG_IPSEC_NAT_TRAVERSAL */
-+
-+
- /* return:
-  * 	1  if the the UDP system should process it
-  *	0  if we should drop this packet
-@@ -922,7 +961,7 @@ int udp_disconnect(struct sock *sk, int 
-  */
- static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb)
- {
--#ifndef CONFIG_XFRM
-+#if !defined(CONFIG_XFRM) && !defined(CONFIG_IPSEC_NAT_TRAVERSAL)
- 	return 1;
- #else
- 	struct udp_sock *up = udp_sk(sk);
-@@ -937,11 +976,11 @@ static int udp_encap_rcv(struct sock * s
- 	/* if we're overly short, let UDP handle it */
- 	len = skb->len - sizeof(struct udphdr);
- 	if (len <= 0)
--		return 1;
-+		return 2;
- 
- 	/* if this is not encapsulated socket, then just return now */
- 	if (!encap_type)
--		return 1;
-+		return 3;
- 
- 	/* If this is a paged skb, make sure we pull up
- 	 * whatever data we need to look at. */
-@@ -964,7 +1003,7 @@ static int udp_encap_rcv(struct sock * s
- 			len = sizeof(struct udphdr);
- 		} else
- 			/* Must be an IKE packet.. pass it through */
--			return 1;
-+			return 4;
- 		break;
- 	case UDP_ENCAP_ESPINUDP_NON_IKE:
- 		/* Check if this is a keepalive packet.  If so, eat it. */
-@@ -977,7 +1016,7 @@ static int udp_encap_rcv(struct sock * s
- 			len = sizeof(struct udphdr) + 2 * sizeof(u32);
- 		} else
- 			/* Must be an IKE packet.. pass it through */
--			return 1;
-+			return 5;
- 		break;
- 	}
- 
-@@ -988,6 +1027,8 @@ static int udp_encap_rcv(struct sock * s
- 	 */
- 	if (skb_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
- 		return 0;
-+	if (skb_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
-+		return 0;
- 
- 	/* Now we can update and verify the packet length... */
- 	iph = skb->nh.iph;
-@@ -1051,9 +1092,13 @@ int udp_queue_rcv_skb(struct sock * sk, 
- 			return 0;
- 		}
- 		if (ret < 0) {
--			/* process the ESP packet */
--			ret = xfrm4_rcv_encap(skb, up->encap_type);
--			UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS, up->pcflag);
-+			if(xfrm4_rcv_encap_func != NULL) {
-+			  ret = (*xfrm4_rcv_encap_func)(skb, up->encap_type);
-+			  UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS, up->pcflag);
-+			} else {
-+			  UDP_INC_STATS_BH(UDP_MIB_INERRORS, up->pcflag);
-+			  ret = 1;
-+			}
- 			return -ret;
- 		}
- 		/* FALLTHROUGH -- it's a UDP Packet */
-@@ -1733,3 +1778,9 @@ EXPORT_SYMBOL(udp_poll);
- EXPORT_SYMBOL(udp_proc_register);
- EXPORT_SYMBOL(udp_proc_unregister);
- #endif
-+
-+#if defined(CONFIG_IPSEC_NAT_TRAVERSAL)
-+EXPORT_SYMBOL(udp4_register_esp_rcvencap);
-+EXPORT_SYMBOL(udp4_unregister_esp_rcvencap);
-+#endif
-+

+ 0 - 237
target/linux/generic-2.6/patches-2.6.21/140-netfilter_time.patch

@@ -1,237 +0,0 @@
---- /dev/null
-+++ b/include/linux/netfilter_ipv4/ipt_time.h
-@@ -0,0 +1,18 @@
-+#ifndef __ipt_time_h_included__
-+#define __ipt_time_h_included__
-+
-+
-+struct ipt_time_info {
-+	u_int8_t  days_match;   /* 1 bit per day. -SMTWTFS                      */
-+	u_int16_t time_start;   /* 0 < time_start < 23*60+59 = 1439             */
-+	u_int16_t time_stop;    /* 0:0 < time_stat < 23:59                      */
-+
-+				/* FIXME: Keep this one for userspace iptables binary compability: */
-+	u_int8_t  kerneltime;   /* ignore skb time (and use kerneltime) or not. */
-+
-+	time_t    date_start;
-+	time_t    date_stop;
-+};
-+
-+
-+#endif /* __ipt_time_h_included__ */
---- /dev/null
-+++ b/net/ipv4/netfilter/ipt_time.c
-@@ -0,0 +1,178 @@
-+/*
-+  This is a module which is used for time matching
-+  It is using some modified code from dietlibc (localtime() function)
-+  that you can find at http://www.fefe.de/dietlibc/
-+  This file is distributed under the terms of the GNU General Public
-+  License (GPL). Copies of the GPL can be obtained from: ftp://prep.ai.mit.edu/pub/gnu/GPL
-+  2001-05-04 Fabrice MARIE <[email protected]> : initial development.
-+  2001-21-05 Fabrice MARIE <[email protected]> : bug fix in the match code,
-+     thanks to "Zeng Yu" <[email protected]> for bug report.
-+  2001-26-09 Fabrice MARIE <[email protected]> : force the match to be in LOCAL_IN or PRE_ROUTING only.
-+  2001-30-11 Fabrice : added the possibility to use the match in FORWARD/OUTPUT with a little hack,
-+     added Nguyen Dang Phuoc Dong <[email protected]> patch to support timezones.
-+  2004-05-02 Fabrice : added support for date matching, from an idea of Fabien COELHO.
-+*/
-+
-+#include <linux/module.h>
-+#include <linux/skbuff.h>
-+#include <linux/netfilter_ipv4/ip_tables.h>
-+#include <linux/netfilter_ipv4/ipt_time.h>
-+#include <linux/time.h>
-+
-+MODULE_AUTHOR("Fabrice MARIE <[email protected]>");
-+MODULE_DESCRIPTION("Match arrival timestamp/date");
-+MODULE_LICENSE("GPL");
-+
-+struct tm
-+{
-+	int tm_sec;                   /* Seconds.     [0-60] (1 leap second) */
-+	int tm_min;                   /* Minutes.     [0-59] */
-+	int tm_hour;                  /* Hours.       [0-23] */
-+	int tm_mday;                  /* Day.         [1-31] */
-+	int tm_mon;                   /* Month.       [0-11] */
-+	int tm_year;                  /* Year - 1900.  */
-+	int tm_wday;                  /* Day of week. [0-6] */
-+	int tm_yday;                  /* Days in year.[0-365] */
-+	int tm_isdst;                 /* DST.         [-1/0/1]*/
-+
-+	long int tm_gmtoff;           /* we don't care, we count from GMT */
-+	const char *tm_zone;          /* we don't care, we count from GMT */
-+};
-+
-+void
-+localtime(const u32 time, struct tm *r);
-+
-+static int
-+match(const struct sk_buff *skb,
-+      const struct net_device *in,
-+      const struct net_device *out,
-+      const struct xt_match *match,
-+      const void *matchinfo,
-+      int offset,
-+      unsigned int protoff,
-+      int *hotdrop)
-+{
-+	const struct ipt_time_info *info = matchinfo;   /* match info for rule */
-+	struct tm currenttime;                          /* time human readable */
-+	u_int8_t days_of_week[7] = {64, 32, 16, 8, 4, 2, 1};
-+	u_int16_t packet_time;
-+
-+	/* We might not have a timestamp, get one */
-+	if (skb->tstamp.off_sec == 0)
-+		__net_timestamp((struct sk_buff *)skb);
-+
-+	/* First we make sure we are in the date start-stop boundaries */
-+	if ((skb->tstamp.off_sec < info->date_start) || (skb->tstamp.off_sec > info->date_stop))
-+		return 0; /* We are outside the date boundaries */
-+
-+	/* Transform the timestamp of the packet, in a human readable form */
-+	localtime(skb->tstamp.off_sec, &currenttime);
-+
-+	/* check if we match this timestamp, we start by the days... */
-+	if ((days_of_week[currenttime.tm_wday] & info->days_match) != days_of_week[currenttime.tm_wday])
-+		return 0; /* the day doesn't match */
-+
-+	/* ... check the time now */
-+	packet_time = (currenttime.tm_hour * 60) + currenttime.tm_min;
-+	if ((packet_time < info->time_start) || (packet_time > info->time_stop))
-+		return 0;
-+
-+	/* here we match ! */
-+	return 1;
-+}
-+
-+static int
-+checkentry(const char *tablename,
-+           const void *ip,
-+	   const struct xt_match *match,
-+           void *matchinfo,
-+           unsigned int hook_mask)
-+{
-+	struct ipt_time_info *info = matchinfo;   /* match info for rule */
-+
-+	/* First, check that we are in the correct hooks */
-+	if (hook_mask
-+            & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT)))
-+	{
-+		printk("ipt_time: error, only valid for PRE_ROUTING, LOCAL_IN, FORWARD and OUTPUT)\n");
-+		return 0;
-+	}
-+
-+	/* Now check the coherence of the data ... */
-+	if ((info->time_start > 1439) ||        /* 23*60+59 = 1439*/
-+	    (info->time_stop  > 1439))
-+	{
-+		printk(KERN_WARNING "ipt_time: invalid argument\n");
-+		return 0;
-+	}
-+
-+	return 1;
-+}
-+
-+static struct ipt_match time_match = {
-+	.name = "time",
-+	.match = &match,
-+	.matchsize = sizeof(struct ipt_time_info),
-+	.checkentry = &checkentry,
-+	.me = THIS_MODULE
-+};
-+
-+static int __init init(void)
-+{
-+	printk("ipt_time loading\n");
-+	return xt_register_match(&time_match);
-+}
-+
-+static void __exit fini(void)
-+{
-+	xt_unregister_match(&time_match);
-+	printk("ipt_time unloaded\n");
-+}
-+
-+module_init(init);
-+module_exit(fini);
-+
-+
-+/* The part below is borowed and modified from dietlibc */
-+
-+/* seconds per day */
-+#define SPD 24*60*60
-+
-+void
-+localtime(const u32 time, struct tm *r) {
-+	u32 i, timep;
-+	extern struct timezone sys_tz;
-+	const unsigned int __spm[12] =
-+		{ 0,
-+		  (31),
-+		  (31+28),
-+		  (31+28+31),
-+		  (31+28+31+30),
-+		  (31+28+31+30+31),
-+		  (31+28+31+30+31+30),
-+		  (31+28+31+30+31+30+31),
-+		  (31+28+31+30+31+30+31+31),
-+		  (31+28+31+30+31+30+31+31+30),
-+		  (31+28+31+30+31+30+31+31+30+31),
-+		  (31+28+31+30+31+30+31+31+30+31+30),
-+		};
-+	register u32 work;
-+
-+	timep = time - (sys_tz.tz_minuteswest * 60);
-+	work=timep%(SPD);
-+	r->tm_sec=work%60; work/=60;
-+	r->tm_min=work%60; r->tm_hour=work/60;
-+	work=timep/(SPD);
-+	r->tm_wday=(4+work)%7;
-+	for (i=1970; ; ++i) {
-+		register time_t k= (!(i%4) && ((i%100) || !(i%400)))?366:365;
-+		if (work>k)
-+			work-=k;
-+		else
-+			break;
-+	}
-+	r->tm_year=i-1900;
-+	for (i=11; i && __spm[i]>work; --i) ;
-+	r->tm_mon=i;
-+	r->tm_mday=work-__spm[i]+1;
-+}
---- a/net/ipv4/netfilter/Kconfig
-+++ b/net/ipv4/netfilter/Kconfig
-@@ -254,6 +254,22 @@ config IP_NF_MATCH_TOS
- 
- 	  To compile it as a module, choose M here.  If unsure, say N.
- 
-+
-+config IP_NF_MATCH_TIME
-+	tristate  'TIME match support'
-+	depends on IP_NF_IPTABLES
-+	help
-+	  This option adds a `time' match, which allows you
-+	  to match based on the packet arrival time/date
-+	  (arrival time/date at the machine which netfilter is running on) or
-+	  departure time/date (for locally generated packets).
-+
-+	  If you say Y here, try iptables -m time --help for more information.
-+	  If you want to compile it as a module, say M here and read
-+
-+	  Documentation/modules.txt.  If unsure, say `N'.
-+
-+
- config IP_NF_MATCH_RECENT
- 	tristate "recent match support"
- 	depends on IP_NF_IPTABLES
---- a/net/ipv4/netfilter/Makefile
-+++ b/net/ipv4/netfilter/Makefile
-@@ -86,6 +86,7 @@ obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
- obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
- obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
- obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
-+obj-$(CONFIG_IP_NF_MATCH_TIME) += ipt_time.o
- obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
- obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
- obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o

+ 0 - 872
target/linux/generic-2.6/patches-2.6.21/150-netfilter_imq.patch

@@ -1,872 +0,0 @@
---- /dev/null
-+++ b/drivers/net/imq.c
-@@ -0,0 +1,402 @@
-+/*
-+ *             Pseudo-driver for the intermediate queue device.
-+ *
-+ *             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.
-+ *
-+ * Authors:    Patrick McHardy, <[email protected]>
-+ *
-+ *            The first version was written by Martin Devera, <[email protected]>
-+ *
-+ * Credits:    Jan Rafaj <[email protected]>
-+ *              - Update patch to 2.4.21
-+ *             Sebastian Strollo <[email protected]>
-+ *              - Fix "Dead-loop on netdevice imq"-issue
-+ *             Marcel Sebek <[email protected]>
-+ *              - Update to 2.6.2-rc1
-+ *
-+ *	       After some time of inactivity there is a group taking care
-+ *	       of IMQ again: http://www.linuximq.net
-+ *
-+ *
-+ *	       2004/06/30 - New version of IMQ patch to kernels <=2.6.7 including
-+ *	       the following changes:
-+ *
-+ *	       - Correction of ipv6 support "+"s issue (Hasso Tepper)
-+ *	       - Correction of imq_init_devs() issue that resulted in
-+ *	       kernel OOPS unloading IMQ as module (Norbert Buchmuller)
-+ *	       - Addition of functionality to choose number of IMQ devices
-+ *	       during kernel config (Andre Correa)
-+ *	       - Addition of functionality to choose how IMQ hooks on
-+ *	       PRE and POSTROUTING (after or before NAT) (Andre Correa)
-+ *	       - Cosmetic corrections (Norbert Buchmuller) (Andre Correa)
-+ *
-+ *
-+ *             2005/12/16 - IMQ versions between 2.6.7 and 2.6.13 were
-+ *             released with almost no problems. 2.6.14-x was released
-+ *             with some important changes: nfcache was removed; After
-+ *             some weeks of trouble we figured out that some IMQ fields
-+ *             in skb were missing in skbuff.c - skb_clone and copy_skb_header.
-+ *             These functions are correctly patched by this new patch version.
-+ *
-+ *             Thanks for all who helped to figure out all the problems with
-+ *             2.6.14.x: Patrick McHardy, Rune Kock, VeNoMouS, Max CtRiX,
-+ *             Kevin Shanahan, Richard Lucassen, Valery Dachev (hopefully
-+ *             I didn't forget anybody). I apologize again for my lack of time.
-+ *
-+ *             More info at: http://www.linuximq.net/ (Andre Correa)
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/moduleparam.h>
-+#include <linux/skbuff.h>
-+#include <linux/netdevice.h>
-+#include <linux/rtnetlink.h>
-+#include <linux/if_arp.h>
-+#include <linux/netfilter.h>
-+#include <linux/netfilter_ipv4.h>
-+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-+	#include <linux/netfilter_ipv6.h>
-+#endif
-+#include <linux/imq.h>
-+#include <net/pkt_sched.h>
-+
-+extern int qdisc_restart1(struct net_device *dev);
-+
-+static nf_hookfn imq_nf_hook;
-+
-+static struct nf_hook_ops imq_ingress_ipv4 = {
-+	.hook		= imq_nf_hook,
-+	.owner		= THIS_MODULE,
-+	.pf		= PF_INET,
-+	.hooknum	= NF_IP_PRE_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+	.priority	= NF_IP_PRI_MANGLE + 1
-+#else
-+	.priority	= NF_IP_PRI_NAT_DST + 1
-+#endif
-+};
-+
-+static struct nf_hook_ops imq_egress_ipv4 = {
-+	.hook		= imq_nf_hook,
-+	.owner		= THIS_MODULE,
-+	.pf		= PF_INET,
-+	.hooknum	= NF_IP_POST_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA)
-+	.priority	= NF_IP_PRI_LAST
-+#else
-+	.priority	= NF_IP_PRI_NAT_SRC - 1
-+#endif
-+};
-+
-+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-+static struct nf_hook_ops imq_ingress_ipv6 = {
-+	.hook		= imq_nf_hook,
-+	.owner		= THIS_MODULE,
-+	.pf		= PF_INET6,
-+	.hooknum	= NF_IP6_PRE_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+	.priority	= NF_IP6_PRI_MANGLE + 1
-+#else
-+	.priority	= NF_IP6_PRI_NAT_DST + 1
-+#endif
-+};
-+
-+static struct nf_hook_ops imq_egress_ipv6 = {
-+	.hook		= imq_nf_hook,
-+	.owner		= THIS_MODULE,
-+	.pf		= PF_INET6,
-+	.hooknum	= NF_IP6_POST_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA)
-+	.priority	= NF_IP6_PRI_LAST
-+#else
-+	.priority	= NF_IP6_PRI_NAT_SRC - 1
-+#endif
-+};
-+#endif
-+
-+#if defined(CONFIG_IMQ_NUM_DEVS)
-+static unsigned int numdevs = CONFIG_IMQ_NUM_DEVS;
-+#else
-+static unsigned int numdevs = 2;
-+#endif
-+
-+static struct net_device *imq_devs;
-+
-+static struct net_device_stats *imq_get_stats(struct net_device *dev)
-+{
-+	return (struct net_device_stats *)dev->priv;
-+}
-+
-+/* called for packets kfree'd in qdiscs at places other than enqueue */
-+static void imq_skb_destructor(struct sk_buff *skb)
-+{
-+	struct nf_info *info = skb->nf_info;
-+
-+	if (info) {
-+		if (info->indev)
-+			dev_put(info->indev);
-+		if (info->outdev)
-+			dev_put(info->outdev);
-+		kfree(info);
-+	}
-+}
-+
-+static int imq_dev_xmit(struct sk_buff *skb, struct net_device *dev)
-+{
-+	struct net_device_stats *stats = (struct net_device_stats*) dev->priv;
-+
-+	stats->tx_bytes += skb->len;
-+	stats->tx_packets++;
-+
-+	skb->imq_flags = 0;
-+	skb->destructor = NULL;
-+
-+	dev->trans_start = jiffies;
-+	nf_reinject(skb, skb->nf_info, NF_ACCEPT);
-+	return 0;
-+}
-+
-+static int imq_nf_queue(struct sk_buff *skb, struct nf_info *info, unsigned queue_num, void *data)
-+{
-+	struct net_device *dev;
-+	struct net_device_stats *stats;
-+	struct sk_buff *skb2 = NULL;
-+	struct Qdisc *q;
-+	unsigned int index = skb->imq_flags&IMQ_F_IFMASK;
-+	int ret = -1;
-+
-+	if (index > numdevs)
-+		return -1;
-+
-+	dev = imq_devs + index;
-+	if (!(dev->flags & IFF_UP)) {
-+		skb->imq_flags = 0;
-+		nf_reinject(skb, info, NF_ACCEPT);
-+		return 0;
-+	}
-+	dev->last_rx = jiffies;
-+
-+	if (skb->destructor) {
-+		skb2 = skb;
-+		skb = skb_clone(skb, GFP_ATOMIC);
-+		if (!skb)
-+			return -1;
-+	}
-+	skb->nf_info = info;
-+
-+	stats = (struct net_device_stats *)dev->priv;
-+	stats->rx_bytes+= skb->len;
-+	stats->rx_packets++;
-+
-+	spin_lock_bh(&dev->queue_lock);
-+	q = dev->qdisc;
-+	if (q->enqueue) {
-+		q->enqueue(skb_get(skb), q);
-+		if (skb_shared(skb)) {
-+			skb->destructor = imq_skb_destructor;
-+			kfree_skb(skb);
-+			ret = 0;
-+		}
-+	}
-+	if (spin_is_locked(&dev->_xmit_lock))
-+		netif_schedule(dev);
-+	else
-+		while (!netif_queue_stopped(dev) && qdisc_restart1(dev) < 0)
-+			/* NOTHING */;
-+
-+	spin_unlock_bh(&dev->queue_lock);
-+
-+	if (skb2)
-+		kfree_skb(ret ? skb : skb2);
-+
-+	return ret;
-+}
-+
-+static struct nf_queue_handler nfqh = {
-+	.name  = "imq",
-+	.outfn = imq_nf_queue,
-+};
-+
-+static unsigned int imq_nf_hook(unsigned int hook, struct sk_buff **pskb,
-+				const struct net_device *indev,
-+				const struct net_device *outdev,
-+				int (*okfn)(struct sk_buff *))
-+{
-+	if ((*pskb)->imq_flags & IMQ_F_ENQUEUE)
-+		return NF_QUEUE;
-+
-+	return NF_ACCEPT;
-+}
-+
-+
-+static int __init imq_init_hooks(void)
-+{
-+	int err;
-+
-+	err = nf_register_queue_handler(PF_INET, &nfqh);
-+	if (err > 0)
-+		goto err1;
-+	if ((err = nf_register_hook(&imq_ingress_ipv4)))
-+		goto err2;
-+	if ((err = nf_register_hook(&imq_egress_ipv4)))
-+		goto err3;
-+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-+	if ((err = nf_register_queue_handler(PF_INET6, &nfqh)))
-+		goto err4;
-+	if ((err = nf_register_hook(&imq_ingress_ipv6)))
-+		goto err5;
-+	if ((err = nf_register_hook(&imq_egress_ipv6)))
-+		goto err6;
-+#endif
-+
-+	return 0;
-+
-+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-+err6:
-+	nf_unregister_hook(&imq_ingress_ipv6);
-+err5:
-+	nf_unregister_queue_handler(PF_INET6);
-+err4:
-+	nf_unregister_hook(&imq_egress_ipv4);
-+#endif
-+err3:
-+	nf_unregister_hook(&imq_ingress_ipv4);
-+err2:
-+	nf_unregister_queue_handler(PF_INET);
-+err1:
-+	return err;
-+}
-+
-+static void __exit imq_unhook(void)
-+{
-+	nf_unregister_hook(&imq_ingress_ipv4);
-+	nf_unregister_hook(&imq_egress_ipv4);
-+	nf_unregister_queue_handler(PF_INET);
-+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-+	nf_unregister_hook(&imq_ingress_ipv6);
-+	nf_unregister_hook(&imq_egress_ipv6);
-+	nf_unregister_queue_handler(PF_INET6);
-+#endif
-+}
-+
-+static int __init imq_dev_init(struct net_device *dev)
-+{
-+	dev->hard_start_xmit    = imq_dev_xmit;
-+	dev->type               = ARPHRD_VOID;
-+	dev->mtu                = 1500;
-+	dev->tx_queue_len       = 30;
-+	dev->flags              = IFF_NOARP;
-+	dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL);
-+	if (dev->priv == NULL)
-+		return -ENOMEM;
-+	memset(dev->priv, 0, sizeof(struct net_device_stats));
-+	dev->get_stats          = imq_get_stats;
-+
-+	return 0;
-+}
-+
-+static void imq_dev_uninit(struct net_device *dev)
-+{
-+	kfree(dev->priv);
-+}
-+
-+static int __init imq_init_devs(void)
-+{
-+	struct net_device *dev;
-+	int i,j;
-+	j = numdevs;
-+
-+	if (!numdevs || numdevs > IMQ_MAX_DEVS) {
-+		printk(KERN_ERR "IMQ: numdevs has to be betweed 1 and %u\n",
-+		       IMQ_MAX_DEVS);
-+		return -EINVAL;
-+	}
-+
-+	imq_devs = kmalloc(sizeof(struct net_device) * numdevs, GFP_KERNEL);
-+	if (!imq_devs)
-+		return -ENOMEM;
-+	memset(imq_devs, 0, sizeof(struct net_device) * numdevs);
-+
-+	/* we start counting at zero */
-+	numdevs--;
-+
-+	for (i = 0, dev = imq_devs; i <= numdevs; i++, dev++) {
-+		SET_MODULE_OWNER(dev);
-+		strcpy(dev->name, "imq%d");
-+		dev->init   = imq_dev_init;
-+		dev->uninit = imq_dev_uninit;
-+
-+		if (register_netdev(dev) < 0)
-+			goto err_register;
-+	}
-+	printk(KERN_INFO "IMQ starting with %u devices...\n", j);
-+	return 0;
-+
-+err_register:
-+	for (; i; i--)
-+		unregister_netdev(--dev);
-+	kfree(imq_devs);
-+	return -EIO;
-+}
-+
-+static void imq_cleanup_devs(void)
-+{
-+	int i;
-+	struct net_device *dev = imq_devs;
-+
-+	for (i = 0; i <= numdevs; i++)
-+		unregister_netdev(dev++);
-+
-+	kfree(imq_devs);
-+}
-+
-+static int __init imq_init_module(void)
-+{
-+	int err;
-+
-+	if ((err = imq_init_devs())) {
-+		printk(KERN_ERR "IMQ: Error trying imq_init_devs()\n");
-+		return err;
-+	}
-+	if ((err = imq_init_hooks())) {
-+		printk(KERN_ERR "IMQ: Error trying imq_init_hooks()\n");
-+		imq_cleanup_devs();
-+		return err;
-+	}
-+
-+	printk(KERN_INFO "IMQ driver loaded successfully.\n");
-+
-+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+	printk(KERN_INFO "\tHooking IMQ before NAT on PREROUTING.\n");
-+#else
-+	printk(KERN_INFO "\tHooking IMQ after NAT on PREROUTING.\n");
-+#endif
-+#if defined(CONFIG_IMQ_BEHAVIOR_AB) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+	printk(KERN_INFO "\tHooking IMQ before NAT on POSTROUTING.\n");
-+#else
-+	printk(KERN_INFO "\tHooking IMQ after NAT on POSTROUTING.\n");
-+#endif
-+
-+	return 0;
-+}
-+
-+static void __exit imq_cleanup_module(void)
-+{
-+	imq_unhook();
-+	imq_cleanup_devs();
-+	printk(KERN_INFO "IMQ driver unloaded successfully.\n");
-+}
-+
-+
-+module_init(imq_init_module);
-+module_exit(imq_cleanup_module);
-+
-+module_param(numdevs, int, 0);
-+MODULE_PARM_DESC(numdevs, "number of IMQ devices (how many imq* devices will be created)");
-+MODULE_AUTHOR("http://www.linuximq.net");
-+MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See http://www.linuximq.net/ for more information.");
-+MODULE_LICENSE("GPL");
---- a/drivers/net/Kconfig
-+++ b/drivers/net/Kconfig
-@@ -96,6 +96,129 @@ config EQUALIZER
- 	  To compile this driver as a module, choose M here: the module
- 	  will be called eql.  If unsure, say N.
- 
-+config IMQ
-+	tristate "IMQ (intermediate queueing device) support"
-+	depends on NETDEVICES && NETFILTER
-+	---help---
-+	  The IMQ device(s) is used as placeholder for QoS queueing
-+	  disciplines. Every packet entering/leaving the IP stack can be
-+	  directed through the IMQ device where it's enqueued/dequeued to the
-+	  attached qdisc. This allows you to treat network devices as classes
-+	  and distribute bandwidth among them. Iptables is used to specify
-+	  through which IMQ device, if any, packets travel.
-+
-+	  More information at: http://www.linuximq.net/
-+
-+	  To compile this driver as a module, choose M here: the module
-+	  will be called imq.  If unsure, say N.
-+
-+choice
-+	prompt "IMQ behavior (PRE/POSTROUTING)"
-+	depends on IMQ
-+	default IMQ_BEHAVIOR_BA
-+	help
-+
-+		This settings defines how IMQ behaves in respect to its
-+		hooking in PREROUTING and POSTROUTING.
-+
-+		IMQ can work in any of the following ways:
-+
-+		    PREROUTING   |      POSTROUTING
-+		-----------------|-------------------
-+		#1  After NAT    |      After NAT
-+		#2  After NAT    |      Before NAT
-+		#3  Before NAT   |      After NAT
-+		#4  Before NAT   |      Before NAT
-+
-+		The default behavior is to hook before NAT on PREROUTING
-+		and after NAT on POSTROUTING (#3).
-+
-+		This settings are specially usefull when trying to use IMQ
-+		to shape NATed clients.
-+
-+		More information can be found at: www.linuximq.net
-+
-+		If not sure leave the default settings alone.
-+
-+config IMQ_BEHAVIOR_AA
-+	bool "IMQ AA"
-+	help
-+		This settings defines how IMQ behaves in respect to its
-+		hooking in PREROUTING and POSTROUTING.
-+
-+		Choosing this option will make IMQ hook like this:
-+
-+		PREROUTING:   After NAT
-+		POSTROUTING:  After NAT
-+
-+		More information can be found at: www.linuximq.net
-+
-+		If not sure leave the default settings alone.
-+
-+config IMQ_BEHAVIOR_AB
-+	bool "IMQ AB"
-+	help
-+		This settings defines how IMQ behaves in respect to its
-+		hooking in PREROUTING and POSTROUTING.
-+
-+		Choosing this option will make IMQ hook like this:
-+
-+		PREROUTING:   After NAT
-+		POSTROUTING:  Before NAT
-+
-+		More information can be found at: www.linuximq.net
-+
-+		If not sure leave the default settings alone.
-+
-+config IMQ_BEHAVIOR_BA
-+	bool "IMQ BA"
-+	help
-+		This settings defines how IMQ behaves in respect to its
-+		hooking in PREROUTING and POSTROUTING.
-+
-+		Choosing this option will make IMQ hook like this:
-+
-+		PREROUTING:   Before NAT
-+		POSTROUTING:  After NAT
-+
-+		More information can be found at: www.linuximq.net
-+
-+		If not sure leave the default settings alone.
-+
-+config IMQ_BEHAVIOR_BB
-+	bool "IMQ BB"
-+	help
-+		This settings defines how IMQ behaves in respect to its
-+		hooking in PREROUTING and POSTROUTING.
-+
-+		Choosing this option will make IMQ hook like this:
-+
-+		PREROUTING:   Before NAT
-+		POSTROUTING:  Before NAT
-+
-+		More information can be found at: www.linuximq.net
-+
-+		If not sure leave the default settings alone.
-+
-+endchoice
-+
-+config IMQ_NUM_DEVS
-+
-+	int "Number of IMQ devices"
-+	range 2 8
-+	depends on IMQ
-+	default "2"
-+	help
-+
-+		This settings defines how many IMQ devices will be
-+		created.
-+
-+		The default value is 2.
-+
-+		More information can be found at: www.linuximq.net
-+
-+		If not sure leave the default settings alone.
-+
- config TUN
- 	tristate "Universal TUN/TAP device driver support"
- 	select CRC32
---- a/drivers/net/Makefile
-+++ b/drivers/net/Makefile
-@@ -124,6 +124,7 @@ obj-$(CONFIG_SLIP) += slip.o
- obj-$(CONFIG_SLHC) += slhc.o
- 
- obj-$(CONFIG_DUMMY) += dummy.o
-+obj-$(CONFIG_IMQ) += imq.o
- obj-$(CONFIG_IFB) += ifb.o
- obj-$(CONFIG_DE600) += de600.o
- obj-$(CONFIG_DE620) += de620.o
---- /dev/null
-+++ b/include/linux/imq.h
-@@ -0,0 +1,9 @@
-+#ifndef _IMQ_H
-+#define _IMQ_H
-+
-+#define IMQ_MAX_DEVS   16
-+
-+#define IMQ_F_IFMASK   0x7f
-+#define IMQ_F_ENQUEUE  0x80
-+
-+#endif /* _IMQ_H */
---- /dev/null
-+++ b/include/linux/netfilter_ipv4/ipt_IMQ.h
-@@ -0,0 +1,8 @@
-+#ifndef _IPT_IMQ_H
-+#define _IPT_IMQ_H
-+
-+struct ipt_imq_info {
-+	unsigned int todev;     /* target imq device */
-+};
-+
-+#endif /* _IPT_IMQ_H */
---- /dev/null
-+++ b/include/linux/netfilter_ipv6/ip6t_IMQ.h
-@@ -0,0 +1,8 @@
-+#ifndef _IP6T_IMQ_H
-+#define _IP6T_IMQ_H
-+
-+struct ip6t_imq_info {
-+	unsigned int todev;     /* target imq device */
-+};
-+
-+#endif /* _IP6T_IMQ_H */
---- a/include/linux/skbuff.h
-+++ b/include/linux/skbuff.h
-@@ -294,6 +294,10 @@ struct sk_buff {
- #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
- 	struct sk_buff		*nfct_reasm;
- #endif
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+	unsigned char		imq_flags;
-+	struct nf_info		*nf_info;
-+#endif
- #ifdef CONFIG_BRIDGE_NETFILTER
- 	struct nf_bridge_info	*nf_bridge;
- #endif
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -94,6 +94,9 @@
- #include <linux/skbuff.h>
- #include <net/sock.h>
- #include <linux/rtnetlink.h>
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+#include <linux/imq.h>
-+#endif
- #include <linux/proc_fs.h>
- #include <linux/seq_file.h>
- #include <linux/stat.h>
-@@ -1340,7 +1343,11 @@ static int dev_gso_segment(struct sk_buf
- int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
- {
- 	if (likely(!skb->next)) {
--		if (netdev_nit)
-+		if (netdev_nit
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+		    && !(skb->imq_flags & IMQ_F_ENQUEUE)
-+#endif
-+		    )
- 			dev_queue_xmit_nit(skb, dev);
- 
- 		if (netif_needs_gso(dev, skb)) {
---- a/net/core/skbuff.c
-+++ b/net/core/skbuff.c
-@@ -430,6 +430,10 @@ struct sk_buff *skb_clone(struct sk_buff
- 	C(nfct_reasm);
- 	nf_conntrack_get_reasm(skb->nfct_reasm);
- #endif
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+	C(imq_flags);
-+	C(nf_info);
-+#endif /*CONFIG_IMQ*/
- #ifdef CONFIG_BRIDGE_NETFILTER
- 	C(nf_bridge);
- 	nf_bridge_get(skb->nf_bridge);
-@@ -494,6 +498,10 @@ static void copy_skb_header(struct sk_bu
- #if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
- 	new->ipvs_property = old->ipvs_property;
- #endif
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+	new->imq_flags	= old->imq_flags;
-+	new->nf_info	= old->nf_info;
-+#endif /*CONFIG_IMQ*/
- #ifdef CONFIG_BRIDGE_NETFILTER
- 	new->nf_bridge	= old->nf_bridge;
- 	nf_bridge_get(old->nf_bridge);
---- /dev/null
-+++ b/net/ipv4/netfilter/ipt_IMQ.c
-@@ -0,0 +1,69 @@
-+/*
-+ * This target marks packets to be enqueued to an imq device
-+ */
-+#include <linux/module.h>
-+#include <linux/skbuff.h>
-+#include <linux/netfilter_ipv4/ip_tables.h>
-+#include <linux/netfilter_ipv4/ipt_IMQ.h>
-+#include <linux/imq.h>
-+
-+static unsigned int imq_target(struct sk_buff **pskb,
-+			       const struct net_device *in,
-+			       const struct net_device *out,
-+			       unsigned int hooknum,
-+			       const struct xt_target *target,
-+			       const void *targinfo)
-+{
-+	struct ipt_imq_info *mr = (struct ipt_imq_info*)targinfo;
-+
-+	(*pskb)->imq_flags = mr->todev | IMQ_F_ENQUEUE;
-+
-+	return XT_CONTINUE;
-+}
-+
-+static int imq_checkentry(const char *tablename,
-+			  const void *e,
-+			  const struct xt_target *target,
-+			  void *targinfo,
-+			  unsigned int hook_mask)
-+{
-+	struct ipt_imq_info *mr;
-+
-+	mr = (struct ipt_imq_info*)targinfo;
-+
-+	if (mr->todev > IMQ_MAX_DEVS) {
-+		printk(KERN_WARNING
-+		       "IMQ: invalid device specified, highest is %u\n",
-+		       IMQ_MAX_DEVS);
-+		return 0;
-+	}
-+
-+	return 1;
-+}
-+
-+static struct xt_target ipt_imq_reg = {
-+	.name		= "IMQ",
-+	.family		= AF_INET,
-+	.target		= imq_target,
-+	.targetsize	= sizeof(struct ipt_imq_info),
-+	.checkentry	= imq_checkentry,
-+	.me		= THIS_MODULE,
-+	.table		= "mangle"
-+};
-+
-+static int __init init(void)
-+{
-+	return xt_register_target(&ipt_imq_reg);
-+}
-+
-+static void __exit fini(void)
-+{
-+	xt_unregister_target(&ipt_imq_reg);
-+}
-+
-+module_init(init);
-+module_exit(fini);
-+
-+MODULE_AUTHOR("http://www.linuximq.net");
-+MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See http://www.linuximq.net/ for more information.");
-+MODULE_LICENSE("GPL");
---- a/net/ipv4/netfilter/Kconfig
-+++ b/net/ipv4/netfilter/Kconfig
-@@ -581,6 +581,17 @@ config IP_NF_MANGLE
- 
- 	  To compile it as a module, choose M here.  If unsure, say N.
- 
-+config IP_NF_TARGET_IMQ
-+       tristate "IMQ target support"
-+       depends on IP_NF_MANGLE
-+       help
-+         This option adds a `IMQ' target which is used to specify if and
-+         to which IMQ device packets should get enqueued/dequeued.
-+
-+	 For more information visit: http://www.linuximq.net/
-+
-+         To compile it as a module, choose M here.  If unsure, say N.
-+
- config IP_NF_TARGET_TOS
- 	tristate "TOS target support"
- 	depends on IP_NF_MANGLE
---- a/net/ipv4/netfilter/Makefile
-+++ b/net/ipv4/netfilter/Makefile
-@@ -97,6 +97,7 @@ obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ip
- obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
- obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o
- obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o
-+obj-$(CONFIG_IP_NF_TARGET_IMQ) += ipt_IMQ.o
- obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o
- obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
- obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
---- /dev/null
-+++ b/net/ipv6/netfilter/ip6t_IMQ.c
-@@ -0,0 +1,69 @@
-+/*
-+ * This target marks packets to be enqueued to an imq device
-+ */
-+#include <linux/module.h>
-+#include <linux/skbuff.h>
-+#include <linux/netfilter_ipv6/ip6_tables.h>
-+#include <linux/netfilter_ipv6/ip6t_IMQ.h>
-+#include <linux/imq.h>
-+
-+static unsigned int imq_target(struct sk_buff **pskb,
-+			       const struct net_device *in,
-+			       const struct net_device *out,
-+			       unsigned int hooknum,
-+			       const struct xt_target *target,
-+			       const void *targinfo)
-+{
-+	struct ip6t_imq_info *mr = (struct ip6t_imq_info*)targinfo;
-+
-+	(*pskb)->imq_flags = mr->todev | IMQ_F_ENQUEUE;
-+
-+	return XT_CONTINUE;
-+}
-+
-+static int imq_checkentry(const char *tablename,
-+			  const void *entry,
-+			  const struct xt_target *target,
-+			  void *targinfo,
-+			  unsigned int hook_mask)
-+{
-+	struct ip6t_imq_info *mr;
-+
-+	mr = (struct ip6t_imq_info*)targinfo;
-+
-+	if (mr->todev > IMQ_MAX_DEVS) {
-+		printk(KERN_WARNING
-+		       "IMQ: invalid device specified, highest is %u\n",
-+		       IMQ_MAX_DEVS);
-+		return 0;
-+	}
-+
-+	return 1;
-+}
-+
-+static struct xt_target ip6t_imq_reg = {
-+	.name           = "IMQ",
-+	.family		= AF_INET6,
-+	.target         = imq_target,
-+	.targetsize	= sizeof(struct ip6t_imq_info),
-+	.table		= "mangle",
-+	.checkentry     = imq_checkentry,
-+	.me             = THIS_MODULE
-+};
-+
-+static int __init init(void)
-+{
-+	return xt_register_target(&ip6t_imq_reg);
-+}
-+
-+static void __exit fini(void)
-+{
-+	xt_unregister_target(&ip6t_imq_reg);
-+}
-+
-+module_init(init);
-+module_exit(fini);
-+
-+MODULE_AUTHOR("http://www.linuximq.net");
-+MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See http://www.linuximq.net/ for more information.");
-+MODULE_LICENSE("GPL");
---- a/net/ipv6/netfilter/Kconfig
-+++ b/net/ipv6/netfilter/Kconfig
-@@ -173,6 +173,15 @@ config IP6_NF_MANGLE
- 
- 	  To compile it as a module, choose M here.  If unsure, say N.
- 
-+config IP6_NF_TARGET_IMQ
-+	tristate "IMQ target support"
-+	depends on IP6_NF_MANGLE
-+	help
-+          This option adds a `IMQ' target which is used to specify if and
-+          to which imq device packets should get enqueued/dequeued.
-+
-+          To compile it as a module, choose M here.  If unsure, say N.
-+
- config IP6_NF_TARGET_HL
- 	tristate  'HL (hoplimit) target support'
- 	depends on IP6_NF_MANGLE
---- a/net/ipv6/netfilter/Makefile
-+++ b/net/ipv6/netfilter/Makefile
-@@ -13,6 +13,7 @@ obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t
- obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o
- obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
- obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
-+obj-$(CONFIG_IP6_NF_TARGET_IMQ) += ip6t_IMQ.o
- obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o
- obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o
- obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
---- a/net/sched/sch_generic.c
-+++ b/net/sched/sch_generic.c
-@@ -87,7 +87,6 @@ void qdisc_unlock_tree(struct net_device
- 
-    NOTE: Called under dev->queue_lock with locally disabled BH.
- */
--
- static inline int qdisc_restart(struct net_device *dev)
- {
- 	struct Qdisc *q = dev->qdisc;
-@@ -181,6 +180,11 @@ requeue:
- 	return q->q.qlen;
- }
- 
-+int qdisc_restart1(struct net_device *dev)
-+{
-+	return qdisc_restart(dev);
-+}
-+
- void __qdisc_run(struct net_device *dev)
- {
- 	if (unlikely(dev->qdisc == &noop_qdisc))
-@@ -617,3 +621,4 @@ EXPORT_SYMBOL(qdisc_destroy);
- EXPORT_SYMBOL(qdisc_reset);
- EXPORT_SYMBOL(qdisc_lock_tree);
- EXPORT_SYMBOL(qdisc_unlock_tree);
-+EXPORT_SYMBOL(qdisc_restart1);

+ 0 - 947
target/linux/generic-2.6/patches-2.6.21/160-netfilter_route.patch

@@ -1,947 +0,0 @@
---- /dev/null
-+++ b/include/linux/netfilter_ipv4/ipt_ROUTE.h
-@@ -0,0 +1,23 @@
-+/* Header file for iptables ipt_ROUTE target
-+ *
-+ * (C) 2002 by Cédric de Launois <[email protected]>
-+ *
-+ * This software is distributed under GNU GPL v2, 1991
-+ */
-+#ifndef _IPT_ROUTE_H_target
-+#define _IPT_ROUTE_H_target
-+
-+#define IPT_ROUTE_IFNAMSIZ 16
-+
-+struct ipt_route_target_info {
-+	char      oif[IPT_ROUTE_IFNAMSIZ];      /* Output Interface Name */
-+	char      iif[IPT_ROUTE_IFNAMSIZ];      /* Input Interface Name  */
-+	u_int32_t gw;                           /* IP address of gateway */
-+	u_int8_t  flags;
-+};
-+
-+/* Values for "flags" field */
-+#define IPT_ROUTE_CONTINUE        0x01
-+#define IPT_ROUTE_TEE             0x02
-+
-+#endif /*_IPT_ROUTE_H_target*/
---- /dev/null
-+++ b/include/linux/netfilter_ipv6/ip6t_ROUTE.h
-@@ -0,0 +1,23 @@
-+/* Header file for iptables ip6t_ROUTE target
-+ *
-+ * (C) 2003 by Cédric de Launois <[email protected]>
-+ *
-+ * This software is distributed under GNU GPL v2, 1991
-+ */
-+#ifndef _IPT_ROUTE_H_target
-+#define _IPT_ROUTE_H_target
-+
-+#define IP6T_ROUTE_IFNAMSIZ 16
-+
-+struct ip6t_route_target_info {
-+	char      oif[IP6T_ROUTE_IFNAMSIZ];     /* Output Interface Name */
-+	char      iif[IP6T_ROUTE_IFNAMSIZ];     /* Input Interface Name  */
-+	u_int32_t gw[4];                        /* IPv6 address of gateway */
-+	u_int8_t  flags;
-+};
-+
-+/* Values for "flags" field */
-+#define IP6T_ROUTE_CONTINUE        0x01
-+#define IP6T_ROUTE_TEE             0x02
-+
-+#endif /*_IP6T_ROUTE_H_target*/
---- /dev/null
-+++ b/net/ipv4/netfilter/ipt_ROUTE.c
-@@ -0,0 +1,483 @@
-+/*
-+ * This implements the ROUTE target, which enables you to setup unusual
-+ * routes not supported by the standard kernel routing table.
-+ *
-+ * Copyright (C) 2002 Cedric de Launois <[email protected]>
-+ *
-+ * v 1.11 2004/11/23
-+ *
-+ * This software is distributed under GNU GPL v2, 1991
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/skbuff.h>
-+#include <linux/ip.h>
-+#include <linux/netfilter_ipv4/ip_tables.h>
-+#include <linux/netfilter_ipv4/ip_conntrack.h>
-+#include <linux/netfilter_ipv4/ipt_ROUTE.h>
-+#include <linux/netdevice.h>
-+#include <linux/route.h>
-+#include <linux/version.h>
-+#include <linux/if_arp.h>
-+#include <net/ip.h>
-+#include <net/route.h>
-+#include <net/icmp.h>
-+#include <net/checksum.h>
-+
-+#if 0
-+#define DEBUGP printk
-+#else
-+#define DEBUGP(format, args...)
-+#endif
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Cedric de Launois <[email protected]>");
-+MODULE_DESCRIPTION("iptables ROUTE target module");
-+
-+/* Try to route the packet according to the routing keys specified in
-+ * route_info. Keys are :
-+ *  - ifindex : 
-+ *      0 if no oif preferred, 
-+ *      otherwise set to the index of the desired oif
-+ *  - route_info->gw :
-+ *      0 if no gateway specified,
-+ *      otherwise set to the next host to which the pkt must be routed
-+ * If success, skb->dev is the output device to which the packet must 
-+ * be sent and skb->dst is not NULL
-+ *
-+ * RETURN: -1 if an error occured
-+ *          1 if the packet was succesfully routed to the 
-+ *            destination desired
-+ *          0 if the kernel routing table could not route the packet
-+ *            according to the keys specified
-+ */
-+static int route(struct sk_buff *skb,
-+		 unsigned int ifindex,
-+		 const struct ipt_route_target_info *route_info)
-+{
-+	int err;
-+	struct rtable *rt;
-+	struct iphdr *iph = skb->nh.iph;
-+	struct flowi fl = {
-+		.oif = ifindex,
-+		.nl_u = {
-+			.ip4_u = {
-+				.daddr = iph->daddr,
-+				.saddr = 0,
-+				.tos = RT_TOS(iph->tos),
-+				.scope = RT_SCOPE_UNIVERSE,
-+			}
-+		} 
-+	};
-+	
-+	/* The destination address may be overloaded by the target */
-+	if (route_info->gw)
-+		fl.fl4_dst = route_info->gw;
-+	
-+	/* Trying to route the packet using the standard routing table. */
-+	if ((err = ip_route_output_key(&rt, &fl))) {
-+		if (net_ratelimit()) 
-+			DEBUGP("ipt_ROUTE: couldn't route pkt (err: %i)",err);
-+		return -1;
-+	}
-+	
-+	/* Drop old route. */
-+	dst_release(skb->dst);
-+	skb->dst = NULL;
-+
-+	/* Success if no oif specified or if the oif correspond to the 
-+	 * one desired */
-+	if (!ifindex || rt->u.dst.dev->ifindex == ifindex) {
-+		skb->dst = &rt->u.dst;
-+		skb->dev = skb->dst->dev;
-+		skb->protocol = htons(ETH_P_IP);
-+		return 1;
-+	}
-+	
-+	/* The interface selected by the routing table is not the one
-+	 * specified by the user. This may happen because the dst address
-+	 * is one of our own addresses.
-+	 */
-+	if (net_ratelimit()) 
-+		DEBUGP("ipt_ROUTE: failed to route as desired gw=%u.%u.%u.%u oif=%i (got oif=%i)\n", 
-+		       NIPQUAD(route_info->gw), ifindex, rt->u.dst.dev->ifindex);
-+	
-+	return 0;
-+}
-+
-+
-+/* Stolen from ip_finish_output2
-+ * PRE : skb->dev is set to the device we are leaving by
-+ *       skb->dst is not NULL
-+ * POST: the packet is sent with the link layer header pushed
-+ *       the packet is destroyed
-+ */
-+static void ip_direct_send(struct sk_buff *skb)
-+{
-+	struct dst_entry *dst = skb->dst;
-+	struct hh_cache *hh = dst->hh;
-+	struct net_device *dev = dst->dev;
-+	int hh_len = LL_RESERVED_SPACE(dev);
-+
-+	/* Be paranoid, rather than too clever. */
-+	if (unlikely(skb_headroom(skb) < hh_len && dev->hard_header)) {
-+		struct sk_buff *skb2;
-+
-+		skb2 = skb_realloc_headroom(skb, LL_RESERVED_SPACE(dev));
-+		if (skb2 == NULL) {
-+			kfree_skb(skb);
-+			return;
-+		}
-+		if (skb->sk)
-+			skb_set_owner_w(skb2, skb->sk);
-+		kfree_skb(skb);
-+		skb = skb2;
-+	}
-+
-+	if (hh) {
-+		int hh_alen;
-+
-+		read_lock_bh(&hh->hh_lock);
-+		hh_alen = HH_DATA_ALIGN(hh->hh_len);
-+  		memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);
-+		read_unlock_bh(&hh->hh_lock);
-+		skb_push(skb, hh->hh_len);
-+		hh->hh_output(skb);
-+	} else if (dst->neighbour)
-+		dst->neighbour->output(skb);
-+	else {
-+		if (net_ratelimit())
-+			DEBUGP(KERN_DEBUG "ipt_ROUTE: no hdr & no neighbour cache!\n");
-+		kfree_skb(skb);
-+	}
-+}
-+
-+
-+/* PRE : skb->dev is set to the device we are leaving by
-+ * POST: - the packet is directly sent to the skb->dev device, without 
-+ *         pushing the link layer header.
-+ *       - the packet is destroyed
-+ */
-+static inline int dev_direct_send(struct sk_buff *skb)
-+{
-+	return dev_queue_xmit(skb);
-+}
-+
-+
-+static unsigned int route_oif(const struct ipt_route_target_info *route_info,
-+			      struct sk_buff *skb) 
-+{
-+	unsigned int ifindex = 0;
-+	struct net_device *dev_out = NULL;
-+
-+	/* The user set the interface name to use.
-+	 * Getting the current interface index.
-+	 */
-+	if ((dev_out = dev_get_by_name(route_info->oif))) {
-+		ifindex = dev_out->ifindex;
-+	} else {
-+		/* Unknown interface name : packet dropped */
-+		if (net_ratelimit()) 
-+			DEBUGP("ipt_ROUTE: oif interface %s not found\n", route_info->oif);
-+		return NF_DROP;
-+	}
-+
-+	/* Trying the standard way of routing packets */
-+	switch (route(skb, ifindex, route_info)) {
-+	case 1:
-+		dev_put(dev_out);
-+		if (route_info->flags & IPT_ROUTE_CONTINUE)
-+			return IPT_CONTINUE;
-+
-+		ip_direct_send(skb);
-+		return NF_STOLEN;
-+
-+	case 0:
-+		/* Failed to send to oif. Trying the hard way */
-+		if (route_info->flags & IPT_ROUTE_CONTINUE)
-+			return NF_DROP;
-+
-+		if (net_ratelimit()) 
-+			DEBUGP("ipt_ROUTE: forcing the use of %i\n",
-+			       ifindex);
-+
-+		/* We have to force the use of an interface.
-+		 * This interface must be a tunnel interface since
-+		 * otherwise we can't guess the hw address for
-+		 * the packet. For a tunnel interface, no hw address
-+		 * is needed.
-+		 */
-+		if ((dev_out->type != ARPHRD_TUNNEL)
-+		    && (dev_out->type != ARPHRD_IPGRE)) {
-+			if (net_ratelimit()) 
-+				DEBUGP("ipt_ROUTE: can't guess the hw addr !\n");
-+			dev_put(dev_out);
-+			return NF_DROP;
-+		}
-+	
-+		/* Send the packet. This will also free skb
-+		 * Do not go through the POST_ROUTING hook because 
-+		 * skb->dst is not set and because it will probably
-+		 * get confused by the destination IP address.
-+		 */
-+		skb->dev = dev_out;
-+		dev_direct_send(skb);
-+		dev_put(dev_out);
-+		return NF_STOLEN;
-+		
-+	default:
-+		/* Unexpected error */
-+		dev_put(dev_out);
-+		return NF_DROP;
-+	}
-+}
-+
-+
-+static unsigned int route_iif(const struct ipt_route_target_info *route_info,
-+			      struct sk_buff *skb) 
-+{
-+	struct net_device *dev_in = NULL;
-+
-+	/* Getting the current interface index. */
-+	if (!(dev_in = dev_get_by_name(route_info->iif))) {
-+		if (net_ratelimit()) 
-+			DEBUGP("ipt_ROUTE: iif interface %s not found\n", route_info->iif);
-+		return NF_DROP;
-+	}
-+
-+	skb->dev = dev_in;
-+	dst_release(skb->dst);
-+	skb->dst = NULL;
-+
-+	netif_rx(skb);
-+	dev_put(dev_in);
-+	return NF_STOLEN;
-+}
-+
-+
-+static unsigned int route_gw(const struct ipt_route_target_info *route_info,
-+			     struct sk_buff *skb) 
-+{
-+	if (route(skb, 0, route_info)!=1)
-+		return NF_DROP;
-+
-+	if (route_info->flags & IPT_ROUTE_CONTINUE)
-+		return IPT_CONTINUE;
-+
-+	ip_direct_send(skb);
-+	return NF_STOLEN;
-+}
-+
-+
-+/* To detect and deter routed packet loopback when using the --tee option,
-+ * we take a page out of the raw.patch book: on the copied skb, we set up
-+ * a fake ->nfct entry, pointing to the local &route_tee_track. We skip
-+ * routing packets when we see they already have that ->nfct.
-+ */
-+
-+static struct ip_conntrack route_tee_track;
-+
-+static unsigned int ipt_route_target(struct sk_buff **pskb,
-+				     const struct net_device *in,
-+				     const struct net_device *out,
-+				     unsigned int hooknum,
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)
-+				     const struct xt_target *target,
-+#endif
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
-+				     const void *targinfo,
-+				     void *userinfo)
-+#else
-+				     const void *targinfo)
-+#endif
-+{
-+	const struct ipt_route_target_info *route_info = targinfo;
-+	struct sk_buff *skb = *pskb;
-+	unsigned int res;
-+
-+	if (skb->nfct == &route_tee_track.ct_general) {
-+		/* Loopback - a packet we already routed, is to be
-+		 * routed another time. Avoid that, now.
-+		 */
-+		if (net_ratelimit()) 
-+			DEBUGP(KERN_DEBUG "ipt_ROUTE: loopback - DROP!\n");
-+		return NF_DROP;
-+	}
-+
-+	/* If we are at PREROUTING or INPUT hook
-+	 * the TTL isn't decreased by the IP stack
-+	 */
-+	if (hooknum == NF_IP_PRE_ROUTING ||
-+	    hooknum == NF_IP_LOCAL_IN) {
-+
-+		struct iphdr *iph = skb->nh.iph;
-+
-+		if (iph->ttl <= 1) {
-+			struct rtable *rt;
-+			struct flowi fl = {
-+				.oif = 0,
-+				.nl_u = {
-+					.ip4_u = {
-+						.daddr = iph->daddr,
-+						.saddr = iph->saddr,
-+						.tos = RT_TOS(iph->tos),
-+						.scope = ((iph->tos & RTO_ONLINK) ?
-+							  RT_SCOPE_LINK :
-+							  RT_SCOPE_UNIVERSE)
-+					}
-+				} 
-+			};
-+
-+			if (ip_route_output_key(&rt, &fl)) {
-+				return NF_DROP;
-+			}
-+
-+			if (skb->dev == rt->u.dst.dev) {
-+				/* Drop old route. */
-+				dst_release(skb->dst);
-+				skb->dst = &rt->u.dst;
-+
-+				/* this will traverse normal stack, and 
-+				 * thus call conntrack on the icmp packet */
-+				icmp_send(skb, ICMP_TIME_EXCEEDED, 
-+					  ICMP_EXC_TTL, 0);
-+			}
-+
-+			return NF_DROP;
-+		}
-+
-+		/*
-+		 * If we are at INPUT the checksum must be recalculated since
-+		 * the length could change as the result of a defragmentation.
-+		 */
-+		if(hooknum == NF_IP_LOCAL_IN) {
-+			iph->ttl = iph->ttl - 1;
-+			iph->check = 0;
-+			iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
-+		} else {
-+			ip_decrease_ttl(iph);
-+		}
-+	}
-+
-+	if ((route_info->flags & IPT_ROUTE_TEE)) {
-+		/*
-+		 * Copy the *pskb, and route the copy. Will later return
-+		 * IPT_CONTINUE for the original skb, which should continue
-+		 * on its way as if nothing happened. The copy should be
-+		 * independantly delivered to the ROUTE --gw.
-+		 */
-+		skb = skb_copy(*pskb, GFP_ATOMIC);
-+		if (!skb) {
-+			if (net_ratelimit()) 
-+				DEBUGP(KERN_DEBUG "ipt_ROUTE: copy failed!\n");
-+			return IPT_CONTINUE;
-+		}
-+	}
-+
-+	/* Tell conntrack to forget this packet since it may get confused 
-+	 * when a packet is leaving with dst address == our address.
-+	 * Good idea ? Dunno. Need advice.
-+	 *
-+	 * NEW: mark the skb with our &route_tee_track, so we avoid looping
-+	 * on any already routed packet.
-+	 */
-+	if (!(route_info->flags & IPT_ROUTE_CONTINUE)) {
-+		nf_conntrack_put(skb->nfct);
-+		skb->nfct = &route_tee_track.ct_general;
-+		skb->nfctinfo = IP_CT_NEW;
-+		nf_conntrack_get(skb->nfct);
-+	}
-+
-+	if (route_info->oif[0] != '\0') {
-+		res = route_oif(route_info, skb);
-+	} else if (route_info->iif[0] != '\0') {
-+		res = route_iif(route_info, skb);
-+	} else if (route_info->gw) {
-+		res = route_gw(route_info, skb);
-+	} else {
-+		if (net_ratelimit()) 
-+			DEBUGP(KERN_DEBUG "ipt_ROUTE: no parameter !\n");
-+		res = IPT_CONTINUE;
-+	}
-+
-+	if ((route_info->flags & IPT_ROUTE_TEE))
-+		res = IPT_CONTINUE;
-+
-+	return res;
-+}
-+
-+
-+static int ipt_route_checkentry(const char *tablename,
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+				const void *e,
-+#else
-+				const struct ipt_ip *ip,
-+#endif
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)
-+				const struct xt_target *target,
-+#endif
-+				void *targinfo,
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
-+				unsigned int targinfosize,
-+#endif
-+				unsigned int hook_mask)
-+{
-+	if (strcmp(tablename, "mangle") != 0) {
-+		printk("ipt_ROUTE: bad table `%s', use the `mangle' table.\n",
-+		       tablename);
-+		return 0;
-+	}
-+
-+	if (hook_mask & ~(  (1 << NF_IP_PRE_ROUTING)
-+			    | (1 << NF_IP_LOCAL_IN)
-+			    | (1 << NF_IP_FORWARD)
-+			    | (1 << NF_IP_LOCAL_OUT)
-+			    | (1 << NF_IP_POST_ROUTING))) {
-+		printk("ipt_ROUTE: bad hook\n");
-+		return 0;
-+	}
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
-+	if (targinfosize != IPT_ALIGN(sizeof(struct ipt_route_target_info))) {
-+		printk(KERN_WARNING "ipt_ROUTE: targinfosize %u != %Zu\n",
-+		       targinfosize,
-+		       IPT_ALIGN(sizeof(struct ipt_route_target_info)));
-+		return 0;
-+	}
-+#endif
-+
-+	return 1;
-+}
-+
-+
-+static struct ipt_target ipt_route_reg = { 
-+	.name = "ROUTE",
-+	.target = ipt_route_target,
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)
-+	.targetsize = sizeof(struct ipt_route_target_info),
-+#endif
-+	.checkentry = ipt_route_checkentry,
-+	.me = THIS_MODULE,
-+};
-+
-+static int __init init(void)
-+{
-+	/* Set up fake conntrack (stolen from raw.patch):
-+	    - to never be deleted, not in any hashes */
-+	atomic_set(&route_tee_track.ct_general.use, 1);
-+	/*  - and look it like as a confirmed connection */
-+	set_bit(IPS_CONFIRMED_BIT, &route_tee_track.status);
-+	/* Initialize fake conntrack so that NAT will skip it */
-+	route_tee_track.status |= IPS_NAT_DONE_MASK;
-+
-+	return xt_register_target(&ipt_route_reg);
-+}
-+
-+
-+static void __exit fini(void)
-+{
-+	xt_unregister_target(&ipt_route_reg);
-+}
-+
-+module_init(init);
-+module_exit(fini);
---- a/net/ipv4/netfilter/Kconfig
-+++ b/net/ipv4/netfilter/Kconfig
-@@ -684,5 +684,22 @@ config IP_NF_ARP_MANGLE
- 	  Allows altering the ARP packet payload: source and destination
- 	  hardware and network addresses.
- 
-+config IP_NF_TARGET_ROUTE
-+	tristate  'ROUTE target support'
-+	depends on IP_NF_MANGLE
-+	help
-+	  This option adds a `ROUTE' target, which enables you to setup unusual
-+	  routes. For example, the ROUTE lets you route a received packet through 
-+	  an interface or towards a host, even if the regular destination of the 
-+	  packet is the router itself. The ROUTE target is also able to change the 
-+	  incoming interface of a packet.
-+	
-+	  The target can be or not a final target. It has to be used inside the 
-+	  mangle table.
-+	  
-+	  If you want to compile it as a module, say M here and read
-+	  Documentation/modules.txt.  The module will be called ipt_ROUTE.o.
-+	  If unsure, say `N'.
-+
- endmenu
- 
---- a/net/ipv4/netfilter/Makefile
-+++ b/net/ipv4/netfilter/Makefile
-@@ -100,6 +100,7 @@ obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_EC
- obj-$(CONFIG_IP_NF_TARGET_IMQ) += ipt_IMQ.o
- obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o
- obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
-+obj-$(CONFIG_IP_NF_TARGET_ROUTE) += ipt_ROUTE.o
- obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
- obj-$(CONFIG_IP_NF_TARGET_SAME) += ipt_SAME.o
- obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o
---- a/net/ipv6/ipv6_syms.c
-+++ b/net/ipv6/ipv6_syms.c
-@@ -10,6 +10,7 @@ EXPORT_SYMBOL(icmpv6_send);
- EXPORT_SYMBOL(icmpv6_statistics);
- EXPORT_SYMBOL(icmpv6_err_convert);
- EXPORT_SYMBOL(ndisc_mc_map);
-+EXPORT_SYMBOL(nd_tbl);
- EXPORT_SYMBOL(register_inet6addr_notifier);
- EXPORT_SYMBOL(unregister_inet6addr_notifier);
- EXPORT_SYMBOL(ip6_route_output);
---- /dev/null
-+++ b/net/ipv6/netfilter/ip6t_ROUTE.c
-@@ -0,0 +1,330 @@
-+/*
-+ * This implements the ROUTE v6 target, which enables you to setup unusual
-+ * routes not supported by the standard kernel routing table.
-+ *
-+ * Copyright (C) 2003 Cedric de Launois <[email protected]>
-+ *
-+ * v 1.1 2004/11/23
-+ *
-+ * This software is distributed under GNU GPL v2, 1991
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/skbuff.h>
-+#include <linux/ipv6.h>
-+#include <linux/netfilter_ipv6/ip6_tables.h>
-+#include <linux/netfilter_ipv6/ip6t_ROUTE.h>
-+#include <linux/netdevice.h>
-+#include <linux/version.h>
-+#include <net/ipv6.h>
-+#include <net/ndisc.h>
-+#include <net/ip6_route.h>
-+#include <linux/icmpv6.h>
-+
-+#if 1
-+#define DEBUGP printk
-+#else
-+#define DEBUGP(format, args...)
-+#endif
-+
-+#define NIP6(addr) \
-+	ntohs((addr).s6_addr16[0]), \
-+	ntohs((addr).s6_addr16[1]), \
-+	ntohs((addr).s6_addr16[2]), \
-+	ntohs((addr).s6_addr16[3]), \
-+	ntohs((addr).s6_addr16[4]), \
-+	ntohs((addr).s6_addr16[5]), \
-+	ntohs((addr).s6_addr16[6]), \
-+	ntohs((addr).s6_addr16[7])
-+
-+/* Route the packet according to the routing keys specified in
-+ * route_info. Keys are :
-+ *  - ifindex : 
-+ *      0 if no oif preferred, 
-+ *      otherwise set to the index of the desired oif
-+ *  - route_info->gw :
-+ *      0 if no gateway specified,
-+ *      otherwise set to the next host to which the pkt must be routed
-+ * If success, skb->dev is the output device to which the packet must 
-+ * be sent and skb->dst is not NULL
-+ *
-+ * RETURN:  1 if the packet was succesfully routed to the 
-+ *            destination desired
-+ *          0 if the kernel routing table could not route the packet
-+ *            according to the keys specified
-+ */
-+static int 
-+route6(struct sk_buff *skb,
-+       unsigned int ifindex,
-+       const struct ip6t_route_target_info *route_info)
-+{
-+	struct rt6_info *rt = NULL;
-+	struct ipv6hdr *ipv6h = skb->nh.ipv6h;
-+	struct in6_addr *gw = (struct in6_addr*)&route_info->gw;
-+
-+	DEBUGP("ip6t_ROUTE: called with: ");
-+	DEBUGP("DST=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(ipv6h->daddr));
-+	DEBUGP("GATEWAY=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(*gw));
-+	DEBUGP("OUT=%s\n", route_info->oif);
-+	
-+	if (ipv6_addr_any(gw))
-+		rt = rt6_lookup(&ipv6h->daddr, &ipv6h->saddr, ifindex, 1);
-+	else
-+		rt = rt6_lookup(gw, &ipv6h->saddr, ifindex, 1);
-+
-+	if (!rt)
-+		goto no_route;
-+
-+	DEBUGP("ip6t_ROUTE: routing gives: ");
-+	DEBUGP("DST=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(rt->rt6i_dst.addr));
-+	DEBUGP("GATEWAY=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(rt->rt6i_gateway));
-+	DEBUGP("OUT=%s\n", rt->rt6i_dev->name);
-+
-+	if (ifindex && rt->rt6i_dev->ifindex!=ifindex)
-+		goto wrong_route;
-+	
-+	if (!rt->rt6i_nexthop) {
-+		DEBUGP("ip6t_ROUTE: discovering neighbour\n");
-+		rt->rt6i_nexthop = ndisc_get_neigh(rt->rt6i_dev, &rt->rt6i_dst.addr);
-+	}
-+
-+	/* Drop old route. */
-+	dst_release(skb->dst);
-+	skb->dst = &rt->u.dst;
-+	skb->dev = rt->rt6i_dev;
-+	return 1;
-+
-+ wrong_route:
-+	dst_release(&rt->u.dst);
-+ no_route:
-+	if (!net_ratelimit())
-+		return 0;
-+
-+	printk("ip6t_ROUTE: no explicit route found ");
-+	if (ifindex)
-+		printk("via interface %s ", route_info->oif);
-+	if (!ipv6_addr_any(gw))
-+		printk("via gateway %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", NIP6(*gw));
-+	printk("\n");
-+	return 0;
-+}
-+
-+
-+/* Stolen from ip6_output_finish
-+ * PRE : skb->dev is set to the device we are leaving by
-+ *       skb->dst is not NULL
-+ * POST: the packet is sent with the link layer header pushed
-+ *       the packet is destroyed
-+ */
-+static void ip_direct_send(struct sk_buff *skb)
-+{
-+	struct dst_entry *dst = skb->dst;
-+	struct hh_cache *hh = dst->hh;
-+
-+	if (hh) {
-+		read_lock_bh(&hh->hh_lock);
-+		memcpy(skb->data - 16, hh->hh_data, 16);
-+		read_unlock_bh(&hh->hh_lock);
-+		skb_push(skb, hh->hh_len);
-+		hh->hh_output(skb);
-+	} else if (dst->neighbour)
-+		dst->neighbour->output(skb);
-+	else {
-+		if (net_ratelimit())
-+			DEBUGP(KERN_DEBUG "ip6t_ROUTE: no hdr & no neighbour cache!\n");
-+		kfree_skb(skb);
-+	}
-+}
-+
-+
-+static unsigned int 
-+route6_oif(const struct ip6t_route_target_info *route_info,
-+	   struct sk_buff *skb) 
-+{
-+	unsigned int ifindex = 0;
-+	struct net_device *dev_out = NULL;
-+
-+	/* The user set the interface name to use.
-+	 * Getting the current interface index.
-+	 */
-+	if ((dev_out = dev_get_by_name(route_info->oif))) {
-+		ifindex = dev_out->ifindex;
-+	} else {
-+		/* Unknown interface name : packet dropped */
-+		if (net_ratelimit()) 
-+			DEBUGP("ip6t_ROUTE: oif interface %s not found\n", route_info->oif);
-+
-+		if (route_info->flags & IP6T_ROUTE_CONTINUE)
-+			return IP6T_CONTINUE;
-+		else
-+			return NF_DROP;
-+	}
-+
-+	/* Trying the standard way of routing packets */
-+	if (route6(skb, ifindex, route_info)) {
-+		dev_put(dev_out);
-+		if (route_info->flags & IP6T_ROUTE_CONTINUE)
-+			return IP6T_CONTINUE;
-+		
-+		ip_direct_send(skb);
-+		return NF_STOLEN;
-+	} else 
-+		return NF_DROP;
-+}
-+
-+
-+static unsigned int 
-+route6_gw(const struct ip6t_route_target_info *route_info,
-+	  struct sk_buff *skb) 
-+{
-+	if (route6(skb, 0, route_info)) {
-+		if (route_info->flags & IP6T_ROUTE_CONTINUE)
-+			return IP6T_CONTINUE;
-+
-+		ip_direct_send(skb);
-+		return NF_STOLEN;
-+	} else
-+		return NF_DROP;
-+}
-+
-+
-+static unsigned int 
-+ip6t_route_target(struct sk_buff **pskb,
-+		  const struct net_device *in,
-+		  const struct net_device *out,
-+		  unsigned int hooknum,
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)
-+		  const struct xt_target *target,
-+#endif
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
-+		  const void *targinfo,
-+		  void *userinfo)
-+#else
-+		  const void *targinfo)
-+#endif
-+{
-+	const struct ip6t_route_target_info *route_info = targinfo;
-+	struct sk_buff *skb = *pskb;
-+	struct in6_addr *gw = (struct in6_addr*)&route_info->gw;
-+	unsigned int res;
-+
-+	if (route_info->flags & IP6T_ROUTE_CONTINUE)
-+		goto do_it;
-+
-+	/* If we are at PREROUTING or INPUT hook
-+	 * the TTL isn't decreased by the IP stack
-+	 */
-+	if (hooknum == NF_IP6_PRE_ROUTING ||
-+	    hooknum == NF_IP6_LOCAL_IN) {
-+
-+		struct ipv6hdr *ipv6h = skb->nh.ipv6h;
-+
-+		if (ipv6h->hop_limit <= 1) {
-+			/* Force OUTPUT device used as source address */
-+			skb->dev = skb->dst->dev;
-+
-+			icmpv6_send(skb, ICMPV6_TIME_EXCEED, 
-+				    ICMPV6_EXC_HOPLIMIT, 0, skb->dev);
-+
-+			return NF_DROP;
-+		}
-+
-+		ipv6h->hop_limit--;
-+	}
-+
-+	if ((route_info->flags & IP6T_ROUTE_TEE)) {
-+		/*
-+		 * Copy the *pskb, and route the copy. Will later return
-+		 * IP6T_CONTINUE for the original skb, which should continue
-+		 * on its way as if nothing happened. The copy should be
-+		 * independantly delivered to the ROUTE --gw.
-+		 */
-+		skb = skb_copy(*pskb, GFP_ATOMIC);
-+		if (!skb) {
-+			if (net_ratelimit()) 
-+				DEBUGP(KERN_DEBUG "ip6t_ROUTE: copy failed!\n");
-+			return IP6T_CONTINUE;
-+		}
-+	}
-+
-+do_it:
-+	if (route_info->oif[0]) {
-+		res = route6_oif(route_info, skb);
-+	} else if (!ipv6_addr_any(gw)) {
-+		res = route6_gw(route_info, skb);
-+	} else {
-+		if (net_ratelimit()) 
-+			DEBUGP(KERN_DEBUG "ip6t_ROUTE: no parameter !\n");
-+		res = IP6T_CONTINUE;
-+	}
-+
-+	if ((route_info->flags & IP6T_ROUTE_TEE))
-+		res = IP6T_CONTINUE;
-+
-+	return res;
-+}
-+
-+
-+static int 
-+ip6t_route_checkentry(const char *tablename,
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+		      const void *entry,
-+#else
-+		      const struct ip6t_entry *entry
-+#endif
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)
-+		      const struct xt_target *target,
-+#endif
-+		      void *targinfo,
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
-+		      unsigned int targinfosize,
-+#endif
-+		      unsigned int hook_mask)
-+{
-+	if (strcmp(tablename, "mangle") != 0) {
-+		printk("ip6t_ROUTE: can only be called from \"mangle\" table.\n");
-+		return 0;
-+	}
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
-+	if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_route_target_info))) {
-+		printk(KERN_WARNING "ip6t_ROUTE: targinfosize %u != %Zu\n",
-+		       targinfosize,
-+		       IP6T_ALIGN(sizeof(struct ip6t_route_target_info)));
-+		return 0;
-+	}
-+#endif
-+
-+	return 1;
-+}
-+
-+
-+static struct ip6t_target ip6t_route_reg = {
-+	.name       = "ROUTE",
-+	.target     = ip6t_route_target,
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)
-+	.targetsize = sizeof(struct ip6t_route_target_info),
-+#endif
-+	.checkentry = ip6t_route_checkentry,
-+	.me         = THIS_MODULE
-+};
-+
-+
-+static int __init init(void)
-+{
-+	printk(KERN_DEBUG "registering ipv6 ROUTE target\n");
-+	if (xt_register_target(&ip6t_route_reg))
-+		return -EINVAL;
-+
-+	return 0;
-+}
-+
-+
-+static void __exit fini(void)
-+{
-+	xt_unregister_target(&ip6t_route_reg);
-+}
-+
-+module_init(init);
-+module_exit(fini);
-+MODULE_LICENSE("GPL");
---- a/net/ipv6/netfilter/Kconfig
-+++ b/net/ipv6/netfilter/Kconfig
-@@ -209,5 +209,18 @@ config IP6_NF_RAW
- 	  If you want to compile it as a module, say M here and read
- 	  <file:Documentation/modules.txt>.  If unsure, say `N'.
- 
-+config IP6_NF_TARGET_ROUTE
-+	tristate 'ROUTE target support'
-+	depends on IP6_NF_MANGLE
-+	help
-+	  This option adds a `ROUTE' target, which enables you to setup unusual
-+	  routes. The ROUTE target is also able to change the incoming interface
-+	  of a packet.
-+	
-+	  The target can be or not a final target. It has to be used inside the 
-+	  mangle table.
-+	  
-+	  Not working as a module.
-+
- endmenu
- 
---- a/net/ipv6/netfilter/Makefile
-+++ b/net/ipv6/netfilter/Makefile
-@@ -20,6 +20,7 @@ obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_
- obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
- obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o
- obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
-+obj-$(CONFIG_IP6_NF_TARGET_ROUTE) += ip6t_ROUTE.o
- obj-$(CONFIG_IP6_NF_MATCH_MH) += ip6t_mh.o
- 
- # objects for l3 independent conntrack

+ 0 - 20
target/linux/generic-2.6/patches-2.6.21/180-netfilter_depends.patch

@@ -1,20 +0,0 @@
---- a/net/netfilter/Kconfig
-+++ b/net/netfilter/Kconfig
-@@ -165,7 +165,7 @@ config NF_CONNTRACK_FTP
- 
- config NF_CONNTRACK_H323
- 	tristate "H.323 protocol support (EXPERIMENTAL)"
--	depends on EXPERIMENTAL && NF_CONNTRACK && (IPV6 || IPV6=n)
-+	depends on EXPERIMENTAL && NF_CONNTRACK
- 	help
- 	  H.323 is a VoIP signalling protocol from ITU-T. As one of the most
- 	  important VoIP protocols, it is widely used by voice hardware and
-@@ -400,7 +400,7 @@ config NETFILTER_XT_TARGET_CONNSECMARK
- 
- config NETFILTER_XT_TARGET_TCPMSS
- 	tristate '"TCPMSS" target support'
--	depends on NETFILTER_XTABLES && (IPV6 || IPV6=n)
-+	depends on NETFILTER_XTABLES
- 	---help---
- 	  This option adds a `TCPMSS' target, which allows you to alter the
- 	  MSS value of TCP SYN packets, to control the maximum size for that

+ 0 - 789
target/linux/generic-2.6/patches-2.6.21/200-sched_esfq.patch

@@ -1,789 +0,0 @@
---- a/include/linux/pkt_sched.h
-+++ b/include/linux/pkt_sched.h
-@@ -146,8 +146,40 @@ struct tc_sfq_qopt
-  *
-  *	The only reason for this is efficiency, it is possible
-  *	to change these parameters in compile time.
-+ *	
-+ *	If you need to play with these values use esfq instead.
-  */
- 
-+/* ESFQ section */
-+
-+enum
-+{
-+        /* traditional */
-+	TCA_SFQ_HASH_CLASSIC,
-+	TCA_SFQ_HASH_DST,
-+	TCA_SFQ_HASH_SRC,
-+	TCA_SFQ_HASH_FWMARK,
-+        /* direct */
-+	TCA_SFQ_HASH_DSTDIR,
-+	TCA_SFQ_HASH_SRCDIR,
-+	TCA_SFQ_HASH_FWMARKDIR,
-+	/* conntrack */
-+	TCA_SFQ_HASH_CTORIGDST,
-+	TCA_SFQ_HASH_CTORIGSRC,
-+	TCA_SFQ_HASH_CTREPLDST,
-+	TCA_SFQ_HASH_CTREPLSRC,
-+};
-+
-+struct tc_esfq_qopt
-+{
-+	unsigned	quantum;	/* Bytes per round allocated to flow */
-+	int		perturb_period;	/* Period of hash perturbation */
-+	__u32		limit;		/* Maximal packets in queue */
-+	unsigned	divisor;	/* Hash divisor  */
-+	unsigned	flows;		/* Maximal number of flows  */
-+	unsigned	hash_kind;	/* Hash function to use for flow identification */
-+};
-+
- /* RED section */
- 
- enum
---- a/net/sched/Kconfig
-+++ b/net/sched/Kconfig
-@@ -189,6 +189,26 @@ config NET_SCH_SFQ
- 	  To compile this code as a module, choose M here: the
- 	  module will be called sch_sfq.
- 
-+config NET_SCH_ESFQ
-+	tristate "Enhanced Stochastic Fairness Queueing (ESFQ)"
-+	---help---
-+	  Say Y here if you want to use the Enhanced Stochastic Fairness
-+	  Queueing (ESFQ) packet scheduling algorithm for some of your network
-+	  devices or as a leaf discipline for a classful qdisc such as HTB or
-+	  CBQ (see the top of <file:net/sched/sch_esfq.c> for details and
-+	  references to the SFQ algorithm).
-+
-+	  This is an enchanced SFQ version which allows you to control some
-+	  hardcoded values in the SFQ scheduler.
-+
-+	  ESFQ also adds control of the hash function used to identify packet
-+	  flows. The original SFQ discipline hashes by connection; ESFQ add
-+	  several other hashing methods, such as by src IP or by dst IP, which
-+	  can be more fair to users in some networking situations.
-+	  
-+	  To compile this code as a module, choose M here: the
-+	  module will be called sch_esfq.
-+
- config NET_SCH_TEQL
- 	tristate "True Link Equalizer (TEQL)"
- 	---help---
---- a/net/sched/Makefile
-+++ b/net/sched/Makefile
-@@ -23,6 +23,7 @@ obj-$(CONFIG_NET_SCH_GRED)	+= sch_gred.o
- obj-$(CONFIG_NET_SCH_INGRESS)	+= sch_ingress.o 
- obj-$(CONFIG_NET_SCH_DSMARK)	+= sch_dsmark.o
- obj-$(CONFIG_NET_SCH_SFQ)	+= sch_sfq.o
-+obj-$(CONFIG_NET_SCH_ESFQ)	+= sch_esfq.o
- obj-$(CONFIG_NET_SCH_TBF)	+= sch_tbf.o
- obj-$(CONFIG_NET_SCH_TEQL)	+= sch_teql.o
- obj-$(CONFIG_NET_SCH_PRIO)	+= sch_prio.o
---- /dev/null
-+++ b/net/sched/sch_esfq.c
-@@ -0,0 +1,704 @@
-+/*
-+ * net/sched/sch_esfq.c	Extended Stochastic Fairness Queueing discipline.
-+ *
-+ *		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.
-+ *
-+ * Authors:	Alexey Kuznetsov, <[email protected]>
-+ *
-+ * Changes:	Alexander Atanasov, <[email protected]>
-+ *		Added dynamic depth,limit,divisor,hash_kind options.
-+ *		Added dst and src hashes.
-+ *
-+ * 		Alexander Clouter, <[email protected]>
-+ *		Ported ESFQ to Linux 2.6.
-+ *
-+ * 		Corey Hickey, <[email protected]>
-+ *		Maintenance of the Linux 2.6 port.
-+ *		Added fwmark hash (thanks to Robert Kurjata).
-+ *		Added direct hashing for src, dst, and fwmark.
-+ *		Added usage of jhash.
-+ *		
-+ */
-+
-+#include <linux/module.h>
-+#include <asm/uaccess.h>
-+#include <asm/system.h>
-+#include <linux/bitops.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/jiffies.h>
-+#include <linux/string.h>
-+#include <linux/mm.h>
-+#include <linux/socket.h>
-+#include <linux/sockios.h>
-+#include <linux/in.h>
-+#include <linux/errno.h>
-+#include <linux/interrupt.h>
-+#include <linux/if_ether.h>
-+#include <linux/inet.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/notifier.h>
-+#include <linux/init.h>
-+#include <net/ip.h>
-+#include <linux/ipv6.h>
-+#include <net/route.h>
-+#include <linux/skbuff.h>
-+#include <net/sock.h>
-+#include <net/pkt_sched.h>
-+#include <linux/jhash.h>
-+
-+#ifdef CONFIG_NF_CONNTRACK_ENABLED
-+#include <net/netfilter/nf_conntrack.h>
-+#endif
-+
-+/*	Stochastic Fairness Queuing algorithm.
-+	For more comments look at sch_sfq.c.
-+	The difference is that you can change limit, depth,
-+	hash table size and choose alternate hash types.
-+	
-+	classic:	same as in sch_sfq.c
-+	dst:		destination IP address
-+	src:		source IP address
-+	fwmark:         netfilter mark value
-+	dst_direct:
-+	src_direct:
-+	fwmark_direct:  direct hashing of the above sources
-+	ctorigdst:	original destination IP address
-+	ctorigsrc:	original source IP address
-+	ctrepldst:	reply destination IP address
-+	ctreplsrc:	reply source IP 
-+	
-+*/
-+
-+
-+/* This type should contain at least SFQ_DEPTH*2 values */
-+typedef unsigned int esfq_index;
-+
-+struct esfq_head
-+{
-+	esfq_index	next;
-+	esfq_index	prev;
-+};
-+
-+struct esfq_sched_data
-+{
-+/* Parameters */
-+	int		perturb_period;
-+	unsigned	quantum;	/* Allotment per round: MUST BE >= MTU */
-+	int		limit;
-+	unsigned	depth;
-+	unsigned	hash_divisor;
-+	unsigned	hash_kind;
-+/* Variables */
-+	struct timer_list perturb_timer;
-+	int		perturbation;
-+	esfq_index	tail;		/* Index of current slot in round */
-+	esfq_index	max_depth;	/* Maximal depth */
-+
-+	esfq_index	*ht;			/* Hash table */
-+	esfq_index	*next;			/* Active slots link */
-+	short		*allot;			/* Current allotment per slot */
-+	unsigned short	*hash;			/* Hash value indexed by slots */
-+	struct sk_buff_head	*qs;		/* Slot queue */
-+	struct esfq_head	*dep;		/* Linked list of slots, indexed by depth */
-+	unsigned	dyn_min;	/* For dynamic divisor adjustment; minimum value seen */
-+	unsigned	dyn_max;	/*                                 maximum value seen */
-+	unsigned	dyn_range;	/*	        		   saved range */
-+};
-+
-+/* This contains the info we will hash. */
-+struct esfq_packet_info
-+{
-+	u32	proto;		/* protocol or port */
-+	u32	src;		/* source from packet header */
-+	u32	dst;		/* destination from packet header */
-+	u32	ctorigsrc;	/* original source from conntrack */
-+	u32	ctorigdst;	/* original destination from conntrack */
-+	u32	ctreplsrc;	/* reply source from conntrack */
-+	u32	ctrepldst;	/* reply destination from conntrack */
-+	u32	mark;		/* netfilter mark (fwmark) */
-+};
-+
-+/* Hash input values directly into the "nearest" slot, taking into account the
-+ * range of input values seen. This is most useful when the hash table is at
-+ * least as large as the range of possible values.
-+ * Note: this functionality was added before the change to using jhash, and may
-+ * no longer be useful. */
-+static __inline__ unsigned esfq_hash_direct(struct esfq_sched_data *q, u32 h)
-+{
-+	/* adjust minimum and maximum */
-+	if (h < q->dyn_min || h > q->dyn_max) {
-+		q->dyn_min = h < q->dyn_min ? h : q->dyn_min;
-+		q->dyn_max = h > q->dyn_max ? h : q->dyn_max;
-+	
-+		/* find new range */
-+		if ((q->dyn_range = q->dyn_max - q->dyn_min) >= q->hash_divisor)
-+			printk(KERN_WARNING "ESFQ: (direct hash) Input range %u is larger than hash "
-+					"table. See ESFQ README for details.\n", q->dyn_range);
-+	}
-+	
-+	/* hash input values into slot numbers */
-+	if (q->dyn_min == q->dyn_max)
-+		return 0; /* only one value seen; avoid division by 0 */
-+	else
-+		return (h - q->dyn_min) * (q->hash_divisor - 1) / q->dyn_range;
-+}
-+
-+static __inline__ unsigned esfq_jhash_1word(struct esfq_sched_data *q,u32 a)
-+{
-+	return jhash_1word(a, q->perturbation) & (q->hash_divisor-1);
-+}
-+
-+static __inline__ unsigned esfq_jhash_2words(struct esfq_sched_data *q, u32 a, u32 b)
-+{
-+	return jhash_2words(a, b, q->perturbation) & (q->hash_divisor-1);
-+}
-+
-+static __inline__ unsigned esfq_jhash_3words(struct esfq_sched_data *q, u32 a, u32 b, u32 c)
-+{
-+	return jhash_3words(a, b, c, q->perturbation) & (q->hash_divisor-1);
-+}
-+
-+
-+static unsigned esfq_hash(struct esfq_sched_data *q, struct sk_buff *skb)
-+{
-+	struct esfq_packet_info info;
-+#ifdef CONFIG_NF_CONNTRACK_ENABLED
-+	enum ip_conntrack_info ctinfo;
-+	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
-+#endif
-+	
-+	switch (skb->protocol) {
-+	case __constant_htons(ETH_P_IP):
-+	{
-+		struct iphdr *iph = skb->nh.iph;
-+		info.dst = iph->daddr;
-+		info.src = iph->saddr;
-+		if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
-+		    (iph->protocol == IPPROTO_TCP ||
-+		     iph->protocol == IPPROTO_UDP ||
-+		     iph->protocol == IPPROTO_SCTP ||
-+		     iph->protocol == IPPROTO_DCCP ||
-+		     iph->protocol == IPPROTO_ESP))
-+			info.proto = *(((u32*)iph) + iph->ihl);
-+		else
-+			info.proto = iph->protocol;
-+		break;
-+	}
-+	case __constant_htons(ETH_P_IPV6):
-+	{
-+		struct ipv6hdr *iph = skb->nh.ipv6h;
-+		/* Hash ipv6 addresses into a u32. This isn't ideal,
-+		 * but the code is simple. */
-+		info.dst = jhash2(iph->daddr.s6_addr32, 4, q->perturbation);
-+		info.src = jhash2(iph->saddr.s6_addr32, 4, q->perturbation);
-+		if (iph->nexthdr == IPPROTO_TCP ||
-+		    iph->nexthdr == IPPROTO_UDP ||
-+		    iph->nexthdr == IPPROTO_SCTP ||
-+		    iph->nexthdr == IPPROTO_DCCP ||
-+		    iph->nexthdr == IPPROTO_ESP)
-+			info.proto = *(u32*)&iph[1];
-+		else
-+			info.proto = iph->nexthdr;
-+		break;
-+	}
-+	default:
-+		info.dst   = (u32)(unsigned long)skb->dst;
-+		info.src   = (u32)(unsigned long)skb->sk;
-+		info.proto = skb->protocol;
-+	}
-+
-+	info.mark = skb->mark;
-+
-+#ifdef CONFIG_NF_CONNTRACK_ENABLED
-+	/* defaults if there is no conntrack info */
-+	info.ctorigsrc = info.src;
-+	info.ctorigdst = info.dst;
-+	info.ctreplsrc = info.dst;
-+	info.ctrepldst = info.src;
-+	/* collect conntrack info */
-+	if (ct && ct != &nf_conntrack_untracked) {
-+		if (skb->protocol == __constant_htons(ETH_P_IP)) {
-+			info.ctorigsrc = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip;
-+			info.ctorigdst = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip;
-+			info.ctreplsrc = ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip;
-+			info.ctrepldst = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip;
-+		}
-+		else if (skb->protocol == __constant_htons(ETH_P_IPV6)) {
-+			/* Again, hash ipv6 addresses into a single u32. */
-+			info.ctorigsrc = jhash2(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip6, 4, q->perturbation);
-+			info.ctorigdst = jhash2(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip6, 4, q->perturbation);
-+			info.ctreplsrc = jhash2(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip6, 4, q->perturbation);
-+			info.ctrepldst = jhash2(ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip6, 4, q->perturbation);
-+		}
-+
-+	}
-+#endif
-+
-+	switch(q->hash_kind)
-+	{
-+	case TCA_SFQ_HASH_CLASSIC:
-+		return esfq_jhash_3words(q, info.dst, info.src, info.proto);
-+	case TCA_SFQ_HASH_DST:
-+		return esfq_jhash_1word(q, info.dst);
-+	case TCA_SFQ_HASH_DSTDIR:
-+		return esfq_hash_direct(q, ntohl(info.dst));
-+	case TCA_SFQ_HASH_SRC:
-+		return esfq_jhash_1word(q, info.src);
-+	case TCA_SFQ_HASH_SRCDIR:
-+		return esfq_hash_direct(q, ntohl(info.src));
-+	case TCA_SFQ_HASH_FWMARK:
-+		return esfq_jhash_1word(q, info.mark);
-+	case TCA_SFQ_HASH_FWMARKDIR:
-+		return esfq_hash_direct(q, info.mark);
-+#ifdef CONFIG_NF_CONNTRACK_ENABLED
-+	case TCA_SFQ_HASH_CTORIGDST:
-+		return esfq_jhash_1word(q, info.ctorigdst);
-+	case TCA_SFQ_HASH_CTORIGSRC:
-+		return esfq_jhash_1word(q, info.ctorigsrc);
-+	case TCA_SFQ_HASH_CTREPLDST:
-+		return esfq_jhash_1word(q, info.ctrepldst);
-+	case TCA_SFQ_HASH_CTREPLSRC:
-+		return esfq_jhash_1word(q, info.ctreplsrc);
-+#endif
-+	default:
-+		if (net_ratelimit())
-+			printk(KERN_WARNING "ESFQ: Unknown hash method. Falling back to classic.\n");
-+	}
-+	return esfq_jhash_3words(q, info.dst, info.src, info.proto);
-+}
-+
-+static inline void esfq_link(struct esfq_sched_data *q, esfq_index x)
-+{
-+	esfq_index p, n;
-+	int d = q->qs[x].qlen + q->depth;
-+
-+	p = d;
-+	n = q->dep[d].next;
-+	q->dep[x].next = n;
-+	q->dep[x].prev = p;
-+	q->dep[p].next = q->dep[n].prev = x;
-+}
-+
-+static inline void esfq_dec(struct esfq_sched_data *q, esfq_index x)
-+{
-+	esfq_index p, n;
-+
-+	n = q->dep[x].next;
-+	p = q->dep[x].prev;
-+	q->dep[p].next = n;
-+	q->dep[n].prev = p;
-+
-+	if (n == p && q->max_depth == q->qs[x].qlen + 1)
-+		q->max_depth--;
-+
-+	esfq_link(q, x);
-+}
-+
-+static inline void esfq_inc(struct esfq_sched_data *q, esfq_index x)
-+{
-+	esfq_index p, n;
-+	int d;
-+
-+	n = q->dep[x].next;
-+	p = q->dep[x].prev;
-+	q->dep[p].next = n;
-+	q->dep[n].prev = p;
-+	d = q->qs[x].qlen;
-+	if (q->max_depth < d)
-+		q->max_depth = d;
-+
-+	esfq_link(q, x);
-+}
-+
-+static unsigned int esfq_drop(struct Qdisc *sch)
-+{
-+	struct esfq_sched_data *q = qdisc_priv(sch);
-+	esfq_index d = q->max_depth;
-+	struct sk_buff *skb;
-+	unsigned int len;
-+
-+	/* Queue is full! Find the longest slot and
-+	   drop a packet from it */
-+
-+	if (d > 1) {
-+		esfq_index x = q->dep[d+q->depth].next;
-+		skb = q->qs[x].prev;
-+		len = skb->len;
-+		__skb_unlink(skb, &q->qs[x]);
-+		kfree_skb(skb);
-+		esfq_dec(q, x);
-+		sch->q.qlen--;
-+		sch->qstats.drops++;
-+		sch->qstats.backlog -= len;
-+		return len;
-+	}
-+
-+	if (d == 1) {
-+		/* It is difficult to believe, but ALL THE SLOTS HAVE LENGTH 1. */
-+		d = q->next[q->tail];
-+		q->next[q->tail] = q->next[d];
-+		q->allot[q->next[d]] += q->quantum;
-+		skb = q->qs[d].prev;
-+		len = skb->len;
-+		__skb_unlink(skb, &q->qs[d]);
-+		kfree_skb(skb);
-+		esfq_dec(q, d);
-+		sch->q.qlen--;
-+		q->ht[q->hash[d]] = q->depth;
-+		sch->qstats.drops++;
-+		sch->qstats.backlog -= len;
-+		return len;
-+	}
-+
-+	return 0;
-+}
-+
-+static int
-+esfq_enqueue(struct sk_buff *skb, struct Qdisc* sch)
-+{
-+	struct esfq_sched_data *q = qdisc_priv(sch);
-+	unsigned hash = esfq_hash(q, skb);
-+	unsigned depth = q->depth;
-+	esfq_index x;
-+
-+	x = q->ht[hash];
-+	if (x == depth) {
-+		q->ht[hash] = x = q->dep[depth].next;
-+		q->hash[x] = hash;
-+	}
-+	sch->qstats.backlog += skb->len;
-+	__skb_queue_tail(&q->qs[x], skb);
-+	esfq_inc(q, x);
-+	if (q->qs[x].qlen == 1) {		/* The flow is new */
-+		if (q->tail == depth) {	/* It is the first flow */
-+			q->tail = x;
-+			q->next[x] = x;
-+			q->allot[x] = q->quantum;
-+		} else {
-+			q->next[x] = q->next[q->tail];
-+			q->next[q->tail] = x;
-+			q->tail = x;
-+		}
-+	}
-+	if (++sch->q.qlen < q->limit-1) {
-+		sch->bstats.bytes += skb->len;
-+		sch->bstats.packets++;
-+		return 0;
-+	}
-+
-+	esfq_drop(sch);
-+	return NET_XMIT_CN;
-+}
-+
-+static int
-+esfq_requeue(struct sk_buff *skb, struct Qdisc* sch)
-+{
-+	struct esfq_sched_data *q = qdisc_priv(sch);
-+	unsigned hash = esfq_hash(q, skb);
-+	unsigned depth = q->depth;
-+	esfq_index x;
-+
-+	x = q->ht[hash];
-+	if (x == depth) {
-+		q->ht[hash] = x = q->dep[depth].next;
-+		q->hash[x] = hash;
-+	}
-+	sch->qstats.backlog += skb->len;
-+	__skb_queue_head(&q->qs[x], skb);
-+	esfq_inc(q, x);
-+	if (q->qs[x].qlen == 1) {		/* The flow is new */
-+		if (q->tail == depth) {	/* It is the first flow */
-+			q->tail = x;
-+			q->next[x] = x;
-+			q->allot[x] = q->quantum;
-+		} else {
-+			q->next[x] = q->next[q->tail];
-+			q->next[q->tail] = x;
-+			q->tail = x;
-+		}
-+	}
-+	if (++sch->q.qlen < q->limit - 1) {
-+		sch->qstats.requeues++;
-+		return 0;
-+	}
-+
-+	sch->qstats.drops++;
-+	esfq_drop(sch);
-+	return NET_XMIT_CN;
-+}
-+
-+
-+
-+
-+static struct sk_buff *
-+esfq_dequeue(struct Qdisc* sch)
-+{
-+	struct esfq_sched_data *q = qdisc_priv(sch);
-+	struct sk_buff *skb;
-+	unsigned depth = q->depth;
-+	esfq_index a, old_a;
-+
-+	/* No active slots */
-+	if (q->tail == depth)
-+		return NULL;
-+	
-+	a = old_a = q->next[q->tail];
-+	
-+	/* Grab packet */
-+	skb = __skb_dequeue(&q->qs[a]);
-+	esfq_dec(q, a);
-+	sch->q.qlen--;
-+	sch->qstats.backlog -= skb->len;
-+	
-+	/* Is the slot empty? */
-+	if (q->qs[a].qlen == 0) {
-+		q->ht[q->hash[a]] = depth;
-+		a = q->next[a];
-+		if (a == old_a) {
-+			q->tail = depth;
-+			return skb;
-+		}
-+		q->next[q->tail] = a;
-+		q->allot[a] += q->quantum;
-+	} else if ((q->allot[a] -= skb->len) <= 0) {
-+		q->tail = a;
-+		a = q->next[a];
-+		q->allot[a] += q->quantum;
-+	}
-+	
-+	return skb;
-+}
-+
-+static void
-+esfq_reset(struct Qdisc* sch)
-+{
-+	struct sk_buff *skb;
-+
-+	while ((skb = esfq_dequeue(sch)) != NULL)
-+		kfree_skb(skb);
-+}
-+
-+static void esfq_perturbation(unsigned long arg)
-+{
-+	struct Qdisc *sch = (struct Qdisc*)arg;
-+	struct esfq_sched_data *q = qdisc_priv(sch);
-+
-+	q->perturbation = net_random()&0x1F;
-+
-+	if (q->perturb_period) {
-+		q->perturb_timer.expires = jiffies + q->perturb_period;
-+		add_timer(&q->perturb_timer);
-+	}
-+}
-+
-+static int esfq_change(struct Qdisc *sch, struct rtattr *opt)
-+{
-+	struct esfq_sched_data *q = qdisc_priv(sch);
-+	struct tc_esfq_qopt *ctl = RTA_DATA(opt);
-+	int old_perturb = q->perturb_period;
-+	
-+	if (opt->rta_len < RTA_LENGTH(sizeof(*ctl)))
-+		return -EINVAL;
-+	
-+	sch_tree_lock(sch);
-+	q->quantum = ctl->quantum ? : psched_mtu(sch->dev);
-+	q->perturb_period = ctl->perturb_period*HZ;
-+//	q->hash_divisor = ctl->divisor;
-+//	q->tail = q->limit = q->depth = ctl->flows;
-+	
-+	if (ctl->limit)
-+		q->limit = min_t(u32, ctl->limit, q->depth);
-+	
-+	if (ctl->hash_kind) {
-+		q->hash_kind = ctl->hash_kind;
-+		if (q->hash_kind != TCA_SFQ_HASH_CLASSIC)
-+			q->perturb_period = 0;
-+	}
-+	
-+	// is sch_tree_lock enough to do this ?
-+	while (sch->q.qlen >= q->limit-1)
-+		esfq_drop(sch);
-+	
-+	if (old_perturb)
-+		del_timer(&q->perturb_timer);
-+	if (q->perturb_period) {
-+		q->perturb_timer.expires = jiffies + q->perturb_period;
-+		add_timer(&q->perturb_timer);
-+	} else {
-+		q->perturbation = 0;
-+	}
-+	sch_tree_unlock(sch);
-+	return 0;
-+}
-+
-+static int esfq_init(struct Qdisc *sch, struct rtattr *opt)
-+{
-+	struct esfq_sched_data *q = qdisc_priv(sch);
-+	struct tc_esfq_qopt *ctl;
-+	esfq_index p = ~0U/2;
-+	int i;
-+	
-+	if (opt && opt->rta_len < RTA_LENGTH(sizeof(*ctl)))
-+		return -EINVAL;
-+
-+	init_timer(&q->perturb_timer);
-+	q->perturb_timer.data = (unsigned long)sch;
-+	q->perturb_timer.function = esfq_perturbation;
-+	q->perturbation = 0;
-+	q->hash_kind = TCA_SFQ_HASH_CLASSIC;
-+	q->max_depth = 0;
-+	q->dyn_min = ~0U; /* maximum value for this type */
-+	q->dyn_max = 0;  /* dyn_min/dyn_max will be set properly upon first packet */
-+	if (opt == NULL) {
-+		q->quantum = psched_mtu(sch->dev);
-+		q->perturb_period = 0;
-+		q->hash_divisor = 1024;
-+		q->tail = q->limit = q->depth = 128;
-+		
-+	} else {
-+		ctl = RTA_DATA(opt);
-+		q->quantum = ctl->quantum ? : psched_mtu(sch->dev);
-+		q->perturb_period = ctl->perturb_period*HZ;
-+		q->hash_divisor = ctl->divisor ? : 1024;
-+		q->tail = q->limit = q->depth = ctl->flows ? : 128;
-+		
-+		if ( q->depth > p - 1 )
-+			return -EINVAL;
-+		
-+		if (ctl->limit)
-+			q->limit = min_t(u32, ctl->limit, q->depth);
-+		
-+		if (ctl->hash_kind) {
-+			q->hash_kind = ctl->hash_kind;
-+		}
-+		
-+		if (q->perturb_period) {
-+			q->perturb_timer.expires = jiffies + q->perturb_period;
-+			add_timer(&q->perturb_timer);
-+		}
-+	}
-+	
-+	q->ht = kmalloc(q->hash_divisor*sizeof(esfq_index), GFP_KERNEL);
-+	if (!q->ht)
-+		goto err_case;
-+		
-+	q->dep = kmalloc((1+q->depth*2)*sizeof(struct esfq_head), GFP_KERNEL);
-+	if (!q->dep)
-+		goto err_case;
-+	q->next = kmalloc(q->depth*sizeof(esfq_index), GFP_KERNEL);
-+	if (!q->next)
-+		goto err_case;
-+	
-+	q->allot = kmalloc(q->depth*sizeof(short), GFP_KERNEL);
-+	if (!q->allot)
-+		goto err_case;
-+	q->hash = kmalloc(q->depth*sizeof(unsigned short), GFP_KERNEL);
-+	if (!q->hash)
-+		goto err_case;
-+	q->qs = kmalloc(q->depth*sizeof(struct sk_buff_head), GFP_KERNEL);
-+	if (!q->qs)
-+		goto err_case;
-+	
-+	for (i=0; i< q->hash_divisor; i++)
-+		q->ht[i] = q->depth;
-+	for (i=0; i<q->depth; i++) {
-+		skb_queue_head_init(&q->qs[i]);
-+		q->dep[i+q->depth].next = i+q->depth;
-+		q->dep[i+q->depth].prev = i+q->depth;
-+	}
-+	
-+	for (i=0; i<q->depth; i++)
-+		esfq_link(q, i);
-+	return 0;
-+err_case:
-+	del_timer(&q->perturb_timer);
-+	if (q->ht)
-+		kfree(q->ht);
-+	if (q->dep)
-+		kfree(q->dep);
-+	if (q->next)
-+		kfree(q->next);
-+	if (q->allot)
-+		kfree(q->allot);
-+	if (q->hash)
-+		kfree(q->hash);
-+	if (q->qs)
-+		kfree(q->qs);
-+	return -ENOBUFS;
-+}
-+
-+static void esfq_destroy(struct Qdisc *sch)
-+{
-+	struct esfq_sched_data *q = qdisc_priv(sch);
-+	del_timer(&q->perturb_timer);
-+	if(q->ht)
-+		kfree(q->ht);
-+	if(q->dep)
-+		kfree(q->dep);
-+	if(q->next)
-+		kfree(q->next);
-+	if(q->allot)
-+		kfree(q->allot);
-+	if(q->hash)
-+		kfree(q->hash);
-+	if(q->qs)
-+		kfree(q->qs);
-+}
-+
-+static int esfq_dump(struct Qdisc *sch, struct sk_buff *skb)
-+{
-+	struct esfq_sched_data *q = qdisc_priv(sch);
-+	unsigned char	 *b = skb->tail;
-+	struct tc_esfq_qopt opt;
-+
-+	opt.quantum = q->quantum;
-+	opt.perturb_period = q->perturb_period/HZ;
-+
-+	opt.limit = q->limit;
-+	opt.divisor = q->hash_divisor;
-+	opt.flows = q->depth;
-+	opt.hash_kind = q->hash_kind;
-+
-+	RTA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
-+
-+	return skb->len;
-+
-+rtattr_failure:
-+	skb_trim(skb, b - skb->data);
-+	return -1;
-+}
-+
-+static struct Qdisc_ops esfq_qdisc_ops =
-+{
-+	.next		=	NULL,
-+	.cl_ops		=	NULL,
-+	.id		=	"esfq",
-+	.priv_size	=	sizeof(struct esfq_sched_data),
-+	.enqueue	=	esfq_enqueue,
-+	.dequeue	=	esfq_dequeue,
-+	.requeue	=	esfq_requeue,
-+	.drop		=	esfq_drop,
-+	.init		=	esfq_init,
-+	.reset		=	esfq_reset,
-+	.destroy	=	esfq_destroy,
-+	.change		=	NULL, /* esfq_change - needs more work */
-+	.dump		=	esfq_dump,
-+	.owner		=	THIS_MODULE,
-+};
-+
-+static int __init esfq_module_init(void)
-+{
-+	return register_qdisc(&esfq_qdisc_ops);
-+}
-+static void __exit esfq_module_exit(void) 
-+{
-+	unregister_qdisc(&esfq_qdisc_ops);
-+}
-+module_init(esfq_module_init)
-+module_exit(esfq_module_exit)
-+MODULE_LICENSE("GPL");

+ 0 - 352
target/linux/generic-2.6/patches-2.6.21/201-multiple_default_gateways.patch

@@ -1,352 +0,0 @@
---- a/include/linux/netfilter_ipv4/ip_nat.h
-+++ b/include/linux/netfilter_ipv4/ip_nat.h
-@@ -64,6 +64,13 @@ struct ip_nat_info
- 
- struct ip_conntrack;
- 
-+/* Call input routing for SNAT-ed traffic */
-+extern unsigned int ip_nat_route_input(unsigned int hooknum,
-+				       struct sk_buff **pskb,
-+				       const struct net_device *in,
-+				       const struct net_device *out,
-+				       int (*okfn)(struct sk_buff *));
-+
- /* Set up the info structure to map into this range. */
- extern unsigned int ip_nat_setup_info(struct ip_conntrack *conntrack,
- 				      const struct ip_nat_range *range,
---- a/include/linux/rtnetlink.h
-+++ b/include/linux/rtnetlink.h
-@@ -293,6 +293,8 @@ struct rtnexthop
- #define RTNH_F_DEAD		1	/* Nexthop is dead (used by multipath)	*/
- #define RTNH_F_PERVASIVE	2	/* Do recursive gateway lookup	*/
- #define RTNH_F_ONLINK		4	/* Gateway is forced on link	*/
-+#define RTNH_F_SUSPECT		8	/* We don't know the real state	*/
-+#define RTNH_F_BADSTATE		(RTNH_F_DEAD | RTNH_F_SUSPECT)
- 
- /* Macros to handle hexthops */
- 
---- a/include/net/flow.h
-+++ b/include/net/flow.h
-@@ -19,6 +19,8 @@ struct flowi {
- 		struct {
- 			__be32			daddr;
- 			__be32			saddr;
-+			__u32			lsrc;
-+			__u32			gw;
- 			__u8			tos;
- 			__u8			scope;
- 		} ip4_u;
-@@ -43,6 +45,8 @@ struct flowi {
- #define fl6_flowlabel	nl_u.ip6_u.flowlabel
- #define fl4_dst		nl_u.ip4_u.daddr
- #define fl4_src		nl_u.ip4_u.saddr
-+#define fl4_lsrc        nl_u.ip4_u.lsrc
-+#define fl4_gw		nl_u.ip4_u.gw
- #define fl4_tos		nl_u.ip4_u.tos
- #define fl4_scope	nl_u.ip4_u.scope
- 
---- a/net/ipv4/route.c
-+++ b/net/ipv4/route.c
-@@ -1208,6 +1208,7 @@ void ip_rt_redirect(__be32 old_gw, __be3
- 
- 				/* Gateway is different ... */
- 				rt->rt_gateway		= new_gw;
-+				if (rt->fl.fl4_gw) rt->fl.fl4_gw = new_gw;
- 
- 				/* Redirect received -> path was valid */
- 				dst_confirm(&rth->u.dst);
-@@ -1643,6 +1644,7 @@ static int ip_route_input_mc(struct sk_b
- 	rth->fl.fl4_tos	= tos;
- 	rth->fl.mark    = skb->mark;
- 	rth->fl.fl4_src	= saddr;
-+	rth->fl.fl4_lsrc = 0;
- 	rth->rt_src	= saddr;
- #ifdef CONFIG_NET_CLS_ROUTE
- 	rth->u.dst.tclassid = itag;
-@@ -1653,6 +1655,7 @@ static int ip_route_input_mc(struct sk_b
- 	dev_hold(rth->u.dst.dev);
- 	rth->idev	= in_dev_get(rth->u.dst.dev);
- 	rth->fl.oif	= 0;
-+	rth->fl.fl4_gw	= 0;
- 	rth->rt_gateway	= daddr;
- 	rth->rt_spec_dst= spec_dst;
- 	rth->rt_type	= RTN_MULTICAST;
-@@ -1716,7 +1719,7 @@ static void ip_handle_martian_source(str
- static inline int __mkroute_input(struct sk_buff *skb,
- 				  struct fib_result* res,
- 				  struct in_device *in_dev,
--				  __be32 daddr, __be32 saddr, u32 tos,
-+				  __be32 daddr, __be32 saddr, u32 tos, u32 lsrc,
- 				  struct rtable **result)
- {
- 
-@@ -1751,6 +1754,7 @@ static inline int __mkroute_input(struct
- 		flags |= RTCF_DIRECTSRC;
- 
- 	if (out_dev == in_dev && err && !(flags & (RTCF_NAT | RTCF_MASQ)) &&
-+	    !lsrc &&
- 	    (IN_DEV_SHARED_MEDIA(out_dev) ||
- 	     inet_addr_onlink(out_dev, saddr, FIB_RES_GW(*res))))
- 		flags |= RTCF_DOREDIRECT;
-@@ -1788,6 +1792,7 @@ static inline int __mkroute_input(struct
- 	rth->fl.mark    = skb->mark;
- 	rth->fl.fl4_src	= saddr;
- 	rth->rt_src	= saddr;
-+	rth->fl.fl4_lsrc	= lsrc;
- 	rth->rt_gateway	= daddr;
- 	rth->rt_iif 	=
- 		rth->fl.iif	= in_dev->dev->ifindex;
-@@ -1795,6 +1800,7 @@ static inline int __mkroute_input(struct
- 	dev_hold(rth->u.dst.dev);
- 	rth->idev	= in_dev_get(rth->u.dst.dev);
- 	rth->fl.oif 	= 0;
-+	rth->fl.fl4_gw	= 0;
- 	rth->rt_spec_dst= spec_dst;
- 
- 	rth->u.dst.input = ip_forward;
-@@ -1816,19 +1822,21 @@ static inline int ip_mkroute_input_def(s
- 				       struct fib_result* res,
- 				       const struct flowi *fl,
- 				       struct in_device *in_dev,
--				       __be32 daddr, __be32 saddr, u32 tos)
-+				       __be32 daddr, __be32 saddr, u32 tos, 
-+				       u32 lsrc)
- {
- 	struct rtable* rth = NULL;
- 	int err;
- 	unsigned hash;
- 
-+	fib_select_default(fl, res);
- #ifdef CONFIG_IP_ROUTE_MULTIPATH
--	if (res->fi && res->fi->fib_nhs > 1 && fl->oif == 0)
-+	if (res->fi && res->fi->fib_nhs > 1)
- 		fib_select_multipath(fl, res);
- #endif
- 
- 	/* create a routing cache entry */
--	err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos, &rth);
-+	err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos, lsrc, &rth);
- 	if (err)
- 		return err;
- 
-@@ -1841,7 +1849,8 @@ static inline int ip_mkroute_input(struc
- 				   struct fib_result* res,
- 				   const struct flowi *fl,
- 				   struct in_device *in_dev,
--				   __be32 daddr, __be32 saddr, u32 tos)
-+				   __be32 daddr, __be32 saddr, u32 tos, 
-+				   u32 lsrc)
- {
- #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
- 	struct rtable* rth = NULL, *rtres;
-@@ -1857,7 +1866,7 @@ static inline int ip_mkroute_input(struc
- 	/* distinguish between multipath and singlepath */
- 	if (hopcount < 2)
- 		return ip_mkroute_input_def(skb, res, fl, in_dev, daddr,
--					    saddr, tos);
-+					    saddr, tos, 0);
- 
- 	/* add all alternatives to the routing cache */
- 	for (hop = 0; hop < hopcount; hop++) {
-@@ -1869,7 +1878,7 @@ static inline int ip_mkroute_input(struc
- 
- 		/* create a routing cache entry */
- 		err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos,
--				      &rth);
-+				      0, &rth);
- 		if (err)
- 			return err;
- 
-@@ -1889,7 +1898,7 @@ static inline int ip_mkroute_input(struc
- 	skb->dst = &rtres->u.dst;
- 	return err;
- #else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED  */
--	return ip_mkroute_input_def(skb, res, fl, in_dev, daddr, saddr, tos);
-+	return ip_mkroute_input_def(skb, res, fl, in_dev, daddr, saddr, tos, lsrc);
- #endif /* CONFIG_IP_ROUTE_MULTIPATH_CACHED  */
- }
- 
-@@ -1905,18 +1914,18 @@ static inline int ip_mkroute_input(struc
-  */
- 
- static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
--			       u8 tos, struct net_device *dev)
-+			       u8 tos, struct net_device *dev, u32 lsrc)
- {
- 	struct fib_result res;
- 	struct in_device *in_dev = in_dev_get(dev);
- 	struct flowi fl = { .nl_u = { .ip4_u =
- 				      { .daddr = daddr,
--					.saddr = saddr,
-+					.saddr = lsrc ? : saddr,
- 					.tos = tos,
- 					.scope = RT_SCOPE_UNIVERSE,
- 				      } },
- 			    .mark = skb->mark,
--			    .iif = dev->ifindex };
-+			    .iif = lsrc? loopback_dev.ifindex : dev->ifindex };
- 	unsigned	flags = 0;
- 	u32		itag = 0;
- 	struct rtable * rth;
-@@ -1949,6 +1958,12 @@ static int ip_route_input_slow(struct sk
- 	if (BADCLASS(daddr) || ZERONET(daddr) || LOOPBACK(daddr))
- 		goto martian_destination;
- 
-+	if (lsrc) {
-+		if (MULTICAST(lsrc) || BADCLASS(lsrc) ||
-+		    ZERONET(lsrc) || LOOPBACK(lsrc))
-+			goto e_inval;
-+	}
-+
- 	/*
- 	 *	Now we are ready to route packet.
- 	 */
-@@ -1958,6 +1973,10 @@ static int ip_route_input_slow(struct sk
- 		goto no_route;
- 	}
- 	free_res = 1;
-+	if (lsrc && res.type != RTN_UNICAST && res.type != RTN_NAT)
-+		goto e_inval;
-+	fl.iif = dev->ifindex;
-+	fl.fl4_src = saddr;
- 
- 	RT_CACHE_STAT_INC(in_slow_tot);
- 
-@@ -1982,7 +2001,7 @@ static int ip_route_input_slow(struct sk
- 	if (res.type != RTN_UNICAST)
- 		goto martian_destination;
- 
--	err = ip_mkroute_input(skb, &res, &fl, in_dev, daddr, saddr, tos);
-+	err = ip_mkroute_input(skb, &res, &fl, in_dev, daddr, saddr, tos, lsrc);
- 	if (err == -ENOBUFS)
- 		goto e_nobufs;
- 	if (err == -EINVAL)
-@@ -1997,6 +2016,8 @@ out:	return err;
- brd_input:
- 	if (skb->protocol != htons(ETH_P_IP))
- 		goto e_inval;
-+	if (lsrc)
-+		goto e_inval;
- 
- 	if (ZERONET(saddr))
- 		spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK);
-@@ -2037,6 +2058,7 @@ local_input:
- 	rth->u.dst.dev	= &loopback_dev;
- 	dev_hold(rth->u.dst.dev);
- 	rth->idev	= in_dev_get(rth->u.dst.dev);
-+	rth->fl.fl4_gw	= 0;
- 	rth->rt_gateway	= daddr;
- 	rth->rt_spec_dst= spec_dst;
- 	rth->u.dst.input= ip_local_deliver;
-@@ -2086,8 +2108,9 @@ martian_source:
- 	goto e_inval;
- }
- 
--int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr,
--		   u8 tos, struct net_device *dev)
-+static inline int
-+ip_route_input_cached(struct sk_buff *skb, __be32 daddr, __be32 saddr,
-+		   u8 tos, struct net_device *dev, u32 lsrc)
- {
- 	struct rtable * rth;
- 	unsigned	hash;
-@@ -2102,6 +2125,7 @@ int ip_route_input(struct sk_buff *skb, 
- 		if (rth->fl.fl4_dst == daddr &&
- 		    rth->fl.fl4_src == saddr &&
- 		    rth->fl.iif == iif &&
-+		    rth->fl.fl4_lsrc == lsrc &&
- 		    rth->fl.oif == 0 &&
- 		    rth->fl.mark == skb->mark &&
- 		    rth->fl.fl4_tos == tos) {
-@@ -2148,7 +2172,19 @@ int ip_route_input(struct sk_buff *skb, 
- 		rcu_read_unlock();
- 		return -EINVAL;
- 	}
--	return ip_route_input_slow(skb, daddr, saddr, tos, dev);
-+	return ip_route_input_slow(skb, daddr, saddr, tos, dev, lsrc);
-+}
-+
-+int ip_route_input(struct sk_buff *skb, u32 daddr, u32 saddr,
-+		   u8 tos, struct net_device *dev)
-+{
-+	return ip_route_input_cached(skb, daddr, saddr, tos, dev, 0);
-+}
-+
-+int ip_route_input_lookup(struct sk_buff *skb, u32 daddr, u32 saddr,
-+			  u8 tos, struct net_device *dev, u32 lsrc)
-+{
-+	return ip_route_input_cached(skb, daddr, saddr, tos, dev, lsrc);
- }
- 
- static inline int __mkroute_output(struct rtable **result,
-@@ -2227,6 +2263,7 @@ static inline int __mkroute_output(struc
- 	rth->fl.fl4_tos	= tos;
- 	rth->fl.fl4_src	= oldflp->fl4_src;
- 	rth->fl.oif	= oldflp->oif;
-+	rth->fl.fl4_gw  = oldflp->fl4_gw;
- 	rth->fl.mark    = oldflp->mark;
- 	rth->rt_dst	= fl->fl4_dst;
- 	rth->rt_src	= fl->fl4_src;
-@@ -2367,6 +2404,7 @@ static int ip_route_output_slow(struct r
- 	struct flowi fl = { .nl_u = { .ip4_u =
- 				      { .daddr = oldflp->fl4_dst,
- 					.saddr = oldflp->fl4_src,
-+					.gw = oldflp->fl4_gw,
- 					.tos = tos & IPTOS_RT_MASK,
- 					.scope = ((tos & RTO_ONLINK) ?
- 						  RT_SCOPE_LINK :
-@@ -2470,6 +2508,7 @@ static int ip_route_output_slow(struct r
- 		dev_out = &loopback_dev;
- 		dev_hold(dev_out);
- 		fl.oif = loopback_dev.ifindex;
-+		fl.fl4_gw = 0;
- 		res.type = RTN_LOCAL;
- 		flags |= RTCF_LOCAL;
- 		goto make_route;
-@@ -2477,7 +2516,7 @@ static int ip_route_output_slow(struct r
- 
- 	if (fib_lookup(&fl, &res)) {
- 		res.fi = NULL;
--		if (oldflp->oif) {
-+		if (oldflp->oif && dev_out->flags & IFF_UP) {
- 			/* Apparently, routing tables are wrong. Assume,
- 			   that the destination is on link.
- 
-@@ -2517,6 +2556,7 @@ static int ip_route_output_slow(struct r
- 		dev_out = &loopback_dev;
- 		dev_hold(dev_out);
- 		fl.oif = dev_out->ifindex;
-+		fl.fl4_gw = 0;
- 		if (res.fi)
- 			fib_info_put(res.fi);
- 		res.fi = NULL;
-@@ -2524,13 +2564,12 @@ static int ip_route_output_slow(struct r
- 		goto make_route;
- 	}
- 
-+	if (res.type == RTN_UNICAST)
-+		fib_select_default(&fl, &res);
- #ifdef CONFIG_IP_ROUTE_MULTIPATH
--	if (res.fi->fib_nhs > 1 && fl.oif == 0)
-+	if (res.fi->fib_nhs > 1)
- 		fib_select_multipath(&fl, &res);
--	else
- #endif
--	if (!res.prefixlen && res.type == RTN_UNICAST && !fl.oif)
--		fib_select_default(&fl, &res);
- 
- 	if (!fl.fl4_src)
- 		fl.fl4_src = FIB_RES_PREFSRC(res);
-@@ -2567,6 +2606,7 @@ int __ip_route_output_key(struct rtable 
- 		    rth->fl.fl4_src == flp->fl4_src &&
- 		    rth->fl.iif == 0 &&
- 		    rth->fl.oif == flp->oif &&
-+		    rth->fl.fl4_gw == flp->fl4_gw &&
- 		    rth->fl.mark == flp->mark &&
- 		    !((rth->fl.fl4_tos ^ flp->fl4_tos) &
- 			    (IPTOS_RT_MASK | RTO_ONLINK))) {
-@@ -3199,3 +3239,4 @@ int __init ip_rt_init(void)
- EXPORT_SYMBOL(__ip_select_ident);
- EXPORT_SYMBOL(ip_route_input);
- EXPORT_SYMBOL(ip_route_output_key);
-+EXPORT_SYMBOL(ip_route_input_lookup);

+ 0 - 12
target/linux/generic-2.6/patches-2.6.21/202-mips-freestanding.patch

@@ -1,12 +0,0 @@
---- a/arch/mips/Makefile
-+++ b/arch/mips/Makefile
-@@ -605,6 +605,9 @@ core-$(CONFIG_TOSHIBA_RBTX4938) += arch/
- core-$(CONFIG_TOSHIBA_RBTX4938) += arch/mips/tx4938/common/
- load-$(CONFIG_TOSHIBA_RBTX4938) += 0xffffffff80100000
- 
-+# temporary until string.h is fixed
-+cflags-y += -ffreestanding
-+
- cflags-y			+= -Iinclude/asm-mips/mach-generic
- drivers-$(CONFIG_PCI)		+= arch/mips/pci/
- 

+ 0 - 56
target/linux/generic-2.6/patches-2.6.21/204-jffs2_eofdetect.patch

@@ -1,56 +0,0 @@
---- a/fs/jffs2/build.c
-+++ b/fs/jffs2/build.c
-@@ -107,6 +107,17 @@ static int jffs2_build_filesystem(struct
- 	dbg_fsbuild("scanned flash completely\n");
- 	jffs2_dbg_dump_block_lists_nolock(c);
- 
-+	if (c->flags & (1 << 7)) {
-+		printk("%s(): unlocking the mtd device... ", __func__);
-+		if (c->mtd->unlock)
-+			c->mtd->unlock(c->mtd, 0, c->mtd->size);
-+		printk("done.\n");
-+		
-+		printk("%s(): erasing all blocks after the end marker... ", __func__);
-+		jffs2_erase_pending_blocks(c, -1);
-+		printk("done.\n");
-+	}
-+
- 	dbg_fsbuild("pass 1 starting\n");
- 	c->flags |= JFFS2_SB_FLAG_BUILDING;
- 	/* Now scan the directory tree, increasing nlink according to every dirent found. */
---- a/fs/jffs2/scan.c
-+++ b/fs/jffs2/scan.c
-@@ -143,9 +143,12 @@ int jffs2_scan_medium(struct jffs2_sb_in
- 
- 		/* reset summary info for next eraseblock scan */
- 		jffs2_sum_reset_collected(s);
--
--		ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset),
--						buf_size, s);
-+		
-+		if (c->flags & (1 << 7))
-+			ret = BLK_STATE_ALLFF;
-+		else
-+			ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset),
-+							buf_size, s);
- 
- 		if (ret < 0)
- 			goto out;
-@@ -546,6 +549,17 @@ static int jffs2_scan_eraseblock (struct
- 			return err;
- 	}
- 
-+	if ((buf[0] == 0xde) &&
-+		(buf[1] == 0xad) &&
-+		(buf[2] == 0xc0) &&
-+		(buf[3] == 0xde)) {
-+		/* end of filesystem. erase everything after this point */
-+		printk("%s(): End of filesystem marker found at 0x%x\n", __func__, jeb->offset);
-+		c->flags |= (1 << 7);
-+
-+		return BLK_STATE_ALLFF;
-+	}
-+	
- 	/* We temporarily use 'ofs' as a pointer into the buffer/jeb */
- 	ofs = 0;
- 

+ 0 - 9
target/linux/generic-2.6/patches-2.6.21/207-powerpc_asm_segment_h.patch

@@ -1,9 +0,0 @@
---- /dev/null
-+++ b/include/asm-powerpc/segment.h
-@@ -0,0 +1,6 @@
-+#ifndef _ASM_SEGMENT_H
-+#define _ASM_SEGMENT_H
-+
-+/* Only here because we have some old header files that expect it.. */
-+
-+#endif /* _ASM_SEGMENT_H */

+ 0 - 24
target/linux/generic-2.6/patches-2.6.21/208-rtl8110sb_fix.patch

@@ -1,24 +0,0 @@
---- a/drivers/net/r8169.c
-+++ b/drivers/net/r8169.c
-@@ -494,7 +494,7 @@ static int rtl8169_poll(struct net_devic
- #endif
- 
- static const u16 rtl8169_intr_mask =
--	SYSErr | LinkChg | RxOverflow | RxFIFOOver | TxErr | TxOK | RxErr | RxOK;
-+	LinkChg | RxOverflow | RxFIFOOver | TxErr | TxOK | RxErr | RxOK;
- static const u16 rtl8169_napi_event =
- 	RxOK | RxOverflow | RxFIFOOver | TxOK | TxErr;
- static const unsigned int rtl8169_rx_config =
-@@ -2652,10 +2652,12 @@ rtl8169_interrupt(int irq, void *dev_ins
- 		if (!(status & rtl8169_intr_mask))
- 			break;
- 
-+#if 0
- 		if (unlikely(status & SYSErr)) {
- 			rtl8169_pcierr_interrupt(dev);
- 			break;
- 		}
-+#endif
- 
- 		if (status & LinkChg)
- 			rtl8169_check_link_status(dev, tp, ioaddr);

+ 0 - 7779
target/linux/generic-2.6/patches-2.6.21/209-mini_fo.patch

@@ -1,7779 +0,0 @@
---- a/fs/Kconfig
-+++ b/fs/Kconfig
-@@ -461,6 +461,9 @@ config OCFS2_DEBUG_MASKLOG
- 	  This option will enlarge your kernel, but it allows debugging of
- 	  ocfs2 filesystem issues.
- 
-+config MINI_FO
-+	tristate "Mini fanout overlay filesystem"
-+
- config MINIX_FS
- 	tristate "Minix fs support"
- 	help
---- a/fs/Makefile
-+++ b/fs/Makefile
-@@ -72,6 +72,7 @@ obj-$(CONFIG_SQUASHFS)		+= squashfs/
- obj-$(CONFIG_RAMFS)		+= ramfs/
- obj-$(CONFIG_HUGETLBFS)		+= hugetlbfs/
- obj-$(CONFIG_CODA_FS)		+= coda/
-+obj-$(CONFIG_MINI_FO)		+= mini_fo/
- obj-$(CONFIG_MINIX_FS)		+= minix/
- obj-$(CONFIG_FAT_FS)		+= fat/
- obj-$(CONFIG_MSDOS_FS)		+= msdos/
---- /dev/null
-+++ b/fs/mini_fo/aux.c
-@@ -0,0 +1,580 @@
-+/*
-+ * Copyright (c) 1997-2003 Erez Zadok
-+ * Copyright (c) 2001-2003 Stony Brook University
-+ *
-+ * For specific licensing information, see the COPYING file distributed with
-+ * this package, or get one from ftp://ftp.filesystems.org/pub/fist/COPYING.
-+ *
-+ * This Copyright notice must be kept intact and distributed with all
-+ * fistgen sources INCLUDING sources generated by fistgen.
-+ */
-+/*
-+ * Copyright (C) 2004, 2005 Markus Klotzbuecher <[email protected]>
-+ *
-+ * 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.
-+ */
-+/*
-+ *  $Id$
-+ */
-+
-+#ifdef HAVE_CONFIG_H
-+# include <config.h>
-+#endif
-+
-+#include "fist.h"
-+#include "mini_fo.h"
-+
-+/* check if file exists in storage  */
-+int exists_in_storage(dentry_t *dentry)
-+{
-+	check_mini_fo_dentry(dentry);
-+	if(dtost(dentry) == MODIFIED || dtost(dentry) == CREATED || dtost(dentry) == DEL_REWRITTEN)
-+		return 1;
-+	return 0;	
-+}
-+
-+/* check if dentry is in an existing state */
-+int is_mini_fo_existant(dentry_t *dentry) 
-+{
-+	check_mini_fo_dentry(dentry);
-+
-+	if(dtost(dentry) == DELETED || dtost(dentry) == NON_EXISTANT)
-+		return 0;
-+	else
-+		return 1;
-+}
-+
-+/* 
-+ * This function will create a negative storage dentry for 
-+ * dentry, what is required for many create like options.
-+ * It will create the storage structure if necessary.
-+ */
-+int get_neg_sto_dentry(dentry_t *dentry) 
-+{
-+	int err = 0;
-+	unsigned int len;
-+	const unsigned char *name;
-+
-+	if(!dentry ||
-+	   !dtopd(dentry) ||
-+	   !(dtost(dentry) == UNMODIFIED ||
-+	     dtost(dentry) == NON_EXISTANT ||
-+	     dtost(dentry) == DELETED)) {
-+		printk(KERN_CRIT "mini_fo: get_neg_sto_dentry: invalid dentry passed.\n");
-+		err = -1;
-+		goto out;
-+	}
-+	/* Have we got a neg. dentry already? */
-+	if(dtohd2(dentry)) {
-+		err = 0;
-+		goto out;
-+	}
-+	if(dtost(dentry->d_parent) == UNMODIFIED) {
-+		/* build sto struct */
-+		err = build_sto_structure(dentry->d_parent->d_parent, dentry->d_parent);
-+		if(err || 
-+		   dtost(dentry->d_parent) != MODIFIED) {
-+			printk(KERN_CRIT "mini_fo: get_neg_sto_dentry: ERROR building sto structure.\n");
-+			err = -1;
-+			goto out;
-+		}		
-+	}
-+
-+	len = dentry->d_name.len;
-+	name = dentry->d_name.name;
-+	 
-+	dtohd2(dentry) = 
-+		lookup_one_len(name, dtohd2(dentry->d_parent), len);
-+
-+ out:
-+	return err;
-+}
-+
-+int check_mini_fo_dentry(dentry_t *dentry)
-+{
-+ 	ASSERT(dentry != NULL);
-+	ASSERT(dtopd(dentry) != NULL);
-+	ASSERT((dtohd(dentry) != NULL) || (dtohd2(dentry) != NULL));
-+	       
-+/* 	if(dtost(dentry) == MODIFIED) { */
-+/* 		ASSERT(dentry->d_inode != NULL); */
-+/* 		ASSERT(dtohd(dentry) != NULL); */
-+/* 		ASSERT(dtohd(dentry)->d_inode != NULL); */
-+/* 		ASSERT(dtohd2(dentry) != NULL); */
-+/* 		ASSERT(dtohd2(dentry)->d_inode != NULL); */
-+/* 	} */
-+/* 	else if(dtost(dentry) == UNMODIFIED) { */
-+/* 		ASSERT(dentry->d_inode != NULL); */
-+/* 		ASSERT( */
-+/* 	} */
-+	return 0;	       
-+}
-+
-+int check_mini_fo_file(file_t *file)
-+{
-+	ASSERT(file != NULL);
-+	ASSERT(ftopd(file) != NULL);
-+	ASSERT(file->f_dentry != NULL);
-+	
-+	/* violent checking, check depending of state and type 
-+	 *	if(S_ISDIR(file->f_dentry->d_inode->i_mode)) {}
-+	 */
-+	ASSERT((ftohf(file) != NULL) || (ftohf2(file) != NULL));
-+	return 0;
-+}
-+
-+int check_mini_fo_inode(inode_t *inode)
-+{
-+	ASSERT(inode != NULL);
-+	ASSERT(itopd(inode) != NULL);
-+	ASSERT((itohi(inode) != NULL) || (itohi2(inode) != NULL));
-+	return 0;
-+}
-+
-+/* 
-+ * will walk a base path as provided by get_mini_fo_bpath and return
-+ * the (hopefully ;-) ) positive dentry of the renamed base dir.
-+ *
-+ * This does some work of path_init.
-+ */
-+dentry_t *bpath_walk(super_block_t *sb, char *bpath) 
-+{
-+	int err;
-+	struct nameidata nd;
-+
-+	/* be paranoid */
-+	if(!bpath || bpath[0] != '/') {
-+		printk(KERN_CRIT "mini_fo: bpath_walk: Invalid string.\n");
-+		return NULL;
-+	}
-+	if(!sb || !stopd(sb)) {
-+		printk(KERN_CRIT "mini_fo: bpath_walk: Invalid sb.\n");
-+		return NULL;
-+	}
-+	
-+	/* setup nd as path_init does */
-+	nd.last_type = LAST_ROOT; /* if there are only slashes... */
-+	nd.flags = LOOKUP_FOLLOW;
-+	/* fix this: how do I reach this lock? 
-+	 * read_lock(&current->fs->lock); */
-+	nd.mnt = mntget(stopd(sb)->hidden_mnt);
-+	nd.dentry = dget(stopd(sb)->base_dir_dentry);
-+	/* read_unlock(&current->fs->lock); */
-+	
-+	err = path_walk(bpath+1, &nd);
-+
-+	/* validate */
-+	if (err || !nd.dentry || !nd.dentry->d_inode) {
-+		printk(KERN_CRIT "mini_fo: bpath_walk: path_walk failed.\n");
-+		return NULL;
-+	}
-+	return nd.dentry;
-+}
-+
-+
-+/* returns the full path of the basefile incl. its name */
-+int get_mini_fo_bpath(dentry_t *dentry, char **bpath, int *bpath_len)
-+{
-+	char *buf_walker;
-+	int len = 0;
-+	dentry_t *sky_walker;
-+	
-+	if(!dentry || !dtohd(dentry)) {
-+		printk(KERN_CRIT "mini_fo: get_mini_fo_bpath: invalid dentry passed.\n");
-+		return -1;
-+	}
-+	sky_walker = dtohd(dentry);
-+
-+	do {
-+		len += sky_walker->d_name.len + 1 ; /* 1 for '/' */
-+		sky_walker = sky_walker->d_parent;
-+	} while(sky_walker != stopd(dentry->d_inode->i_sb)->base_dir_dentry);
-+
-+	/* 1 to oil the loop */
-+	*bpath = (char*)  kmalloc(len + 1, GFP_KERNEL);
-+	if(!*bpath) {
-+		printk(KERN_CRIT "mini_fo: get_mini_fo_bpath: out of mem.\n");
-+		return -1;
-+	}
-+	buf_walker = *bpath+len; /* put it on last char */
-+	*buf_walker = '\n';
-+	sky_walker = dtohd(dentry);
-+	
-+	do {
-+		buf_walker -= sky_walker->d_name.len;
-+		strncpy(buf_walker, 
-+			sky_walker->d_name.name, 
-+			sky_walker->d_name.len);
-+		*(--buf_walker) = '/';
-+		sky_walker = sky_walker->d_parent;
-+	} while(sky_walker != stopd(dentry->d_inode->i_sb)->base_dir_dentry);
-+
-+	/* bpath_len doesn't count newline! */
-+	*bpath_len = len;
-+ 	return 0;
-+}
-+
-+int mini_fo_cp_cont(dentry_t *tgt_dentry, struct vfsmount *tgt_mnt,
-+		    dentry_t *src_dentry, struct vfsmount *src_mnt)
-+{
-+	void *buf;
-+	mm_segment_t old_fs;
-+	file_t *tgt_file;
-+	file_t *src_file;
-+	int bytes, len, tmp, err;
-+	err = 0;
-+
-+	if(!(tgt_dentry->d_inode && src_dentry->d_inode)) {
-+		printk(KERN_CRIT "mini_fo_cp_cont: ERROR, neg. dentry passed.\n");
-+		err = -EINVAL;
-+		goto out;
-+	}
-+
-+	dget(tgt_dentry);
-+	dget(src_dentry);
-+	mntget(tgt_mnt);
-+	mntget(src_mnt);
-+
-+	/* open file write only */
-+	tgt_file = dentry_open(tgt_dentry, tgt_mnt, 0x1);
-+	if(!tgt_file || IS_ERR(tgt_file)) {
-+		printk(KERN_CRIT "mini_fo_cp_cont: ERROR opening target file.\n");
-+		err = PTR_ERR(tgt_file);
-+		goto out_err;
-+	}
-+
-+	/* open file read only */
-+	src_file = dentry_open(src_dentry, src_mnt, 0x0);
-+	if(!src_file || IS_ERR(src_file)) {
-+		printk(KERN_CRIT "mini_fo_cp_cont: ERROR opening source file.\n");
-+		err = PTR_ERR(src_file);
-+
-+		/* close target file */
-+		fput(tgt_file);
-+		goto out_err;
-+	}
-+
-+	/* check if the filesystem(s) support read respective write */
-+	if(!src_file->f_op->read || !tgt_file->f_op->write) {
-+		printk(KERN_CRIT "mini_fo_cp_cont: ERROR, no fs read or write support.\n");
-+		err = -EPERM;
-+		goto out_close;
-+	}
-+
-+	/* allocate a page for transfering the data */
-+	buf = (void *) __get_free_page(GFP_KERNEL);
-+	if(!buf) {
-+		printk(KERN_CRIT "mini_fo_cp_cont: ERROR, out of kernel mem.\n");
-+		goto out_err;
-+	}
-+
-+	tgt_file->f_pos = 0;
-+	src_file->f_pos = 0;
-+
-+	old_fs = get_fs();
-+	set_fs(KERNEL_DS);
-+
-+	/* Doing this I assume that a read operation will return a full
-+	 * buffer while there is still data to read, and a less than
-+	 * full buffer when all data has been read.
-+	 */
-+	bytes = len = PAGE_SIZE;
-+	while(bytes == len) {
-+		bytes = src_file->f_op->read(src_file, buf, len, 
-+					     &src_file->f_pos);
-+		tmp = tgt_file->f_op->write(tgt_file, buf, bytes, 
-+					    &tgt_file->f_pos);
-+		if(tmp != bytes) {
-+			printk(KERN_CRIT "mini_fo_cp_cont: ERROR writing.\n");
-+			goto out_close_unset;
-+		}
-+	}
-+
-+	free_page((unsigned long) buf);
-+	set_fs(old_fs);
-+	fput(tgt_file);
-+	fput(src_file);
-+	goto out;
-+
-+ out_close_unset:
-+	free_page((unsigned long) buf);
-+	set_fs(old_fs);
-+
-+ out_close:
-+	fput(tgt_file);
-+	fput(src_file);
-+
-+ out_err:
-+	dput(tgt_dentry);
-+	dput(src_dentry);
-+
-+	/* mk: not sure if this need to be done */
-+	mntput(tgt_mnt);
-+	mntput(src_mnt);
-+
-+ out:
-+	return err;
-+}
-+
-+/* mk:
-+ * ndl (no-duplicate list) stuff
-+ * This is used in mini_fo_readdir, to save the storage directory contents
-+ * and later when reading base, match them against the list in order
-+ * to avoid duplicates.
-+ */
-+
-+/* add a file specified by name and len to the ndl
-+ * Return values: 0 on success, <0 on failure.
-+ */
-+int ndl_add_entry(struct readdir_data *rd, const char *name, int len)
-+{
-+	struct ndl_entry *tmp_entry;
-+
-+	tmp_entry = (struct ndl_entry *) 
-+		kmalloc(sizeof(struct ndl_entry), GFP_KERNEL);
-+	if(!tmp_entry) {
-+                printk(KERN_CRIT "mini_fo: ndl_add_entry: out of mem.\n");
-+                return -ENOMEM;
-+        }
-+        tmp_entry->name = (char*) kmalloc(len, GFP_KERNEL);
-+        if(!tmp_entry->name) {
-+                printk(KERN_CRIT "mini_fo: ndl_add_entry: out of mem.\n");
-+                return -ENOMEM;
-+        }
-+	strncpy(tmp_entry->name, name, len);
-+        tmp_entry->len = len;
-+
-+        list_add(&tmp_entry->list, &rd->ndl_list);
-+        rd->ndl_size++;
-+        return 0;
-+}
-+
-+/* delete all list entries and free memory */
-+void ndl_put_list(struct readdir_data *rd)
-+{
-+	struct list_head *tmp;
-+	struct ndl_entry *tmp_entry;
-+
-+	if(rd->ndl_size <= 0)
-+		return;
-+	while(!list_empty(&rd->ndl_list)) {
-+		tmp = rd->ndl_list.next;
-+                list_del(tmp);
-+                tmp_entry = list_entry(tmp, struct ndl_entry, list);
-+		kfree(tmp_entry->name);
-+                kfree(tmp_entry);
-+        }
-+	rd->ndl_size = 0;
-+}
-+
-+/* Check if a file specified by name and len is in the ndl
-+ * Return value: 0 if not in list, 1 if file is found in ndl.
-+ */
-+int ndl_check_entry(struct readdir_data *rd, const char *name, int len)
-+{
-+	struct list_head *tmp;
-+	struct ndl_entry *tmp_entry;
-+
-+	if(rd->ndl_size <= 0)
-+		return 0;
-+
-+	list_for_each(tmp, &rd->ndl_list) {
-+                tmp_entry = list_entry(tmp, struct ndl_entry, list);
-+                if(tmp_entry->len != len)
-+                        continue;
-+                if(!strncmp(tmp_entry->name, name, len))
-+                        return 1;
-+        }
-+        return 0;
-+}
-+
-+/* mk:
-+ * Recursive function to create corresponding directorys in the storage fs.
-+ * The function will build the storage directorys up to dentry.
-+ */
-+int build_sto_structure(dentry_t *dir, dentry_t *dentry)
-+{
-+	int err;
-+	dentry_t *hidden_sto_dentry;
-+	dentry_t *hidden_sto_dir_dentry;
-+
-+	if(dentry->d_parent != dir) {
-+		printk(KERN_CRIT "mini_fo: build_sto_structure: invalid parameter or meta data corruption [1].\n");
-+		return 1;
-+	}
-+
-+       	if(dtost(dir) != MODIFIED) {
-+		err = build_sto_structure(dir->d_parent, dentry->d_parent);
-+		if(err)
-+			return err;
-+	}
-+
-+	/* ok, coming back again. */
-+	check_mini_fo_dentry(dentry);
-+	hidden_sto_dentry = dtohd2(dentry);
-+
-+	if(!hidden_sto_dentry) {
-+		/*
-+		 * This is the case after creating the first 
-+		 * hidden_sto_dentry.
-+		 * After one negative storage_dentry, all pointers to 
-+		 * hidden_storage dentries are set to NULL. We need to
-+		 * create the negative dentry before we create the storage
-+		 * file.
-+		 */
-+		unsigned int len;
-+		const unsigned char *name;
-+		len = dtohd(dentry)->d_name.len;
-+		name = dtohd(dentry)->d_name.name;
-+		hidden_sto_dentry = lookup_one_len(name, dtohd2(dir), len);
-+		dtohd2(dentry) = hidden_sto_dentry;
-+	}
-+
-+	/* was:	hidden_sto_dir_dentry = lock_parent(hidden_sto_dentry); */
-+	hidden_sto_dir_dentry = dget(hidden_sto_dentry->d_parent);
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+	mutex_lock(&hidden_sto_dir_dentry->d_inode->i_mutex);
-+#else
-+	down(&hidden_sto_dir_dentry->d_inode->i_sem);
-+#endif
-+	/* lets be safe */
-+	if(dtohd2(dir) != hidden_sto_dir_dentry) {
-+		printk(KERN_CRIT "mini_fo: build_sto_structure: invalid parameter or meta data corruption [2].\n");
-+		return 1;
-+	}
-+
-+	/* check for errors in lock_parent */
-+	err = PTR_ERR(hidden_sto_dir_dentry);
-+	if(IS_ERR(hidden_sto_dir_dentry)) {
-+		printk(KERN_CRIT "mini_fo: build_sto_structure: lock_parent failed.\n");
-+		return err;
-+	}
-+
-+	err = vfs_mkdir(hidden_sto_dir_dentry->d_inode,
-+			hidden_sto_dentry,
-+			dir->d_inode->i_mode);
-+
-+	if(err) {
-+		printk(KERN_CRIT "mini_fo: build_sto_structure: failed to create storage dir [1].\n");
-+		/* was: unlock_dir(dir); */
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+		mutex_unlock(&dir->d_inode->i_mutex);
-+#else
-+		up(&dir->d_inode->i_sem);
-+#endif
-+		dput(dir);
-+		return err;
-+	}
-+	
-+	/* everything ok! */
-+	if(!dtohd2(dentry)->d_inode) {
-+		printk(KERN_CRIT "mini_fo: build_sto_structure: failed to create storage dir [2].\n");
-+		/* was: unlock_dir(dir); */
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+		mutex_unlock(&dir->d_inode->i_mutex);
-+#else
-+		up(&dir->d_inode->i_sem);
-+#endif
-+		dput(dir);
-+		return 1;
-+	}
-+
-+	/* interpose the new inode and set new state */
-+	itohi2(dentry->d_inode) = igrab(dtohd2(dentry)->d_inode);
-+	dtopd(dentry)->state = MODIFIED;
-+
-+	/* initalize the wol list */
-+	itopd(dentry->d_inode)->deleted_list_size = -1;
-+	itopd(dentry->d_inode)->renamed_list_size = -1;
-+	meta_build_lists(dentry);
-+	
-+	fist_copy_attr_all(dentry->d_inode, itohi2(dentry->d_inode));
-+	fist_copy_attr_timesizes(dir->d_inode, 
-+				 hidden_sto_dir_dentry->d_inode);
-+	dir->d_inode->i_nlink++;
-+	/* was: unlock_dir(hidden_sto_dir_dentry); */
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+	mutex_unlock(&hidden_sto_dir_dentry->d_inode->i_mutex);
-+#else
-+	up(&hidden_sto_dir_dentry->d_inode->i_sem);
-+#endif
-+	dput(hidden_sto_dir_dentry);
-+	return 0;
-+}
-+
-+
-+#if 0 /* unused */
-+
-+/*
-+ * Read "len" bytes from "filename" into "buf".
-+ * "buf" is in kernel space.
-+ */
-+int
-+mini_fo_read_file(const char *filename, void *buf, int len)
-+{
-+    file_t *filp;
-+    mm_segment_t oldfs;
-+    int bytes;
-+    /* Chroot? Maybe NULL isn't right here */
-+    filp = filp_open(filename, O_RDONLY, 0);
-+    if (!filp || IS_ERR(filp)) {
-+	printk("mini_fo_read_file err %d\n", (int) PTR_ERR(filp));
-+	return -1;  /* or do something else */
-+    }
-+
-+    if (!filp->f_op->read)
-+	return -2;  /* file(system) doesn't allow reads */
-+
-+    /* now read len bytes from offset 0 */
-+    filp->f_pos = 0;		/* start offset */
-+    oldfs = get_fs();
-+    set_fs(KERNEL_DS);
-+    bytes = filp->f_op->read(filp, buf, len, &filp->f_pos);
-+    set_fs(oldfs);
-+
-+    /* close the file */
-+    fput(filp);
-+
-+    return bytes;
-+}
-+
-+
-+
-+/*
-+ * Write "len" bytes from "buf" to "filename"
-+ * "buf" is in kernel space.
-+ */
-+int
-+mini_fo_write_file(const char *filename, void *buf, int len)
-+{
-+    file_t *filp;
-+    mm_segment_t oldfs;
-+    int bytes;
-+				/* Chroot? Maybe NULL isn't right here */
-+    filp = filp_open(filename, O_RDWR|O_CREAT, 0640);
-+    if (!filp || IS_ERR(filp)) {
-+	printk("mini_fo_write_file err %d\n", (int) PTR_ERR(filp));
-+	return -1;  /* or do something else */
-+    }
-+
-+    if (!filp->f_op->write)
-+	return -2;  /* file(system) doesn't allow writes */
-+
-+    /* now write len bytes from offset 0 */
-+    filp->f_pos = 0;		/* start offset */
-+    oldfs = get_fs();
-+    set_fs(KERNEL_DS);
-+    bytes = filp->f_op->write(filp, buf, len, &filp->f_pos);
-+    set_fs(oldfs);
-+
-+    /* close the file */
-+    fput(filp);
-+
-+    return bytes;
-+}
-+
-+#endif /* unused */
-+
---- /dev/null
-+++ b/fs/mini_fo/ChangeLog
-@@ -0,0 +1,281 @@
-+2006-01-24  Markus Klotzbuecher  <[email protected]>
-+
-+	* Add tons of ugly ifdefs to Ed L. Cashin's mutex patch to
-+          retain backwards compatibility.
-+	
-+2006-01-24  Ed L. Cashin <[email protected]>
-+
-+	* Support for the new mutex infrastructure
-+	(7892f2f48d165a34b0b8130c8a195dfd807b8cb6)
-+
-+2005-10-15  Markus Klotzbuecher  <[email protected]>
-+
-+	* Bugfix for a serious memory leak in mini_fo_follow_link.
-+
-+2005-09-21  Markus Klotzbuecher  <mk@mary>
-+
-+	* new release 0.6.1
-+
-+	* fix of a compiler warning due to changes in 2.6.13
-+
-+2005-09-21  Klaus Wenninger  <[email protected]>
-+
-+	* file.c: readdir: fix for a bug that caused directory entries
-+          to show up twice when using storage filesystems such as
-+          minixfs or pramfs.
-+
-+2005-06-30  Eric Lammerts <[email protected]>
-+
-+	* fix for an oops when overwriting a binary thats beeing
-+          executed.
-+
-+2005-06-09    <mk@mary>
-+
-+	* Renamed overlay to mini_fo-overlay.
-+
-+	* Added mini_fo-merge script to allow merging of storage and base
-+	after making modifications.
-+
-+2005-05-22  root  <mk@mary>
-+
-+	* Added overlay script that allows to easily mount mini_fo ontop
-+	of a given base directory
-+
-+2005-05-10    <mk@mary>
-+
-+	* inode.c: xattr functions return -EOPNOSUPP instead of
-+          -ENOSUPP, what confuses "ls -l"
-+
-+	* Changed license from LGPL to GPL.
-+
-+2005-05-08  root  <mk@mary>
-+
-+	* Makefile: clean it up and added make install and make
-+          uninstall.
-+	
-+2005-05-06    <mk@mary>
-+
-+	* merged devel branch back to main. [v0-6-0-pre3]
-+
-+	* removed unused files print.c and fist_ioctl. [devel-0-0-18]
-+
-+	* ioctl: removed fist_ioctl stuff, that is not needed for
-+          now.
-+
-+2005-05-03    <mk@mary>
-+
-+	* file.c: simplified mini_fo_open and mini_fo_setattr using
-+          new state changing functions. [devel-0-0-17]
-+
-+	* inode.c: Fixed getattr state bug (see below) in 2.4 function
-+          mini_fo_inode revalidate.
-+
-+	* inode.c: found an other bug in mini_fo_getattr. States are not
-+	  reliable in this function, as a file can be opened, unlinked and
-+	  the getattr function called. This results in a deleted dentry
-+	  with an inode. Fix is to ignore states and simply use the inode
-+	  available.
-+
-+2005-04-29    <mk@mary>
-+
-+	* file.c: Bugfix and cleanup in fasync and fsync. [devel-0-0-16]
-+
-+	* file.c: do not use mini_fo_lock so the generic version is
-+          used (I guess).
-+
-+	* inode.c: getattr, never call getattr on lower files, as this
-+          will cause the inum to change.
-+
-+	* inode.c: rename_reg_file renamed to rename_nondir, as it
-+          doesn't matter as long it't not a dir. Removed all
-+          rename_dev_file etc. 	  
-+
-+	* tagged as devel-0-0-15
-+
-+	* inode.c: added support for chosing support for extended
-+          attrs at compile time by XATTR define in mini_fo.h .
-+
-+	* inode.c: fixed mini_fo_getattr to use mini_fo inode and not
-+          lower again, what avoids inode number changes that confused
-+          rm again. This is the proper solution.
-+
-+2005-04-24    <mk@mary>
-+
-+	* all files: updated Copyright notive to 2005. [devel-0-0-14]
-+
-+	* inode.c: fixed mini_fo_getattr to not change the inode
-+          number, even if lower files change.
-+
-+	* super.c: fixed a bug that caused deleted base file to show
-+          up suddenly after some time, or after creating a special
-+          file. The problem was that after some time or after special
-+          file creating sync_sb_inodes is called by the vfs, that
-+          called our mini_fo_put_inode. There was (wrongly) called
-+          __meta_put_lists, that nuked the lists, although the inode
-+          was going to continue its life. Moving __meta_put_lists to
-+          mini_fo_clear_inode, where an inode is really destroyed,
-+          solved the problem.
-+
-+
-+2005-04-23    <mk@mary>
-+
-+	* state.c, aux.c: more cleaning up and
-+          simplifications. [devel-0-0-13] 
-+
-+	* inode.c: implemented mini_fo_getattr, that was required for
-+          2.6 because inode_revalidate has been remove there, and the
-+	  old "du" bug returned.
-+
-+
-+2005-04-20    <mk@mary>
-+
-+	* aux.c: get_neg_sto_dentry(): allow to be called for dentries
-+          in state UNMODIFIED, NON_EXISTANT _and_ DELETED.
-+
-+2005-04-19    <mk@mary>
-+
-+	* Fixed a bug under 2.6 that caused files deleted via mini_fo
-+          not to be deleted properly and therefore the fs filled up
-+          untill no memory was left. [devel-0-0-12]
-+
-+	* Added basic hard link support. This means that creating
-+          hardlinks will work, but existing ones will be treated as
-+          individual files. [devel-0-0-11]
-+
-+2005-04-17    <mk@mary>
-+
-+	* Bugfixes
-+
-+2005-04-13  root  <mk@mary>
-+
-+	* Added file state.c for the state transition
-+          functions. Doesn't work very well yet, though...
-+
-+2005-04-12    <mk@mary>
-+
-+	* Porting to 2.6 started, which is easier than expected, also
-+          due to Olivier previous work.
-+
-+2005-04-08    <mk@mary>
-+
-+	* Fixed the bug that caused du to return invalid sizes of
-+          directory trees. The problem was that
-+          mini_fo_inode_revalidate didn't always copy the attributes
-+          from the base inode properly.
-+
-+2005-04-01  Markus Klotzbuecher  <mk@chasey>
-+
-+	* Merged devel branch back to main trunk and updated the
-+          RELEASE notes. This will be 0-6-0-pre1.
-+
-+2005-03-31  Markus Klotzbuecher  <mk@chasey>
-+
-+	* Fixed some bugs in rename_reg_file, that only showed up in
-+          the kernel compile test. Kernel compiles cleanly ontop of
-+          mini_fo, now also make mrproper etc. work. Seems pretty stable.
-+
-+2005-03-28  Markus Klotzbuecher  <mk@chasey>
-+
-+	* Many, many directory renaming bugfixes and a lot of other
-+          cleanup. Dir renaming seems to work relatively stable.
-+
-+2005-03-22  Markus Klotzbuecher  <mk@chasey>
-+
-+	* Finished implementing lightweight directory renaming. Some
-+          basic testing indicates it works fine.
-+	  Next is to implement testcases for the testsuite and confirm
-+          everything is really working ok.
-+
-+2005-03-18  Markus Klotzbuecher  <mk@chasey>
-+
-+	* Finished implementing meta.c stuff required for directory
-+          renaming.
-+
-+2005-03-17  Markus Klotzbuecher  <mk@chasey>
-+
-+	* Fixed all compile warnings + an extremly old bug that
-+          somehow crept in while reworking the wol stuff to the META
-+          system. Turning on -Werror again... :-)
-+
-+	* Fixed some bugs in the new rename_reg_file function.
-+
-+	* Rewrote mini_fo rename and split it into several
-+          subfunctions, that handle the different types
-+          seperately. Rewrote the regular file function aswell, as it
-+          was implemented somewhat inefficient. 
-+
-+2005-03-16  Markus Klotzbuecher  <mk@chasey>
-+
-+	* Implemented new META subsystem, removed old WOL stuff in favor 
-+	  if it.
-+
-+	* After some basic testing everything seems ok...
-+
-+2005-03-11  Markus Klotzbuecher  <mk@chasey>
-+
-+	* Renaming a non regular file caused trouble because I always
-+	  tried to copy the contents. Now I only do this for regular
-+	  files. mini_fo_rename still isn't implemented properly, renaming
-+	  of device files, symlinks etc. results in a empty regular file
-+	  instead of the proper type.
-+	
-+	* Directory renaming suddenly works! What a surprise! I guess
-+          this is because renaming is implemented as making a copy and
-+          removing the original. Still this might not work
-+          everywhere...
-+
-+2005-03-09  Markus Klotzbuecher  <mk@chasey>
-+
-+	* Bugfix, when a mini_fo directory that exists in storage
-+  	  (state: MODIFIED, CREATED and DEL_REWRITTEN) is deleted, a
-+  	  possibly existing WOL file contained in it needs to be
-+  	  deleted too.
-+
-+	* Starting cleanup: defined state names in order to get rid of
-+          the state numbers.
-+
-+2005-03-08  Markus Klotzbuecher  <mk@chasey>
-+	
-+	* Makefile fix, fist_ioctl was built against wrong sources if ARCH=um
-+
-+	* Fixed a bug in dentry.c, mini_fo_d_hash. In state 4 =
-+          DEL_REWRITTEN the hash was calculated from the base dentry,
-+          which was wrong and and caused assertions in
-+          __mini_fo_hidden_dentry to fail.
-+
-+2005-02-21    <mk@mary>
-+
-+	* Implemented directory deleting (inode.c)
-+
-+	* main.c: made mini_fo_parse_options a little more robust.
-+
-+2004-12-22    <mk@mary>
-+
-+	* Makefile cleanup and uml stuff, removed unneccessary files
-+
-+	* Created a new and hopefully more informative README
-+
-+	* CHANGELOG: created a new CHANGELOG and added old entries reversely
-+
-+
-+2004-10-24 Gleb Natapov <[email protected]>
-+
-+	* Fix: owner and group where not correctly copied from base to
-+          storage. 
-+
-+
-+2004-10-05 Gleb Natapov <[email protected]>
-+
-+	* Implementation of fsync, fasync and lock mini_fo functions.
-+	
-+
-+2004-09-29 Bob Lee <[email protected]>
-+
-+	* Fix of a serious pointer bug
-+	
-+
-+2004-09-28 Gleb Natapov <[email protected]>
-+
-+	* Implementation of mini_fo_mknod and mini_fo_rename, support
-+          for device files.
-+	
---- /dev/null
-+++ b/fs/mini_fo/dentry.c
-@@ -0,0 +1,244 @@
-+/*
-+ * Copyright (c) 1997-2003 Erez Zadok
-+ * Copyright (c) 2001-2003 Stony Brook University
-+ *
-+ * For specific licensing information, see the COPYING file distributed with
-+ * this package, or get one from ftp://ftp.filesystems.org/pub/fist/COPYING.
-+ *
-+ * This Copyright notice must be kept intact and distributed with all
-+ * fistgen sources INCLUDING sources generated by fistgen.
-+ */
-+/*
-+ * Copyright (C) 2004, 2005 Markus Klotzbuecher <[email protected]>
-+ *
-+ * 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.
-+ */
-+
-+/*
-+ *  $Id$
-+ */
-+
-+#ifdef HAVE_CONFIG_H
-+# include <config.h>
-+#endif
-+
-+#include "fist.h"
-+#include "mini_fo.h"
-+
-+/*
-+ * THIS IS A BOOLEAN FUNCTION: returns 1 if valid, 0 otherwise.
-+ */
-+STATIC int
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+mini_fo_d_revalidate(dentry_t *dentry, struct nameidata *nd)
-+#else
-+mini_fo_d_revalidate(dentry_t *dentry, int flags)
-+#endif
-+{
-+	int err1 = 1; /* valid = 1, invalid = 0 */
-+	int err2 = 1;
-+	dentry_t *hidden_dentry;
-+	dentry_t *hidden_sto_dentry;
-+
-+
-+	check_mini_fo_dentry(dentry);
-+
-+	hidden_dentry  = dtohd(dentry);
-+	hidden_sto_dentry = dtohd2(dentry);
-+
-+	if(hidden_dentry &&
-+	   hidden_dentry->d_op &&
-+	   hidden_dentry->d_op->d_revalidate) {
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+		err1 = hidden_dentry->d_op->d_revalidate(hidden_dentry, nd);
-+#else
-+		err1 = hidden_dentry->d_op->d_revalidate(hidden_dentry, flags);
-+#endif
-+	}
-+	if(hidden_sto_dentry &&
-+	   hidden_sto_dentry->d_op &&
-+	   hidden_sto_dentry->d_op->d_revalidate) {
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+		err2 = hidden_sto_dentry->d_op->d_revalidate(hidden_sto_dentry, 
-+							     nd);
-+#else
-+		err2 = hidden_sto_dentry->d_op->d_revalidate(hidden_sto_dentry, 
-+							     flags);
-+#endif
-+	}
-+
-+	/* mk: if one of the lower level dentries are valid,
-+	 * the mini_fo dentry is too.
-+	 */
-+	return (err1 || err2);
-+}
-+
-+
-+STATIC int
-+mini_fo_d_hash(dentry_t *dentry, qstr_t *name)
-+{
-+	int err = 0;
-+	dentry_t *hidden_dentry;
-+	dentry_t *hidden_sto_dentry;
-+
-+	/* hidden_dentry = mini_fo_hidden_dentry(dentry);
-+	 * hidden_sto_dentry = mini_fo_hidden_sto_dentry(dentry); */
-+
-+	/* state 1, 3, 4, 5: build the hash for the storage dentry */
-+	if((dtopd(dentry)->state == MODIFIED) ||
-+	   (dtopd(dentry)->state == CREATED) ||
-+	   (dtopd(dentry)->state == DEL_REWRITTEN) ||
-+	   (dtopd(dentry)->state == DELETED)) {
-+		hidden_sto_dentry = dtohd2(dentry);
-+		if(hidden_sto_dentry &&
-+		   hidden_sto_dentry->d_op &&
-+		   hidden_sto_dentry->d_op->d_hash) {
-+			err = hidden_sto_dentry->d_op->d_hash(hidden_sto_dentry, name);
-+		}
-+		goto out;
-+	}
-+	/* state 2: build the hash for the base dentry */
-+	if(dtopd(dentry)->state == UNMODIFIED) {
-+		hidden_dentry = dtohd(dentry);
-+		if(hidden_dentry &&
-+		   hidden_dentry->d_op &&
-+		   hidden_dentry->d_op->d_hash) {
-+			err = hidden_dentry->d_op->d_hash(hidden_dentry, name);
-+		}
-+		goto out;
-+	}
-+	/* state 6: build hash for the dentry that exists */
-+	if(dtopd(dentry)->state == NON_EXISTANT) {
-+		hidden_sto_dentry = dtohd2(dentry);
-+		if(hidden_sto_dentry &&
-+		   hidden_sto_dentry->d_op &&
-+		   hidden_sto_dentry->d_op->d_hash) {
-+			err = hidden_sto_dentry->d_op->d_hash(hidden_sto_dentry, name);
-+			goto out;
-+		}
-+		hidden_dentry = dtohd(dentry);
-+		if(hidden_dentry &&
-+		   hidden_dentry->d_op &&
-+		   hidden_dentry->d_op->d_hash) {
-+			err = hidden_dentry->d_op->d_hash(hidden_dentry, name);
-+			goto out;
-+		}
-+	}
-+
-+	printk(KERN_CRIT "mini_fo: d_hash: invalid state detected.\n");
-+
-+ out:
-+	return err;
-+}
-+
-+
-+STATIC int
-+mini_fo_d_compare(dentry_t *dentry, qstr_t *a, qstr_t *b)
-+{
-+	int err;
-+	dentry_t *hidden_dentry=NULL;
-+
-+	/* hidden_dentry = mini_fo_hidden_dentry(dentry); */
-+	if(dtohd2(dentry))
-+		hidden_dentry = dtohd2(dentry);
-+	else if(dtohd(dentry))
-+		hidden_dentry = dtohd(dentry);
-+
-+	if (hidden_dentry && hidden_dentry->d_op && hidden_dentry->d_op->d_compare) {
-+		err = hidden_dentry->d_op->d_compare(hidden_dentry, a, b);
-+	} else {
-+		err = ((a->len != b->len) || memcmp(a->name, b->name, b->len));
-+	}
-+
-+	return err;
-+}
-+
-+
-+int
-+mini_fo_d_delete(dentry_t *dentry)
-+{
-+	dentry_t *hidden_dentry;
-+	dentry_t *hidden_sto_dentry;
-+	int err = 0;
-+
-+	/* this could be a negative dentry, so check first */
-+	if (!dtopd(dentry)) {
-+		printk(KERN_CRIT "mini_fo_d_delete: negative dentry passed.\n");
-+		goto out;
-+	}
-+	hidden_dentry = dtohd(dentry);
-+	hidden_sto_dentry = dtohd2(dentry);
-+
-+	if(hidden_dentry) {
-+		if(hidden_dentry->d_op &&
-+		   hidden_dentry->d_op->d_delete) {
-+			err = hidden_dentry->d_op->d_delete(hidden_dentry);
-+		}
-+	}
-+	if(hidden_sto_dentry) {
-+		if(hidden_sto_dentry->d_op &&
-+		   hidden_sto_dentry->d_op->d_delete) {
-+			err = hidden_sto_dentry->d_op->d_delete(hidden_sto_dentry);
-+		}
-+	}
-+
-+ out:
-+	return err;
-+}
-+
-+
-+void
-+mini_fo_d_release(dentry_t *dentry)
-+{
-+	dentry_t *hidden_dentry;
-+	dentry_t *hidden_sto_dentry;
-+
-+
-+	/* this could be a negative dentry, so check first */
-+	if (!dtopd(dentry)) {
-+		printk(KERN_CRIT "mini_fo_d_release: no private data.\n");
-+		goto out;
-+	}
-+	hidden_dentry = dtohd(dentry);
-+	hidden_sto_dentry = dtohd2(dentry);
-+
-+	if(hidden_dentry) {
-+		/* decrement hidden dentry's counter and free its inode */
-+		dput(hidden_dentry);
-+	}
-+	if(hidden_sto_dentry) {
-+                /* decrement hidden dentry's counter and free its inode */
-+		dput(hidden_sto_dentry);
-+	}
-+
-+	/* free private data (mini_fo_dentry_info) here */
-+	kfree(dtopd(dentry));
-+	__dtopd(dentry) = NULL;	/* just to be safe */
-+ out:
-+	return;
-+}
-+
-+
-+/*
-+ * we don't really need mini_fo_d_iput, because dentry_iput will call iput() if
-+ * mini_fo_d_iput is not defined. We left this implemented for ease of
-+ * tracing/debugging.
-+ */
-+void
-+mini_fo_d_iput(dentry_t *dentry, inode_t *inode)
-+{
-+	iput(inode);
-+}
-+
-+
-+struct dentry_operations mini_fo_dops = {
-+	d_revalidate:	mini_fo_d_revalidate,
-+	d_hash:		mini_fo_d_hash,
-+	d_compare:		mini_fo_d_compare,
-+	d_release:		mini_fo_d_release,
-+	d_delete:		mini_fo_d_delete,
-+	d_iput:		mini_fo_d_iput,
-+};
---- /dev/null
-+++ b/fs/mini_fo/file.c
-@@ -0,0 +1,713 @@
-+/*
-+ * Copyright (c) 1997-2003 Erez Zadok
-+ * Copyright (c) 2001-2003 Stony Brook University
-+ *
-+ * For specific licensing information, see the COPYING file distributed with
-+ * this package, or get one from ftp://ftp.filesystems.org/pub/fist/COPYING.
-+ *
-+ * This Copyright notice must be kept intact and distributed with all
-+ * fistgen sources INCLUDING sources generated by fistgen.
-+ */
-+/*
-+ * Copyright (C) 2004, 2005 Markus Klotzbuecher <[email protected]>
-+ *
-+ * 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.
-+ */
-+
-+/*
-+ *  $Id$
-+ */
-+
-+#ifdef HAVE_CONFIG_H
-+# include <config.h>
-+#endif
-+
-+#include "fist.h"
-+#include "mini_fo.h"
-+#define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1))
-+
-+/*******************
-+ * File Operations *
-+ *******************/
-+
-+STATIC loff_t
-+mini_fo_llseek(file_t *file, loff_t offset, int origin)
-+{
-+	loff_t err;
-+	file_t *hidden_file = NULL;
-+
-+	if(S_ISDIR(file->f_dentry->d_inode->i_mode)) {
-+		/* Check if trying to llseek from a directory */
-+		err = -EISDIR;
-+		goto out;
-+	}
-+	if (ftopd(file) != NULL) {
-+		if(ftohf2(file)) {
-+			hidden_file = ftohf2(file);
-+		} else {
-+			hidden_file = ftohf(file);
-+		}
-+	}
-+
-+	/* always set hidden position to this one */
-+	hidden_file->f_pos = file->f_pos;
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+	memcpy(&(hidden_file->f_ra), 
-+	       &(file->f_ra), 
-+	       sizeof(struct file_ra_state));
-+#else
-+	if (file->f_reada) { /* update readahead information if needed */
-+		hidden_file->f_reada = file->f_reada;
-+		hidden_file->f_ramax = file->f_ramax;
-+		hidden_file->f_raend = file->f_raend;
-+		hidden_file->f_ralen = file->f_ralen;
-+		hidden_file->f_rawin = file->f_rawin;
-+	}
-+#endif
-+	if (hidden_file->f_op && hidden_file->f_op->llseek)
-+		err = hidden_file->f_op->llseek(hidden_file, offset, origin);
-+	else
-+		err = generic_file_llseek(hidden_file, offset, origin);
-+
-+	if (err < 0)
-+		goto out;
-+
-+	if (err != file->f_pos) {
-+		file->f_pos = err;
-+		// ION maybe this?
-+		// 	file->f_pos = hidden_file->f_pos;
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-+		file->f_reada = 0;
-+#endif
-+		file->f_version++;
-+	}
-+
-+ out:
-+	return err;
-+}
-+
-+
-+/* mk: fanout capable */
-+STATIC ssize_t
-+mini_fo_read(file_t *file, char *buf, size_t count, loff_t *ppos)
-+{
-+	int err = -EINVAL;
-+	file_t *hidden_file = NULL;
-+	loff_t pos = *ppos;
-+
-+	if(S_ISDIR(file->f_dentry->d_inode->i_mode)) {
-+		/* Check if trying to read from a directory */
-+		/* printk(KERN_CRIT "mini_fo_read: ERROR: trying to read data from a directory.\n"); */
-+		err = -EISDIR;
-+		goto out;
-+	}
-+
-+	if (ftopd(file) != NULL) {
-+		if(ftohf2(file)) {
-+			hidden_file = ftohf2(file);
-+		} else {
-+			hidden_file = ftohf(file);
-+		}
-+	}
-+
-+	if (!hidden_file->f_op || !hidden_file->f_op->read)
-+		goto out;
-+
-+	err = hidden_file->f_op->read(hidden_file, buf, count, &pos);
-+	*ppos = pos;
-+
-+	if (err >= 0) {
-+		/* atime should also be updated for reads of size zero or more */
-+		fist_copy_attr_atime(file->f_dentry->d_inode,
-+				     hidden_file->f_dentry->d_inode);
-+	}
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-+	/*
-+	 * MAJOR HACK
-+	 * because pread() does not have any way to tell us that it is
-+	 * our caller, then we don't know for sure if we have to update
-+	 * the file positions.  This hack relies on read() having passed us
-+	 * the "real" pointer of its struct file's f_pos field.
-+	 */
-+	if (ppos == &file->f_pos)
-+		hidden_file->f_pos = *ppos = pos;
-+	if (hidden_file->f_reada) { /* update readahead information if needed */
-+		file->f_reada = hidden_file->f_reada;
-+		file->f_ramax = hidden_file->f_ramax;
-+		file->f_raend = hidden_file->f_raend;
-+		file->f_ralen = hidden_file->f_ralen;
-+		file->f_rawin = hidden_file->f_rawin;
-+	}
-+#else
-+	memcpy(&(file->f_ra),&(hidden_file->f_ra),sizeof(struct file_ra_state));
-+#endif
-+
-+ out:
-+	return err;
-+}
-+
-+
-+/* this mini_fo_write() does not modify data pages! */
-+STATIC ssize_t
-+mini_fo_write(file_t *file, const char *buf, size_t count, loff_t *ppos)
-+{
-+	int err = -EINVAL;
-+	file_t *hidden_file = NULL;
-+	inode_t *inode;
-+	inode_t *hidden_inode;
-+	loff_t pos = *ppos;
-+
-+	/* mk: fan out: */
-+	if (ftopd(file) != NULL) {
-+		if(ftohf2(file)) {
-+			hidden_file = ftohf2(file);
-+		} else {
-+			/* This is bad! We have no storage file to write to. This
-+			 * should never happen because if a file is opened for
-+			 * writing, a copy should have been made earlier.
-+			 */
-+			printk(KERN_CRIT "mini_fo: write : ERROR, no storage file to write.\n");
-+			err = -EINVAL;
-+			goto out;
-+		}
-+	}
-+
-+	inode = file->f_dentry->d_inode;
-+	hidden_inode = itohi2(inode);
-+	if(!hidden_inode) {
-+		printk(KERN_CRIT "mini_fo: write: no sto inode found, not good.\n");
-+		goto out;
-+	}
-+
-+	if (!hidden_file->f_op || !hidden_file->f_op->write)
-+		goto out;
-+
-+	/* adjust for append -- seek to the end of the file */
-+	if (file->f_flags & O_APPEND)
-+		pos = inode->i_size;
-+
-+	err = hidden_file->f_op->write(hidden_file, buf, count, &pos);
-+
-+	/*
-+	 * copy ctime and mtime from lower layer attributes
-+	 * atime is unchanged for both layers
-+	 */
-+	if (err >= 0)
-+		fist_copy_attr_times(inode, hidden_inode);
-+	
-+	*ppos = pos;
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-+	/*
-+	 * XXX: MAJOR HACK
-+	 *
-+	 * because pwrite() does not have any way to tell us that it is
-+	 * our caller, then we don't know for sure if we have to update
-+	 * the file positions.  This hack relies on write() having passed us
-+	 * the "real" pointer of its struct file's f_pos field.
-+	 */
-+	if (ppos == &file->f_pos)
-+		hidden_file->f_pos = *ppos = pos;
-+#endif
-+	/* update this inode's size */
-+	if (pos > inode->i_size)
-+		inode->i_size = pos;
-+
-+ out:
-+	return err;
-+}
-+
-+/* Global variable to hold a file_t pointer.
-+ * This serves to allow mini_fo_filldir function to know which file is
-+ * beeing read, which is required for two reasons:
-+ *
-+ *   - be able to call wol functions in order to avoid listing deleted
-+ *     base files.
-+ *   - if we're reading a directory which is in state 1, we need to
-+ *     maintain a list (in mini_fo_filldir) of which files allready 
-+ *     have been copied to userspace,to detect files existing in base
-+ *     and storage and not list them twice.
-+ */
-+filldir_t mini_fo_filldir_orig;
-+file_t *mini_fo_filldir_file;
-+
-+/* mainly copied from fs/readdir.c */
-+STATIC int
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
-+mini_fo_filldir(void * __buf, const char * name, int namlen, loff_t offset,
-+		  u64 ino, unsigned int d_type)
-+#else
-+mini_fo_filldir(void * __buf, const char * name, int namlen, loff_t offset,
-+		  ino_t ino, unsigned int d_type)
-+#endif
-+{
-+	struct getdents_callback * buf = (struct getdents_callback *) __buf;
-+	file_t* file = mini_fo_filldir_file;
-+
-+	/* In theses states we filter meta files in storage (WOL) */
-+	if(file && (dtopd(file->f_dentry)->state == MODIFIED ||
-+		    dtopd(file->f_dentry)->state == CREATED ||
-+		    dtopd(file->f_dentry)->state == DEL_REWRITTEN)) {
-+
-+		int tmp = strlen(META_FILENAME);
-+		if(tmp  == namlen) {
-+			if(!strncmp(name, META_FILENAME, namlen))
-+				return 0;
-+		}
-+	}
-+
-+	/* check if we are merging the contents of storage and base */
-+	if(file && dtopd(file->f_dentry)->state == MODIFIED) {
-+		/* check if we are still reading storage contents, if
-+		 * yes, we just save the name of the file for duplicate
-+		 * checking later. */
-+
-+		if(!ftopd(file)->rd.sto_done) {
-+			/* put file into ndl list */
-+			if(ndl_add_entry(&ftopd(file)->rd, name, namlen))
-+				printk(KERN_CRIT "mini_fo_filldir: Error adding to ndl.\n");
-+		} else {
-+			/* check if file has been deleted */
-+			if(meta_check_d_entry(file->f_dentry, name, namlen))
-+				return 0;
-+			
-+			/* do duplicate checking */
-+			if(ndl_check_entry(&ftopd(file)->rd, name, namlen))
-+				return 0;
-+		}
-+	}
-+
-+	return mini_fo_filldir_orig(buf, name, namlen, offset, ino, d_type);
-+}
-+
-+
-+STATIC int
-+mini_fo_readdir(file_t *file, void *dirent, filldir_t filldir)
-+{
-+	int err = 0;/* mk: ??? -ENOTDIR; */
-+	file_t *hidden_file = NULL;
-+	file_t *hidden_sto_file = NULL;
-+	inode_t *inode;
-+	struct getdents_callback *buf;
-+	int oldcount;
-+
-+#if defined(FIST_FILTER_NAME) || defined(FIST_FILTER_SCA)
-+	struct mini_fo_getdents_callback buf;
-+#endif /* FIST_FILTER_NAME || FIST_FILTER_SCA */
-+
-+	buf = (struct getdents_callback *) dirent;
-+	oldcount = buf->count;
-+	inode = file->f_dentry->d_inode;
-+	mini_fo_filldir_file = file;
-+	mini_fo_filldir_orig = filldir;
-+
-+	ftopd(file)->rd.sto_done = 0;
-+	do {
-+		if (ftopd(file) != NULL) {
-+			if(ftohf2(file)) { 
-+				hidden_sto_file = ftohf2(file);
-+				err = vfs_readdir(hidden_sto_file, mini_fo_filldir, dirent);
-+				file->f_pos = hidden_sto_file->f_pos;
-+				if (err > 0)
-+					fist_copy_attr_atime(inode, hidden_sto_file->f_dentry->d_inode);
-+				/* not finshed yet, we'll be called again */
-+				if (buf->count != oldcount)
-+					break;
-+			}
-+
-+			ftopd(file)->rd.sto_done = 1;
-+
-+			if(ftohf(file)) { 
-+				hidden_file = ftohf(file);
-+				err = vfs_readdir(hidden_file, mini_fo_filldir, dirent);
-+				file->f_pos = hidden_file->f_pos;
-+				if (err > 0)
-+					fist_copy_attr_atime(inode, hidden_file->f_dentry->d_inode);
-+			}
-+
-+		}
-+	} while (0);
-+
-+	/* mk:
-+	 * we need to check if all the directory data has been copied to userspace,
-+	 * or if we will be called again by userspace to complete the operation.
-+	 */
-+	if(buf->count == oldcount) {
-+		ndl_put_list(&ftopd(file)->rd);
-+	}
-+
-+	/* unset this, safe */
-+	mini_fo_filldir_file = NULL;
-+	return err;
-+}
-+
-+
-+STATIC unsigned int
-+mini_fo_poll(file_t *file, poll_table *wait)
-+{
-+	unsigned int mask = DEFAULT_POLLMASK;
-+	file_t *hidden_file = NULL;
-+
-+	if (ftopd(file) != NULL) {
-+		if(ftohf2(file)) {
-+			hidden_file = ftohf2(file);
-+		} else {
-+			hidden_file = ftohf(file);
-+		}
-+	}
-+
-+	if (!hidden_file->f_op || !hidden_file->f_op->poll)
-+		goto out;
-+
-+	mask = hidden_file->f_op->poll(hidden_file, wait);
-+
-+ out:
-+	return mask;
-+}
-+
-+/* FIST-LITE special version of mmap */
-+STATIC int
-+mini_fo_mmap(file_t *file, vm_area_t *vma)
-+{
-+	int err = 0;
-+	file_t *hidden_file = NULL;
-+
-+	/* fanout capability */
-+	if (ftopd(file) != NULL) {
-+		if(ftohf2(file)) {
-+			hidden_file = ftohf2(file);
-+		} else {
-+			hidden_file = ftohf(file);
-+		}
-+	}
-+
-+	ASSERT(hidden_file != NULL);
-+	ASSERT(hidden_file->f_op != NULL);
-+	ASSERT(hidden_file->f_op->mmap != NULL);
-+
-+	vma->vm_file = hidden_file;
-+	err = hidden_file->f_op->mmap(hidden_file, vma);
-+	get_file(hidden_file); /* make sure it doesn't get freed on us */
-+	fput(file);	       /* no need to keep extra ref on ours */
-+
-+	return err;
-+}
-+
-+
-+
-+STATIC int
-+mini_fo_open(inode_t *inode, file_t *file)
-+{
-+	int err = 0;
-+ 	int hidden_flags; 
-+	file_t *hidden_file = NULL;
-+	dentry_t *hidden_dentry = NULL;
-+
-+	/* fanout stuff */
-+	file_t *hidden_sto_file = NULL;
-+	dentry_t *hidden_sto_dentry = NULL;
-+
-+	__ftopd(file) = 
-+		kmalloc(sizeof(struct mini_fo_file_info), GFP_KERNEL);
-+	if (!ftopd(file)) {
-+		err = -ENOMEM;
-+		goto out;
-+	}
-+
-+	/* init the readdir_helper structure */
-+	INIT_LIST_HEAD(&ftopd(file)->rd.ndl_list);
-+	ftopd(file)->rd.ndl_size = 0;
-+
-+	/* In certain paths this could stay uninitalized and cause trouble */
-+	ftohf(file) = NULL;
-+	ftohf2(file) = NULL;
-+	hidden_flags = file->f_flags;
-+
-+	/* create storage files? */
-+	if(dtost(file->f_dentry) == UNMODIFIED) {
-+		if(!IS_WRITE_FLAG(file->f_flags)) {
-+			hidden_dentry = dtohd(file->f_dentry);
-+			dget(hidden_dentry);
-+			/* dentry_open will decrement mnt refcnt if err.
-+			 * otherwise fput() will do an mntput() for us upon file close. */
-+			mntget(stopd(inode->i_sb)->hidden_mnt);
-+			hidden_file = dentry_open(hidden_dentry,
-+						  stopd(inode->i_sb)->hidden_mnt,
-+						  hidden_flags);
-+			if (IS_ERR(hidden_file)) {
-+				err = PTR_ERR(hidden_file);
-+				dput(hidden_dentry);
-+				goto out;
-+			}
-+			ftohf(file) = hidden_file;	/* link two files */
-+			goto out;
-+		}
-+		else {
-+			if(S_ISDIR(file->f_dentry->d_inode->i_mode)) {
-+				err = dir_unmod_to_mod(file->f_dentry);
-+			} else
-+				err = nondir_unmod_to_mod(file->f_dentry, 1);
-+
-+			if (err) {
-+				printk("mini_fo_open: ERROR creating storage file.\n");
-+				goto out;
-+			}
-+		}
-+	}
-+	hidden_sto_dentry = dtohd2(file->f_dentry);
-+	dget(hidden_sto_dentry);
-+
-+	if(dtopd(file->f_dentry)->state == MODIFIED) {
-+		/* Directorys are special, interpose on both lower level files */
-+		if(S_ISDIR(itohi(inode)->i_mode)) {
-+			/* check for invalid file types of lower level files */
-+			if(!(S_ISDIR(itohi(inode)->i_mode) && S_ISDIR(itohi2(inode)->i_mode))) {
-+				printk(KERN_CRIT "mini_fo_open: meta data corruption detected.\n");
-+				dput(hidden_sto_dentry);
-+				err = -EINVAL;
-+				goto out;
-+			}
-+
-+			/* lower level directorys are ok, open the base file */
-+			hidden_dentry = dtohd(file->f_dentry);
-+			dget(hidden_dentry);
-+
-+			mntget(stopd(inode->i_sb)->hidden_mnt);
-+			hidden_file = dentry_open(hidden_dentry,
-+						  stopd(inode->i_sb)->hidden_mnt,
-+						  hidden_flags);
-+			if (IS_ERR(hidden_file)) {
-+				err = PTR_ERR(hidden_file);
-+				dput(hidden_dentry);
-+				dput(hidden_sto_dentry);
-+				goto out;
-+			}
-+			ftohf(file) = hidden_file; /* link the two files */
-+		}
-+	}
-+
-+	if(!exists_in_storage(file->f_dentry)) {
-+		printk(KERN_CRIT "mini_fo_open: invalid file state detected.\n");
-+		err = -EINVAL;
-+		dput(hidden_sto_dentry);
-+
-+		/* If the base file has been opened, we need to close it here */
-+		if(ftohf(file)) {
-+			if (hidden_file->f_op && hidden_file->f_op->flush)
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
-+				hidden_file->f_op->flush(hidden_file, NULL);
-+#else
-+				hidden_file->f_op->flush(hidden_file);
-+#endif
-+			dput(hidden_dentry);
-+		}
-+		goto out;
-+	}
-+
-+	/* ok, now we can safely open the storage file */
-+	mntget(stopd(inode->i_sb)->hidden_mnt2);
-+	hidden_sto_file = dentry_open(hidden_sto_dentry,
-+				      stopd(inode->i_sb)->hidden_mnt2,
-+				      hidden_flags);
-+
-+	/* dentry_open dputs the dentry if it fails */
-+	if (IS_ERR(hidden_sto_file)) {
-+		err = PTR_ERR(hidden_sto_file);
-+		/* close base file if open */
-+		if(ftohf(file)) {
-+			if (hidden_file->f_op && hidden_file->f_op->flush)
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
-+				hidden_file->f_op->flush(hidden_file, NULL);
-+#else
-+				hidden_file->f_op->flush(hidden_file);
-+#endif
-+			dput(hidden_dentry);
-+		}
-+		goto out;
-+	}
-+	ftohf2(file) = hidden_sto_file; /* link storage file */
-+	
-+ out:
-+	if (err < 0 && ftopd(file)) {
-+		kfree(ftopd(file));
-+	}
-+	return err;
-+}
-+
-+STATIC int
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
-+mini_fo_flush(file_t *file, fl_owner_t id)
-+#else
-+mini_fo_flush(file_t *file)
-+#endif
-+{
-+	int err1 = 0;		/* assume ok (see open.c:close_fp) */
-+	int err2 = 0;
-+	file_t *hidden_file = NULL;
-+	
-+	check_mini_fo_file(file);
-+
-+	/* mk: we don't do any state checking here, as its not worth the time.
-+	 * Just flush the lower level files if they exist.
-+	 */
-+	if(ftopd(file) != NULL) {
-+		if(ftohf(file) != NULL) {
-+			hidden_file = ftohf(file);
-+			if (hidden_file->f_op && hidden_file->f_op->flush)
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
-+				err1 = hidden_file->f_op->flush(hidden_file, id);
-+#else
-+				err1 = hidden_file->f_op->flush(hidden_file);
-+#endif
-+		}
-+		if(ftohf2(file) != NULL) {
-+			hidden_file = ftohf2(file);
-+			if (hidden_file->f_op && hidden_file->f_op->flush)
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
-+				err2 = hidden_file->f_op->flush(hidden_file, id);
-+#else
-+				err2 = hidden_file->f_op->flush(hidden_file);
-+#endif
-+		}
-+	}
-+	return (err1 | err2);
-+}
-+
-+
-+STATIC int
-+mini_fo_release(inode_t *inode, file_t *file)
-+{
-+	int err = 0;
-+	file_t *hidden_file = NULL;
-+
-+	if (ftopd(file) != NULL) {
-+		if(ftohf(file)) {
-+			hidden_file = ftohf(file);
-+			fput(hidden_file);
-+		}
-+		if(ftohf2(file)) {
-+			hidden_file = ftohf2(file);
-+			fput(hidden_file);
-+		}
-+		kfree(ftopd(file));
-+	}
-+	return err;
-+}
-+
-+STATIC int
-+mini_fo_fsync(file_t *file, dentry_t *dentry, int datasync)
-+{
-+	int err1 = 0;
-+	int err2 = 0;
-+	file_t *hidden_file = NULL;
-+	dentry_t *hidden_dentry;
-+
-+	check_mini_fo_file(file);
-+
-+	if ((hidden_file = ftohf(file)) != NULL) {
-+		hidden_dentry = dtohd(dentry);
-+		if (hidden_file->f_op && hidden_file->f_op->fsync) {
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+			mutex_lock(&hidden_dentry->d_inode->i_mutex);
-+#else
-+			down(&hidden_dentry->d_inode->i_sem);
-+#endif
-+			err1 = hidden_file->f_op->fsync(hidden_file, hidden_dentry, datasync);
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+			mutex_unlock(&hidden_dentry->d_inode->i_mutex);
-+#else
-+			up(&hidden_dentry->d_inode->i_sem);
-+#endif
-+		}
-+	}
-+
-+	if ((hidden_file = ftohf2(file)) != NULL) {
-+		hidden_dentry = dtohd2(dentry);
-+		if (hidden_file->f_op && hidden_file->f_op->fsync) {
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+			mutex_lock(&hidden_dentry->d_inode->i_mutex);
-+#else
-+			down(&hidden_dentry->d_inode->i_sem);
-+#endif
-+			err2 = hidden_file->f_op->fsync(hidden_file, hidden_dentry, datasync);
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+			mutex_unlock(&hidden_dentry->d_inode->i_mutex);
-+#else
-+			up(&hidden_dentry->d_inode->i_sem);
-+#endif
-+		}
-+	}
-+	else
-+		goto err;
-+
-+err:
-+	return (err1 || err2);
-+}
-+
-+
-+STATIC int
-+mini_fo_fasync(int fd, file_t *file, int flag)
-+{
-+	int err1 = 0;
-+	int err2 = 0;
-+
-+	file_t *hidden_file = NULL;
-+
-+	check_mini_fo_file(file);
-+
-+	if((hidden_file = ftohf(file)) != NULL) {
-+		err1 = hidden_file->f_op->fasync(fd, hidden_file, flag);
-+	}
-+	if((hidden_file = ftohf2(file)) != NULL) {
-+		err2 = hidden_file->f_op->fasync(fd, hidden_file, flag);
-+	}
-+	
-+	return (err1 || err2);
-+}
-+
-+
-+
-+struct file_operations mini_fo_dir_fops =
-+	{
-+		read:	generic_read_dir,
-+		write:	mini_fo_write,
-+		readdir: mini_fo_readdir,
-+		poll:	mini_fo_poll,
-+		/* ioctl:	mini_fo_ioctl, */
-+		mmap:	mini_fo_mmap,
-+		open:	mini_fo_open,
-+		flush:	mini_fo_flush,
-+		release: mini_fo_release,
-+		fsync:	mini_fo_fsync,
-+		fasync:	mini_fo_fasync,
-+		/* not needed lock:	mini_fo_lock, */
-+		/* not needed: readv */
-+		/* not needed: writev */
-+		/* not implemented: sendpage */
-+		/* not implemented: get_unmapped_area */
-+	};
-+
-+struct file_operations mini_fo_main_fops =
-+	{
-+		llseek:	mini_fo_llseek,
-+		read:	mini_fo_read,
-+		write:	mini_fo_write,
-+		readdir: mini_fo_readdir,
-+		poll:	mini_fo_poll,
-+		/* ioctl:	mini_fo_ioctl, */
-+		mmap:	mini_fo_mmap,
-+		open:	mini_fo_open,
-+		flush:	mini_fo_flush,
-+		release: mini_fo_release,
-+		fsync:	mini_fo_fsync,
-+		fasync:	mini_fo_fasync,
-+		/* not needed: lock:	mini_fo_lock, */
-+		/* not needed: readv */
-+		/* not needed: writev */
-+		/* not implemented: sendpage */
-+		/* not implemented: get_unmapped_area */
-+	};
---- /dev/null
-+++ b/fs/mini_fo/fist.h
-@@ -0,0 +1,252 @@
-+/*
-+ * Copyright (c) 1997-2003 Erez Zadok
-+ * Copyright (c) 2001-2003 Stony Brook University
-+ *
-+ * For specific licensing information, see the COPYING file distributed with
-+ * this package, or get one from ftp://ftp.filesystems.org/pub/fist/COPYING.
-+ *
-+ * This Copyright notice must be kept intact and distributed with all
-+ * fistgen sources INCLUDING sources generated by fistgen.
-+ */
-+/*
-+ * Copyright (C) 2004, 2005 Markus Klotzbuecher <[email protected]>
-+ *
-+ * 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.
-+ */
-+
-+
-+/*
-+ *  $Id$
-+ */
-+
-+#ifndef __FIST_H_
-+#define __FIST_H_
-+
-+/*
-+ * KERNEL ONLY CODE:
-+ */
-+#ifdef __KERNEL__
-+#include <linux/version.h>
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
-+#include <linux/autoconf.h>
-+#else
-+#include <linux/config.h>
-+#endif
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-+#ifdef CONFIG_MODVERSIONS
-+# define MODVERSIONS
-+# include <linux/modversions.h>
-+#endif /* CONFIG_MODVERSIONS */
-+#endif /* KERNEL_VERSION < 2.6.0 */
-+#include <linux/sched.h>
-+#include <linux/kernel.h>
-+#include <linux/mm.h>
-+#include <linux/string.h>
-+#include <linux/stat.h>
-+#include <linux/errno.h>
-+#include <linux/wait.h>
-+#include <linux/limits.h>
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-+#include <linux/locks.h>
-+#else
-+#include <linux/buffer_head.h>
-+#include <linux/pagemap.h>
-+#include <linux/namei.h>
-+#include <linux/module.h>
-+#include <linux/mount.h>
-+#include <linux/page-flags.h>
-+#include <linux/writeback.h>
-+#include <linux/statfs.h>
-+#endif
-+#include <linux/smp.h>
-+#include <linux/smp_lock.h>
-+#include <linux/file.h>
-+#include <linux/slab.h>
-+#include <linux/vmalloc.h>
-+#include <linux/poll.h>
-+#include <linux/list.h>
-+#include <linux/init.h>
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20)
-+#include <linux/xattr.h>
-+#endif
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+#include <linux/security.h>
-+#endif
-+
-+#include <linux/swap.h>
-+
-+#include <asm/system.h>
-+/* #include <asm/segment.h> */
-+#include <asm/mman.h>
-+#include <linux/seq_file.h>
-+
-+/*
-+ * MACROS:
-+ */
-+
-+/* those mapped to ATTR_* were copied from linux/fs.h */
-+#define FA_MODE		ATTR_MODE
-+#define FA_UID		ATTR_UID
-+#define FA_GID		ATTR_GID
-+#define FA_SIZE		ATTR_SIZE
-+#define FA_ATIME	ATTR_ATIME
-+#define FA_MTIME	ATTR_MTIME
-+#define FA_CTIME	ATTR_CTIME
-+#define FA_ATIME_SET	ATTR_ATIME_SET
-+#define FA_MTIME_SET	ATTR_MTIME_SET
-+#define FA_FORCE	ATTR_FORCE
-+#define FA_ATTR_FLAGS	ATTR_ATTR_FLAG
-+
-+/* must be greater than all other ATTR_* flags! */
-+#define FA_NLINK	2048
-+#define FA_BLKSIZE	4096
-+#define FA_BLOCKS	8192
-+#define FA_TIMES	(FA_ATIME|FA_MTIME|FA_CTIME)
-+#define FA_ALL		0
-+
-+/* macros to manage changes between kernels */
-+#define INODE_DATA(i)	(&(i)->i_data)
-+
-+#define MIN(x,y) ((x < y) ? (x) : (y))
-+#define MAX(x,y) ((x > y) ? (x) : (y))
-+#define MAXPATHLEN PATH_MAX
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,5)
-+# define lookup_one_len(a,b,c) lookup_one(a,b)
-+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,4,5) */
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,8)
-+# define generic_file_llseek default_llseek
-+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,4,8) */
-+
-+#ifndef SEEK_SET
-+# define SEEK_SET 0
-+#endif /* not SEEK_SET */
-+
-+#ifndef SEEK_CUR
-+# define SEEK_CUR 1
-+#endif /* not SEEK_CUR */
-+
-+#ifndef SEEK_END
-+# define SEEK_END 2
-+#endif /* not SEEK_END */
-+
-+#ifndef DEFAULT_POLLMASK
-+# define DEFAULT_POLLMASK (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)
-+#endif /* not DEFAULT_POLLMASK */
-+
-+/* XXX: fix this so fistgen generates kfree() code directly */
-+#define kfree_s(a,b) kfree(a)
-+
-+/*
-+ * TYPEDEFS:
-+ */
-+typedef struct dentry dentry_t;
-+typedef struct file file_t;
-+typedef struct inode inode_t;
-+typedef inode_t vnode_t;
-+typedef struct page page_t;
-+typedef struct qstr qstr_t;
-+typedef struct super_block super_block_t;
-+typedef super_block_t vfs_t;
-+typedef struct vm_area_struct vm_area_t;
-+
-+
-+/*
-+ * EXTERNALS:
-+ */
-+
-+#define FPPF(str,page) printk("PPF %s 0x%x/%d: Lck:%d Err:%d Ref:%d Upd:%d Other::%d:%d:%d:%d:\n", \
-+		str, \
-+		(int) page, \
-+		(int) page->index, \
-+		(PageLocked(page) ? 1 : 0), \
-+		(PageError(page) ? 1 : 0), \
-+		(PageReferenced(page) ? 1 : 0), \
-+		(Page_Uptodate(page) ? 1 : 0), \
-+		(PageDecrAfter(page) ? 1 : 0), \
-+		(PageSlab(page) ? 1 : 0), \
-+		(PageSwapCache(page) ? 1 : 0), \
-+		(PageReserved(page) ? 1 : 0) \
-+		)
-+#define EZKDBG printk("EZK %s:%d:%s\n",__FILE__,__LINE__,__FUNCTION__)
-+#if 0
-+# define EZKDBG1 printk("EZK %s:%d\n",__FILE__,__LINE__)
-+#else
-+# define EZKDBG1
-+#endif
-+
-+extern int fist_get_debug_value(void);
-+extern int fist_set_debug_value(int val);
-+#if 0 /* mini_fo doesn't need these */
-+extern void fist_dprint_internal(int level, char *str,...);
-+extern void fist_print_dentry(char *str, const dentry_t *dentry);
-+extern void fist_print_inode(char *str, const inode_t *inode);
-+extern void fist_print_file(char *str, const file_t *file);
-+extern void fist_print_buffer_flags(char *str, struct buffer_head *buffer);
-+extern void fist_print_page_flags(char *str, page_t *page);
-+extern void fist_print_page_bytes(char *str, page_t *page);
-+extern void fist_print_pte_flags(char *str, const page_t *page);
-+extern void fist_checkinode(inode_t *inode, char *msg);
-+extern void fist_print_sb(char *str, const super_block_t *sb);
-+
-+/* §$% by mk: special debug functions */
-+extern void fist_mk_print_dentry(char *str, const dentry_t *dentry);
-+extern void fist_mk_print_inode(char *str, const inode_t *inode);
-+
-+extern char *add_indent(void);
-+extern char *del_indent(void);
-+#endif/* mini_fo doesn't need these */
-+
-+
-+#define STATIC
-+#define ASSERT(EX)	\
-+do {	\
-+    if (!(EX)) {	\
-+	printk(KERN_CRIT "ASSERTION FAILED: %s at %s:%d (%s)\n", #EX,	\
-+	       __FILE__, __LINE__, __FUNCTION__);	\
-+	(*((char *)0))=0;	\
-+    }	\
-+} while (0)
-+/* same ASSERT, but tell me who was the caller of the function */
-+#define ASSERT2(EX)	\
-+do {	\
-+    if (!(EX)) {	\
-+	printk(KERN_CRIT "ASSERTION FAILED (caller): %s at %s:%d (%s)\n", #EX,	\
-+	       file, line, func);	\
-+	(*((char *)0))=0;	\
-+    }	\
-+} while (0)
-+
-+#if 0 /* mini_fo doesn't need these */
-+#define dprintk(format, args...) printk(KERN_DEBUG format, ##args)
-+#define fist_dprint(level, str, args...) fist_dprint_internal(level, KERN_DEBUG str, ## args)
-+#define print_entry_location() fist_dprint(4, "%sIN:  %s %s:%d\n", add_indent(), __FUNCTION__, __FILE__, __LINE__)
-+#define print_exit_location() fist_dprint(4, "%s OUT: %s %s:%d\n", del_indent(), __FUNCTION__, __FILE__, __LINE__)
-+#define print_exit_status(status) fist_dprint(4, "%s OUT: %s %s:%d, STATUS: %d\n", del_indent(), __FUNCTION__, __FILE__, __LINE__, status)
-+#define print_exit_pointer(status) \
-+do { \
-+  if (IS_ERR(status)) \
-+    fist_dprint(4, "%s OUT: %s %s:%d, RESULT: %ld\n", del_indent(), __FUNCTION__, __FILE__, __LINE__, PTR_ERR(status)); \
-+  else \
-+    fist_dprint(4, "%s OUT: %s %s:%d, RESULT: 0x%x\n", del_indent(), __FUNCTION__, __FILE__, __LINE__, PTR_ERR(status)); \
-+} while (0)
-+#endif/* mini_fo doesn't need these */
-+
-+#endif /* __KERNEL__ */
-+
-+
-+/*
-+ * DEFINITIONS FOR USER AND KERNEL CODE:
-+ * (Note: ioctl numbers 1--9 are reserved for fistgen, the rest
-+ *  are auto-generated automatically based on the user's .fist file.)
-+ */
-+# define FIST_IOCTL_GET_DEBUG_VALUE	_IOR(0x15, 1, int)
-+# define FIST_IOCTL_SET_DEBUG_VALUE	_IOW(0x15, 2, int)
-+
-+#endif /* not __FIST_H_ */
---- /dev/null
-+++ b/fs/mini_fo/inode.c
-@@ -0,0 +1,1564 @@
-+/*
-+ * Copyright (c) 1997-2003 Erez Zadok
-+ * Copyright (c) 2001-2003 Stony Brook University
-+ *
-+ * For specific licensing information, see the COPYING file distributed with
-+ * this package, or get one from ftp://ftp.filesystems.org/pub/fist/COPYING.
-+ *
-+ * This Copyright notice must be kept intact and distributed with all
-+ * fistgen sources INCLUDING sources generated by fistgen.
-+ */
-+/*
-+ * Copyright (C) 2004, 2005 Markus Klotzbuecher <[email protected]>
-+ *
-+ * 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.
-+ */
-+
-+/*
-+ *  $Id$
-+ */
-+
-+#ifdef HAVE_CONFIG_H
-+# include <config.h>
-+#endif 
-+
-+#include "fist.h"
-+#include "mini_fo.h"
-+
-+STATIC int
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+mini_fo_create(inode_t *dir, dentry_t *dentry, int mode, struct nameidata *nd)
-+#else
-+mini_fo_create(inode_t *dir, dentry_t *dentry, int mode)
-+#endif
-+{
-+	int err = 0;
-+
-+	check_mini_fo_dentry(dentry);
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+	err = create_sto_reg_file(dentry, mode, nd);
-+#else
-+	err = create_sto_reg_file(dentry, mode);
-+#endif
-+	check_mini_fo_dentry(dentry);
-+	return err;
-+}
-+
-+
-+STATIC dentry_t *
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+mini_fo_lookup(inode_t *dir, dentry_t *dentry, struct nameidata* nd)
-+#else
-+mini_fo_lookup(inode_t *dir, dentry_t *dentry)
-+#endif
-+{
-+	int err = 0;
-+	dentry_t *hidden_dir_dentry;
-+	dentry_t *hidden_dentry = NULL;
-+
-+	dentry_t *hidden_sto_dir_dentry;
-+	dentry_t *hidden_sto_dentry = NULL;
-+
-+	/* whiteout flag */
-+	int del_flag = 0; 
-+	char *bpath = NULL;
-+
-+	const char *name;
-+	unsigned int namelen;
-+
-+	/* Don't allow lookups of META-files */
-+	namelen = strlen(META_FILENAME);
-+	if(namelen == dentry->d_name.len) {
-+		if(!strncmp(dentry->d_name.name, META_FILENAME, namelen)) {
-+			err = -ENOENT;
-+			goto out;
-+		}
-+	}
-+
-+	hidden_dir_dentry = dtohd(dentry->d_parent);
-+	hidden_sto_dir_dentry = dtohd2(dentry->d_parent);
-+
-+	name = dentry->d_name.name;
-+	namelen = dentry->d_name.len;
-+
-+	/* must initialize dentry operations */
-+	dentry->d_op = &mini_fo_dops;
-+
-+	/* setup the del_flag */
-+	del_flag = __meta_check_d_entry(dir, name, namelen);
-+	bpath = __meta_check_r_entry(dir, name, namelen);
-+
-+	/* perform the lookups of base and storage files:
-+	 *
-+	 * This caused some serious trouble, as a lookup_one_len passing
-+	 * a negative dentry oopses. Solution is to only do the lookup
-+	 * if the dentry is positive, else we set it to NULL
-+	 * More trouble, who said a *_dir_dentry can't be NULL?
-+	 */
-+	if(bpath) {
-+		/* Cross-Interposing (C), yeah! */
-+		hidden_dentry = bpath_walk(dir->i_sb, bpath);
-+		if(!hidden_dentry || !hidden_dentry->d_inode) {
-+			printk(KERN_CRIT "mini_fo_lookup: bpath_walk failed.\n");
-+			err= -EINVAL;
-+			goto out;
-+		}
-+		
-+		/* this can be set up safely without fear of spaghetti
-+		 * interposing as it is only used for copying times */
-+		hidden_dir_dentry = hidden_dentry->d_parent;
-+		kfree(bpath);
-+	}
-+	else if(hidden_dir_dentry && hidden_dir_dentry->d_inode)
-+		hidden_dentry = 
-+			lookup_one_len(name, hidden_dir_dentry, namelen);
-+	else
-+		hidden_dentry = NULL;
-+
-+	if(hidden_sto_dir_dentry && hidden_sto_dir_dentry->d_inode)
-+		hidden_sto_dentry = 
-+			lookup_one_len(name, hidden_sto_dir_dentry, namelen);
-+	else
-+		hidden_sto_dentry =  NULL;
-+
-+	/* catch error in lookup */
-+	if (IS_ERR(hidden_dentry) || IS_ERR(hidden_sto_dentry)) {
-+		/* mk: we need to call dput on the dentry, whose 
-+		 * lookup_one_len operation failed, in order to avoid
-+		 * unmount trouble.
-+		 */
-+		if(IS_ERR(hidden_dentry)) {
-+			printk(KERN_CRIT "mini_fo_lookup: ERR from base dentry, lookup failed.\n");
-+			err = PTR_ERR(hidden_dentry);
-+		} else {
-+			dput(hidden_dentry);
-+		}
-+		if(IS_ERR(hidden_sto_dentry)) {
-+			printk(KERN_CRIT "mini_fo_lookup: ERR from storage dentry, lookup failed.\n");
-+			err = PTR_ERR(hidden_sto_dentry);
-+		} else {
-+			dput(hidden_sto_dentry);
-+		}
-+		goto out;
-+	}
-+
-+	/* allocate dentry private data */
-+	__dtopd(dentry) = (struct mini_fo_dentry_info *)
-+		kmalloc(sizeof(struct mini_fo_dentry_info), GFP_KERNEL);
-+	
-+	if (!dtopd(dentry)) {
-+		err = -ENOMEM;
-+		goto out_dput;
-+	}
-+
-+	/* check for different states of the mini_fo file to be looked up. */
-+	
-+	/* state 1, file has been modified */
-+	if(hidden_dentry && hidden_sto_dentry &&
-+	   hidden_dentry->d_inode && hidden_sto_dentry->d_inode && !del_flag) {
-+
-+		/* update parent directory's atime */
-+		fist_copy_attr_atime(dir, hidden_sto_dir_dentry->d_inode);
-+
-+		dtopd(dentry)->state = MODIFIED;
-+		dtohd(dentry) = hidden_dentry;
-+		dtohd2(dentry) = hidden_sto_dentry;
-+
-+		err = mini_fo_tri_interpose(hidden_dentry,
-+					    hidden_sto_dentry,
-+					    dentry, dir->i_sb, 1);
-+		if (err) {
-+			printk(KERN_CRIT "mini_fo_lookup: error interposing (state1).\n");
-+			goto out_free;
-+		}
-+		goto out;
-+	}
-+	/* state 2, file is unmodified */
-+	if(hidden_dentry && hidden_dentry->d_inode && !del_flag) {
-+
-+		fist_copy_attr_atime(dir, hidden_dir_dentry->d_inode);
-+
-+		dtopd(dentry)->state = UNMODIFIED;
-+		dtohd(dentry) = hidden_dentry;
-+		dtohd2(dentry) = hidden_sto_dentry; /* could be negative */
-+
-+		err = mini_fo_tri_interpose(hidden_dentry,
-+					    hidden_sto_dentry,
-+					    dentry, dir->i_sb, 1);
-+		if (err) {
-+			printk(KERN_CRIT "mini_fo_lookup: error interposing (state2).\n");
-+			goto out_free;
-+		}
-+		goto out;
-+	}
-+	/* state 3, file has been newly created */
-+	if(hidden_sto_dentry && hidden_sto_dentry->d_inode && !del_flag) {
-+
-+		fist_copy_attr_atime(dir, hidden_sto_dir_dentry->d_inode);
-+		dtopd(dentry)->state = CREATED;
-+		dtohd(dentry) = hidden_dentry; /* could be negative */
-+		dtohd2(dentry) = hidden_sto_dentry;
-+
-+		err = mini_fo_tri_interpose(hidden_dentry,
-+					    hidden_sto_dentry,
-+					    dentry, dir->i_sb, 1);
-+		if (err) {
-+			printk(KERN_CRIT "mini_fo_lookup: error interposing (state3).\n");
-+			goto out_free;
-+		}
-+		goto out;
-+	}
-+
-+	/* state 4, file has deleted and created again. */
-+	if(hidden_dentry && hidden_sto_dentry &&
-+	   hidden_dentry->d_inode && 
-+	   hidden_sto_dentry->d_inode && del_flag) {
-+
-+		fist_copy_attr_atime(dir, hidden_sto_dir_dentry->d_inode);
-+		dtopd(dentry)->state = DEL_REWRITTEN;
-+		dtohd(dentry) = NULL;
-+		dtohd2(dentry) = hidden_sto_dentry;
-+
-+		err = mini_fo_tri_interpose(NULL,
-+					    hidden_sto_dentry,
-+					    dentry, dir->i_sb, 1);
-+		if (err) {
-+			printk(KERN_CRIT "mini_fo_lookup: error interposing (state4).\n");
-+			goto out_free;
-+		}
-+		/* We will never need this dentry again, as the file has been
-+		 * deleted from base */
-+		dput(hidden_dentry);
-+		goto out;
-+	}
-+	/* state 5, file has been deleted in base */
-+	if(hidden_dentry && hidden_sto_dentry &&
-+	   hidden_dentry->d_inode && 
-+	   !hidden_sto_dentry->d_inode && del_flag) {
-+
-+		/* check which parents atime we need for updating */
-+		if(hidden_sto_dir_dentry->d_inode)
-+			fist_copy_attr_atime(dir, 
-+					     hidden_sto_dir_dentry->d_inode);
-+		else
-+			fist_copy_attr_atime(dir, 
-+					     hidden_dir_dentry->d_inode);
-+
-+		dtopd(dentry)->state = DELETED;
-+		dtohd(dentry) = NULL;
-+		dtohd2(dentry) = hidden_sto_dentry;
-+
-+		/* add negative dentry to dcache to speed up lookups */
-+		d_add(dentry, NULL);
-+		dput(hidden_dentry);
-+		goto out;
-+	}
-+	/* state 6, file does not exist */
-+	if(((hidden_dentry && !hidden_dentry->d_inode) ||
-+	    (hidden_sto_dentry && !hidden_sto_dentry->d_inode)) && !del_flag)
-+		{
-+			/* check which parents atime we need for updating */
-+			if(hidden_sto_dir_dentry && hidden_sto_dir_dentry->d_inode)
-+				fist_copy_attr_atime(dir, hidden_sto_dir_dentry->d_inode);
-+			else
-+				fist_copy_attr_atime(dir, hidden_dir_dentry->d_inode);
-+
-+			dtopd(dentry)->state = NON_EXISTANT;
-+			dtohd(dentry) = hidden_dentry;
-+			dtohd2(dentry) = hidden_sto_dentry;
-+			d_add(dentry, NULL);
-+			goto out;
-+		}
-+
-+	/* if we get to here, were in an invalid state. bad. */
-+	printk(KERN_CRIT "mini_fo_lookup: ERROR, meta data corruption detected.\n");
-+
-+	/* end state checking */
-+ out_free:
-+	d_drop(dentry);		/* so that our bad dentry will get destroyed */
-+	kfree(dtopd(dentry));
-+	__dtopd(dentry) = NULL;	/* be safe */
-+
-+ out_dput:
-+	if(hidden_dentry)
-+		dput(hidden_dentry);
-+	if(hidden_sto_dentry)
-+		dput(hidden_sto_dentry); /* drops usage count and marks for release */
-+
-+ out:
-+	/* initalize wol if file exists and is directory */
-+	if(dentry->d_inode) {
-+		if(S_ISDIR(dentry->d_inode->i_mode)) {
-+			itopd(dentry->d_inode)->deleted_list_size = -1;
-+			itopd(dentry->d_inode)->renamed_list_size = -1;
-+			meta_build_lists(dentry);
-+		}
-+	}
-+	return ERR_PTR(err);
-+}
-+
-+
-+STATIC int
-+mini_fo_link(dentry_t *old_dentry, inode_t *dir, dentry_t *new_dentry)
-+{
-+	int err;
-+	dentry_t *hidden_old_dentry;
-+	dentry_t *hidden_new_dentry;
-+	dentry_t *hidden_dir_dentry;
-+
-+
-+	check_mini_fo_dentry(old_dentry);
-+	check_mini_fo_dentry(new_dentry);
-+	check_mini_fo_inode(dir);
-+
-+	/* no links to directorys and existing targets target allowed */
-+	if(S_ISDIR(old_dentry->d_inode->i_mode) ||
-+	   is_mini_fo_existant(new_dentry)) {
-+		err = -EPERM;
-+		goto out;
-+	}
-+
-+	/* bring it directly from unmod to del_rew */
-+	if(dtost(old_dentry) == UNMODIFIED) {
-+		err = nondir_unmod_to_mod(old_dentry, 1);
-+		if(err) {
-+			err = -EINVAL;
-+			goto out;
-+		}
-+		err = meta_add_d_entry(old_dentry->d_parent,
-+				       old_dentry->d_name.name,
-+				       old_dentry->d_name.len);
-+		if(err) {
-+			err = -EINVAL;
-+			goto out;
-+		}
-+		dput(dtohd(old_dentry));
-+		dtohd(old_dentry) = NULL;
-+		dtost(old_dentry) = DEL_REWRITTEN;
-+	}
-+	
-+	err = get_neg_sto_dentry(new_dentry);
-+	if(err) {
-+		err = -EINVAL;
-+		goto out;
-+	}
-+
-+	hidden_old_dentry = dtohd2(old_dentry);
-+	hidden_new_dentry = dtohd2(new_dentry);
-+
-+	dget(hidden_old_dentry);
-+	dget(hidden_new_dentry);
-+
-+	/* was: hidden_dir_dentry = lock_parent(hidden_new_dentry); */
-+	hidden_dir_dentry = dget(hidden_new_dentry->d_parent);
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+	mutex_lock(&hidden_dir_dentry->d_inode->i_mutex);
-+#else
-+	down(&hidden_dir_dentry->d_inode->i_sem);
-+#endif
-+
-+	err = vfs_link(hidden_old_dentry,
-+		       hidden_dir_dentry->d_inode,
-+		       hidden_new_dentry);
-+	if (err || !hidden_new_dentry->d_inode)
-+		goto out_lock;
-+
-+	dtost(new_dentry) = CREATED;
-+ 	err = mini_fo_tri_interpose(NULL, hidden_new_dentry, new_dentry, dir->i_sb, 0);
-+	if (err)
-+		goto out_lock;
-+
-+	fist_copy_attr_timesizes(dir, hidden_new_dentry->d_inode);
-+	/* propagate number of hard-links */
-+	old_dentry->d_inode->i_nlink = itohi2(old_dentry->d_inode)->i_nlink;
-+
-+ out_lock:
-+	/* was: unlock_dir(hidden_dir_dentry); */
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+	mutex_unlock(&hidden_dir_dentry->d_inode->i_mutex);
-+#else
-+	up(&hidden_dir_dentry->d_inode->i_sem);
-+#endif
-+	dput(hidden_dir_dentry);
-+
-+	dput(hidden_new_dentry);
-+	dput(hidden_old_dentry);
-+	if (!new_dentry->d_inode)
-+		d_drop(new_dentry);
-+
-+ out:
-+	return err;
-+}
-+
-+
-+STATIC int
-+mini_fo_unlink(inode_t *dir, dentry_t *dentry)
-+{
-+	int err = 0;
-+
-+	dget(dentry);
-+	if(dtopd(dentry)->state == MODIFIED) {
-+		err = nondir_mod_to_del(dentry);
-+		goto out;
-+	}
-+	else if(dtopd(dentry)->state == UNMODIFIED) {
-+		err = nondir_unmod_to_del(dentry);
-+		goto out;
-+	}
-+	else if(dtopd(dentry)->state == CREATED) {
-+		err = nondir_creat_to_del(dentry);
-+		goto out;
-+	}
-+	else if(dtopd(dentry)->state == DEL_REWRITTEN) {
-+		err = nondir_del_rew_to_del(dentry);
-+		goto out;
-+	}
-+
-+	printk(KERN_CRIT "mini_fo_unlink: ERROR, invalid state detected.\n");
-+
-+ out:
-+	fist_copy_attr_times(dir, itohi2(dentry->d_parent->d_inode));
-+
-+	if(!err) {
-+		/* is this causing my pain? d_delete(dentry); */
-+		d_drop(dentry);
-+	}
-+
-+	dput(dentry);
-+	return err;
-+}
-+
-+
-+STATIC int
-+mini_fo_symlink(inode_t *dir, dentry_t *dentry, const char *symname)
-+{
-+	int err=0;
-+	dentry_t *hidden_sto_dentry;
-+	dentry_t *hidden_sto_dir_dentry;
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+        umode_t mode;
-+#endif
-+
-+	/* Fail if the symlink file exists */
-+	if(!(dtost(dentry) == DELETED || 
-+	     dtost(dentry) == NON_EXISTANT)) {
-+		err = -EEXIST;
-+		goto out;
-+	}
-+
-+	err = get_neg_sto_dentry(dentry);
-+	if(err) {
-+		err = -EINVAL;
-+		goto out;
-+	}
-+	hidden_sto_dentry = dtohd2(dentry);
-+
-+	dget(hidden_sto_dentry);
-+	/* was: hidden_sto_dir_dentry = lock_parent(hidden_sto_dentry); */
-+	hidden_sto_dir_dentry = dget(hidden_sto_dentry->d_parent);
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+	mutex_lock(&hidden_sto_dir_dentry->d_inode->i_mutex);
-+#else
-+	down(&hidden_sto_dir_dentry->d_inode->i_sem);
-+#endif
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+	mode = S_IALLUGO;
-+	err = vfs_symlink(hidden_sto_dir_dentry->d_inode,
-+			  hidden_sto_dentry, symname, mode);
-+#else
-+	err = vfs_symlink(hidden_sto_dir_dentry->d_inode,
-+			  hidden_sto_dentry,
-+			  symname);
-+#endif
-+	if (err || !hidden_sto_dentry->d_inode)
-+                goto out_lock;
-+
-+        if(dtost(dentry) == DELETED) {
-+                dtost(dentry) = DEL_REWRITTEN;
-+                err = mini_fo_tri_interpose(NULL, hidden_sto_dentry, dentry, dir->i_sb, 0);
-+                if(err)
-+                        goto out_lock;
-+        } else if(dtost(dentry) == NON_EXISTANT) {
-+                dtost(dentry) = CREATED;
-+                err = mini_fo_tri_interpose(dtohd(dentry), hidden_sto_dentry, dentry, dir->i_sb, 0);
-+                if(err)
-+                        goto out_lock;
-+        }
-+	fist_copy_attr_timesizes(dir, hidden_sto_dir_dentry->d_inode);
-+	
-+ out_lock:
-+        /* was: unlock_dir(hidden_sto_dir_dentry); */
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+	mutex_unlock(&hidden_sto_dir_dentry->d_inode->i_mutex);
-+#else
-+	up(&hidden_sto_dir_dentry->d_inode->i_sem);
-+#endif
-+	dput(hidden_sto_dir_dentry);
-+
-+        dput(hidden_sto_dentry);
-+        if (!dentry->d_inode)
-+                d_drop(dentry);
-+ out:
-+        return err;
-+}
-+
-+STATIC int
-+mini_fo_mkdir(inode_t *dir, dentry_t *dentry, int mode)
-+{
-+	int err;
-+
-+	err = create_sto_dir(dentry, mode);
-+
-+	check_mini_fo_dentry(dentry);
-+
-+	return err;
-+}
-+
-+
-+STATIC int
-+mini_fo_rmdir(inode_t *dir, dentry_t *dentry)
-+{
-+	int err = 0;
-+	
-+	dentry_t *hidden_sto_dentry;
-+	dentry_t *hidden_sto_dir_dentry;
-+	dentry_t *meta_dentry;
-+	inode_t *hidden_sto_dir = NULL;
-+
-+	check_mini_fo_dentry(dentry);
-+	check_mini_fo_inode(dir);
-+
-+	dget(dentry);
-+	if(dtopd(dentry)->state == MODIFIED) {
-+		/* XXX: disabled, because it does not bother to check files on
-+		 * the original filesystem - just a hack, but better than simply
-+		 * removing it without testing */
-+		err = -EINVAL;
-+		goto out;
-+
-+		hidden_sto_dir = itohi2(dir);
-+		hidden_sto_dentry = dtohd2(dentry);
-+
-+		/* was:hidden_sto_dir_dentry = lock_parent(hidden_sto_dentry); */
-+		hidden_sto_dir_dentry = dget(hidden_sto_dentry->d_parent);
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+		mutex_lock(&hidden_sto_dir_dentry->d_inode->i_mutex);
-+#else
-+		down(&hidden_sto_dir_dentry->d_inode->i_sem);
-+#endif
-+
-+		/* Delete an old WOL file contained in the storage dir */
-+		meta_dentry = lookup_one_len(META_FILENAME, 
-+					     hidden_sto_dentry, 
-+					     strlen(META_FILENAME));
-+		if(meta_dentry->d_inode) {
-+			err = vfs_unlink(hidden_sto_dentry->d_inode, meta_dentry);
-+			dput(meta_dentry);
-+			if(!err)
-+				d_delete(meta_dentry);
-+		}
-+
-+		err = vfs_rmdir(hidden_sto_dir, hidden_sto_dentry);
-+		dput(hidden_sto_dentry);
-+		if(!err)
-+			d_delete(hidden_sto_dentry);
-+
-+		/* propagate number of hard-links */
-+		dentry->d_inode->i_nlink = itohi2(dentry->d_inode)->i_nlink;
-+
-+		dput(dtohd(dentry));
-+		
-+		dtohd(dentry) = NULL;
-+		dtopd(dentry)->state = DELETED;
-+
-+		/* carefull with R files */
-+		if( __meta_is_r_entry(dir, 
-+				      dentry->d_name.name, 
-+				      dentry->d_name.len) == 1) {
-+			err = meta_remove_r_entry(dentry->d_parent, 
-+						  dentry->d_name.name,
-+						  dentry->d_name.len);
-+			if(err) {
-+				printk(KERN_CRIT "mini_fo: rmdir: meta_remove_r_entry failed.\n");
-+				goto out;
-+			}
-+		}
-+		else {
-+			/* ok, add deleted file to META */		
-+			meta_add_d_entry(dentry->d_parent, 
-+					 dentry->d_name.name, 
-+					 dentry->d_name.len);
-+		}
-+		/* was: unlock_dir(hidden_sto_dir_dentry); */
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+		mutex_unlock(&hidden_sto_dir_dentry->d_inode->i_mutex);
-+#else
-+		up(&hidden_sto_dir_dentry->d_inode->i_sem);
-+#endif
-+		dput(hidden_sto_dir_dentry);
-+		goto out;
-+	}
-+	else if(dtopd(dentry)->state == UNMODIFIED) {
-+		/* XXX: simply adding it to the delete list here is fscking dangerous!
-+		 * as a temporary hack, i will disable rmdir on unmodified directories 
-+		 * for now.
-+		 */
-+		err = -EINVAL;
-+		goto out;
-+
-+		err = get_neg_sto_dentry(dentry);
-+		if(err) {
-+			err = -EINVAL;
-+			goto out;
-+		}
-+		
-+		/* dput base dentry, this will relase the inode and free the
-+		 * dentry, as we will never need it again. */
-+		dput(dtohd(dentry));
-+		dtohd(dentry) = NULL;
-+		dtopd(dentry)->state = DELETED;
-+
-+		/* add deleted file to META-file */
-+		meta_add_d_entry(dentry->d_parent, 
-+				 dentry->d_name.name, 
-+				 dentry->d_name.len);
-+		goto out;
-+	}
-+	else if(dtopd(dentry)->state == CREATED) {
-+		hidden_sto_dir = itohi2(dir);
-+		hidden_sto_dentry = dtohd2(dentry);
-+
-+		/* was: hidden_sto_dir_dentry = lock_parent(hidden_sto_dentry);*/
-+		hidden_sto_dir_dentry = dget(hidden_sto_dentry->d_parent);
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+		mutex_lock(&hidden_sto_dir_dentry->d_inode->i_mutex);
-+#else
-+		down(&hidden_sto_dir_dentry->d_inode->i_sem);
-+#endif
-+
-+		/* Delete an old WOL file contained in the storage dir */
-+		meta_dentry = lookup_one_len(META_FILENAME, 
-+					     hidden_sto_dentry, 
-+					     strlen(META_FILENAME));
-+		if(meta_dentry->d_inode) {
-+			/* is this necessary? dget(meta_dentry); */
-+			err = vfs_unlink(hidden_sto_dentry->d_inode, 
-+					 meta_dentry);
-+			dput(meta_dentry);
-+			if(!err)
-+				d_delete(meta_dentry);
-+		}
-+
-+		err = vfs_rmdir(hidden_sto_dir, hidden_sto_dentry);
-+		dput(hidden_sto_dentry);
-+		if(!err)
-+			d_delete(hidden_sto_dentry);
-+
-+		/* propagate number of hard-links */
-+		dentry->d_inode->i_nlink = itohi2(dentry->d_inode)->i_nlink;
-+		dtopd(dentry)->state = NON_EXISTANT;
-+
-+		/* was: unlock_dir(hidden_sto_dir_dentry); */
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+		mutex_unlock(&hidden_sto_dir_dentry->d_inode->i_mutex);
-+#else
-+		up(&hidden_sto_dir_dentry->d_inode->i_sem);
-+#endif
-+		dput(hidden_sto_dir_dentry);
-+
-+		goto out;
-+	}
-+	else if(dtopd(dentry)->state == DEL_REWRITTEN) {
-+		hidden_sto_dir = itohi2(dir);
-+		hidden_sto_dentry = dtohd2(dentry);
-+
-+		/* was: hidden_sto_dir_dentry = lock_parent(hidden_sto_dentry);*/
-+		hidden_sto_dir_dentry = dget(hidden_sto_dentry->d_parent);
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+		mutex_lock(&hidden_sto_dir_dentry->d_inode->i_mutex);
-+#else
-+		down(&hidden_sto_dir_dentry->d_inode->i_sem);
-+#endif
-+
-+		/* Delete an old WOL file contained in the storage dir */
-+		meta_dentry = lookup_one_len(META_FILENAME, 
-+					     hidden_sto_dentry, 
-+					     strlen(META_FILENAME));
-+		if(meta_dentry->d_inode) {
-+			/* is this necessary? dget(meta_dentry); */
-+			err = vfs_unlink(hidden_sto_dentry->d_inode,
-+					 meta_dentry);
-+			dput(meta_dentry);
-+			if(!err)
-+				d_delete(meta_dentry);
-+		}
-+
-+		err = vfs_rmdir(hidden_sto_dir, hidden_sto_dentry);
-+		dput(hidden_sto_dentry);
-+		if(!err)
-+			d_delete(hidden_sto_dentry);
-+
-+		/* propagate number of hard-links */
-+		dentry->d_inode->i_nlink = itohi2(dentry->d_inode)->i_nlink;
-+		dtopd(dentry)->state = DELETED;
-+		/* was: unlock_dir(hidden_sto_dir_dentry); */
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+		mutex_unlock(&hidden_sto_dir_dentry->d_inode->i_mutex);
-+#else
-+		up(&hidden_sto_dir_dentry->d_inode->i_sem);
-+#endif
-+		dput(hidden_sto_dir_dentry);
-+		goto out;
-+	}
-+
-+	printk(KERN_CRIT "mini_fo_rmdir: ERROR, invalid state detected.\n");
-+
-+ out:
-+	if(!err) {
-+		d_drop(dentry);
-+	}
-+		
-+	fist_copy_attr_times(dir, itohi2(dentry->d_parent->d_inode));
-+	dput(dentry);
-+
-+	return err;
-+}
-+
-+
-+STATIC int
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+mini_fo_mknod(inode_t *dir, dentry_t *dentry, int mode, dev_t dev)
-+#else
-+mini_fo_mknod(inode_t *dir, dentry_t *dentry, int mode, int dev)
-+#endif
-+{
-+	int err = 0;
-+
-+	check_mini_fo_dentry(dentry);
-+
-+	err = create_sto_nod(dentry, mode, dev);
-+	if(err) {
-+		printk(KERN_CRIT "mini_fo_mknod: creating sto nod failed.\n");
-+		err = -EINVAL;
-+	}
-+	
-+	check_mini_fo_dentry(dentry);
-+	return err;
-+}
-+
-+
-+STATIC int
-+mini_fo_rename(inode_t *old_dir, dentry_t *old_dentry,
-+	       inode_t *new_dir, dentry_t *new_dentry)
-+{
-+	/* dispatch */
-+	if(S_ISDIR(old_dentry->d_inode->i_mode))
-+		return rename_directory(old_dir, old_dentry, new_dir, new_dentry);
-+	return rename_nondir(old_dir, old_dentry, new_dir, new_dentry);
-+	
-+}
-+
-+int rename_directory(inode_t *old_dir, dentry_t *old_dentry,
-+		     inode_t *new_dir, dentry_t *new_dentry)
-+{
-+	int err, bpath_len;
-+	char *bpath;
-+
-+	dentry_t *hidden_old_dentry;
-+	dentry_t *hidden_new_dentry;
-+	dentry_t *hidden_old_dir_dentry;
-+	dentry_t *hidden_new_dir_dentry;
-+
-+	err = 0;
-+	bpath = NULL;
-+	bpath_len = 0;
-+
-+	/* this is a test, chuck out if it works */
-+	if(!(dtopd(new_dentry)->state == DELETED ||
-+	     dtopd(new_dentry)->state == NON_EXISTANT)) {
-+		printk(KERN_CRIT "mini_fo: rename_directory: \
-+                                  uh, ah, new_dentry not negative.\n");
-+		/* return -1; */
-+	}
-+	
-+	/* state = UNMODIFIED */
-+	if(dtopd(old_dentry)->state == UNMODIFIED) {
-+		err = dir_unmod_to_mod(old_dentry);
-+		if (err) 
-+			goto out;
-+	}
-+
-+	/* state = MODIFIED */
-+	if(dtopd(old_dentry)->state == MODIFIED) {
-+		bpath = meta_check_r_entry(old_dentry->d_parent, 
-+					   old_dentry->d_name.name,
-+					   old_dentry->d_name.len);
-+		if(bpath) {
-+			err = meta_remove_r_entry(old_dentry->d_parent,
-+						  old_dentry->d_name.name,
-+						  old_dentry->d_name.len);
-+			if(err) {
-+				printk(KERN_CRIT "mini_fo: rename_directory:\
-+                                                   meta_remove_r_entry \
-+                                                  failed.\n");
-+				goto out;
-+			}
-+			err = meta_add_r_entry(new_dentry->d_parent,
-+					       bpath,
-+					       strlen(bpath),
-+					       new_dentry->d_name.name,
-+					       new_dentry->d_name.len);
-+			kfree(bpath);
-+		}
-+		else {/* wol it */
-+			err = meta_add_d_entry(old_dentry->d_parent, 
-+					       old_dentry->d_name.name,
-+					       old_dentry->d_name.len);
-+			if (err) 
-+				goto out;
-+			/* put it on rename list */
-+			err = get_mini_fo_bpath(old_dentry,
-+						&bpath, 
-+						&bpath_len);
-+			if (err) 
-+				goto out;
-+			err = meta_add_r_entry(new_dentry->d_parent,
-+					       bpath, bpath_len,
-+					       new_dentry->d_name.name,
-+					       new_dentry->d_name.len);
-+			if (err) 
-+				goto out;
-+		}
-+		/* no state change, MODIFIED stays MODIFIED */
-+	}
-+	/* state = CREATED */
-+	if(dtopd(old_dentry)->state == CREATED ||
-+	   dtopd(old_dentry)->state == DEL_REWRITTEN) {
-+		if(dtohd(old_dentry))
-+			dput(dtohd(old_dentry));
-+		
-+		if(dtopd(new_dentry)->state == DELETED) {
-+			dtopd(old_dentry)->state = DEL_REWRITTEN;
-+			dtohd(old_dentry) = NULL;
-+		} 
-+		else if(dtopd(new_dentry)->state == NON_EXISTANT) {
-+			dtopd(old_dentry)->state = CREATED;
-+			/* steal new dentry's neg. base dentry */
-+			dtohd(old_dentry) = dtohd(new_dentry);
-+			dtohd(new_dentry) = NULL;
-+		}
-+	}		
-+	if(dtopd(new_dentry)->state == UNMODIFIED ||
-+	   dtopd(new_dentry)->state == NON_EXISTANT) {
-+		err = get_neg_sto_dentry(new_dentry);
-+		if(err)
-+			goto out;
-+	}
-+			
-+	/* now move sto file */
-+	hidden_old_dentry = dtohd2(old_dentry);
-+	hidden_new_dentry = dtohd2(new_dentry);
-+	
-+	dget(hidden_old_dentry);
-+	dget(hidden_new_dentry);
-+	
-+	hidden_old_dir_dentry = dget(hidden_old_dentry->d_parent);
-+	hidden_new_dir_dentry = dget(hidden_new_dentry->d_parent);
-+	double_lock(hidden_old_dir_dentry, hidden_new_dir_dentry);
-+	
-+	err = vfs_rename(hidden_old_dir_dentry->d_inode, hidden_old_dentry,
-+			 hidden_new_dir_dentry->d_inode, hidden_new_dentry);
-+	if(err)
-+		goto out_lock;
-+	
-+	fist_copy_attr_all(new_dir, hidden_new_dir_dentry->d_inode);
-+	if (new_dir != old_dir)
-+		fist_copy_attr_all(old_dir, 
-+				   hidden_old_dir_dentry->d_inode);
-+	
-+ out_lock:
-+	/* double_unlock will dput the new/old parent dentries
-+	 * whose refcnts were incremented via get_parent above. */
-+	double_unlock(hidden_old_dir_dentry, hidden_new_dir_dentry);
-+	dput(hidden_new_dentry);
-+	dput(hidden_old_dentry);
-+	
-+ out:
-+	return err;
-+}
-+
-+int rename_nondir(inode_t *old_dir, dentry_t *old_dentry,
-+		  inode_t *new_dir, dentry_t *new_dentry)
-+{
-+	int err=0;
-+
-+	check_mini_fo_dentry(old_dentry);
-+	check_mini_fo_dentry(new_dentry);
-+	check_mini_fo_inode(old_dir);
-+	check_mini_fo_inode(new_dir);
-+
-+	/* state: UNMODIFIED */
-+	if(dtost(old_dentry) == UNMODIFIED) {
-+		err = nondir_unmod_to_mod(old_dentry, 1);
-+		if(err) {
-+			err = -EINVAL;
-+			goto out;
-+		}
-+	}
-+
-+	/* the easy states */
-+	if(exists_in_storage(old_dentry)) {
-+		
-+		dentry_t *hidden_old_dentry;
-+		dentry_t *hidden_new_dentry;
-+		dentry_t *hidden_old_dir_dentry;
-+		dentry_t *hidden_new_dir_dentry;
-+
-+		/* if old file is MODIFIED, add it to the deleted_list */
-+		if(dtopd(old_dentry)->state == MODIFIED) {
-+			meta_add_d_entry(old_dentry->d_parent,
-+					 old_dentry->d_name.name,
-+					 old_dentry->d_name.len);
-+
-+			dput(dtohd(old_dentry));
-+		}
-+		/* if old file is CREATED, we only release the base dentry */
-+		if(dtopd(old_dentry)->state == CREATED) {
-+			if(dtohd(old_dentry))
-+				dput(dtohd(old_dentry));
-+		}
-+
-+		/* now setup the new states (depends on new_dentry state) */
-+		/* new dentry state =  MODIFIED */
-+		if(dtopd(new_dentry)->state == MODIFIED) {
-+			meta_add_d_entry(new_dentry->d_parent,
-+					 new_dentry->d_name.name,
-+					 new_dentry->d_name.len);
-+
-+			/* new dentry will be d_put'ed later by the vfs
-+			 * so don't do it here
-+			 * dput(dtohd(new_dentry));
-+			 */
-+			dtohd(old_dentry) = NULL;
-+			dtopd(old_dentry)->state = DEL_REWRITTEN;
-+		}
-+		/* new dentry state =  UNMODIFIED */
-+		else if(dtopd(new_dentry)->state == UNMODIFIED) {
-+			if(get_neg_sto_dentry(new_dentry))
-+				return -EINVAL;
-+
-+			meta_add_d_entry(new_dentry->d_parent,
-+					 new_dentry->d_name.name,
-+					 new_dentry->d_name.len);
-+
-+			/* is this right??? */
-+			/*dput(dtohd(new_dentry));*/
-+			dtohd(old_dentry) = NULL;
-+			dtopd(old_dentry)->state = DEL_REWRITTEN;
-+		}
-+		/* new dentry state =  CREATED */
-+		else if(dtopd(new_dentry)->state == CREATED) {
-+			/* we keep the neg. base dentry (if exists) */
-+			dtohd(old_dentry) = dtohd(new_dentry);
-+			/* ...and set it to Null, or we'll get
-+			 * dcache.c:345 if it gets dput twice... */
-+			dtohd(new_dentry) = NULL;
-+			dtopd(old_dentry)->state = CREATED;
-+		}
-+		/* new dentry state =  NON_EXISTANT */
-+		else if(dtopd(new_dentry)->state == NON_EXISTANT) {
-+			if(get_neg_sto_dentry(new_dentry))
-+				return -EINVAL;
-+
-+			/* we keep the neg. base dentry (if exists) */
-+			dtohd(old_dentry) = dtohd(new_dentry);
-+			/* ...and set it to Null, or we'll get 
-+			 * Dr. dcache.c:345 if it gets dput twice... */
-+			dtohd(new_dentry) = NULL;
-+			dtopd(old_dentry)->state = CREATED;
-+		}
-+		/* new dentry state =  DEL_REWRITTEN or DELETED */
-+		else if(dtopd(new_dentry)->state == DEL_REWRITTEN ||
-+			dtopd(new_dentry)->state == DELETED) {
-+			dtohd(old_dentry) = NULL;
-+			dtopd(old_dentry)->state = DEL_REWRITTEN;
-+		}
-+		else { /* not possible, uhh, ahh */
-+			printk(KERN_CRIT 
-+			       "mini_fo: rename_reg_file: invalid state detected [1].\n");
-+			return -1;
-+		}
-+		
-+		/* now we definitely have a sto file */
-+		hidden_old_dentry = dtohd2(old_dentry);
-+		hidden_new_dentry = dtohd2(new_dentry);
-+
-+		dget(hidden_old_dentry);
-+		dget(hidden_new_dentry);
-+		
-+		hidden_old_dir_dentry = dget(hidden_old_dentry->d_parent);
-+		hidden_new_dir_dentry = dget(hidden_new_dentry->d_parent);
-+		double_lock(hidden_old_dir_dentry, hidden_new_dir_dentry);
-+
-+		err = vfs_rename(hidden_old_dir_dentry->d_inode, 
-+				 hidden_old_dentry,
-+				 hidden_new_dir_dentry->d_inode, 
-+				 hidden_new_dentry);
-+		if(err) 
-+			goto out_lock;
-+
-+		fist_copy_attr_all(new_dir, hidden_new_dir_dentry->d_inode);
-+		if (new_dir != old_dir)
-+			fist_copy_attr_all(old_dir, hidden_old_dir_dentry->d_inode);
-+		
-+	out_lock:
-+		/* double_unlock will dput the new/old parent dentries 
-+		 * whose refcnts were incremented via get_parent above.
-+		 */
-+		double_unlock(hidden_old_dir_dentry, hidden_new_dir_dentry);
-+		dput(hidden_new_dentry);
-+		dput(hidden_old_dentry);
-+	out:		
-+		return err;
-+	}
-+	else { /* invalid state */
-+		printk(KERN_CRIT "mini_fo: rename_reg_file: ERROR: invalid state detected [2].\n");
-+		return -1;
-+	}
-+}
-+
-+
-+STATIC int
-+mini_fo_readlink(dentry_t *dentry, char *buf, int bufsiz)
-+{
-+	int err=0;
-+	dentry_t *hidden_dentry = NULL;
-+
-+	if(dtohd2(dentry) && dtohd2(dentry)->d_inode) {
-+		hidden_dentry = dtohd2(dentry);
-+	} else if(dtohd(dentry) && dtohd(dentry)->d_inode) {
-+		hidden_dentry = dtohd(dentry);
-+	} else {
-+		goto out;
-+	}
-+
-+	if (!hidden_dentry->d_inode->i_op ||
-+	    !hidden_dentry->d_inode->i_op->readlink) {
-+		err = -EINVAL;		goto out;
-+	}
-+
-+	err = hidden_dentry->d_inode->i_op->readlink(hidden_dentry,
-+						     buf,
-+						     bufsiz);
-+	if (err > 0)
-+		fist_copy_attr_atime(dentry->d_inode, hidden_dentry->d_inode);
-+
-+ out:
-+	return err;
-+}
-+
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13)
-+static int mini_fo_follow_link(dentry_t *dentry, struct nameidata *nd)
-+#else
-+static void* mini_fo_follow_link(dentry_t *dentry, struct nameidata *nd)
-+#endif
-+{
-+	char *buf;
-+	int len = PAGE_SIZE, err;
-+	mm_segment_t old_fs;
-+
-+	/* in 2.6 this is freed by mini_fo_put_link called by __do_follow_link */
-+	buf = kmalloc(len, GFP_KERNEL);
-+	if (!buf) {
-+		err = -ENOMEM;
-+		goto out;
-+	}
-+
-+	/* read the symlink, and then we will follow it */
-+	old_fs = get_fs();
-+	set_fs(KERNEL_DS);
-+	err = dentry->d_inode->i_op->readlink(dentry, buf, len);
-+	set_fs(old_fs);
-+	if (err < 0) {
-+		kfree(buf);
-+		buf = NULL;
-+		goto out;
-+	}
-+	buf[err] = 0;
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+        nd_set_link(nd, buf);
-+        err = 0;
-+#else
-+	err = vfs_follow_link(nd, buf);
-+#endif
-+
-+ out:
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-+	kfree(buf);
-+#endif
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13)
-+        return err;
-+#else
-+        return ERR_PTR(err);
-+#endif
-+}
-+
-+STATIC
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13)
-+void mini_fo_put_link(struct dentry *dentry, struct nameidata *nd)
-+#else
-+void mini_fo_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
-+#endif
-+{
-+        char *link;
-+        link = nd_get_link(nd);
-+        kfree(link);
-+}
-+#endif
-+
-+STATIC int
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+mini_fo_permission(inode_t *inode, int mask, struct nameidata *nd)
-+#else
-+mini_fo_permission(inode_t *inode, int mask)
-+#endif
-+{
-+	inode_t *hidden_inode;
-+	int mode;
-+	int err;
-+
-+	if(itohi2(inode)) {
-+		hidden_inode = itohi2(inode);
-+	} else {
-+		hidden_inode = itohi(inode);
-+	}
-+	mode = inode->i_mode;
-+
-+	/* not really needed, as permission handles everything:
-+	 *	err = vfs_permission(inode, mask);
-+	 *	if (err)
-+	 *		goto out;
-+	 */
-+	
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+	err = permission(hidden_inode, mask, nd);
-+#else
-+	err = permission(hidden_inode, mask);
-+#endif
-+	
-+	/*  out: */
-+	return err;
-+}
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-+STATIC int
-+mini_fo_inode_revalidate(dentry_t *dentry)
-+{
-+	int err = 0;
-+	dentry_t *hidden_dentry;
-+	inode_t *hidden_inode;
-+
-+	ASSERT(dentry->d_inode);
-+	ASSERT(itopd(dentry->d_inode));
-+
-+	if(itohi2(dentry->d_inode)) {
-+                hidden_dentry = dtohd2(dentry);
-+		hidden_inode = hidden_dentry->d_inode;
-+	} else if(itohi(dentry->d_inode)) {
-+                hidden_dentry = dtohd(dentry);
-+		hidden_inode = hidden_dentry->d_inode;
-+	} else {
-+                printk(KERN_CRIT "mini_fo_inode_revalidate: ERROR, invalid state detected.\n");
-+                err = -ENOENT;
-+                goto out;
-+        }
-+	if (hidden_inode && hidden_inode->i_op && hidden_inode->i_op->revalidate){
-+		err = hidden_inode->i_op->revalidate(hidden_dentry);
-+		if (err)
-+			goto out;
-+	}
-+	fist_copy_attr_all(dentry->d_inode, hidden_inode);
-+ out:
-+	return err;
-+}
-+#endif
-+
-+STATIC int
-+mini_fo_setattr(dentry_t *dentry, struct iattr *ia)
-+{
-+	int err = 0;
-+
-+	check_mini_fo_dentry(dentry);
-+	
-+	if(!is_mini_fo_existant(dentry)) {
-+		printk(KERN_CRIT "mini_fo_setattr: ERROR, invalid state detected [1].\n");
-+		goto out;
-+	}
-+
-+	if(dtost(dentry) == UNMODIFIED) {
-+		if(!IS_COPY_FLAG(ia->ia_valid))
-+			goto out; /* we ignore these changes to base */
-+
-+		if(S_ISDIR(dentry->d_inode->i_mode)) {
-+			err = dir_unmod_to_mod(dentry);
-+		} else {
-+			/* we copy contents if file is not beeing truncated */
-+			if(S_ISREG(dentry->d_inode->i_mode) && 
-+			   !(ia->ia_size == 0 && (ia->ia_valid & ATTR_SIZE))) {
-+				err = nondir_unmod_to_mod(dentry, 1);
-+			} else
-+				err = nondir_unmod_to_mod(dentry, 0);
-+		}
-+		if(err) {
-+			err = -EINVAL;
-+			printk(KERN_CRIT "mini_fo_setattr: ERROR changing states.\n");
-+			goto out;
-+		}
-+	}
-+	if(!exists_in_storage(dentry)) {
-+		printk(KERN_CRIT "mini_fo_setattr: ERROR, invalid state detected [2].\n");
-+		err = -EINVAL;
-+		goto out;
-+	}
-+	ASSERT(dentry->d_inode);
-+	ASSERT(dtohd2(dentry));
-+	ASSERT(itopd(dentry->d_inode));
-+	ASSERT(itohi2(dentry->d_inode));
-+	
-+	err = notify_change(dtohd2(dentry), ia);
-+	fist_copy_attr_all(dentry->d_inode, itohi2(dentry->d_inode));
-+ out:
-+	return err;
-+}
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+STATIC int
-+mini_fo_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
-+{
-+	int err = 0;
-+        dentry_t *hidden_dentry;
-+
-+	ASSERT(dentry->d_inode);
-+	ASSERT(itopd(dentry->d_inode));
-+
-+	if(itohi2(dentry->d_inode)) {
-+                hidden_dentry = dtohd2(dentry);
-+	} else if(itohi(dentry->d_inode)) {
-+                hidden_dentry = dtohd(dentry);
-+	} else {
-+                printk(KERN_CRIT "mini_fo_getattr: ERROR, invalid state detected.\n");
-+                err = -ENOENT;
-+                goto out;
-+        }
-+	fist_copy_attr_all(dentry->d_inode, hidden_dentry->d_inode);
-+
-+	ASSERT(hidden_dentry);
-+	ASSERT(hidden_dentry->d_inode);
-+	ASSERT(hidden_dentry->d_inode->i_op);
-+
-+	generic_fillattr(dentry->d_inode, stat);
-+	if (!stat->blksize) {
-+		struct super_block *s = hidden_dentry->d_inode->i_sb;
-+		unsigned blocks;
-+		blocks = (stat->size+s->s_blocksize-1) >> s->s_blocksize_bits;
-+		stat->blocks = (s->s_blocksize / 512) * blocks;
-+		stat->blksize = s->s_blocksize;
-+	}
-+ out:
-+        return err;
-+}
-+#endif
-+
-+#if defined(XATTR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20))
-+#if 0 /* no xattr_alloc() and xattr_free() */
-+/* This is lifted from fs/xattr.c */
-+static void *
-+xattr_alloc(size_t size, size_t limit)
-+{
-+	void *ptr;
-+
-+	if (size > limit)
-+		return ERR_PTR(-E2BIG);
-+
-+	if (!size)	/* size request, no buffer is needed */
-+		return NULL;
-+	else if (size <= PAGE_SIZE)
-+		ptr = kmalloc((unsigned long) size, GFP_KERNEL);
-+	else
-+		ptr = vmalloc((unsigned long) size);
-+	if (!ptr)
-+		return ERR_PTR(-ENOMEM);
-+	return ptr;
-+}
-+
-+static void
-+xattr_free(void *ptr, size_t size)
-+{
-+	if (!size)	/* size request, no buffer was needed */
-+		return;
-+	else if (size <= PAGE_SIZE)
-+		kfree(ptr);
-+	else
-+		vfree(ptr);
-+}
-+#endif /* no xattr_alloc() and xattr_free() */
-+
-+/* BKL held by caller.
-+ * dentry->d_inode->i_sem down
-+ */
-+STATIC int
-+mini_fo_getxattr(struct dentry *dentry, const char *name, void *value, size_t size) {
-+	struct dentry *hidden_dentry = NULL;
-+	int err = -EOPNOTSUPP;
-+	/* Define these anyway so we don't need as much ifdef'ed code. */
-+	char *encoded_name = NULL;
-+	char *encoded_value = NULL;
-+
-+	check_mini_fo_dentry(dentry);
-+
-+	if(exists_in_storage(dentry))
-+		hidden_dentry = dtohd2(dentry);
-+	else
-+		hidden_dentry = dtohd(dentry);
-+	   
-+	ASSERT(hidden_dentry);
-+	ASSERT(hidden_dentry->d_inode);
-+	ASSERT(hidden_dentry->d_inode->i_op);
-+
-+	if (hidden_dentry->d_inode->i_op->getxattr) {
-+		encoded_name = (char *)name;
-+		encoded_value = (char *)value;
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+		mutex_lock(&hidden_dentry->d_inode->i_mutex);
-+#else
-+		down(&hidden_dentry->d_inode->i_sem);
-+#endif
-+		/* lock_kernel() already done by caller. */
-+		err = hidden_dentry->d_inode->i_op->getxattr(hidden_dentry, encoded_name, encoded_value, size);
-+		/* unlock_kernel() will be done by caller. */
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+		mutex_lock(&hidden_dentry->d_inode->i_mutex);
-+#else
-+		up(&hidden_dentry->d_inode->i_sem);
-+#endif
-+	}
-+	return err;
-+}
-+
-+/* BKL held by caller.
-+ * dentry->d_inode->i_sem down
-+ */
-+STATIC int
-+#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,21) \
-+     && LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,23)) \
-+     || LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
-+mini_fo_setxattr(struct dentry *dentry, const char *name, 
-+		 const void *value, size_t size, int flags)
-+#else
-+mini_fo_setxattr(struct dentry *dentry, const char *name, 
-+		 void *value, size_t size, int flags)
-+#endif
-+
-+{
-+	struct dentry *hidden_dentry = NULL;
-+	int err = -EOPNOTSUPP;
-+
-+	/* Define these anyway, so we don't have as much ifdef'ed code. */
-+	char *encoded_value = NULL;
-+	char *encoded_name = NULL;
-+
-+	check_mini_fo_dentry(dentry);
-+
-+	if(exists_in_storage(dentry))
-+		hidden_dentry = dtohd2(dentry);
-+	else
-+		hidden_dentry = dtohd(dentry);
-+	
-+	ASSERT(hidden_dentry);
-+	ASSERT(hidden_dentry->d_inode);
-+	ASSERT(hidden_dentry->d_inode->i_op);
-+
-+	if (hidden_dentry->d_inode->i_op->setxattr) {
-+		encoded_name = (char *)name;
-+		encoded_value = (char *)value;
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+		mutex_lock(&hidden_dentry->d_inode->i_mutex);
-+#else
-+		down(&hidden_dentry->d_inode->i_sem);
-+#endif
-+		/* lock_kernel() already done by caller. */
-+		err = hidden_dentry->d_inode->i_op->setxattr(hidden_dentry, encoded_name, encoded_value, size, flags);
-+		/* unlock_kernel() will be done by caller. */
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+		mutex_unlock(&hidden_dentry->d_inode->i_mutex);
-+#else
-+		up(&hidden_dentry->d_inode->i_sem);
-+#endif
-+	}
-+	return err;
-+}
-+
-+/* BKL held by caller.
-+ * dentry->d_inode->i_sem down
-+ */
-+STATIC int
-+mini_fo_removexattr(struct dentry *dentry, const char *name) {
-+	struct dentry *hidden_dentry = NULL;
-+	int err = -EOPNOTSUPP;
-+	char *encoded_name;
-+
-+	check_mini_fo_dentry(dentry);
-+
-+	if(exists_in_storage(dentry))
-+		hidden_dentry = dtohd2(dentry);
-+	else
-+		hidden_dentry = dtohd(dentry);
-+	
-+	ASSERT(hidden_dentry);
-+	ASSERT(hidden_dentry->d_inode);
-+	ASSERT(hidden_dentry->d_inode->i_op);
-+
-+	if (hidden_dentry->d_inode->i_op->removexattr) {
-+		encoded_name = (char *)name;
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+		mutex_lock(&hidden_dentry->d_inode->i_mutex);
-+#else
-+		down(&hidden_dentry->d_inode->i_sem);
-+#endif
-+		/* lock_kernel() already done by caller. */
-+		err = hidden_dentry->d_inode->i_op->removexattr(hidden_dentry, encoded_name);
-+		/* unlock_kernel() will be done by caller. */
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+		mutex_unlock(&hidden_dentry->d_inode->i_mutex);
-+#else
-+		up(&hidden_dentry->d_inode->i_sem);
-+#endif
-+	}
-+	return err;
-+}
-+
-+/* BKL held by caller.
-+ * dentry->d_inode->i_sem down
-+ */
-+STATIC int
-+mini_fo_listxattr(struct dentry *dentry, char *list, size_t size) {
-+	struct dentry *hidden_dentry = NULL;
-+	int err = -EOPNOTSUPP;
-+	char *encoded_list = NULL;
-+
-+	check_mini_fo_dentry(dentry);
-+
-+	if(exists_in_storage(dentry))
-+		hidden_dentry = dtohd2(dentry);
-+	else
-+		hidden_dentry = dtohd(dentry);
-+
-+	ASSERT(hidden_dentry);
-+	ASSERT(hidden_dentry->d_inode);
-+	ASSERT(hidden_dentry->d_inode->i_op);
-+
-+	if (hidden_dentry->d_inode->i_op->listxattr) {
-+		encoded_list = list;
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+		mutex_lock(&hidden_dentry->d_inode->i_mutex);
-+#else
-+		down(&hidden_dentry->d_inode->i_sem);
-+#endif
-+		/* lock_kernel() already done by caller. */
-+		err = hidden_dentry->d_inode->i_op->listxattr(hidden_dentry, encoded_list, size);
-+		/* unlock_kernel() will be done by caller. */
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+		mutex_unlock(&hidden_dentry->d_inode->i_mutex);
-+#else
-+		up(&hidden_dentry->d_inode->i_sem);
-+#endif
-+	}
-+	return err;
-+}
-+# endif /* defined(XATTR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20)) */
-+
-+struct inode_operations mini_fo_symlink_iops =
-+	{
-+		readlink:	mini_fo_readlink,
-+		follow_link: mini_fo_follow_link,
-+		/* mk: permission:	mini_fo_permission, */
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-+		revalidate:	mini_fo_inode_revalidate,
-+#endif
-+		setattr:	mini_fo_setattr,
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+		getattr:	mini_fo_getattr,
-+		put_link:       mini_fo_put_link,
-+#endif
-+
-+#if defined(XATTR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20))
-+		setxattr:	mini_fo_setxattr,
-+		getxattr:	mini_fo_getxattr,
-+		listxattr:	mini_fo_listxattr,
-+		removexattr: mini_fo_removexattr
-+# endif /* defined(XATTR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20)) */
-+	};
-+
-+struct inode_operations mini_fo_dir_iops =
-+	{
-+		create:	mini_fo_create,
-+		lookup:	mini_fo_lookup,
-+		link:	mini_fo_link,
-+		unlink:	mini_fo_unlink,
-+		symlink:	mini_fo_symlink,
-+		mkdir:	mini_fo_mkdir,
-+		rmdir:	mini_fo_rmdir,
-+		mknod:	mini_fo_mknod,
-+		rename:	mini_fo_rename,
-+		/* no readlink/follow_link for non-symlinks */
-+		// off because we have setattr
-+		//    truncate:	mini_fo_truncate,
-+		/* mk:permission:	mini_fo_permission, */
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-+		revalidate:	mini_fo_inode_revalidate,
-+#endif
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+		getattr:	mini_fo_getattr,
-+#endif
-+		setattr:	mini_fo_setattr,
-+#if defined(XATTR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20))
-+		setxattr:	mini_fo_setxattr,
-+		getxattr:	mini_fo_getxattr,
-+		listxattr:	mini_fo_listxattr,
-+		removexattr: mini_fo_removexattr
-+# endif /* XATTR && LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) */
-+	};
-+
-+struct inode_operations mini_fo_main_iops =
-+	{
-+		/* permission:	mini_fo_permission, */
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-+		revalidate:	mini_fo_inode_revalidate,
-+#endif
-+		setattr:	mini_fo_setattr,
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+		getattr:	mini_fo_getattr,
-+#endif
-+#if defined(XATTR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20))
-+		setxattr:	mini_fo_setxattr,
-+		getxattr:	mini_fo_getxattr,
-+		listxattr:	mini_fo_listxattr,
-+		removexattr:    mini_fo_removexattr
-+# endif /* XATTR && LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) */
-+	};
---- /dev/null
-+++ b/fs/mini_fo/main.c
-@@ -0,0 +1,423 @@
-+/*
-+ * Copyright (c) 1997-2003 Erez Zadok
-+ * Copyright (c) 2001-2003 Stony Brook University
-+ *
-+ * For specific licensing information, see the COPYING file distributed with
-+ * this package, or get one from ftp://ftp.filesystems.org/pub/fist/COPYING.
-+ *
-+ * This Copyright notice must be kept intact and distributed with all
-+ * fistgen sources INCLUDING sources generated by fistgen.
-+ */
-+/*
-+ * Copyright (C) 2004, 2005 Markus Klotzbuecher <[email protected]>
-+ *
-+ * 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.
-+ */
-+
-+/*
-+ *  $Id$
-+ */
-+
-+#ifdef HAVE_CONFIG_H
-+# include <config.h>
-+#endif
-+
-+#include "fist.h"
-+#include "mini_fo.h"
-+#include <linux/module.h>
-+
-+/* This definition must only appear after we include <linux/module.h> */
-+#ifndef MODULE_LICENSE
-+# define MODULE_LICENSE(bison)
-+#endif /* not MODULE_LICENSE */
-+
-+/*
-+ * This is the mini_fo tri interpose function, which extends the
-+ * functionality of the regular interpose by interposing a higher
-+ * level inode on top of two lower level ones: the base filesystem
-+ * inode and the storage filesystem inode.
-+ *
-+ *  sb we pass is mini_fo's super_block
-+ */
-+int
-+mini_fo_tri_interpose(dentry_t *hidden_dentry,
-+		      dentry_t *hidden_sto_dentry,
-+		      dentry_t *dentry, super_block_t *sb, int flag)
-+{
-+	inode_t *hidden_inode = NULL;
-+	inode_t *hidden_sto_inode = NULL; /* store corresponding storage inode */
-+	int err = 0;
-+	inode_t *inode;
-+
-+	/* Pointer to hidden_sto_inode if exists, else to hidden_inode.
-+	 * This is used to copy the attributes of the correct inode. */
-+	inode_t *master_inode;
-+
-+	if(hidden_dentry)
-+		hidden_inode = hidden_dentry->d_inode;
-+	if(hidden_sto_dentry)
-+		hidden_sto_inode = hidden_sto_dentry->d_inode;
-+
-+	ASSERT(dentry->d_inode == NULL);
-+
-+	/* mk: One of the inodes associated with the dentrys is likely to
-+	 * be NULL, so carefull:
-+	 */
-+	ASSERT((hidden_inode != NULL) || (hidden_sto_inode != NULL));
-+
-+	if(hidden_sto_inode)
-+		master_inode = hidden_sto_inode;
-+	else
-+		master_inode = hidden_inode;
-+
-+	/*
-+	 * We allocate our new inode below, by calling iget.
-+	 * iget will call our read_inode which will initialize some
-+	 * of the new inode's fields
-+	 */
-+
-+	/*
-+	 * original: inode = iget(sb, hidden_inode->i_ino);
-+	 */
-+	inode = iget(sb, iunique(sb, 25));
-+	if (!inode) {
-+		err = -EACCES;		/* should be impossible??? */
-+		goto out;
-+	}
-+
-+	/*
-+	 * interpose the inode if not already interposed
-+	 *   this is possible if the inode is being reused
-+	 * XXX: what happens if we get_empty_inode() but there's another already?
-+	 * for now, ASSERT() that this can't happen; fix later.
-+	 */
-+	if (itohi(inode) != NULL) {
-+		printk(KERN_CRIT "mini_fo_tri_interpose: itohi(inode) != NULL.\n");
-+	}
-+	if (itohi2(inode) != NULL) {
-+		printk(KERN_CRIT "mini_fo_tri_interpose: itohi2(inode) != NULL.\n");
-+	}
-+
-+	/* mk: Carefull, igrab can't handle NULL inodes (ok, why should it?), so
-+	 * we need to check here:
-+	 */
-+	if(hidden_inode)
-+		itohi(inode) = igrab(hidden_inode);
-+	else
-+		itohi(inode) = NULL;
-+
-+	if(hidden_sto_inode)
-+		itohi2(inode) = igrab(hidden_sto_inode);
-+	else
-+		itohi2(inode) = NULL;
-+
-+
-+	/* Use different set of inode ops for symlinks & directories*/
-+	if (S_ISLNK(master_inode->i_mode))
-+		inode->i_op = &mini_fo_symlink_iops;
-+	else if (S_ISDIR(master_inode->i_mode))
-+		inode->i_op = &mini_fo_dir_iops;
-+
-+	/* Use different set of file ops for directories */
-+	if (S_ISDIR(master_inode->i_mode))
-+		inode->i_fop = &mini_fo_dir_fops;
-+
-+	/* properly initialize special inodes */
-+	if (S_ISBLK(master_inode->i_mode) || S_ISCHR(master_inode->i_mode) ||
-+	    S_ISFIFO(master_inode->i_mode) || S_ISSOCK(master_inode->i_mode)) {
-+		init_special_inode(inode, master_inode->i_mode, master_inode->i_rdev);
-+	}
-+
-+	/* Fix our inode's address operations to that of the lower inode */
-+	if (inode->i_mapping->a_ops != master_inode->i_mapping->a_ops) {
-+		inode->i_mapping->a_ops = master_inode->i_mapping->a_ops;
-+	}
-+
-+	/* only (our) lookup wants to do a d_add */
-+	if (flag)
-+		d_add(dentry, inode);
-+	else
-+		d_instantiate(dentry, inode);
-+
-+	ASSERT(dtopd(dentry) != NULL);
-+
-+	/* all well, copy inode attributes */
-+	fist_copy_attr_all(inode, master_inode);
-+
-+ out:
-+	return err;
-+}
-+
-+/* parse mount options "base=" and "sto=" */
-+dentry_t *
-+mini_fo_parse_options(super_block_t *sb, char *options)
-+{
-+	dentry_t *hidden_root = ERR_PTR(-EINVAL);
-+	dentry_t *hidden_root2 = ERR_PTR(-EINVAL);
-+	struct nameidata nd, nd2; 
-+	char *name, *tmp, *end;
-+	int err = 0;
-+
-+	/* We don't want to go off the end of our arguments later on. */
-+	for (end = options; *end; end++);
-+
-+	while (options < end) {
-+		tmp = options;
-+		while (*tmp && *tmp != ',')
-+			tmp++;
-+		*tmp = '\0';
-+		if (!strncmp("base=", options, 5)) {
-+			name = options + 5;
-+			printk(KERN_INFO "mini_fo: using base directory: %s\n", name);
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-+			if (path_init(name, LOOKUP_FOLLOW, &nd))
-+				err = path_walk(name, &nd);
-+#else
-+			err = path_lookup(name, LOOKUP_FOLLOW, &nd);
-+#endif
-+			if (err) {
-+				printk(KERN_CRIT "mini_fo: error accessing hidden directory '%s'\n", name);
-+				hidden_root = ERR_PTR(err);
-+				goto out;
-+			}
-+			hidden_root = nd.dentry;
-+			stopd(sb)->base_dir_dentry = nd.dentry;
-+			stopd(sb)->hidden_mnt = nd.mnt;
-+
-+		} else if(!strncmp("sto=", options, 4)) {
-+			/* parse the storage dir */
-+			name = options + 4;
-+			printk(KERN_INFO "mini_fo: using storage directory: %s\n", name);
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-+			if(path_init(name, LOOKUP_FOLLOW, &nd2))
-+				err = path_walk(name, &nd2);
-+#else
-+                        err = path_lookup(name, LOOKUP_FOLLOW, &nd2);
-+#endif
-+			if(err) {
-+				printk(KERN_CRIT "mini_fo: error accessing hidden storage directory '%s'\n", name);
-+
-+				hidden_root2 = ERR_PTR(err);
-+				goto out;
-+			}
-+			hidden_root2 = nd2.dentry;
-+			stopd(sb)->storage_dir_dentry = nd2.dentry;
-+			stopd(sb)->hidden_mnt2 = nd2.mnt;
-+			stohs2(sb) = hidden_root2->d_sb;
-+
-+			/* validate storage dir, this is done in 
-+			 * mini_fo_read_super for the base directory.
-+			 */
-+			if (IS_ERR(hidden_root2)) {
-+				printk(KERN_WARNING "mini_fo_parse_options: storage dentry lookup failed (err = %ld)\n", PTR_ERR(hidden_root2));
-+				goto out;
-+			}
-+			if (!hidden_root2->d_inode) {
-+				printk(KERN_WARNING "mini_fo_parse_options: no storage dir to interpose on.\n");
-+				goto out;
-+			}
-+			stohs2(sb) = hidden_root2->d_sb;
-+		} else {
-+			printk(KERN_WARNING "mini_fo: unrecognized option '%s'\n", options);
-+			hidden_root = ERR_PTR(-EINVAL);
-+			goto out;
-+		}
-+		options = tmp + 1;
-+	}
-+
-+ out:
-+	if(IS_ERR(hidden_root2))
-+		return hidden_root2;
-+	return hidden_root;
-+}
-+
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+static int
-+#else
-+super_block_t *
-+#endif
-+mini_fo_read_super(super_block_t *sb, void *raw_data, int silent)
-+{
-+	dentry_t *hidden_root;
-+	int err = 0;
-+
-+	if (!raw_data) {
-+		printk(KERN_WARNING "mini_fo_read_super: missing argument\n");
-+		err = -EINVAL;
-+		goto out;
-+	}
-+	/*
-+	 * Allocate superblock private data
-+	 */
-+	__stopd(sb) = kmalloc(sizeof(struct mini_fo_sb_info), GFP_KERNEL);
-+	if (!stopd(sb)) {
-+		printk(KERN_WARNING "%s: out of memory\n", __FUNCTION__);
-+		err = -ENOMEM;
-+		goto out;
-+	}
-+	stohs(sb) = NULL;
-+
-+	hidden_root = mini_fo_parse_options(sb, raw_data);
-+	if (IS_ERR(hidden_root)) {
-+		printk(KERN_WARNING "mini_fo_read_super: lookup_dentry failed (err = %ld)\n", PTR_ERR(hidden_root));
-+		err = PTR_ERR(hidden_root);
-+		goto out_free;
-+	}
-+	if (!hidden_root->d_inode) {
-+		printk(KERN_WARNING "mini_fo_read_super: no directory to interpose on\n");
-+		goto out_free;
-+	}
-+	stohs(sb) = hidden_root->d_sb;
-+
-+	/*
-+	 * Linux 2.4.2-ac3 and beyond has code in
-+	 * mm/filemap.c:generic_file_write() that requires sb->s_maxbytes
-+	 * to be populated.  If not set, all write()s under that sb will
-+	 * return 0.
-+	 *
-+	 * Linux 2.4.4+ automatically sets s_maxbytes to MAX_NON_LFS;
-+	 * the filesystem should override it only if it supports LFS.
-+	 */
-+	/* non-SCA code is good to go with LFS */
-+	sb->s_maxbytes = hidden_root->d_sb->s_maxbytes;
-+
-+	sb->s_op = &mini_fo_sops;
-+	/*
-+	 * we can't use d_alloc_root if we want to use
-+	 * our own interpose function unchanged,
-+	 * so we simply replicate *most* of the code in d_alloc_root here
-+	 */
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-+	sb->s_root = d_alloc(NULL, &(const struct qstr) { "/", 1, 0 });
-+#else
-+	sb->s_root = d_alloc(NULL, &(const struct qstr){hash: 0, name: "/", len : 1});
-+#endif
-+	if (IS_ERR(sb->s_root)) {
-+		printk(KERN_WARNING "mini_fo_read_super: d_alloc failed\n");
-+		err = -ENOMEM;
-+		goto out_dput;
-+	}
-+
-+	sb->s_root->d_op = &mini_fo_dops;
-+	sb->s_root->d_sb = sb;
-+	sb->s_root->d_parent = sb->s_root;
-+
-+	/* link the upper and lower dentries */
-+	__dtopd(sb->s_root) = (struct mini_fo_dentry_info *) 
-+		kmalloc(sizeof(struct mini_fo_dentry_info), GFP_KERNEL);
-+	if (!dtopd(sb->s_root)) {
-+		err = -ENOMEM;
-+		goto out_dput2;
-+	}
-+	dtopd(sb->s_root)->state = MODIFIED;
-+	dtohd(sb->s_root) = hidden_root;
-+
-+	/* fanout relevant, interpose on storage root dentry too */
-+	dtohd2(sb->s_root) = stopd(sb)->storage_dir_dentry;
-+
-+	/* ...and call tri-interpose to interpose root dir inodes
-+	 * if (mini_fo_interpose(hidden_root, sb->s_root, sb, 0))
-+	 */
-+	if(mini_fo_tri_interpose(hidden_root, dtohd2(sb->s_root), sb->s_root, sb, 0))
-+		goto out_dput2;
-+
-+	/* initalize the wol list */
-+	itopd(sb->s_root->d_inode)->deleted_list_size = -1;
-+	itopd(sb->s_root->d_inode)->renamed_list_size = -1;
-+	meta_build_lists(sb->s_root);
-+
-+	goto out;
-+
-+ out_dput2:
-+	dput(sb->s_root);
-+ out_dput:
-+	dput(hidden_root);
-+	dput(dtohd2(sb->s_root)); /* release the hidden_sto_dentry too */
-+ out_free:
-+	kfree(stopd(sb));
-+	__stopd(sb) = NULL;
-+ out:
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+        return err;
-+#else
-+        if (err) {
-+		return ERR_PTR(err);
-+        } else {
-+		return sb;
-+        }
-+#endif
-+}
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
-+static int mini_fo_get_sb(struct file_system_type *fs_type,
-+					  int flags, const char *dev_name,
-+					  void *raw_data, struct vfsmount *mnt) 
-+{
-+	return get_sb_nodev(fs_type, flags, raw_data, mini_fo_read_super, mnt);
-+}
-+#else
-+static struct super_block *mini_fo_get_sb(struct file_system_type *fs_type,
-+					  int flags, const char *dev_name,
-+					  void *raw_data) 
-+{
-+	return get_sb_nodev(fs_type, flags, raw_data, mini_fo_read_super);
-+}
-+#endif
-+
-+void mini_fo_kill_block_super(struct super_block *sb)
-+{
-+	generic_shutdown_super(sb);
-+	/*
-+	 *      XXX: BUG: Halcrow: Things get unstable sometime after this point:
-+	 *      lib/rwsem-spinlock.c:127: spin_is_locked on uninitialized
-+	 *      fs/fs-writeback.c:402: spin_lock(fs/super.c:a0381828) already
-+	 *      locked by fs/fs-writeback.c/402
-+	 *
-+	 *      Apparently, someone's not releasing a lock on sb_lock...
-+	 */
-+}
-+
-+static struct file_system_type mini_fo_fs_type = {
-+	.owner          = THIS_MODULE,
-+	.name           = "mini_fo",
-+	.get_sb         = mini_fo_get_sb,
-+	.kill_sb        = mini_fo_kill_block_super,
-+	.fs_flags       = 0,
-+};
-+
-+
-+#else
-+static DECLARE_FSTYPE(mini_fo_fs_type, "mini_fo", mini_fo_read_super, 0);
-+#endif
-+
-+static int __init init_mini_fo_fs(void)
-+{
-+	printk("Registering mini_fo version $Id$\n");
-+	return register_filesystem(&mini_fo_fs_type);
-+}
-+static void __exit exit_mini_fo_fs(void)
-+{
-+	printk("Unregistering mini_fo version $Id$\n");
-+	unregister_filesystem(&mini_fo_fs_type);
-+}
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-+EXPORT_NO_SYMBOLS;
-+#endif
-+
-+MODULE_AUTHOR("Erez Zadok <[email protected]>");
-+MODULE_DESCRIPTION("FiST-generated mini_fo filesystem");
-+MODULE_LICENSE("GPL");
-+
-+/* MODULE_PARM(fist_debug_var, "i"); */
-+/* MODULE_PARM_DESC(fist_debug_var, "Debug level"); */
-+
-+module_init(init_mini_fo_fs)
-+module_exit(exit_mini_fo_fs)
---- /dev/null
-+++ b/fs/mini_fo/Makefile
-@@ -0,0 +1,17 @@
-+#
-+# Makefile for mini_fo 2.4 and 2.6 Linux kernels
-+#
-+# Copyright (C) 2004, 2005 Markus Klotzbuecher <[email protected]>
-+#
-+# 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.
-+#
-+
-+obj-$(CONFIG_MINI_FO) := mini_fo.o
-+mini_fo-objs   := meta.o dentry.o file.o inode.o main.o super.o state.o aux.o
-+
-+# dependencies
-+${mini_fo-objs}: mini_fo.h fist.h
-+
---- /dev/null
-+++ b/fs/mini_fo/meta.c
-@@ -0,0 +1,1000 @@
-+/*
-+ * Copyright (C) 2004, 2005 Markus Klotzbuecher <[email protected]>
-+ *
-+ * 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.
-+ */
-+
-+#ifdef HAVE_CONFIG_H
-+# include <config.h>
-+#endif /* HAVE_CONFIG_H */
-+#include "fist.h"
-+#include "mini_fo.h"
-+
-+int meta_build_lists(dentry_t *dentry) 
-+{
-+	struct mini_fo_inode_info *inode_info;
-+
-+	dentry_t *meta_dentry = 0;
-+	file_t *meta_file = 0;
-+	mm_segment_t old_fs;
-+	void *buf;
-+
-+	int bytes, len;
-+	struct vfsmount *meta_mnt;
-+	char *entry;
-+
-+	inode_info = itopd(dentry->d_inode);
-+	if(!(inode_info->deleted_list_size == -1 &&
-+	     inode_info->renamed_list_size == -1)) {
-+		printk(KERN_CRIT "mini_fo: meta_build_lists: \
-+                                  Error, list(s) not virgin.\n");
-+		return -1;
-+	}
-+
-+	/* init our meta lists */
-+	INIT_LIST_HEAD(&inode_info->deleted_list);
-+	inode_info->deleted_list_size = 0;
-+
-+	INIT_LIST_HEAD(&inode_info->renamed_list);
-+	inode_info->renamed_list_size = 0;
-+
-+  	/* might there be a META-file? */
-+	if(dtohd2(dentry) && dtohd2(dentry)->d_inode) {
-+		meta_dentry = lookup_one_len(META_FILENAME,
-+					     dtohd2(dentry), 
-+					     strlen(META_FILENAME));
-+		if(!meta_dentry->d_inode) {
-+			dput(meta_dentry);
-+			goto out_ok;
-+		}
-+		/* $%& err, is this correct? */
-+		meta_mnt = stopd(dentry->d_inode->i_sb)->hidden_mnt2;
-+		mntget(meta_mnt);
-+		
-+
-+		/* open META-file for reading */
-+		meta_file = dentry_open(meta_dentry, meta_mnt, 0x0);
-+		if(!meta_file || IS_ERR(meta_file)) {
-+			printk(KERN_CRIT "mini_fo: meta_build_lists: \
-+                                          ERROR opening META file.\n");
-+			goto out_err;
-+		}
-+
-+		/* check if fs supports reading */
-+		if(!meta_file->f_op->read) {
-+			printk(KERN_CRIT "mini_fo: meta_build_lists: \
-+                                          ERROR, fs does not support reading.\n");
-+			goto out_err_close;
-+		}
-+
-+		/* allocate a page for transfering the data */
-+		buf = (void *) __get_free_page(GFP_KERNEL);
-+		if(!buf) {
-+			printk(KERN_CRIT "mini_fo: meta_build_lists: \
-+                                          ERROR, out of mem.\n");
-+			goto out_err_close;
-+		}
-+		meta_file->f_pos = 0;
-+		old_fs = get_fs();
-+		set_fs(KERNEL_DS);
-+		do {
-+			char *c;
-+			bytes = meta_file->f_op->read(meta_file, buf, PAGE_SIZE, &meta_file->f_pos);
-+			if(bytes == PAGE_SIZE) {
-+				/* trim a cut off filename and adjust f_pos to get it next time */
-+				for(c = (char*) buf+PAGE_SIZE;
-+				    *c != '\n';
-+				    c--, bytes--, meta_file->f_pos--);
-+			}
-+			entry = (char *) buf;
-+			while(entry < (char *) buf+bytes) {
-+
-+				char *old_path;
-+				char *dir_name;
-+				int old_len, new_len;
-+
-+				/* len without '\n'*/
-+				len = (int) (strchr(entry, '\n') - entry);
-+				switch (*entry) {
-+				case 'D':
-+					/* format: "D filename" */
-+					meta_list_add_d_entry(dentry, 
-+							      entry+2, 
-+							      len-2);
-+					break;
-+				case 'R':
-+					/* format: "R path/xy/dir newDir" */
-+					old_path = entry+2;
-+					dir_name = strchr(old_path, ' ') + 1;
-+					old_len =  dir_name - old_path - 1;
-+					new_len = ((int) entry) + len - ((int ) dir_name);
-+					meta_list_add_r_entry(dentry, 
-+							      old_path, 
-+							      old_len,
-+							      dir_name, 
-+							      new_len);
-+					break;
-+				default:
-+					/* unknown entry type detected */
-+					break;
-+				}
-+				entry += len+1;
-+			}
-+
-+		} while(meta_file->f_pos < meta_dentry->d_inode->i_size);
-+
-+		free_page((unsigned long) buf);
-+		set_fs(old_fs);
-+		fput(meta_file);
-+	}
-+	goto out_ok;
-+
-+ out_err_close:
-+	fput(meta_file);
-+ out_err:
-+	mntput(meta_mnt);
-+	dput(meta_dentry);
-+	return -1;
-+ out_ok:
-+	return 1; /* check this!!! inode_info->wol_size; */ 
-+}
-+
-+/* cleanups up all lists and free's the mem by dentry */
-+int meta_put_lists(dentry_t *dentry) 
-+{
-+	if(!dentry || !dentry->d_inode) {
-+		printk("mini_fo: meta_put_lists: invalid dentry passed.\n");
-+		return -1;
-+	}
-+	return __meta_put_lists(dentry->d_inode);
-+}
-+
-+/* cleanups up all lists and free's the mem by inode */
-+int __meta_put_lists(inode_t *inode) 
-+{
-+	int err = 0;
-+	if(!inode || !itopd(inode)) {
-+		printk("mini_fo: __meta_put_lists: invalid inode passed.\n");
-+		return -1;
-+	}
-+	err = __meta_put_d_list(inode);
-+	err |= __meta_put_r_list(inode);
-+	return err;
-+}
-+
-+int meta_sync_lists(dentry_t *dentry)
-+{
-+	int err = 0;
-+	if(!dentry || !dentry->d_inode) {
-+		printk("mini_fo: meta_sync_lists: \
-+                        invalid dentry passed.\n");
-+		return -1;
-+	}
-+	err = meta_sync_d_list(dentry, 0);
-+	err |= meta_sync_r_list(dentry, 1);
-+	return err;
-+}
-+
-+
-+/* remove all D entries from the renamed list and free the mem */
-+int __meta_put_d_list(inode_t *inode) 
-+{
-+	struct list_head *tmp;
-+        struct deleted_entry *del_entry;
-+        struct mini_fo_inode_info *inode_info;
-+	
-+	if(!inode || !itopd(inode)) {
-+		printk(KERN_CRIT "mini_fo: __meta_put_d_list: \
-+                                  invalid inode passed.\n");
-+		return -1;
-+	}
-+	inode_info = itopd(inode);
-+	
-+        /* nuke the DELETED-list */
-+        if(inode_info->deleted_list_size <= 0)
-+		return 0;
-+
-+	while(!list_empty(&inode_info->deleted_list)) {
-+		tmp = inode_info->deleted_list.next;
-+		list_del(tmp);
-+		del_entry = list_entry(tmp, struct deleted_entry, list);
-+		kfree(del_entry->name);
-+		kfree(del_entry);
-+	}
-+	inode_info->deleted_list_size = 0;
-+	
-+	return 0;
-+}
-+
-+/* remove all R entries from the renamed list and free the mem */
-+int __meta_put_r_list(inode_t *inode) 
-+{
-+	struct list_head *tmp;
-+	struct renamed_entry *ren_entry;
-+        struct mini_fo_inode_info *inode_info;
-+	
-+	if(!inode || !itopd(inode)) {
-+		printk(KERN_CRIT "mini_fo: meta_put_r_list: invalid inode.\n");
-+		return -1;
-+	}
-+	inode_info = itopd(inode);
-+	
-+        /* nuke the RENAMED-list */
-+        if(inode_info->renamed_list_size <= 0) 
-+		return 0;
-+
-+	while(!list_empty(&inode_info->renamed_list)) {
-+		tmp = inode_info->renamed_list.next;
-+		list_del(tmp);
-+		ren_entry = list_entry(tmp, struct renamed_entry, list);
-+		kfree(ren_entry->new_name);
-+		kfree(ren_entry->old_name);
-+		kfree(ren_entry);
-+	}
-+	inode_info->renamed_list_size = 0;
-+	
-+	return 0;
-+}
-+
-+int meta_add_d_entry(dentry_t *dentry, const char *name, int len)
-+{
-+	int err = 0;
-+	err = meta_list_add_d_entry(dentry, name, len);
-+	err |= meta_write_d_entry(dentry,name,len);
-+	return err;	
-+}
-+
-+/* add a D entry to the deleted list */
-+int meta_list_add_d_entry(dentry_t *dentry, const char *name, int len) 
-+{
-+        struct deleted_entry *del_entry;
-+        struct mini_fo_inode_info *inode_info;
-+
-+	if(!dentry || !dentry->d_inode) {
-+		printk(KERN_CRIT "mini_fo: meta_list_add_d_entry: \
-+                                  invalid dentry passed.\n");
-+		return -1;
-+	}
-+	inode_info = itopd(dentry->d_inode);
-+
-+        if(inode_info->deleted_list_size < 0)
-+                return -1;
-+
-+        del_entry = (struct deleted_entry *) 
-+		kmalloc(sizeof(struct deleted_entry), GFP_KERNEL);
-+        del_entry->name = (char*) kmalloc(len, GFP_KERNEL);
-+        if(!del_entry || !del_entry->name) {
-+                printk(KERN_CRIT "mini_fo: meta_list_add_d_entry: \
-+                                  out of mem.\n");
-+		kfree(del_entry->name);
-+		kfree(del_entry);
-+                return -ENOMEM;
-+        }
-+
-+        strncpy(del_entry->name, name, len);
-+        del_entry->len = len;
-+
-+        list_add(&del_entry->list, &inode_info->deleted_list);
-+        inode_info->deleted_list_size++;
-+        return 0;
-+}
-+
-+int meta_add_r_entry(dentry_t *dentry, 
-+			  const char *old_name, int old_len, 
-+			  const char *new_name, int new_len)
-+{
-+	int err = 0;
-+	err = meta_list_add_r_entry(dentry, 
-+				    old_name, old_len,
-+				    new_name, new_len);
-+	err |= meta_write_r_entry(dentry,
-+				  old_name, old_len,
-+				  new_name, new_len);
-+	return err;
-+}
-+
-+/* add a R entry to the renamed list */
-+int meta_list_add_r_entry(dentry_t *dentry, 
-+			  const char *old_name, int old_len, 
-+			  const char *new_name, int new_len)
-+{
-+        struct renamed_entry *ren_entry;
-+        struct mini_fo_inode_info *inode_info;
-+
-+	if(!dentry || !dentry->d_inode) {
-+		printk(KERN_CRIT "mini_fo: meta_list_add_r_entry: \
-+                                  invalid dentry passed.\n");
-+		return -1;
-+	}
-+	inode_info = itopd(dentry->d_inode);
-+
-+        if(inode_info->renamed_list_size < 0)
-+                return -1;
-+
-+        ren_entry = (struct renamed_entry *) 
-+		kmalloc(sizeof(struct renamed_entry), GFP_KERNEL);
-+        ren_entry->old_name = (char*) kmalloc(old_len, GFP_KERNEL);
-+        ren_entry->new_name = (char*) kmalloc(new_len, GFP_KERNEL);
-+
-+        if(!ren_entry || !ren_entry->old_name || !ren_entry->new_name) {
-+                printk(KERN_CRIT "mini_fo: meta_list_add_r_entry: \
-+                                  out of mem.\n");
-+		kfree(ren_entry->new_name);
-+		kfree(ren_entry->old_name);
-+		kfree(ren_entry);
-+                return -ENOMEM;
-+        }
-+
-+        strncpy(ren_entry->old_name, old_name, old_len);
-+        ren_entry->old_len = old_len;
-+        strncpy(ren_entry->new_name, new_name, new_len);
-+        ren_entry->new_len = new_len;
-+
-+        list_add(&ren_entry->list, &inode_info->renamed_list);
-+        inode_info->renamed_list_size++;
-+        return 0;
-+}
-+
-+
-+int meta_remove_r_entry(dentry_t *dentry, const char *name, int len)
-+{
-+	int err = 0;
-+	if(!dentry || !dentry->d_inode) {
-+		printk(KERN_CRIT 
-+		       "mini_fo: meta_remove_r_entry: \
-+                        invalid dentry passed.\n");
-+		return -1;
-+	}
-+
-+	err = meta_list_remove_r_entry(dentry, name, len);
-+	err |= meta_sync_lists(dentry);
-+	return err;
-+}
-+
-+int meta_list_remove_r_entry(dentry_t *dentry, const char *name, int len)
-+{
-+	if(!dentry || !dentry->d_inode) {
-+		printk(KERN_CRIT 
-+		       "mini_fo: meta_list_remove_r_entry: \
-+                        invalid dentry passed.\n");
-+		return -1;
-+	}
-+	return __meta_list_remove_r_entry(dentry->d_inode, name, len);
-+}
-+
-+int __meta_list_remove_r_entry(inode_t *inode, const char *name, int len)
-+{
-+	struct list_head *tmp;
-+        struct renamed_entry *ren_entry;
-+        struct mini_fo_inode_info *inode_info;
-+
-+	if(!inode || !itopd(inode))
-+		printk(KERN_CRIT 
-+		       "mini_fo: __meta_list_remove_r_entry: \
-+                        invalid inode passed.\n");
-+	inode_info = itopd(inode);
-+
-+        if(inode_info->renamed_list_size < 0)
-+                return -1;
-+        if(inode_info->renamed_list_size == 0)
-+                return 1;
-+	
-+	list_for_each(tmp, &inode_info->renamed_list) {
-+		ren_entry = list_entry(tmp, struct renamed_entry, list);
-+		if(ren_entry->new_len != len)
-+			continue;
-+		
-+		if(!strncmp(ren_entry->new_name, name, len)) {
-+			list_del(tmp);
-+			kfree(ren_entry->new_name);
-+			kfree(ren_entry->old_name);
-+			kfree(ren_entry);
-+			inode_info->renamed_list_size--;
-+			return 0;
-+		}
-+	}
-+	return 1;
-+}
-+
-+
-+/* append a single D entry to the meta file */
-+int meta_write_d_entry(dentry_t *dentry, const char *name, int len) 
-+{
-+	dentry_t *meta_dentry = 0;
-+        file_t *meta_file = 0;
-+        mm_segment_t old_fs;
-+
-+        int bytes, err;
-+        struct vfsmount *meta_mnt = 0;
-+        char *buf;
-+
-+	err = 0;
-+
-+	if(itopd(dentry->d_inode)->deleted_list_size < 0) {
-+		err = -1;
-+		goto out;
-+	}
-+
-+	if(dtopd(dentry)->state == UNMODIFIED) {
-+                err = build_sto_structure(dentry->d_parent, dentry);
-+                if(err) {
-+                        printk(KERN_CRIT "mini_fo: meta_write_d_entry: \
-+                                          build_sto_structure failed.\n");
-+			goto out;
-+                }
-+        }
-+	meta_dentry = lookup_one_len(META_FILENAME, 
-+				     dtohd2(dentry), strlen (META_FILENAME));
-+
-+	/* We need to create a META-file */
-+        if(!meta_dentry->d_inode) {
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+		vfs_create(dtohd2(dentry)->d_inode,
-+			   meta_dentry, 
-+			   S_IRUSR | S_IWUSR,
-+			   NULL);
-+#else
-+                vfs_create(dtohd2(dentry)->d_inode,
-+			   meta_dentry, 
-+			   S_IRUSR | S_IWUSR);
-+#endif
-+	}
-+        /* open META-file for writing */
-+        meta_file = dentry_open(meta_dentry, meta_mnt, 0x1);
-+        if(!meta_file || IS_ERR(meta_file)) {
-+                printk(KERN_CRIT "mini_fo: meta_write_d_entry: \
-+                                  ERROR opening meta file.\n");
-+                mntput(meta_mnt); /* $%& is this necessary? */
-+                dput(meta_dentry);
-+		err = -1;
-+                goto out;
-+        }
-+
-+        /* check if fs supports writing */
-+        if(!meta_file->f_op->write) {
-+                printk(KERN_CRIT "mini_fo: meta_write_d_entry: \
-+                                  ERROR, fs does not support writing.\n");
-+                goto out_err_close;
-+        }
-+
-+	meta_file->f_pos = meta_dentry->d_inode->i_size; /* append */
-+        old_fs = get_fs();
-+        set_fs(KERNEL_DS);
-+
-+	/* size: len for name, 1 for \n and 2 for "D " */
-+	buf = (char *) kmalloc(len+3, GFP_KERNEL);
-+	if (!buf) {
-+		printk(KERN_CRIT "mini_fo: meta_write_d_entry: \
-+                                  out of mem.\n");
-+		return -ENOMEM;
-+	}
-+		      
-+	buf[0] = 'D';
-+	buf[1] = ' ';
-+	strncpy(buf+2, name, len);
-+	buf[len+2] = '\n';
-+	bytes = meta_file->f_op->write(meta_file, buf, len+3, 
-+				       &meta_file->f_pos);
-+	if(bytes != len+3) {
-+		printk(KERN_CRIT "mini_fo: meta_write_d_entry: \
-+                                  ERROR writing.\n");
-+		err = -1;
-+	}
-+	kfree(buf);
-+	set_fs(old_fs);
-+
-+ out_err_close:
-+	fput(meta_file);
-+ out:
-+	return err;
-+}
-+
-+/* append a single R entry to the meta file */
-+int meta_write_r_entry(dentry_t *dentry, 
-+		       const char *old_name, int old_len, 
-+		       const char *new_name, int new_len) 
-+{
-+	dentry_t *meta_dentry = 0;
-+        file_t *meta_file = 0;
-+        mm_segment_t old_fs;
-+
-+        int bytes, err, buf_len;
-+	struct vfsmount *meta_mnt = 0;
-+        char *buf;
-+
-+
-+	err = 0;
-+
-+	if(itopd(dentry->d_inode)->renamed_list_size < 0) {
-+		err = -1;
-+		goto out;
-+	}
-+
-+	/* build the storage structure? */
-+	if(dtopd(dentry)->state == UNMODIFIED) {
-+                err = build_sto_structure(dentry->d_parent, dentry);
-+                if(err) {
-+                        printk(KERN_CRIT "mini_fo: meta_write_r_entry: \
-+                                          build_sto_structure failed.\n");
-+			goto out;
-+                }
-+        }
-+	meta_dentry = lookup_one_len(META_FILENAME, 
-+				     dtohd2(dentry), 
-+				     strlen (META_FILENAME));
-+        if(!meta_dentry->d_inode) {
-+                /* We need to create a META-file */
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+                vfs_create(dtohd2(dentry)->d_inode, 
-+			   meta_dentry, S_IRUSR | S_IWUSR, NULL);
-+#else
-+                vfs_create(dtohd2(dentry)->d_inode, 
-+			   meta_dentry, S_IRUSR | S_IWUSR);
-+#endif
-+	}
-+        /* open META-file for writing */
-+        meta_file = dentry_open(meta_dentry, meta_mnt, 0x1);
-+        if(!meta_file || IS_ERR(meta_file)) {
-+                printk(KERN_CRIT "mini_fo: meta_write_r_entry: \
-+                                  ERROR opening meta file.\n");
-+                mntput(meta_mnt);
-+                dput(meta_dentry);
-+		err = -1;
-+                goto out;
-+        }
-+
-+        /* check if fs supports writing */
-+        if(!meta_file->f_op->write) {
-+                printk(KERN_CRIT "mini_fo: meta_write_r_entry: \
-+                                  ERROR, fs does not support writing.\n");
-+                goto out_err_close;
-+        }
-+
-+	meta_file->f_pos = meta_dentry->d_inode->i_size; /* append */
-+        old_fs = get_fs();
-+        set_fs(KERNEL_DS);
-+
-+	/* size: 2 for "R ", old_len+new_len for names, 1 blank+1 \n */
-+	buf_len = old_len + new_len + 4;
-+	buf = (char *) kmalloc(buf_len, GFP_KERNEL);
-+	if (!buf) {
-+		printk(KERN_CRIT "mini_fo: meta_write_r_entry: out of mem.\n");
-+		return -ENOMEM;
-+	}
-+		      
-+	buf[0] = 'R';
-+	buf[1] = ' ';
-+	strncpy(buf + 2, old_name, old_len);
-+	buf[old_len + 2] = ' ';
-+	strncpy(buf + old_len + 3, new_name, new_len);
-+	buf[buf_len -1] = '\n';
-+	bytes = meta_file->f_op->write(meta_file, buf, buf_len, &meta_file->f_pos);
-+	if(bytes != buf_len) {
-+		printk(KERN_CRIT "mini_fo: meta_write_r_entry: ERROR writing.\n");
-+		err = -1;
-+	}
-+	
-+	kfree(buf);
-+	set_fs(old_fs);
-+
-+ out_err_close:
-+	fput(meta_file);
-+ out:
-+	return err;
-+}
-+
-+/* sync D list to disk, append data if app_flag is 1 */
-+/* check the meta_mnt, which seems not to be used (properly)  */
-+
-+int meta_sync_d_list(dentry_t *dentry, int app_flag)
-+{
-+	dentry_t *meta_dentry;
-+        file_t *meta_file;
-+        mm_segment_t old_fs;
-+	
-+        int bytes, err;
-+        struct vfsmount *meta_mnt;
-+        char *buf;
-+
-+	struct list_head *tmp;
-+        struct deleted_entry *del_entry;
-+        struct mini_fo_inode_info *inode_info;
-+
-+	err = 0;
-+	meta_file=0;
-+	meta_mnt=0;
-+	
-+	if(!dentry || !dentry->d_inode) {
-+		printk(KERN_CRIT "mini_fo: meta_sync_d_list: \
-+                                  invalid inode passed.\n");
-+		err = -1;
-+		goto out;
-+	}
-+	inode_info = itopd(dentry->d_inode);
-+	
-+        if(inode_info->deleted_list_size < 0) {
-+		err = -1;
-+		goto out;
-+	}
-+	
-+	/* ok, there is something to sync */
-+
-+	/* build the storage structure? */
-+        if(!dtohd2(dentry) && !itohi2(dentry->d_inode)) {
-+                err = build_sto_structure(dentry->d_parent, dentry);
-+                if(err) {
-+                        printk(KERN_CRIT "mini_fo: meta_sync_d_list: \
-+                                          build_sto_structure failed.\n");
-+			goto out;
-+                }
-+        }
-+	meta_dentry = lookup_one_len(META_FILENAME, 
-+				     dtohd2(dentry), 
-+				     strlen(META_FILENAME));
-+        if(!meta_dentry->d_inode) {
-+                /* We need to create a META-file */
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+                vfs_create(dtohd2(dentry)->d_inode, 
-+			   meta_dentry, S_IRUSR | S_IWUSR, NULL);
-+#else
-+                vfs_create(dtohd2(dentry)->d_inode, 
-+			   meta_dentry, S_IRUSR | S_IWUSR);
-+#endif
-+		app_flag = 0;
-+	}
-+	/* need we truncate the meta file? */
-+	if(!app_flag) {
-+		struct iattr newattrs;
-+                newattrs.ia_size = 0;
-+                newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+		mutex_lock(&meta_dentry->d_inode->i_mutex);
-+#else
-+                down(&meta_dentry->d_inode->i_sem);
-+#endif
-+                err = notify_change(meta_dentry, &newattrs);
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+		mutex_unlock(&meta_dentry->d_inode->i_mutex);
-+#else
-+                up(&meta_dentry->d_inode->i_sem);
-+#endif
-+
-+                if(err || meta_dentry->d_inode->i_size != 0) {
-+                        printk(KERN_CRIT "mini_fo: meta_sync_d_list: \
-+                                          ERROR truncating meta file.\n");
-+                        goto out_err_close;
-+		}
-+	}
-+
-+        /* open META-file for writing */
-+        meta_file = dentry_open(meta_dentry, meta_mnt, 0x1);
-+        if(!meta_file || IS_ERR(meta_file)) {
-+                printk(KERN_CRIT "mini_fo: meta_sync_d_list: \
-+                                  ERROR opening meta file.\n");
-+		/* we don't mntget so we dont't mntput (for now)
-+		 * mntput(meta_mnt); 
-+		 */
-+		dput(meta_dentry);
-+		err = -1;
-+                goto out;
-+        }
-+
-+        /* check if fs supports writing */
-+        if(!meta_file->f_op->write) {
-+                printk(KERN_CRIT "mini_fo: meta_sync_d_list: \
-+                                  ERROR, fs does not support writing.\n");
-+                goto out_err_close;
-+        }
-+	
-+	meta_file->f_pos = meta_dentry->d_inode->i_size; /* append */
-+        old_fs = get_fs();
-+        set_fs(KERNEL_DS);
-+
-+	/* here we go... */
-+        list_for_each(tmp, &inode_info->deleted_list) {
-+		del_entry = list_entry(tmp, struct deleted_entry, list);
-+		
-+		/* size: len for name, 1 for \n and 2 for "D " */
-+		buf = (char *) kmalloc(del_entry->len+3, GFP_KERNEL);
-+		if (!buf) {
-+			printk(KERN_CRIT "mini_fo: meta_sync_d_list: \
-+                                          out of mem.\n");
-+			return -ENOMEM;
-+		}
-+		      
-+		buf[0] = 'D';
-+		buf[1] = ' ';
-+		strncpy(buf+2, del_entry->name, del_entry->len);
-+		buf[del_entry->len+2] = '\n';
-+		bytes = meta_file->f_op->write(meta_file, buf, 
-+					       del_entry->len+3, 
-+					       &meta_file->f_pos);
-+		if(bytes != del_entry->len+3) {
-+			printk(KERN_CRIT "mini_fo: meta_sync_d_list: \
-+                                          ERROR writing.\n");
-+			err |= -1;
-+		}
-+		kfree(buf);
-+	}
-+	set_fs(old_fs);
-+	
-+ out_err_close:
-+	fput(meta_file);
-+ out:
-+	return err;
-+
-+}
-+
-+int meta_sync_r_list(dentry_t *dentry, int app_flag)
-+{
-+	dentry_t *meta_dentry;
-+        file_t *meta_file;
-+        mm_segment_t old_fs;
-+	
-+        int bytes, err, buf_len;
-+        struct vfsmount *meta_mnt;
-+        char *buf;
-+	
-+	struct list_head *tmp;
-+        struct renamed_entry *ren_entry;
-+        struct mini_fo_inode_info *inode_info;
-+	
-+	err = 0;
-+	meta_file=0;
-+	meta_mnt=0;
-+	
-+	if(!dentry || !dentry->d_inode) {
-+		printk(KERN_CRIT "mini_fo: meta_sync_r_list: \
-+                                  invalid dentry passed.\n");
-+		err = -1;
-+		goto out;
-+	}
-+	inode_info = itopd(dentry->d_inode);
-+	
-+        if(inode_info->deleted_list_size < 0) {
-+		err = -1;
-+		goto out;
-+	}
-+	
-+	/* ok, there is something to sync */
-+
-+	/* build the storage structure? */
-+        if(!dtohd2(dentry) && !itohi2(dentry->d_inode)) {
-+                err = build_sto_structure(dentry->d_parent, dentry);
-+                if(err) {
-+                        printk(KERN_CRIT "mini_fo: meta_sync_r_list: \
-+                                          build_sto_structure failed.\n");
-+			goto out;
-+                }
-+        }
-+	meta_dentry = lookup_one_len(META_FILENAME, 
-+				     dtohd2(dentry), 
-+				     strlen(META_FILENAME));
-+        if(!meta_dentry->d_inode) {
-+                /* We need to create a META-file */
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+                vfs_create(dtohd2(dentry)->d_inode, 
-+			   meta_dentry, S_IRUSR | S_IWUSR, NULL);
-+#else
-+                vfs_create(dtohd2(dentry)->d_inode, 
-+			   meta_dentry, S_IRUSR | S_IWUSR);
-+#endif
-+		app_flag = 0;
-+	}
-+	/* need we truncate the meta file? */
-+	if(!app_flag) {
-+		struct iattr newattrs;
-+                newattrs.ia_size = 0;
-+                newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+		mutex_lock(&meta_dentry->d_inode->i_mutex);
-+#else
-+                down(&meta_dentry->d_inode->i_sem);
-+#endif
-+                err = notify_change(meta_dentry, &newattrs);
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+		mutex_unlock(&meta_dentry->d_inode->i_mutex);
-+#else
-+                up(&meta_dentry->d_inode->i_sem);
-+#endif
-+                if(err || meta_dentry->d_inode->i_size != 0) {
-+                        printk(KERN_CRIT "mini_fo: meta_sync_r_list: \
-+                                          ERROR truncating meta file.\n");
-+                        goto out_err_close;
-+		}
-+	}
-+
-+        /* open META-file for writing */
-+        meta_file = dentry_open(meta_dentry, meta_mnt, 0x1);
-+        if(!meta_file || IS_ERR(meta_file)) {
-+                printk(KERN_CRIT "mini_fo: meta_sync_r_list: \
-+                                  ERROR opening meta file.\n");
-+		/* we don't mntget so we dont't mntput (for now)
-+		 * mntput(meta_mnt); 
-+		 */
-+		dput(meta_dentry);
-+		err = -1;
-+                goto out;
-+        }
-+
-+        /* check if fs supports writing */
-+        if(!meta_file->f_op->write) {
-+                printk(KERN_CRIT "mini_fo: meta_sync_r_list: \
-+                                  ERROR, fs does not support writing.\n");
-+                goto out_err_close;
-+        }
-+	
-+	meta_file->f_pos = meta_dentry->d_inode->i_size; /* append */
-+        old_fs = get_fs();
-+        set_fs(KERNEL_DS);
-+
-+	/* here we go... */
-+        list_for_each(tmp, &inode_info->renamed_list) {
-+		ren_entry = list_entry(tmp, struct renamed_entry, list);
-+		/* size: 
-+		 * 2 for "R ", old_len+new_len for names, 1 blank+1 \n */
-+		buf_len = ren_entry->old_len + ren_entry->new_len + 4;
-+		buf = (char *) kmalloc(buf_len, GFP_KERNEL);
-+		if (!buf) {
-+			printk(KERN_CRIT "mini_fo: meta_sync_r_list: \
-+                                          out of mem.\n");
-+			return -ENOMEM;
-+		}
-+		buf[0] = 'R';
-+		buf[1] = ' ';
-+		strncpy(buf + 2, ren_entry->old_name, ren_entry->old_len);
-+		buf[ren_entry->old_len + 2] = ' ';
-+		strncpy(buf + ren_entry->old_len + 3, 
-+			ren_entry->new_name, ren_entry->new_len);
-+		buf[buf_len - 1] = '\n';
-+		bytes = meta_file->f_op->write(meta_file, buf, 
-+					       buf_len, &meta_file->f_pos);
-+		if(bytes != buf_len) {
-+			printk(KERN_CRIT "mini_fo: meta_sync_r_list: \
-+                                          ERROR writing.\n");
-+			err |= -1;
-+		}		
-+		kfree(buf);
-+	}
-+	set_fs(old_fs);
-+	
-+ out_err_close:
-+	fput(meta_file);
-+ out:
-+	return err;
-+}
-+
-+int meta_check_d_entry(dentry_t *dentry, const char *name, int len) 
-+{
-+	if(!dentry || !dentry->d_inode)
-+		printk(KERN_CRIT "mini_fo: meta_check_d_dentry: \
-+                                  invalid dentry passed.\n");
-+	return __meta_check_d_entry(dentry->d_inode, name, len);	
-+}
-+
-+int __meta_check_d_entry(inode_t *inode, const char *name, int len) 
-+{
-+	struct list_head *tmp;
-+        struct deleted_entry *del_entry;
-+        struct mini_fo_inode_info *inode_info;
-+
-+	if(!inode || !itopd(inode))
-+		printk(KERN_CRIT "mini_fo: __meta_check_d_dentry: \
-+                                  invalid inode passed.\n");
-+
-+        inode_info = itopd(inode);
-+	
-+        if(inode_info->deleted_list_size <= 0)
-+                return 0;
-+
-+        list_for_each(tmp, &inode_info->deleted_list) {
-+		del_entry = list_entry(tmp, struct deleted_entry, list);
-+		if(del_entry->len != len)
-+			continue;
-+		
-+		if(!strncmp(del_entry->name, name, len))
-+			return 1;
-+	}
-+	return 0;
-+}
-+
-+/* 
-+ * check if file has been renamed and return path to orig. base dir.
-+ * Implements no error return values so far, what of course sucks.
-+ * String is null terminated.'
-+ */
-+char* meta_check_r_entry(dentry_t *dentry, const char *name, int len) 
-+{
-+	if(!dentry || !dentry->d_inode) {
-+		printk(KERN_CRIT "mini_fo: meta_check_r_dentry: \
-+                                  invalid dentry passed.\n");
-+		return NULL;
-+	}
-+	return __meta_check_r_entry(dentry->d_inode, name, len);	
-+}
-+
-+char* __meta_check_r_entry(inode_t *inode, const char *name, int len)
-+{
-+	struct list_head *tmp;
-+        struct renamed_entry *ren_entry;
-+        struct mini_fo_inode_info *inode_info;
-+	char *old_path;
-+	
-+	if(!inode || !itopd(inode)) {
-+		printk(KERN_CRIT "mini_fo: meta_check_r_dentry: \
-+                                  invalid inode passed.\n");
-+		return NULL;
-+	}
-+	inode_info = itopd(inode);
-+	
-+        if(inode_info->renamed_list_size <= 0)
-+                return NULL;
-+	
-+        list_for_each(tmp, &inode_info->renamed_list) {
-+		ren_entry = list_entry(tmp, struct renamed_entry, list);
-+		if(ren_entry->new_len != len)
-+			continue;
-+		
-+		if(!strncmp(ren_entry->new_name, name, len)) {
-+			old_path = (char *) 
-+				kmalloc(ren_entry->old_len+1, GFP_KERNEL);
-+			strncpy(old_path, 
-+				ren_entry->old_name, 
-+				ren_entry->old_len);
-+			old_path[ren_entry->old_len]='\0';
-+			return old_path;
-+		}
-+	}
-+	return NULL;
-+}
-+
-+/*
-+ * This version only checks if entry exists and return:
-+ *     1 if exists,
-+ *     0 if not,
-+ *    -1 if error.
-+ */
-+int meta_is_r_entry(dentry_t *dentry, const char *name, int len) 
-+{
-+	if(!dentry || !dentry->d_inode) {
-+		printk(KERN_CRIT "mini_fo: meta_check_r_dentry [2]: \
-+                                  invalid dentry passed.\n");
-+		return -1;
-+	}
-+	return __meta_is_r_entry(dentry->d_inode, name, len);	
-+}
-+
-+int __meta_is_r_entry(inode_t *inode, const char *name, int len)
-+{
-+	struct list_head *tmp;
-+        struct renamed_entry *ren_entry;
-+        struct mini_fo_inode_info *inode_info;
-+	
-+	if(!inode || !itopd(inode)) {
-+		printk(KERN_CRIT "mini_fo: meta_check_r_dentry [2]: \
-+                                  invalid inode passed.\n");
-+		return -1;
-+	}
-+	inode_info = itopd(inode);
-+	
-+        if(inode_info->renamed_list_size <= 0)
-+                return -1;
-+	
-+        list_for_each(tmp, &inode_info->renamed_list) {
-+		ren_entry = list_entry(tmp, struct renamed_entry, list);
-+		if(ren_entry->new_len != len)
-+			continue;
-+		
-+		if(!strncmp(ren_entry->new_name, name, len)) 
-+			return 1;
-+	}
-+	return 0;
-+}
-+
---- /dev/null
-+++ b/fs/mini_fo/mini_fo.h
-@@ -0,0 +1,510 @@
-+/*
-+ * Copyright (c) 1997-2003 Erez Zadok
-+ * Copyright (c) 2001-2003 Stony Brook University
-+ *
-+ * For specific licensing information, see the COPYING file distributed with
-+ * this package, or get one from ftp://ftp.filesystems.org/pub/fist/COPYING.
-+ *
-+ * This Copyright notice must be kept intact and distributed with all
-+ * fistgen sources INCLUDING sources generated by fistgen.
-+ */
-+/*
-+ * Copyright (C) 2004, 2005 Markus Klotzbuecher <[email protected]>
-+ *
-+ * 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.
-+ */
-+
-+/*
-+ *  $Id$
-+ */
-+
-+#ifndef __MINI_FO_H_
-+#define __MINI_FO_H_
-+
-+#ifdef __KERNEL__
-+
-+/* META stuff */
-+#define META_FILENAME "META_dAfFgHE39ktF3HD2sr"
-+
-+/* use xattrs? */
-+#define XATTR
-+
-+/* File attributes that when changed, result in a file beeing copied to storage */
-+#define COPY_FLAGS ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_SIZE
-+
-+/*
-+ * mini_fo filestates
-+ */
-+#define MODIFIED       1
-+#define UNMODIFIED     2
-+#define CREATED        3
-+#define DEL_REWRITTEN  4
-+#define DELETED        5
-+#define NON_EXISTANT   6
-+
-+/* fist file systems superblock magic */
-+# define MINI_FO_SUPER_MAGIC 0xf15f
-+
-+/*
-+ * STRUCTURES:
-+ */
-+
-+/* mini_fo inode data in memory */
-+struct mini_fo_inode_info {
-+	inode_t *wii_inode;
-+	inode_t *wii_inode2; /* pointer to storage inode */
-+
-+	/* META-data lists */
-+	/* deleted list, ex wol */
-+	struct list_head deleted_list;
-+	int deleted_list_size;
-+
-+	/* renamed list */
-+	struct list_head renamed_list;
-+	int renamed_list_size;
-+
-+	/* add other lists here ... */
-+};
-+
-+/* mini_fo dentry data in memory */
-+struct mini_fo_dentry_info {
-+	dentry_t *wdi_dentry;
-+	dentry_t *wdi_dentry2; /* pointer to  storage dentry */
-+	unsigned int state;  /* state of the mini_fo dentry */
-+};
-+
-+
-+/* mini_fo super-block data in memory */
-+struct mini_fo_sb_info {
-+	super_block_t *wsi_sb, *wsi_sb2; /* mk: might point to the same sb */
-+	struct vfsmount *hidden_mnt, *hidden_mnt2;
-+	dentry_t *base_dir_dentry;
-+	dentry_t *storage_dir_dentry;
-+	;
-+};
-+
-+/* readdir_data, readdir helper struct */
-+struct readdir_data {
-+	struct list_head ndl_list; /* linked list head ptr */
-+	int ndl_size; /* list size */
-+	int sto_done; /* flag to show that the storage dir entries have
-+		       * all been read an now follow base entries */
-+};
-+
-+/* file private data. */
-+struct mini_fo_file_info {
-+	struct file *wfi_file;
-+	struct file *wfi_file2; /* pointer to storage file */
-+	struct readdir_data rd;
-+};
-+
-+/* struct ndl_entry */
-+struct ndl_entry {
-+	struct list_head list;
-+	char *name;
-+	int len;
-+};
-+
-+/********************************
-+ *  META-data structures
-+ ********************************/
-+
-+/* deleted entry */
-+struct deleted_entry {
-+	struct list_head list;
-+	char *name;
-+	int len;
-+};
-+
-+/* renamed entry */
-+struct renamed_entry {
-+	struct list_head list;
-+	char *old_name;     /* old directory with full path */
-+	int old_len;        /* length of above string */
-+	char *new_name;     /* new directory name */
-+	int new_len;        /* length of above string */
-+};
-+
-+/* attr_change entry */
-+struct attr_change_entry {
-+	struct list_head list;
-+	char *name;
-+	int len;
-+};
-+
-+/* link entry */
-+struct link_entry {
-+	struct list_head list;
-+	int links_moved;
-+	int inum_base;
-+	int inum_sto;
-+	char *weird_name;
-+	int weird_name_len;
-+};
-+
-+
-+/* Some other stuff required for mini_fo_filldir64, copied from
-+ * fs/readdir.c
-+ */
-+
-+#define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1))
-+#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
-+
-+
-+struct linux_dirent64 {
-+        u64             d_ino;
-+        s64             d_off;
-+        unsigned short  d_reclen;
-+        unsigned char   d_type;
-+        char            d_name[0];
-+};
-+
-+
-+struct getdents_callback64 {
-+        struct linux_dirent64 * current_dir;
-+        struct linux_dirent64 * previous;
-+        int count;
-+        int error;
-+};
-+
-+struct linux_dirent {
-+	unsigned long   d_ino;
-+	unsigned long   d_off;
-+	unsigned short  d_reclen;
-+	char            d_name[1];
-+};
-+
-+struct getdents_callback {
-+	struct linux_dirent * current_dir;
-+	struct linux_dirent * previous;
-+	int count;
-+	int error;
-+};
-+
-+
-+/*
-+ * MACROS:
-+ */
-+
-+/* file TO private_data */
-+# define ftopd(file) ((struct mini_fo_file_info *)((file)->private_data))
-+# define __ftopd(file) ((file)->private_data)
-+/* file TO hidden_file */
-+# define ftohf(file) ((ftopd(file))->wfi_file)
-+# define ftohf2(file) ((ftopd(file))->wfi_file2) 
-+
-+/* inode TO private_data */
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
-+# define itopd(ino) ((struct mini_fo_inode_info *)(ino)->i_private)
-+# define __itopd(ino) ((ino)->i_private)
-+#else
-+# define itopd(ino) ((struct mini_fo_inode_info *)(ino)->u.generic_ip)
-+# define __itopd(ino) ((ino)->u.generic_ip)
-+#endif
-+/* inode TO hidden_inode */
-+# define itohi(ino) (itopd(ino)->wii_inode)
-+# define itohi2(ino) (itopd(ino)->wii_inode2)
-+
-+/* superblock TO private_data */
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+# define stopd(super) ((struct mini_fo_sb_info *)(super)->s_fs_info)
-+# define __stopd(super) ((super)->s_fs_info)
-+#else
-+# define stopd(super) ((struct mini_fo_sb_info *)(super)->u.generic_sbp)
-+# define __stopd(super) ((super)->u.generic_sbp)
-+#endif
-+
-+/* unused? # define vfs2priv stopd */
-+/* superblock TO hidden_superblock */
-+
-+# define stohs(super) (stopd(super)->wsi_sb)
-+# define stohs2(super) (stopd(super)->wsi_sb2)
-+
-+/* dentry TO private_data */
-+# define dtopd(dentry) ((struct mini_fo_dentry_info *)(dentry)->d_fsdata)
-+# define __dtopd(dentry) ((dentry)->d_fsdata)
-+/* dentry TO hidden_dentry */
-+# define dtohd(dent) (dtopd(dent)->wdi_dentry)
-+# define dtohd2(dent) (dtopd(dent)->wdi_dentry2)
-+
-+/* dentry to state */
-+# define dtost(dent) (dtopd(dent)->state)
-+# define sbt(sb) ((sb)->s_type->name)
-+
-+#define IS_WRITE_FLAG(flag) (flag & (O_RDWR | O_WRONLY | O_APPEND))
-+#define IS_COPY_FLAG(flag) (flag & (COPY_FLAGS))
-+
-+/* macros to simplify non-SCA code */
-+#  define MALLOC_PAGE_POINTERS(hidden_pages, num_hidden_pages)
-+#  define MALLOC_PAGEDATA_POINTERS(hidden_pages_data, num_hidden_pages)
-+#  define FREE_PAGE_POINTERS(hidden_pages, num)
-+#  define FREE_PAGEDATA_POINTERS(hidden_pages_data, num)
-+#  define FOR_EACH_PAGE
-+#  define CURRENT_HIDDEN_PAGE hidden_page
-+#  define CURRENT_HIDDEN_PAGEDATA hidden_page_data
-+#  define CURRENT_HIDDEN_PAGEINDEX page->index
-+
-+/*
-+ * EXTERNALS:
-+ */
-+extern struct file_operations mini_fo_main_fops;
-+extern struct file_operations mini_fo_dir_fops;
-+extern struct inode_operations mini_fo_main_iops;
-+extern struct inode_operations mini_fo_dir_iops;
-+extern struct inode_operations mini_fo_symlink_iops;
-+extern struct super_operations mini_fo_sops;
-+extern struct dentry_operations mini_fo_dops;
-+extern struct vm_operations_struct mini_fo_shared_vmops;
-+extern struct vm_operations_struct mini_fo_private_vmops;
-+extern struct address_space_operations mini_fo_aops;
-+
-+#if 0 /* unused by mini_fo */
-+extern int mini_fo_interpose(dentry_t *hidden_dentry, dentry_t *this_dentry, super_block_t *sb, int flag);
-+#if defined(FIST_FILTER_DATA) || defined(FIST_FILTER_SCA)
-+extern page_t *mini_fo_get1page(file_t *file, int index);
-+extern int mini_fo_fill_zeros(file_t *file, page_t *page, unsigned from);
-+# endif /* FIST_FILTER_DATA || FIST_FILTER_SCA */
-+
-+
-+#  define mini_fo_hidden_dentry(d) __mini_fo_hidden_dentry(__FILE__,__FUNCTION__,__LINE__,(d))
-+#  define mini_fo_hidden_sto_dentry(d) __mini_fo_hidden_sto_dentry(__FILE__,__FUNCTION__,__LINE__,(d))
-+
-+extern dentry_t *__mini_fo_hidden_dentry(char *file, char *func, int line, dentry_t *this_dentry);
-+extern dentry_t *__mini_fo_hidden_sto_dentry(char *file, char *func, int line, dentry_t *this_dentry);
-+
-+extern int mini_fo_read_file(const char *filename, void *buf, int len);
-+extern int mini_fo_write_file(const char *filename, void *buf, int len);
-+extern dentry_t *fist_lookup(dentry_t *dir, const char *name, vnode_t **out, uid_t uid, gid_t gid);
-+#endif /* unused by mini_fo */
-+
-+/* state transition functions */
-+extern int nondir_unmod_to_mod(dentry_t *dentry, int cp_flag);
-+extern int nondir_del_rew_to_del(dentry_t *dentry);
-+extern int nondir_creat_to_del(dentry_t *dentry);
-+extern int nondir_mod_to_del(dentry_t *dentry);
-+extern int nondir_unmod_to_del(dentry_t *dentry);
-+
-+extern int dir_unmod_to_mod(dentry_t *dentry);
-+
-+/* rename specials */
-+extern int rename_directory(inode_t *old_dir, dentry_t *old_dentry, inode_t *new_dir, dentry_t *new_dentry);
-+extern int rename_nondir(inode_t *old_dir, dentry_t *old_dentry, inode_t *new_dir, dentry_t *new_dentry);
-+
-+/* misc stuff */
-+extern int mini_fo_tri_interpose(dentry_t *hidden_dentry,
-+				 dentry_t *hidden_sto_dentry,
-+				 dentry_t *dentry, 
-+				 super_block_t *sb, int flag);
-+
-+extern int mini_fo_cp_cont(dentry_t *tgt_dentry, struct vfsmount *tgt_mnt,
-+			   dentry_t *src_dentry, struct vfsmount *src_mnt);
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+extern int mini_fo_create(inode_t *dir, dentry_t *dentry, int mode, struct nameidata *nd);
-+
-+extern int create_sto_nod(dentry_t *dentry, int mode, dev_t dev);
-+extern int create_sto_reg_file(dentry_t *dentry, int mode, struct nameidata *nd);
-+#else
-+extern int mini_fo_create(inode_t *dir, dentry_t *dentry, int mode);
-+
-+extern int create_sto_nod(dentry_t *dentry, int mode, int dev);
-+extern int create_sto_reg_file(dentry_t *dentry, int mode);
-+#endif
-+
-+extern int create_sto_dir(dentry_t *dentry, int mode);
-+
-+extern int exists_in_storage(dentry_t *dentry);
-+extern int is_mini_fo_existant(dentry_t *dentry);
-+extern int get_neg_sto_dentry(dentry_t *dentry);
-+extern int build_sto_structure(dentry_t *dir, dentry_t *dentry);
-+extern int get_mini_fo_bpath(dentry_t *dentry, char **bpath, int *bpath_len);
-+extern dentry_t *bpath_walk(super_block_t *sb, char *bpath);
-+extern int bpath_put(dentry_t *dentry);
-+
-+/* check_mini_fo types functions */
-+extern int check_mini_fo_dentry(dentry_t *dentry);
-+extern int check_mini_fo_file(file_t *file);
-+extern int check_mini_fo_inode(inode_t *inode);
-+
-+/* General meta functions, can be called from outside of meta.c */
-+extern int meta_build_lists(dentry_t *dentry);
-+extern int meta_put_lists(dentry_t *dentry);
-+extern int __meta_put_lists(inode_t *inode);
-+
-+extern int meta_add_d_entry(dentry_t *dentry, const char *name, int len);
-+extern int meta_add_r_entry(dentry_t *dentry, 
-+			    const char *old_name, int old_len, 
-+			    const char *new_name, int new_len);
-+
-+extern int meta_remove_r_entry(dentry_t *dentry, const char *name, int len);
-+
-+extern int meta_check_d_entry(dentry_t *dentry, const char *name, int len);
-+extern int __meta_check_d_entry(inode_t *inode, const char *name, int len);
-+
-+extern char* meta_check_r_entry(dentry_t *dentry, const char *name, int len);
-+extern char* __meta_check_r_entry(inode_t *inode, const char *name, int len);
-+extern int meta_is_r_entry(dentry_t *dentry, const char *name, int len);
-+extern int __meta_is_r_entry(inode_t *inode, const char *name, int len);
-+
-+/* Specific meta functions, should be called only inside meta.c */
-+extern int __meta_put_d_list(inode_t *inode);
-+extern int __meta_put_r_list(inode_t *inode);
-+
-+extern int meta_list_add_d_entry(dentry_t *dentry, 
-+				 const char *name, int len);
-+extern int meta_list_add_r_entry(dentry_t *dentry, 
-+				 const char *old_name, int old_len, 
-+				 const char *new_name, int new_len);
-+
-+extern int meta_list_remove_r_entry(dentry_t *dentry, 
-+				    const char *name, int len);
-+
-+extern int __meta_list_remove_r_entry(inode_t *inode, 
-+				      const char *name, int len);
-+
-+extern int meta_write_d_entry(dentry_t *dentry, const char *name, int len);
-+extern int meta_write_r_entry(dentry_t *dentry, 
-+			      const char *old_name, int old_len, 
-+			      const char *new_name, int new_len);
-+
-+extern int meta_sync_lists(dentry_t *dentry);
-+extern int meta_sync_d_list(dentry_t *dentry, int app_flag);
-+extern int meta_sync_r_list(dentry_t *dentry, int app_flag);
-+
-+/* ndl stuff */
-+extern int ndl_add_entry(struct readdir_data *rd, const char *name, int len);
-+extern void ndl_put_list(struct readdir_data *rd);
-+extern int ndl_check_entry(struct readdir_data *rd, 
-+			   const char *name, int len);
-+
-+
-+# define copy_inode_size(dst, src) \
-+    dst->i_size = src->i_size; \
-+    dst->i_blocks = src->i_blocks;
-+
-+static inline void
-+fist_copy_attr_atime(inode_t *dest, const inode_t *src)
-+{
-+	ASSERT(dest != NULL);
-+	ASSERT(src != NULL);
-+	dest->i_atime = src->i_atime;
-+}
-+static inline void
-+fist_copy_attr_times(inode_t *dest, const inode_t *src)
-+{
-+	ASSERT(dest != NULL);
-+	ASSERT(src != NULL);
-+	dest->i_atime = src->i_atime;
-+	dest->i_mtime = src->i_mtime;
-+	dest->i_ctime = src->i_ctime;
-+}
-+static inline void
-+fist_copy_attr_timesizes(inode_t *dest, const inode_t *src)
-+{
-+	ASSERT(dest != NULL);
-+	ASSERT(src != NULL);
-+	dest->i_atime = src->i_atime;
-+	dest->i_mtime = src->i_mtime;
-+	dest->i_ctime = src->i_ctime;
-+	copy_inode_size(dest, src);
-+}
-+static inline void
-+fist_copy_attr_all(inode_t *dest, const inode_t *src)
-+{
-+	ASSERT(dest != NULL);
-+	ASSERT(src != NULL);
-+	dest->i_mode = src->i_mode;
-+	dest->i_nlink = src->i_nlink;
-+	dest->i_uid = src->i_uid;
-+	dest->i_gid = src->i_gid;
-+	dest->i_rdev = src->i_rdev;
-+	dest->i_atime = src->i_atime;
-+	dest->i_mtime = src->i_mtime;
-+	dest->i_ctime = src->i_ctime;
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
-+	dest->i_blksize = src->i_blksize;
-+#endif
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,12)
-+	dest->i_blkbits = src->i_blkbits;
-+# endif /* linux 2.4.12 and newer */
-+	copy_inode_size(dest, src);
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-+	dest->i_attr_flags = src->i_attr_flags;
-+#else
-+	dest->i_flags = src->i_flags;
-+#endif
-+}
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+/* copied from linux/fs.h */
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+static inline void double_lock(struct dentry *d1, struct dentry *d2)
-+{
-+	struct mutex *m1 = &d1->d_inode->i_mutex;
-+	struct mutex *m2 = &d2->d_inode->i_mutex;
-+	if (m1 != m2) {
-+		if ((unsigned long) m1 < (unsigned long) m2) {
-+			struct mutex *tmp = m2;
-+			m2 = m1; m1 = tmp;
-+		}
-+		mutex_lock(m1);
-+	}
-+	mutex_lock(m2);
-+}
-+
-+static inline void double_unlock(struct dentry *d1, struct dentry *d2)
-+{
-+	struct mutex *m1 = &d1->d_inode->i_mutex;
-+	struct mutex *m2 = &d2->d_inode->i_mutex;
-+	mutex_unlock(m1);
-+	if (m1 != m2)
-+		mutex_unlock(m2);
-+	dput(d1);
-+	dput(d2);
-+}
-+
-+#else
-+static inline void double_down(struct semaphore *s1, struct semaphore *s2)
-+{
-+        if (s1 != s2) {
-+                if ((unsigned long) s1 < (unsigned long) s2) {
-+                        struct semaphore *tmp = s2;
-+                        s2 = s1; s1 = tmp;
-+                }
-+                down(s1);
-+        }
-+        down(s2);
-+}
-+
-+static inline void double_up(struct semaphore *s1, struct semaphore *s2)
-+{
-+        up(s1);
-+        if (s1 != s2)
-+                up(s2);
-+}
-+
-+static inline void double_lock(struct dentry *d1, struct dentry *d2)
-+{
-+        double_down(&d1->d_inode->i_sem, &d2->d_inode->i_sem);
-+}
-+
-+static inline void double_unlock(struct dentry *d1, struct dentry *d2)
-+{
-+        double_up(&d1->d_inode->i_sem,&d2->d_inode->i_sem);
-+        dput(d1);
-+        dput(d2);
-+}
-+#endif   /* if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) */
-+#endif  /* if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) */
-+#endif /* __KERNEL__ */
-+
-+/*
-+ * Definitions for user and kernel code
-+ */
-+
-+/* ioctls */
-+
-+#endif	/* not __MINI_FO_H_ */
---- /dev/null
-+++ b/fs/mini_fo/mini_fo-merge
-@@ -0,0 +1,180 @@
-+#!/bin/bash
-+#
-+# Copyright (C) 2005 Markus Klotzbuecher <[email protected]>
-+# 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.
-+#
-+
-+BASE=
-+STO=
-+HELP=
-+DRYRUN=
-+VERBOSE=
-+TMP="/tmp/"
-+META_NAME="META_dAfFgHE39ktF3HD2sr"
-+SKIP_DEL_LIST="skip-delete-list.mini_fo-merge"
-+
-+COMMAND=
-+exec_command()
-+{
-+    if [ x$DRYRUN == "xset" ]; then
-+	echo "  would run: $COMMAND"
-+    elif ! [ x$DRYRUN == "xset" ]; then
-+	if [ x$VERBOSE == "xset" ]; then
-+	    echo "  running: $COMMAND"
-+	fi
-+	eval $COMMAND
-+    fi
-+}
-+
-+usage()
-+{
-+cat <<EOF
-+
-+USAGE: $0 -b <base dir> -s <storage dir>
-+Version 0.1
-+
-+This script merges the contents of a mini_fo storage file system back
-+to the base file system.
-+
-+!!! Warning: This will modify the base filesystem and can destroy data
-+             if used wrongly.
-+
-+Options:
-+     -b <base dir>
-+          the directory of the base file system.
-+
-+     -s <storage dir>
-+          the directory of the storage file system.
-+
-+     -d   dry run, will not change anything and print the commands that
-+          would be executed.
-+
-+     -t   tmp dir for storing temporary file. default: $TMP
-+
-+     -v   show what operations are performed.
-+
-+     -h   displays this message.
-+
-+EOF
-+}
-+
-+# parse parameters
-+while getopts hdvt:b:s: OPTS
-+  do
-+  case $OPTS in
-+      h)  HELP="set";;
-+      d)  DRYRUN="set";;
-+      v)  VERBOSE="set";;
-+      b)  BASE="$OPTARG";;
-+      s)  STO="$OPTARG";;
-+      t)  TMP="$OPTARG";;
-+      ?)  usage
-+	  exit 1;;
-+  esac
-+done
-+
-+if [ "x$HELP" == "xset" ]; then
-+    usage
-+    exit -1
-+fi
-+
-+if ! [ -d "$BASE" ] || ! [ -d "$STO" ]; then
-+    echo -e "$0:\n Error, -s and/or -b argument missing. type $0 -h for help."
-+    exit -1;
-+fi
-+
-+# get full paths
-+pushd $STO; STO=`pwd`; popd
-+pushd $BASE; BASE=`pwd`; popd
-+TMP=${TMP%/}
-+
-+
-+cat<<EOF
-+###############################################################################
-+# mini_fo-merge
-+#
-+# base dir:       $BASE
-+# storage dir:    $STO
-+# meta filename:  $META_NAME
-+# dry run:        $DRYRUN
-+# verbose:        $VERBOSE     
-+# tmp files:      $TMP
-+###############################################################################
-+
-+EOF
-+
-+rm $TMP/$SKIP_DEL_LIST
-+
-+# first process all renamed dirs
-+echo "Merging renamed directories..."
-+pushd $STO &> /dev/null
-+find . -name $META_NAME -type f -print0  | xargs -0 -e grep  -e '^R ' | tr -s ':R' ' ' | while read ENTRY; do 
-+    echo "entry: $ENTRY"
-+    META_FILE=`echo $ENTRY | cut -d ' ' -f 1`
-+    OLD_B_DIR=`echo $ENTRY | cut -d ' ' -f 2 | sed -e 's/\///'`
-+    NEW_NAME=`echo $ENTRY | cut -d ' ' -f 3`
-+    NEW_B_DIR=`echo $META_FILE | sed -e "s/$META_NAME/$NEW_NAME/" | sed -e 's/^\.\///'`
-+    echo "META_FILE: $META_FILE"
-+    echo "OLD_B_DIR: $OLD_B_DIR"
-+    echo "NEW_NAME: $NEW_NAME"
-+    echo  "NEW_B_DIR: $NEW_B_DIR"
-+
-+    pushd $BASE &> /dev/null
-+    # remove an existing dir in storage
-+    COMMAND="rm -rf $NEW_B_DIR"; exec_command
-+    COMMAND="cp -R $OLD_B_DIR $NEW_B_DIR"; exec_command
-+    echo ""
-+    popd &> /dev/null
-+
-+    # remember this dir to exclude it from deleting later
-+    echo $NEW_B_DIR >> $TMP/$SKIP_DEL_LIST
-+done
-+
-+# delete all whiteouted files from base
-+echo -e "\nDeleting whiteout'ed files from base file system..."
-+find . -name $META_NAME -type f -print0  | xargs -0 -e grep  -e '^D ' | sed -e 's/:D//' | while read ENTRY; do 
-+    META_FILE=`echo $ENTRY | cut -d ' ' -f 1`
-+    DEL_NAME=`echo $ENTRY | cut -d ' ' -f 2`
-+    DEL_FILE=`echo $META_FILE | sed -e "s/$META_NAME/$DEL_NAME/" | sed -e 's/^\.\///'`
-+    grep -x $DEL_FILE $TMP/$SKIP_DEL_LIST &> /dev/null
-+    if [ $? -ne 0 ]; then
-+	pushd $BASE &> /dev/null
-+	COMMAND="rm -rf $DEL_FILE"; exec_command
-+	popd &> /dev/null
-+    else
-+	echo "  excluding: $DEL_FILE as in skip-del-list."
-+    fi
-+done
-+
-+# create all dirs and update permissions
-+echo -e "\nSetting up directory structures in base file system..."
-+find . -type d | sed -e 's/^\.\///' | while read DIR; do
-+    PERMS=`stat -c %a $DIR`
-+    DIR_UID=`stat -c %u $DIR`
-+    DIR_GID=`stat -c %g $DIR`
-+    pushd $BASE &> /dev/null
-+    if ! [ -d $DIR ]; then
-+	COMMAND="mkdir -p $DIR"; exec_command
-+    fi
-+    COMMAND="chmod $PERMS $DIR"; exec_command
-+    COMMAND="chown $DIR_UID:$DIR_GID $DIR"; exec_command
-+    popd &> /dev/null
-+done
-+
-+# merge all non-directory files
-+echo -e "\nMerging all non-directory files...."
-+for i in b c p f l s; do
-+    find . -type $i | sed -e 's/^\.\///' | grep -v "$META_NAME" | while read FILE; do
-+	pushd $BASE #&> /dev/null
-+	COMMAND="cp -df $STO/$FILE $BASE/$FILE"; exec_command
-+	popd &> /dev/null
-+    done   
-+done
-+popd &> /dev/null
-+
-+#rm $TMP/$SKIP_DEL_LIST 
-+
-+echo "Done!"
---- /dev/null
-+++ b/fs/mini_fo/mini_fo-overlay
-@@ -0,0 +1,130 @@
-+#!/bin/bash
-+#
-+# Copyright (C) 2005 Markus Klotzbuecher <[email protected]>
-+# 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.
-+#
-+
-+HELP=
-+SUFF=
-+MNTP=
-+MNT_DIR="/mnt"
-+STO=
-+STO_DIR="/tmp"
-+BASE=
-+
-+usage() 
-+{
-+cat <<EOF
-+
-+Usage: $0 [-s suffix] [-d sto_dir_dir] [-m mount point] base_dir
-+Version 0.1
-+
-+This script overlays the given base directory using the mini_fo file
-+system. If only the base directory base_dir is given, $0 
-+will use a storage directory called "sto-<base_dir_name>" in $STO_DIR,
-+and mount point "mini_fo-<base_dir_dir>" in $MNT_DIR.
-+
-+Options:
-+     -s <suffix>
-+          add given suffix to storage directory and the mount
-+          point. This is usefull for overlaying one base directory
-+          several times and avoiding conflicts with storage directory
-+          names and mount points.
-+
-+     -d <sto_dir_dir>
-+          change the directory in which the storage directory will be
-+          created (default is currently "$STO_DIR".
-+
-+     -m <mount point>
-+          use an alternative directory to create the mini_fo
-+          mountpoint (default is currently "$MNT_DIR".
-+
-+     -h   displays this message.
-+
-+EOF
-+exit 1;
-+}
-+
-+while getopts hm:s:d: OPTS
-+  do
-+  case $OPTS in
-+      s)  SUFF="$OPTARG";;
-+      d)  STO_DIR="$OPTARG";;
-+      m)  MNT_DIR="$OPTARG";;
-+      h)  HELP="set";;
-+      ?)  usage
-+	  exit 1;;
-+  esac
-+done
-+shift $(($OPTIND - 1))
-+
-+BASE="$1"
-+
-+if [ "x$HELP" == "xset" ]; then
-+    usage
-+    exit -1
-+fi
-+
-+# fix suffix 
-+if [ "x$SUFF" != "x" ]; then
-+    SUFF="-$SUFF"
-+fi
-+
-+# kill trailing slashes
-+MNT_DIR=${MNT_DIR%/}
-+STO_DIR=${STO_DIR%/}
-+BASE=${BASE%/}
-+
-+
-+if ! [ -d "$BASE" ]; then
-+    echo "invalid base dir $BASE, run $0 -h for help."
-+    exit -1
-+fi
-+
-+# check opts
-+if ! [ -d "$MNT_DIR" ]; then
-+    echo "invalid mount dir $MNT_DIR, run $0 -h for help."
-+    exit -1
-+fi
-+
-+if ! [ -d "$STO_DIR" ]; then
-+    echo "invalid sto_dir_dir $STO_DIR, run $0 -h for help."
-+    exit -1
-+fi
-+
-+MNTP="$MNT_DIR/mini_fo-`basename $BASE`$SUFF"
-+STO="$STO_DIR/sto-`basename $BASE`$SUFF"
-+
-+# create the mount point if it doesn't exist
-+mkdir -p $MNTP
-+if [ $? -ne 0 ]; then
-+    echo "Error, failed to create mount point $MNTP"
-+fi
-+
-+mkdir -p $STO
-+if [ $? -ne 0 ]; then
-+    echo "Error, failed to create storage dir $STO"
-+fi
-+
-+# check if fs is already mounted
-+mount | grep mini_fo | grep $MNTP &> /dev/null
-+if [ $? -eq 0 ]; then
-+    echo "Error, existing mini_fo mount at $MNTP."
-+    exit -1
-+fi
-+
-+mount | grep mini_fo | grep $STO &> /dev/null
-+if [ $? -eq 0 ]; then
-+    echo "Error, $STO seems to be used already."
-+    exit -1
-+fi
-+
-+# mount 
-+mount -t mini_fo -o base=$BASE,sto=$STO $BASE $MNTP
-+
-+if [ $? -ne 0 ]; then
-+    echo "Error, mounting failed, maybe no permisson to mount?"
-+fi
---- /dev/null
-+++ b/fs/mini_fo/mmap.c
-@@ -0,0 +1,637 @@
-+/*
-+ * Copyright (c) 1997-2003 Erez Zadok
-+ * Copyright (c) 2001-2003 Stony Brook University
-+ *
-+ * For specific licensing information, see the COPYING file distributed with
-+ * this package, or get one from ftp://ftp.filesystems.org/pub/fist/COPYING.
-+ *
-+ * This Copyright notice must be kept intact and distributed with all
-+ * fistgen sources INCLUDING sources generated by fistgen.
-+ */
-+/*
-+ * Copyright (C) 2004, 2005 Markus Klotzbuecher <[email protected]>
-+ *
-+ * 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.
-+ */
-+
-+/*
-+ *  $Id$
-+ */
-+
-+#ifdef HAVE_CONFIG_H
-+# include <config.h>
-+#endif /* HAVE_CONFIG_H */
-+
-+#include "fist.h"
-+#include "mini_fo.h"
-+
-+
-+#ifdef FIST_COUNT_WRITES
-+/* for counting writes in the middle vs. regular writes */
-+unsigned long count_writes = 0, count_writes_middle = 0;
-+#endif /* FIST_COUNT_WRITES */
-+
-+/* forward declaration of commit write and prepare write */
-+STATIC int mini_fo_commit_write(file_t *file, page_t *page, unsigned from, unsigned to);
-+STATIC int mini_fo_prepare_write(file_t *file, page_t *page, unsigned from, unsigned to);
-+
-+
-+/*
-+ * Function for handling creation of holes when lseek-ing past the
-+ * end of the file and then writing some data.
-+ */
-+int
-+mini_fo_fill_zeros(file_t* file, page_t *page, unsigned from)
-+{
-+	int err = 0;
-+	dentry_t *dentry = file->f_dentry;
-+	inode_t *inode = dentry->d_inode;
-+	page_t *tmp_page;
-+	int index;
-+
-+	print_entry_location();
-+
-+	for (index = inode->i_size >> PAGE_CACHE_SHIFT; index < page->index; index++) {
-+		tmp_page = mini_fo_get1page(file, index);
-+		if (IS_ERR(tmp_page)) {
-+			err = PTR_ERR(tmp_page);
-+			goto out;
-+		}
-+
-+		/*
-+		 * zero out rest of the contents of the page between the appropriate
-+		 * offsets.
-+		 */
-+		memset((char*)page_address(tmp_page) + (inode->i_size & ~PAGE_CACHE_MASK), 0, PAGE_CACHE_SIZE - (inode->i_size & ~PAGE_CACHE_MASK));
-+
-+		if (! (err = mini_fo_prepare_write(file, tmp_page, 0, PAGE_CACHE_SIZE)))
-+			err = mini_fo_commit_write(file, tmp_page, 0, PAGE_CACHE_SIZE);
-+
-+		page_cache_release(tmp_page);
-+		if (err < 0)
-+			goto out;
-+		if (current->need_resched)
-+			schedule();
-+	}
-+
-+	/* zero out appropriate parts of last page */
-+
-+	/*
-+	 * if the encoding type is block, then adjust the 'from' (where the
-+	 * zeroing will start) offset appropriately
-+	 */
-+	from = from & (~(FIST_ENCODING_BLOCKSIZE - 1));
-+
-+	if ((from - (inode->i_size & ~PAGE_CACHE_MASK)) > 0) {
-+
-+		memset((char*)page_address(page) + (inode->i_size & ~PAGE_CACHE_MASK), 0, from - (inode->i_size & ~PAGE_CACHE_MASK));
-+		if (! (err = mini_fo_prepare_write(file, page, 0, PAGE_CACHE_SIZE)))
-+			err = mini_fo_commit_write(file, page, 0, PAGE_CACHE_SIZE);
-+
-+		if (err < 0)
-+			goto out;
-+		if (current->need_resched)
-+			schedule();
-+	}
-+
-+ out:
-+	print_exit_status(err);
-+	return err;
-+}
-+
-+
-+
-+STATIC int
-+mini_fo_writepage(page_t *page)
-+{
-+	int err = -EIO;
-+	inode_t *inode;
-+	inode_t *hidden_inode;
-+	page_t *hidden_page;
-+	char *kaddr, *hidden_kaddr;
-+
-+	print_entry_location();
-+
-+	inode = page->mapping->host;
-+	hidden_inode = itohi(inode);
-+
-+	/*
-+	 * writepage is called when shared mmap'ed files need to write
-+	 * their pages, while prepare/commit_write are called from the
-+	 * non-paged write() interface.  (However, in 2.3 the two interfaces
-+	 * share the same cache, while in 2.2 they didn't.)
-+	 *
-+	 * So we pretty much have to duplicate much of what commit_write does.
-+	 */
-+
-+	/* find lower page (returns a locked page) */
-+	hidden_page = grab_cache_page(hidden_inode->i_mapping, page->index);
-+	if (!hidden_page)
-+		goto out;
-+
-+	/* get page address, and encode it */
-+	kaddr = (char *) kmap(page);
-+	hidden_kaddr = (char*) kmap(hidden_page);
-+	mini_fo_encode_block(kaddr, hidden_kaddr, PAGE_CACHE_SIZE, inode, inode->i_sb, page->index);
-+	/* if encode_block could fail, then return error */
-+	kunmap(page);
-+	kunmap(hidden_page);
-+
-+	/* call lower writepage (expects locked page) */
-+	err = hidden_inode->i_mapping->a_ops->writepage(hidden_page);
-+
-+	/*
-+	 * update mtime and ctime of lower level file system
-+	 * mini_fo' mtime and ctime are updated by generic_file_write
-+	 */
-+	hidden_inode->i_mtime = hidden_inode->i_ctime = CURRENT_TIME;
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,1)
-+	UnlockPage(hidden_page);	/* b/c grab_cache_page locked it */
-+# endif /* kernel older than 2.4.1 */
-+	page_cache_release(hidden_page); /* b/c grab_cache_page increased refcnt */
-+
-+	if (err)
-+		ClearPageUptodate(page);
-+	else
-+		SetPageUptodate(page);
-+ out:
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,1)
-+	UnlockPage(page);
-+# endif /* kernel 2.4.1 and newer */
-+	print_exit_status(err);
-+	return err;
-+}
-+
-+
-+/*
-+ * get one page from cache or lower f/s, return error otherwise.
-+ * returns unlocked, up-to-date page (if ok), with increased refcnt.
-+ */
-+page_t *
-+mini_fo_get1page(file_t *file, int index)
-+{
-+	page_t *page;
-+	dentry_t *dentry;
-+	inode_t *inode;
-+	struct address_space *mapping;
-+	int err;
-+
-+	print_entry_location();
-+
-+	dentry = file->f_dentry; /* CPW: Moved below print_entry_location */
-+	inode = dentry->d_inode;
-+	mapping = inode->i_mapping;
-+
-+	fist_dprint(8, "%s: read page index %d pid %d\n", __FUNCTION__, index, current->pid);
-+	if (index < 0) {
-+		printk("%s BUG: index=%d\n", __FUNCTION__, index);
-+		page = ERR_PTR(-EIO);
-+		goto out;
-+	}
-+	page = read_cache_page(mapping,
-+			       index,
-+			       (filler_t *) mapping->a_ops->readpage,
-+			       (void *) file);
-+	if (IS_ERR(page))
-+		goto out;
-+	wait_on_page(page);
-+	if (!Page_Uptodate(page)) {
-+		lock_page(page);
-+		err = mapping->a_ops->readpage(file, page);
-+		if (err) {
-+			page = ERR_PTR(err);
-+			goto out;
-+		}
-+		wait_on_page(page);
-+		if (!Page_Uptodate(page)) {
-+			page = ERR_PTR(-EIO);
-+			goto out;
-+		}
-+	}
-+
-+ out:
-+	print_exit_pointer(page);
-+	return page;
-+}
-+
-+
-+/*
-+ * get one page from cache or lower f/s, return error otherwise.
-+ * similar to get1page, but doesn't guarantee that it will return
-+ * an unlocked page.
-+ */
-+page_t *
-+mini_fo_get1page_cached(file_t *file, int index)
-+{
-+	page_t *page;
-+	dentry_t *dentry;
-+	inode_t *inode;
-+	struct address_space *mapping;
-+	int err;
-+
-+	print_entry_location();
-+
-+	dentry = file->f_dentry; /* CPW: Moved below print_entry_location */
-+	inode = dentry->d_inode;
-+	mapping = inode->i_mapping;
-+
-+	fist_dprint(8, "%s: read page index %d pid %d\n", __FUNCTION__, index, current->pid);
-+	if (index < 0) {
-+		printk("%s BUG: index=%d\n", __FUNCTION__, index);
-+		page = ERR_PTR(-EIO);
-+		goto out;
-+	}
-+	page = read_cache_page(mapping,
-+			       index,
-+			       (filler_t *) mapping->a_ops->readpage,
-+			       (void *) file);
-+	if (IS_ERR(page))
-+		goto out;
-+
-+ out:
-+	print_exit_pointer(page);
-+	return page;
-+}
-+
-+
-+/*
-+ * readpage is called from generic_page_read and the fault handler.
-+ * If your file system uses generic_page_read for the read op, it
-+ * must implement readpage.
-+ *
-+ * Readpage expects a locked page, and must unlock it.
-+ */
-+STATIC int
-+mini_fo_do_readpage(file_t *file, page_t *page)
-+{
-+	int err = -EIO;
-+	dentry_t *dentry;
-+	file_t *hidden_file = NULL;
-+	dentry_t *hidden_dentry;
-+	inode_t *inode;
-+	inode_t *hidden_inode;
-+	char *page_data;
-+	page_t *hidden_page;
-+	char *hidden_page_data;
-+	int real_size;
-+
-+	print_entry_location();
-+
-+	dentry = file->f_dentry; /* CPW: Moved below print_entry_location */
-+	if (ftopd(file) != NULL)
-+		hidden_file = ftohf(file);
-+	hidden_dentry = dtohd(dentry);
-+	inode = dentry->d_inode;
-+	hidden_inode = itohi(inode);
-+
-+	fist_dprint(7, "%s: requesting page %d from file %s\n", __FUNCTION__, page->index, dentry->d_name.name);
-+
-+	MALLOC_PAGE_POINTERS(hidden_pages, num_hidden_pages);
-+	MALLOC_PAGEDATA_POINTERS(hidden_pages_data, num_hidden_pages);
-+	FOR_EACH_PAGE
-+		CURRENT_HIDDEN_PAGE = NULL;
-+
-+	/* find lower page (returns a locked page) */
-+	FOR_EACH_PAGE {
-+		fist_dprint(8, "%s: Current page index = %d\n", __FUNCTION__, CURRENT_HIDDEN_PAGEINDEX);
-+		CURRENT_HIDDEN_PAGE = read_cache_page(hidden_inode->i_mapping,
-+						      CURRENT_HIDDEN_PAGEINDEX,
-+						      (filler_t *) hidden_inode->i_mapping->a_ops->readpage,
-+						      (void *) hidden_file);
-+		if (IS_ERR(CURRENT_HIDDEN_PAGE)) {
-+			err = PTR_ERR(CURRENT_HIDDEN_PAGE);
-+			CURRENT_HIDDEN_PAGE = NULL;
-+			goto out_release;
-+		}
-+	}
-+
-+	/*
-+	 * wait for the page data to show up
-+	 * (signaled by readpage as unlocking the page)
-+	 */
-+	FOR_EACH_PAGE {
-+		wait_on_page(CURRENT_HIDDEN_PAGE);
-+		if (!Page_Uptodate(CURRENT_HIDDEN_PAGE)) {
-+			/*
-+			 * call readpage() again if we returned from wait_on_page with a
-+			 * page that's not up-to-date; that can happen when a partial
-+			 * page has a few buffers which are ok, but not the whole
-+			 * page.
-+			 */
-+			lock_page(CURRENT_HIDDEN_PAGE);
-+			err = hidden_inode->i_mapping->a_ops->readpage(hidden_file,
-+								       CURRENT_HIDDEN_PAGE);
-+			if (err) {
-+				CURRENT_HIDDEN_PAGE = NULL;
-+				goto out_release;
-+			}
-+			wait_on_page(CURRENT_HIDDEN_PAGE);
-+			if (!Page_Uptodate(CURRENT_HIDDEN_PAGE)) {
-+				err = -EIO;
-+				goto out_release;
-+			}
-+		}
-+	}
-+
-+	/* map pages, get their addresses */
-+	page_data = (char *) kmap(page);
-+	FOR_EACH_PAGE
-+		CURRENT_HIDDEN_PAGEDATA = (char *) kmap(CURRENT_HIDDEN_PAGE);
-+
-+	/* if decode_block could fail, then return error */
-+	err = 0;
-+	real_size = hidden_inode->i_size - (page->index << PAGE_CACHE_SHIFT);
-+	if (real_size <= 0)
-+		memset(page_data, 0, PAGE_CACHE_SIZE);
-+	else if (real_size < PAGE_CACHE_SIZE) {
-+		mini_fo_decode_block(hidden_page_data, page_data, real_size, inode, inode->i_sb, page->index);
-+		memset(page_data + real_size, 0, PAGE_CACHE_SIZE - real_size);
-+	} else
-+		mini_fo_decode_block(hidden_page_data, page_data, PAGE_CACHE_SIZE, inode, inode->i_sb, page->index);
-+
-+	FOR_EACH_PAGE
-+		kunmap(CURRENT_HIDDEN_PAGE);
-+	kunmap(page);
-+
-+ out_release:
-+	FOR_EACH_PAGE
-+		if (CURRENT_HIDDEN_PAGE)
-+			page_cache_release(CURRENT_HIDDEN_PAGE); /* undo read_cache_page */
-+
-+	FREE_PAGE_POINTERS(hidden_pages, num_hidden_pages);
-+	FREE_PAGEDATA_POINTERS(hidden_pages_data, num_hidden_pages);
-+
-+ out:
-+	if (err == 0)
-+		SetPageUptodate(page);
-+	else
-+		ClearPageUptodate(page);
-+
-+	print_exit_status(err);
-+	return err;
-+}
-+
-+
-+STATIC int
-+mini_fo_readpage(file_t *file, page_t *page)
-+{
-+	int err;
-+	print_entry_location();
-+
-+	err = mini_fo_do_readpage(file, page);
-+
-+	/*
-+	 * we have to unlock our page, b/c we _might_ have gotten a locked page.
-+	 * but we no longer have to wakeup on our page here, b/c UnlockPage does
-+	 * it
-+	 */
-+	UnlockPage(page);
-+
-+	print_exit_status(err);
-+	return err;
-+}
-+
-+
-+STATIC int
-+mini_fo_prepare_write(file_t *file, page_t *page, unsigned from, unsigned to)
-+{
-+	int err = 0;
-+
-+	print_entry_location();
-+
-+	/*
-+	 * we call kmap(page) only here, and do the kunmap
-+	 * and the actual downcalls, including unlockpage and uncache
-+	 * in commit_write.
-+	 */
-+	kmap(page);
-+
-+	/* fast path for whole page writes */
-+	if (from == 0 && to == PAGE_CACHE_SIZE)
-+		goto out;
-+	/* read the page to "revalidate" our data */
-+	/* call the helper function which doesn't unlock the page */
-+	if (!Page_Uptodate(page))
-+		err = mini_fo_do_readpage(file, page);
-+
-+ out:
-+	print_exit_status(err);
-+	return err;
-+}
-+
-+
-+
-+STATIC int
-+mini_fo_commit_write(file_t *file, page_t *page, unsigned from, unsigned to)
-+{
-+	int err = -ENOMEM;
-+	inode_t *inode;
-+	inode_t *hidden_inode;
-+	page_t *hidden_page;
-+	file_t *hidden_file = NULL;
-+	loff_t pos;
-+	unsigned bytes = to - from;
-+	unsigned hidden_from, hidden_to, hidden_bytes;
-+
-+	print_entry_location();
-+
-+	inode = page->mapping->host; /* CPW: Moved below print_entry_location */
-+	hidden_inode = itohi(inode);
-+
-+	ASSERT(file != NULL);
-+	/*
-+	 * here we have a kmapped page, with data from the user copied
-+	 * into it.  we need to encode_block it, and then call the lower
-+	 * commit_write.  We also need to simulate same behavior of
-+	 * generic_file_write, and call prepare_write on the lower f/s first.
-+	 */
-+#ifdef FIST_COUNT_WRITES
-+	count_writes++;
-+# endif /* FIST_COUNT_WRITES */
-+
-+	/* this is append and/or extend -- we can't have holes so fill them in */
-+	if (page->index > (hidden_inode->i_size >> PAGE_CACHE_SHIFT)) {
-+		page_t *tmp_page;
-+		int index;
-+		for (index = hidden_inode->i_size >> PAGE_CACHE_SHIFT; index < page->index; index++) {
-+			tmp_page = mini_fo_get1page(file, index);
-+			if (IS_ERR(tmp_page)) {
-+				err = PTR_ERR(tmp_page);
-+				goto out;
-+			}
-+			/* zero out the contents of the page at the appropriate offsets */
-+			memset((char*)page_address(tmp_page) + (inode->i_size & ~PAGE_CACHE_MASK), 0, PAGE_CACHE_SIZE - (inode->i_size & ~PAGE_CACHE_MASK));
-+			if (!(err = mini_fo_prepare_write(file, tmp_page, 0, PAGE_CACHE_SIZE)))
-+				err = mini_fo_commit_write(file, tmp_page, 0, PAGE_CACHE_SIZE);
-+			page_cache_release(tmp_page);
-+			if (err < 0)
-+				goto out;
-+			if (current->need_resched)
-+				schedule();
-+		}
-+	}
-+
-+	if (ftopd(file) != NULL)
-+		hidden_file = ftohf(file);
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+	mutex_lock(&hidden_inode->i_mutex);
-+#else
-+	down(&hidden_inode->i_sem);
-+#endif
-+	/* find lower page (returns a locked page) */
-+	hidden_page = grab_cache_page(hidden_inode->i_mapping, page->index);
-+	if (!hidden_page)
-+		goto out;
-+
-+#if FIST_ENCODING_BLOCKSIZE > 1
-+#  error encoding_blocksize greater than 1 is not yet supported
-+# endif /* FIST_ENCODING_BLOCKSIZE > 1 */
-+
-+	hidden_from = from & (~(FIST_ENCODING_BLOCKSIZE - 1));
-+	hidden_to = ((to + FIST_ENCODING_BLOCKSIZE - 1) & (~(FIST_ENCODING_BLOCKSIZE - 1)));
-+	if ((page->index << PAGE_CACHE_SHIFT) + to > hidden_inode->i_size) {
-+
-+		/*
-+		 * if this call to commit_write had introduced holes and the code
-+		 * for handling holes was invoked, then the beginning of this page
-+		 * must be zeroed out
-+		 * zero out bytes from 'size_of_file%pagesize' to 'from'.
-+		 */
-+		if ((hidden_from - (inode->i_size & ~PAGE_CACHE_MASK)) > 0)
-+			memset((char*)page_address(page) + (inode->i_size & ~PAGE_CACHE_MASK), 0, hidden_from - (inode->i_size & ~PAGE_CACHE_MASK));
-+
-+	}
-+	hidden_bytes = hidden_to - hidden_from;
-+
-+	/* call lower prepare_write */
-+	err = -EINVAL;
-+	if (hidden_inode->i_mapping &&
-+	    hidden_inode->i_mapping->a_ops &&
-+	    hidden_inode->i_mapping->a_ops->prepare_write)
-+		err = hidden_inode->i_mapping->a_ops->prepare_write(hidden_file,
-+								    hidden_page,
-+								    hidden_from,
-+								    hidden_to);
-+	if (err)
-+		/* don't leave locked pages behind, esp. on an ENOSPC */
-+		goto out_unlock;
-+
-+	fist_dprint(8, "%s: encoding %d bytes\n", __FUNCTION__, hidden_bytes);
-+	mini_fo_encode_block((char *) page_address(page) + hidden_from, (char*) page_address(hidden_page) + hidden_from, hidden_bytes, inode, inode->i_sb, page->index);
-+	/* if encode_block could fail, then goto unlock and return error */
-+
-+	/* call lower commit_write */
-+	err = hidden_inode->i_mapping->a_ops->commit_write(hidden_file,
-+							   hidden_page,
-+							   hidden_from,
-+							   hidden_to);
-+
-+	if (err < 0)
-+		goto out_unlock;
-+
-+	err = bytes;	/* convert error to no. of bytes */
-+
-+	inode->i_blocks = hidden_inode->i_blocks;
-+	/* we may have to update i_size */
-+	pos = (page->index << PAGE_CACHE_SHIFT) + to;
-+	if (pos > inode->i_size)
-+		inode->i_size = pos;
-+
-+	/*
-+	 * update mtime and ctime of lower level file system
-+	 * mini_fo' mtime and ctime are updated by generic_file_write
-+	 */
-+	hidden_inode->i_mtime = hidden_inode->i_ctime = CURRENT_TIME;
-+
-+	mark_inode_dirty_sync(inode);
-+
-+ out_unlock:
-+	UnlockPage(hidden_page);
-+	page_cache_release(hidden_page);
-+	kunmap(page);		/* kmap was done in prepare_write */
-+ out:
-+	/* we must set our page as up-to-date */
-+	if (err < 0)
-+		ClearPageUptodate(page);
-+	else
-+		SetPageUptodate(page);
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+	mutex_unlock(&hidden_inode->i_mutex);
-+#else
-+	up(&hidden_inode->i_sem);
-+#endif
-+	print_exit_status(err);
-+	return err;			/* assume all is ok */
-+}
-+
-+
-+STATIC int
-+mini_fo_bmap(struct address_space *mapping, long block)
-+{
-+	int err = 0;
-+	inode_t *inode;
-+	inode_t *hidden_inode;
-+
-+	print_entry_location();
-+
-+	inode = (inode_t *) mapping->host;
-+	hidden_inode = itohi(inode);
-+
-+	if (hidden_inode->i_mapping->a_ops->bmap)
-+		err = hidden_inode->i_mapping->a_ops->bmap(hidden_inode->i_mapping, block);
-+	print_exit_location();
-+	return err;
-+}
-+
-+
-+/*
-+ * This function is copied verbatim from mm/filemap.c.
-+ * XXX: It should be simply moved to some header file instead -- bug Al about it!
-+ */
-+static inline int sync_page(struct page *page)
-+{
-+	struct address_space *mapping = page->mapping;
-+
-+	if (mapping && mapping->a_ops && mapping->a_ops->sync_page)
-+		return mapping->a_ops->sync_page(page);
-+	return 0;
-+}
-+
-+
-+/*
-+ * XXX: we may not need this function if not FIST_FILTER_DATA.
-+ * FIXME: for FIST_FILTER_SCA, get all lower pages and sync them each.
-+ */
-+STATIC int
-+mini_fo_sync_page(page_t *page)
-+{
-+	int err = 0;
-+	inode_t *inode;
-+	inode_t *hidden_inode;
-+	page_t *hidden_page;
-+
-+	print_entry_location();
-+
-+	inode = page->mapping->host; /* CPW: Moved below print_entry_location */
-+	hidden_inode = itohi(inode);
-+
-+	/* find lower page (returns a locked page) */
-+	hidden_page = grab_cache_page(hidden_inode->i_mapping, page->index);
-+	if (!hidden_page)
-+		goto out;
-+
-+	err = sync_page(hidden_page);
-+
-+	UnlockPage(hidden_page);	/* b/c grab_cache_page locked it */
-+	page_cache_release(hidden_page); /* b/c grab_cache_page increased refcnt */
-+
-+ out:
-+	print_exit_status(err);
-+	return err;
-+}
---- /dev/null
-+++ b/fs/mini_fo/README
-@@ -0,0 +1,163 @@
-+README for the mini_fo overlay file system
-+=========================================
-+
-+
-+WHAT IS MINI_FO?
-+----------------
-+
-+mini_fo is a virtual kernel file system that can make read-only
-+file systems writable. This is done by redirecting modifying operations
-+to a writeable location called "storage directory", and leaving the
-+original data in the "base directory" untouched. When reading, the
-+file system merges the modifed and original data so that only the
-+newest versions will appear. This occurs transparently to the user,
-+who can access the data like on any other read-write file system.
-+
-+Base and storage directories may be located on the same or on
-+different partitions and may be of different file system types. While
-+the storage directory obviously needs to be writable, the base may or
-+may not be writable, what doesn't matter as it will no be modified
-+anyway.
-+
-+
-+WHAT IS GOOD FOR?
-+-----------------
-+
-+The primary purpose of the mini_fo file system is to allow easy
-+software updates to embedded systems, that often store their root
-+file system in a read-only flash file system, but there are many
-+more as for example sandboxing, or for allowing live-cds to
-+permanently store information.
-+
-+
-+BUILDING
-+--------
-+This should be simple. Adjust the Makefile to point to the correct
-+kernel headers you want to build the module for. Then:
-+
-+    # make
-+
-+should build "mini_fo.o" for a 2.4 kernel or "mini_fo.ko" for a 2.6
-+kernel.
-+
-+If you are building the module for you current kernel, you can install
-+the module (as root):
-+
-+    # make install
-+
-+or uninstall with
-+
-+    # make uninstall
-+
-+
-+USING THE FILE SYSTEM
-+--------------------
-+
-+the general mount syntax is:
-+
-+   mount -t mini_fo -o base=<base directory>,sto=<storage directory>\
-+                            <base directory> <mount point>
-+
-+Example:
-+
-+You have mounted a cdrom to /mnt/cdrom and want to modifiy some files
-+on it:
-+
-+load the module (as root)
-+    
-+    # insmod mini_fo.o for a 2.4 kernel or
-+ 
-+    # insmod mini_fo.ko for a 2.6 kernel
-+
-+
-+create a storage dir in tmp and a mountpoint for mini_fo:
-+
-+    # mkdir /tmp/sto
-+    # mkdir /mnt/mini_fo
-+
-+and mount the mini_fo file system:
-+
-+    # mount -t mini_fo -o base=/mnt/cdrom,sto=/tmp/sto /mnt/cdrom /mnt/mini_fo
-+
-+
-+Now the data stored on the cd can be accessed via the mini_fo
-+mountpoint just like any read-write file system, files can be modified
-+and deleted, new ones can be created and so on. When done unmount the
-+file system:
-+
-+    # unmount /mnt/mini_fo
-+
-+Note that if the file system is mounted again using the same storage
-+file system, of course it will appear in the modified state again. If
-+you remount it using an new empty storage directory, it will be
-+unmodified. Therefore by executing:
-+
-+    # cd /tmp/sto
-+    # rm -rf *
-+
-+you can nuke all the changes you made to the original file system. But
-+ remember NEVER do this while the mini_fo file system is mounted!
-+
-+
-+Alternatively you can use the mini_fo-overlay bash script, that
-+simplifies managing mini_fo mounts. See TOOLS Section.
-+
-+
-+TOOLS
-+-----
-+
-+mini_fo-merge (experimental):
-+
-+This is a bash script that will merge changes contained in the storage
-+directory back to the base directory. This allows mini_fo to function
-+as a cache file system by overlaying a slow (network, ...) file system
-+and using a fast (ramdisk, ...) as storage. When done, changes can be
-+merged back to the (slow) base with mini_fo-merge. See "mini_fo-merge
-+-h" for details.
-+
-+It can be usefull for merging changes back after a successfull test
-+(patches, software updates...)
-+
-+
-+mini_fo-overlay:
-+
-+This bash script simplifies managing one or more mini_fo mounts. For
-+overlaying a directory called "basedir1", you can just call:
-+
-+    # mini_fo-overlay basedir1
-+
-+This will mount mini_fo with "basedir1" as base, "/tmp/sto-basedir1/"
-+as storage to "/mnt/mini_fo-basedir1/". It has more options though,
-+type "mini_fo-overlay -h" for details.
-+
-+
-+DOCUMENTATION, REPORTING BUGS, GETTING HELP
-+-------------------------------------------
-+
-+Please visit the mini_fo project page at:
-+
-+http://www.denx.de/twiki/bin/view/Know/MiniFOHome
-+
-+
-+WARNINGS
-+--------
-+
-+Never modify the base or the storage directorys while the mini_fo
-+file system is mounted, or you might crash you system. Simply accessing
-+and reading should not cause any trouble.
-+
-+Exporting a mini_fo mount point via NFS has not been tested, and may
-+or may not work.
-+
-+Check the RELEASE_NOTES for details on bugs and features.
-+
-+
-+
-+Copyright (C) 2004, 2005 Markus Klotzbuecher <[email protected]>
-+
-+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.
-+
-+
---- /dev/null
-+++ b/fs/mini_fo/RELEASE_NOTES
-@@ -0,0 +1,111 @@
-+Release:	mini_fo-0.6.1 (v0-6-1)
-+Date:		21.09.2005
-+
-+
-+Changes:
-+--------
-+v0-6-1:
-+
-+- bugfixes (see ChangeLog)
-+
-+- two helper scripts "mini_fo_merge" and "mini_fo_overlay" (see
-+  README for details).
-+
-+v0-6-0:
-+
-+- Support for 2.4 and 2.6 (see Makefile)
-+
-+- Partial hard link support (creating works as expected, but already
-+  existing links in the base file system will be treated as if they
-+  were individual files).
-+
-+- Various bugfixes and cleanups.
-+
-+
-+v0-6-0-pre1:
-+
-+- This is mini_fo-0-6-0-pre1! This release is a complete rewrite of
-+  many vital mini_fo parts such as the old whiteout list code which
-+  has been replaced by the new META subsystem.
-+
-+- Light weight directory renaming implemented. This means if a
-+  directory is renamed via the mini_fo filesystem this will no longer
-+  result in a complete copy in storage, instead only one empty
-+  directory will be created. All base filed contained in the original
-+  directory stay there until modified.
-+
-+- Special files (creating, renaming, deleting etc.) now working.
-+
-+- Many bugfixes and cleanup, mini_fo is now a lot more stable.
-+
-+
-+v0-5-10:
-+
-+- Final release of the 0-5-* versions. Next will be a complete rewrite
-+  of many features. This release contains several bugfixes related to
-+  directory renaming.
-+
-+
-+v0-5-10-pre6:
-+
-+- Lots of cleanup and several bugfixes related to directory deleting
-+
-+- Directory renaming suddenly works, what is most likely due to the
-+  fact tha that "mv" is smart: if the classic rename doesn't work it
-+  will assume that source and target file are on different fs and will
-+  copy the directory and try to remove the source directory. Until
-+  directory removing wasn't implemented, it would fail to do this and
-+  rollback.
-+  So, directory renaming works for now, but it doesn't yet do what you
-+  would expect from a overlay fs, so use with care.
-+
-+
-+v0-5-10-pre5:
-+
-+- implemented directory deleting 
-+- made parsing of mount options more stable
-+- New format of mount options! (See README)
-+- I can't reproduce the unknown panic with 2.4.25 anymore, so I'll
-+  happily assume it never existed!
-+
-+
-+Implemented features:
-+---------------------
-+
-+- creating hard links (see BUGS on already existing hard links)	
-+- lightweight directory renaming
-+- renaming device files, pipes, sockets, etc.	
-+- creating, renaming, deleting of special files 
-+- deleting directorys
-+- general directory reading (simple "ls" )
-+- creating files in existing directorys
-+- creating directorys
-+- renaming files.
-+- reading and writing files (involves opening)
-+- appending to files (creates copy in storage)
-+- deleting files
-+- llseek works too, what allows editors to work
-+- persistency (a deleted file stay deleted over remounts)
-+- use of symbolic links
-+- creating of device files
-+
-+
-+Not (yet) implemented features:
-+-------------------------------
-+
-+- full hard link support.
-+
-+
-+
-+BUGS:
-+-----
-+
-+Hard links in the base file system will be treated as individual
-+files, not as links to one inode.
-+
-+The main problem with hard links isn't allowing to create them, but
-+their pure existence. If you modify a base hard link, the changes made
-+will only show up on this link, the other link will remain in the
-+original state. I hope to fix this someday. Please note that this does
-+not effect the special hard links '.' and '..', that are handled
-+seperately by the lower fs.
---- /dev/null
-+++ b/fs/mini_fo/state.c
-@@ -0,0 +1,620 @@
-+/*
-+ * Copyright (C) 2005 Markus Klotzbuecher <[email protected]>
-+ *
-+ * 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.
-+ */
-+
-+#ifdef HAVE_CONFIG_H
-+# include <config.h>
-+#endif /* HAVE_CONFIG_H */
-+
-+#include "fist.h"
-+#include "mini_fo.h"
-+
-+
-+/* create the storage file, setup new states */
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+int create_sto_reg_file(dentry_t *dentry, int mode, struct nameidata *nd)
-+#else
-+int create_sto_reg_file(dentry_t *dentry, int mode)
-+#endif
-+{
-+	int err = 0;
-+	inode_t *dir;
-+	dentry_t *hidden_sto_dentry;
-+	dentry_t *hidden_sto_dir_dentry;
-+
-+	if(exists_in_storage(dentry)) {
-+		printk(KERN_CRIT "mini_fo: create_sto_file: wrong type or state.\n");
-+		err = -EINVAL;
-+		goto out;
-+	}
-+	err = get_neg_sto_dentry(dentry);
-+
-+	if (err) {
-+		printk(KERN_CRIT "mini_fo: create_sto_file: ERROR getting neg. sto dentry.\n");
-+		goto out;
-+	}
-+	
-+	dir = dentry->d_parent->d_inode;
-+	hidden_sto_dentry = dtohd2(dentry);
-+
-+	/* lock parent */
-+	hidden_sto_dir_dentry = dget(hidden_sto_dentry->d_parent);
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+	mutex_lock(&hidden_sto_dir_dentry->d_inode->i_mutex);
-+#else
-+        down(&hidden_sto_dir_dentry->d_inode->i_sem);
-+#endif
-+
-+	err = PTR_ERR(hidden_sto_dir_dentry);
-+        if (IS_ERR(hidden_sto_dir_dentry))
-+                goto out;
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+	err = vfs_create(hidden_sto_dir_dentry->d_inode,
-+			 hidden_sto_dentry,
-+			 mode, nd);
-+#else
-+	err = vfs_create(hidden_sto_dir_dentry->d_inode,
-+			 hidden_sto_dentry,
-+			 mode);
-+#endif
-+        if(err) {
-+		printk(KERN_CRIT "mini_fo: create_sto_file: ERROR creating sto file.\n");
-+                goto out_lock;
-+	}
-+
-+	if(!dtohd2(dentry)->d_inode) {
-+		printk(KERN_CRIT "mini_fo: create_sto_file: ERROR creating sto file [2].\n");
-+                err = -EINVAL;
-+                goto out_lock;
-+        }
-+
-+        /* interpose the new inode */
-+        if(dtost(dentry) == DELETED) {
-+                dtost(dentry) = DEL_REWRITTEN;
-+                err = mini_fo_tri_interpose(NULL, hidden_sto_dentry, dentry, dir->i_sb, 0);
-+                if(err)
-+                        goto out_lock;
-+        }
-+        else if(dtost(dentry) == NON_EXISTANT) {
-+                dtost(dentry) = CREATED;
-+                err = mini_fo_tri_interpose(dtohd(dentry), hidden_sto_dentry, dentry, dir->i_sb, 0);
-+                if(err)
-+                        goto out_lock;
-+        }
-+        else if(dtost(dentry) == UNMODIFIED) {
-+                dtost(dentry) = MODIFIED;
-+                /* interpose on new inode */
-+                if(itohi2(dentry->d_inode) != NULL) {
-+                        printk(KERN_CRIT "mini_fo: create_sto_file: invalid inode detected.\n");
-+                        err = -EINVAL;
-+                        goto out_lock;
-+                }
-+                itohi2(dentry->d_inode) = igrab(dtohd2(dentry)->d_inode);
-+	}
-+	fist_copy_attr_timesizes(dentry->d_parent->d_inode, 
-+				 hidden_sto_dir_dentry->d_inode);
-+
-+ out_lock:
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+	mutex_unlock(&hidden_sto_dir_dentry->d_inode->i_mutex);
-+#else
-+	up(&hidden_sto_dir_dentry->d_inode->i_sem);
-+#endif
-+        dput(hidden_sto_dir_dentry);
-+ out:
-+	return err;
-+}
-+
-+/* create the sto dir, setup states */
-+int create_sto_dir(dentry_t *dentry, int mode)
-+{
-+	int err = 0;
-+	inode_t *dir;
-+	dentry_t *hidden_sto_dentry;
-+        dentry_t *hidden_sto_dir_dentry;
-+
-+	/* had to take the "!S_ISDIR(mode))" check out, because it failed */
-+	if(exists_in_storage(dentry)) {
-+                printk(KERN_CRIT "mini_fo: create_sto_dir: wrong type or state.\\
-+n");
-+                err = -EINVAL;
-+                goto out;
-+        }
-+	
-+	err = get_neg_sto_dentry(dentry);
-+	if(err) {
-+		err = -EINVAL;
-+		goto out;
-+	}
-+
-+	dir = dentry->d_parent->d_inode;
-+	hidden_sto_dentry = dtohd2(dentry);
-+
-+	/* was: hidden_sto_dir_dentry = lock_parent(hidden_sto_dentry); */
-+	hidden_sto_dir_dentry = dget(hidden_sto_dentry->d_parent);
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+	mutex_lock(&hidden_sto_dir_dentry->d_inode->i_mutex);
-+#else
-+	down(&hidden_sto_dir_dentry->d_inode->i_sem);
-+#endif
-+
-+	err = PTR_ERR(hidden_sto_dir_dentry);
-+	if (IS_ERR(hidden_sto_dir_dentry))
-+		goto out;
-+	
-+	err = vfs_mkdir(hidden_sto_dir_dentry->d_inode,
-+			hidden_sto_dentry,
-+			mode);
-+	if(err) {
-+		printk(KERN_CRIT "mini_fo: create_sto_dir: ERROR creating sto dir.\n");
-+		goto out_lock;
-+	}
-+
-+	if(!dtohd2(dentry)->d_inode) {
-+		printk(KERN_CRIT "mini_fo: create_sto_dir: ERROR creating sto dir [2].\n");
-+		err = -EINVAL;
-+		goto out_lock;
-+	}
-+
-+	/* interpose the new inode */
-+	if(dtost(dentry) == DELETED) {
-+		dtost(dentry) = DEL_REWRITTEN;
-+		err = mini_fo_tri_interpose(NULL, hidden_sto_dentry, dentry, dir->i_sb, 0);
-+		if(err)
-+			goto out_lock;
-+	}
-+	else if(dtopd(dentry)->state == NON_EXISTANT) {
-+		dtopd(dentry)->state = CREATED;
-+		err = mini_fo_tri_interpose(dtohd(dentry), hidden_sto_dentry, dentry, dir->i_sb, 0);
-+		if(err)
-+			goto out_lock;
-+	}
-+	else if(dtopd(dentry)->state == UNMODIFIED) {
-+		dtopd(dentry)->state = MODIFIED;
-+		/* interpose on new inode */
-+		if(itohi2(dentry->d_inode) != NULL) {
-+			printk(KERN_CRIT "mini_fo:  create_sto_dir: ERROR, invalid inode detected.\n");
-+			err = -EINVAL;
-+			goto out_lock;
-+		}
-+		itohi2(dentry->d_inode) = igrab(dtohd2(dentry)->d_inode);
-+	}
-+
-+	fist_copy_attr_timesizes(dir, hidden_sto_dir_dentry->d_inode);
-+
-+	/* initalize the wol list */
-+	itopd(dentry->d_inode)->deleted_list_size = -1;
-+	itopd(dentry->d_inode)->renamed_list_size = -1;
-+	meta_build_lists(dentry);
-+
-+
-+ out_lock:
-+	/* was: unlock_dir(hidden_sto_dir_dentry); */
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+	mutex_unlock(&hidden_sto_dir_dentry->d_inode->i_mutex);
-+#else
-+	up(&hidden_sto_dir_dentry->d_inode->i_sem);
-+#endif
-+	dput(hidden_sto_dir_dentry);
-+ out:
-+	return err;
-+}
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+int create_sto_nod(dentry_t *dentry, int mode, dev_t dev) 
-+#else
-+int create_sto_nod(dentry_t *dentry, int mode, int dev) 
-+#endif
-+{
-+	int err = 0;
-+	inode_t *dir;
-+	dentry_t *hidden_sto_dentry;
-+	dentry_t *hidden_sto_dir_dentry;
-+
-+	if(exists_in_storage(dentry)) {
-+		err = -EEXIST;
-+		goto out;
-+	}
-+	err = get_neg_sto_dentry(dentry);
-+
-+	if (err) {
-+                printk(KERN_CRIT "mini_fo: create_sto_nod: ERROR getting neg. sto dentry.\n");
-+                goto out;
-+        }	
-+
-+	dir = dentry->d_parent->d_inode;
-+	hidden_sto_dentry = dtohd2(dentry);
-+	
-+	/* lock parent */
-+	hidden_sto_dir_dentry = dget(hidden_sto_dentry->d_parent);
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+	mutex_lock(&hidden_sto_dir_dentry->d_inode->i_mutex);
-+#else
-+	down(&hidden_sto_dir_dentry->d_inode->i_sem);
-+#endif
-+	
-+	err = PTR_ERR(hidden_sto_dir_dentry);
-+	if (IS_ERR(hidden_sto_dir_dentry))
-+		goto out;
-+
-+	err = vfs_mknod(hidden_sto_dir_dentry->d_inode, hidden_sto_dentry, mode, dev);
-+	if(err)
-+		goto out_lock;
-+
-+	if(!dtohd2(dentry)->d_inode) {
-+		printk(KERN_CRIT "mini_fo: create_sto_nod: creating storage inode failed [1].\n");
-+		err = -EINVAL; /* return something indicating failure */
-+		goto out_lock;
-+	}
-+
-+	/* interpose the new inode */
-+	if(dtost(dentry) == DELETED) {
-+		dtost(dentry) = DEL_REWRITTEN;
-+		err = mini_fo_tri_interpose(NULL, hidden_sto_dentry, dentry, dir->i_sb, 0);
-+		if(err)
-+			goto out_lock;
-+	}
-+	else if(dtost(dentry) == NON_EXISTANT) {
-+		dtost(dentry) = CREATED;
-+		err = mini_fo_tri_interpose(dtohd(dentry), hidden_sto_dentry, dentry, dir->i_sb, 0);
-+		if(err)
-+			goto out_lock;
-+	}
-+	else if(dtost(dentry) == UNMODIFIED) {
-+		dtost(dentry) = MODIFIED;
-+		/* interpose on new inode */
-+		if(itohi2(dentry->d_inode) != NULL) {
-+			printk(KERN_CRIT "mini_fo: create_sto_nod: error, invalid inode detected.\n");
-+			err = -EINVAL;
-+			goto out_lock;
-+		}
-+		itohi2(dentry->d_inode) = igrab(dtohd2(dentry)->d_inode);
-+	}
-+
-+	fist_copy_attr_timesizes(dir, hidden_sto_dir_dentry->d_inode);
-+
-+ out_lock:
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+	mutex_unlock(&hidden_sto_dir_dentry->d_inode->i_mutex);
-+#else
-+	up(&hidden_sto_dir_dentry->d_inode->i_sem);
-+#endif
-+	dput(hidden_sto_dir_dentry);
-+ out:
-+	return err;
-+}
-+
-+
-+/* unimplemented (and possibly not usefull): 
-+
-+   nondir-del_to_del_rew
-+   nondir-non_exist_to_creat
-+
-+   dir-unmod_to_del
-+   dir-mod_to_del
-+   dir-creat_to_del
-+   dir-del_rew_to_del
-+   dir-del_to_del_rew
-+   dir-non_exist_to_creat
-+*/
-+
-+
-+/* bring a file of any type from state UNMODIFIED to MODIFIED */
-+int nondir_unmod_to_mod(dentry_t *dentry, int cp_flag) 
-+{
-+	int err = 0;
-+	struct vfsmount *tgt_mnt;
-+	struct vfsmount *src_mnt;
-+	dentry_t *tgt_dentry;
-+	dentry_t *src_dentry;
-+	dentry_t *hidden_sto_dentry;
-+	dentry_t *hidden_sto_dir_dentry;
-+
-+	check_mini_fo_dentry(dentry);
-+
-+	if((dtost(dentry) != UNMODIFIED) ||
-+	   S_ISDIR(dentry->d_inode->i_mode)) {
-+		printk(KERN_CRIT "mini_fo: nondir_unmod_to_mod: \
-+                                  wrong type or state.\n");
-+		err = -1;
-+		goto out;
-+	}
-+	err = get_neg_sto_dentry(dentry);
-+
-+	if (err) {
-+		printk(KERN_CRIT "mini_fo: nondir_unmod_to_mod: \
-+                                  ERROR getting neg. sto dentry.\n");
-+		goto out;
-+	}
-+	
-+	/* create sto file */
-+	hidden_sto_dentry = dtohd2(dentry);
-+
-+	/* lock parent */
-+	hidden_sto_dir_dentry = dget(hidden_sto_dentry->d_parent);
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+	mutex_lock(&hidden_sto_dir_dentry->d_inode->i_mutex);
-+#else
-+        down(&hidden_sto_dir_dentry->d_inode->i_sem);
-+#endif
-+
-+	err = PTR_ERR(hidden_sto_dir_dentry);
-+        if (IS_ERR(hidden_sto_dir_dentry))
-+                goto out;
-+
-+	/* handle different types of nondirs */
-+	if(S_ISCHR(dentry->d_inode->i_mode) ||
-+	   S_ISBLK(dentry->d_inode->i_mode)) {
-+		err = vfs_mknod(hidden_sto_dir_dentry->d_inode,
-+				hidden_sto_dentry,
-+				dtohd(dentry)->d_inode->i_mode,
-+				dtohd(dentry)->d_inode->i_rdev);
-+	}
-+	
-+	else if(S_ISREG(dentry->d_inode->i_mode)) {
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+		err = vfs_create(hidden_sto_dir_dentry->d_inode,
-+				 hidden_sto_dentry,
-+				 dtohd(dentry)->d_inode->i_mode, NULL);
-+#else
-+		err = vfs_create(hidden_sto_dir_dentry->d_inode,
-+				 hidden_sto_dentry,
-+				 dtohd(dentry)->d_inode->i_mode);
-+#endif
-+	}
-+        if(err) {
-+		printk(KERN_CRIT "mini_fo: nondir_unmod_to_mod: \
-+                                  ERROR creating sto file.\n");
-+                goto out_lock;
-+	}
-+
-+	/* interpose on new inode */
-+	if(itohi2(dentry->d_inode) != NULL) {
-+		printk(KERN_CRIT "mini_fo: nondir_unmod_to_mod: \
-+                                  ERROR, invalid inode detected.\n");
-+		err = -EINVAL;
-+		goto out_lock;
-+	}
-+
-+	itohi2(dentry->d_inode) = igrab(dtohd2(dentry)->d_inode);
-+        
-+        fist_copy_attr_timesizes(dentry->d_parent->d_inode, 
-+				 hidden_sto_dir_dentry->d_inode);
-+	dtost(dentry) = MODIFIED;
-+
-+	/* copy contents if regular file and cp_flag = 1 */
-+	if((cp_flag == 1) && S_ISREG(dentry->d_inode->i_mode)) {
-+
-+		/* unlock first */
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+		mutex_unlock(&hidden_sto_dir_dentry->d_inode->i_mutex);
-+#else
-+		up(&hidden_sto_dir_dentry->d_inode->i_sem);
-+#endif
-+
-+		dput(hidden_sto_dir_dentry);
-+
-+		tgt_dentry = dtohd2(dentry);
-+		tgt_mnt = stopd(dentry->d_inode->i_sb)->hidden_mnt2;
-+		src_dentry = dtohd(dentry);
-+		src_mnt = stopd(dentry->d_inode->i_sb)->hidden_mnt;
-+		
-+		err = mini_fo_cp_cont(tgt_dentry, tgt_mnt, 
-+				      src_dentry, src_mnt);
-+		if(err) {
-+			printk(KERN_CRIT "mini_fo: nondir_unmod_to_mod: \
-+                                          ERROR copying contents.\n");
-+		}
-+		goto out;	
-+	}
-+
-+ out_lock:
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+	mutex_unlock(&hidden_sto_dir_dentry->d_inode->i_mutex);
-+#else
-+	up(&hidden_sto_dir_dentry->d_inode->i_sem);
-+#endif
-+        dput(hidden_sto_dir_dentry);
-+ out:
-+	return err;
-+}
-+
-+/* this function is currently identical to nondir_creat_to_del */
-+int nondir_del_rew_to_del(dentry_t *dentry)
-+{
-+	return nondir_creat_to_del(dentry);
-+}
-+
-+int nondir_creat_to_del(dentry_t *dentry) 
-+{
-+	int err = 0;
-+
-+	inode_t *hidden_sto_dir_inode;
-+	dentry_t *hidden_sto_dir_dentry;
-+	dentry_t *hidden_sto_dentry;
-+	
-+	check_mini_fo_dentry(dentry);
-+
-+	/* for now this function serves for both state DEL_REWRITTEN and 
-+	 * CREATED */
-+	if(!(dtost(dentry) == CREATED || (dtost(dentry) == DEL_REWRITTEN)) ||
-+	   S_ISDIR(dentry->d_inode->i_mode)) {
-+		printk(KERN_CRIT "mini_fo: nondir_mod_to_del/del_rew_to_del: \
-+                                  wrong type or state.\n");
-+		err = -1;
-+		goto out;
-+	}
-+	
-+	hidden_sto_dir_inode = itohi2(dentry->d_parent->d_inode);
-+	hidden_sto_dentry = dtohd2(dentry);
-+	
-+	/* was: hidden_sto_dir_dentry = lock_parent(hidden_sto_dentry);*/
-+	hidden_sto_dir_dentry = dget(hidden_sto_dentry->d_parent);
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+	mutex_lock(&hidden_sto_dir_dentry->d_inode->i_mutex);
-+#else
-+	down(&hidden_sto_dir_dentry->d_inode->i_sem);
-+#endif
-+	
-+	/* avoid destroying the hidden inode if the file is in use */
-+	dget(hidden_sto_dentry);
-+	err = vfs_unlink(hidden_sto_dir_inode, hidden_sto_dentry);
-+	dput(hidden_sto_dentry);
-+	if(!err)
-+		d_delete(hidden_sto_dentry);
-+	
-+	/* propagate number of hard-links */
-+	dentry->d_inode->i_nlink = itohi2(dentry->d_inode)->i_nlink;
-+	
-+	dtost(dentry) = NON_EXISTANT;
-+	
-+	/* was: unlock_dir(hidden_sto_dir_dentry); */
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+	mutex_unlock(&hidden_sto_dir_dentry->d_inode->i_mutex);
-+#else
-+	up(&hidden_sto_dir_dentry->d_inode->i_sem);
-+#endif
-+	dput(hidden_sto_dir_dentry);
-+	
-+ out:
-+	return err;
-+}
-+
-+int nondir_mod_to_del(dentry_t *dentry)
-+{
-+	int err;
-+	dentry_t *hidden_sto_dentry;
-+	inode_t *hidden_sto_dir_inode;
-+	dentry_t *hidden_sto_dir_dentry;
-+	
-+	check_mini_fo_dentry(dentry);
-+
-+	if(dtost(dentry) != MODIFIED ||
-+	   S_ISDIR(dentry->d_inode->i_mode)) {
-+		printk(KERN_CRIT "mini_fo: nondir_mod_to_del: \
-+                                  wrong type or state.\n");
-+		err = -1;
-+		goto out;
-+	}
-+
-+	hidden_sto_dir_inode = itohi2(dentry->d_parent->d_inode);
-+	hidden_sto_dentry = dtohd2(dentry);
-+	
-+	/* was hidden_sto_dir_dentry = lock_parent(hidden_sto_dentry); */
-+	hidden_sto_dir_dentry = dget(hidden_sto_dentry->d_parent);
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+	mutex_lock(&hidden_sto_dir_dentry->d_inode->i_mutex);
-+#else
-+	down(&hidden_sto_dir_dentry->d_inode->i_sem);
-+#endif
-+	
-+	/* avoid destroying the hidden inode if the file is in use */
-+	dget(hidden_sto_dentry);
-+	err = vfs_unlink(hidden_sto_dir_inode, hidden_sto_dentry);
-+	dput(hidden_sto_dentry);
-+	if(!err)
-+		d_delete(hidden_sto_dentry);
-+	
-+	/* propagate number of hard-links */
-+	dentry->d_inode->i_nlink = itohi2(dentry->d_inode)->i_nlink;
-+	
-+	/* dput base dentry, this will relase the inode and free the
-+	 * dentry, as we will never need it again. */
-+	dput(dtohd(dentry));
-+	dtohd(dentry) = NULL;
-+	dtost(dentry) = DELETED;
-+
-+	/* add deleted file to META-file */
-+	meta_add_d_entry(dentry->d_parent, 
-+			 dentry->d_name.name, 
-+			 dentry->d_name.len);
-+	
-+	/* was: unlock_dir(hidden_sto_dir_dentry); */
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+	mutex_unlock(&hidden_sto_dir_dentry->d_inode->i_mutex);
-+#else
-+	up(&hidden_sto_dir_dentry->d_inode->i_sem);
-+#endif
-+	dput(hidden_sto_dir_dentry);
-+
-+ out:
-+	return err;
-+}
-+
-+int nondir_unmod_to_del(dentry_t *dentry)
-+{
-+	int err = 0;
-+
-+	check_mini_fo_dentry(dentry);
-+
-+	if(dtost(dentry) != UNMODIFIED ||
-+	   S_ISDIR(dentry->d_inode->i_mode)) {
-+		printk(KERN_CRIT "mini_fo: nondir_unmod_to_del: \
-+                                  wrong type or state.\n");
-+		err = -1;
-+		goto out;
-+	}
-+	
-+	 /* next we have to get a negative dentry for the storage file */
-+	err = get_neg_sto_dentry(dentry);
-+
-+	if(err)
-+		goto out;		
-+
-+	/* add deleted file to META lists */
-+	err = meta_add_d_entry(dentry->d_parent, 
-+			       dentry->d_name.name, 
-+			       dentry->d_name.len);
-+
-+	if(err)
-+		goto out;
-+	
-+	/* dput base dentry, this will relase the inode and free the
-+	 * dentry, as we will never need it again. */
-+	dput(dtohd(dentry));
-+	dtohd(dentry) = NULL;
-+	dtost(dentry) = DELETED;
-+	
-+ out:
-+	return err;
-+}
-+
-+/* bring a dir from state UNMODIFIED to MODIFIED */
-+int dir_unmod_to_mod(dentry_t *dentry) 
-+{
-+	int err;
-+
-+	check_mini_fo_dentry(dentry);
-+
-+	if(dtost(dentry) != UNMODIFIED ||
-+	   !S_ISDIR(dentry->d_inode->i_mode)) {
-+		printk(KERN_CRIT "mini_fo: dir_unmod_to_mod: \
-+                                  wrong type or state.\n");
-+		err = -1;
-+		goto out;
-+	}
-+
-+	/* this creates our dir incl. sto. structure */
-+	err = build_sto_structure(dentry->d_parent, dentry);
-+	if(err) {
-+		printk(KERN_CRIT "mini_fo: dir_unmod_to_mod: \
-+                                  build_sto_structure failed.\n");
-+		goto out;
-+	}
-+ out:
-+	return err;
-+}
-+
---- /dev/null
-+++ b/fs/mini_fo/super.c
-@@ -0,0 +1,281 @@
-+/*
-+ * Copyright (c) 1997-2003 Erez Zadok
-+ * Copyright (c) 2001-2003 Stony Brook University
-+ *
-+ * For specific licensing information, see the COPYING file distributed with
-+ * this package, or get one from ftp://ftp.filesystems.org/pub/fist/COPYING.
-+ *
-+ * This Copyright notice must be kept intact and distributed with all
-+ * fistgen sources INCLUDING sources generated by fistgen.
-+ */
-+/*
-+ * Copyright (C) 2004, 2005 Markus Klotzbuecher <[email protected]>
-+ *
-+ * 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.
-+ */
-+
-+/*
-+ *  $Id$
-+ */
-+
-+#ifdef HAVE_CONFIG_H
-+# include <config.h>
-+#endif 
-+
-+#include "fist.h"
-+#include "mini_fo.h"
-+
-+
-+STATIC void
-+mini_fo_read_inode(inode_t *inode)
-+{
-+	static struct address_space_operations mini_fo_empty_aops;
-+
-+	__itopd(inode) = kmalloc(sizeof(struct mini_fo_inode_info), GFP_KERNEL);
-+	if (!itopd(inode)) {
-+		printk("<0>%s:%s:%d: No kernel memory!\n", __FILE__, __FUNCTION__, __LINE__);
-+		ASSERT(NULL);
-+	}
-+	itohi(inode) = NULL;
-+	itohi2(inode) = NULL;
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+	inode->i_version++;
-+#else
-+	inode->i_version = ++event;	/* increment inode version */
-+#endif
-+	inode->i_op = &mini_fo_main_iops;
-+	inode->i_fop = &mini_fo_main_fops;
-+#if 0
-+	/*
-+	 * XXX: To export a file system via NFS, it has to have the
-+	 * FS_REQUIRES_DEV flag, so turn it on.  But should we inherit it from
-+	 * the lower file system, or can we allow our file system to be exported
-+	 * even if the lower one cannot be natively exported.
-+	 */
-+	inode->i_sb->s_type->fs_flags |= FS_REQUIRES_DEV;
-+	/*
-+	 * OK, the above was a hack, which is now turned off because it may
-+	 * cause a panic/oops on some systems.  The correct way to export a
-+	 * "nodev" filesystem is via using nfs-utils > 1.0 and the "fsid=" export
-+	 * parameter, which requires 2.4.20 or later.
-+	 */
-+#endif
-+	/* I don't think ->a_ops is ever allowed to be NULL */
-+	inode->i_mapping->a_ops = &mini_fo_empty_aops;
-+}
-+
-+
-+#if defined(FIST_DEBUG) || defined(FIST_FILTER_SCA)
-+/*
-+ * No need to call write_inode() on the lower inode, as it
-+ * will have been marked 'dirty' anyway. But we might need
-+ * to write some of our own stuff to disk.
-+ */
-+STATIC void
-+mini_fo_write_inode(inode_t *inode, int sync)
-+{
-+	print_entry_location();
-+	print_exit_location();
-+}
-+#endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */
-+
-+
-+STATIC void
-+mini_fo_put_inode(inode_t *inode)
-+{
-+	/*
-+	 * This is really funky stuff:
-+	 * Basically, if i_count == 1, iput will then decrement it and this inode will be destroyed.
-+	 * It is currently holding a reference to the hidden inode.
-+	 * Therefore, it needs to release that reference by calling iput on the hidden inode.
-+	 * iput() _will_ do it for us (by calling our clear_inode), but _only_ if i_nlink == 0.
-+	 * The problem is, NFS keeps i_nlink == 1 for silly_rename'd files.
-+	 * So we must for our i_nlink to 0 here to trick iput() into calling our clear_inode.
-+	 */
-+	if (atomic_read(&inode->i_count) == 1)
-+		inode->i_nlink = 0;
-+}
-+
-+
-+#if defined(FIST_DEBUG) || defined(FIST_FILTER_SCA)
-+/*
-+ * we now define delete_inode, because there are two VFS paths that may
-+ * destroy an inode: one of them calls clear inode before doing everything
-+ * else that's needed, and the other is fine.  This way we truncate the inode
-+ * size (and its pages) and then clear our own inode, which will do an iput
-+ * on our and the lower inode.
-+ */
-+STATIC void
-+mini_fo_delete_inode(inode_t *inode)
-+{
-+	print_entry_location();
-+
-+	fist_checkinode(inode, "mini_fo_delete_inode IN");
-+	inode->i_size = 0;		/* every f/s seems to do that */
-+	clear_inode(inode);
-+
-+	print_exit_location();
-+}
-+#endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */
-+
-+
-+/* final actions when unmounting a file system */
-+STATIC void
-+mini_fo_put_super(super_block_t *sb)
-+{
-+	if (stopd(sb)) {
-+		mntput(stopd(sb)->hidden_mnt);
-+		mntput(stopd(sb)->hidden_mnt2);
-+
-+		/* mk: no! dput(stopd(sb)->base_dir_dentry); 
-+		   dput(stopd(sb)->storage_dir_dentry); */
-+
-+		kfree(stopd(sb));
-+		__stopd(sb) = NULL;
-+	}
-+}
-+
-+
-+#ifdef NOT_NEEDED
-+/*
-+ * This is called in do_umount before put_super.
-+ * The superblock lock is not held yet.
-+ * We probably do not need to define this or call write_super
-+ * on the hidden_sb, because sync_supers() will get to hidden_sb
-+ * sooner or later.  But it is also called from file_fsync()...
-+ */
-+STATIC void
-+mini_fo_write_super(super_block_t *sb)
-+{
-+	return;
-+}
-+#endif /* NOT_NEEDED */
-+
-+
-+STATIC int
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
-+mini_fo_statfs(struct dentry *d, struct kstatfs *buf)
-+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+mini_fo_statfs(super_block_t *sb, struct kstatfs *buf)
-+#else
-+mini_fo_statfs(super_block_t *sb, struct statfs *buf)
-+#endif
-+{
-+	int err = 0;
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
-+	struct dentry *hidden_d;
-+
-+	hidden_d = dtohd(d);
-+	err = vfs_statfs(hidden_d, buf);
-+#else
-+	super_block_t *hidden_sb;
-+
-+	hidden_sb = stohs(sb);
-+	err = vfs_statfs(hidden_sb, buf);
-+#endif
-+
-+	return err;
-+}
-+
-+
-+/*
-+ * XXX: not implemented.  This is not allowed yet.
-+ * Should we call this on the hidden_sb?  Probably not.
-+ */
-+STATIC int
-+mini_fo_remount_fs(super_block_t *sb, int *flags, char *data)
-+{
-+	//printk(KERN_CRIT "mini_fo_remount_fs: WARNING, this function is umimplemented.\n");
-+	return -ENOSYS;
-+}
-+
-+
-+/*
-+ * Called by iput() when the inode reference count reached zero
-+ * and the inode is not hashed anywhere.  Used to clear anything
-+ * that needs to be, before the inode is completely destroyed and put
-+ * on the inode free list.
-+ */
-+STATIC void
-+mini_fo_clear_inode(inode_t *inode)
-+{
-+	/*
-+	 * Decrement a reference to a hidden_inode, which was incremented
-+	 * by our read_inode when it was created initially.
-+	 */
-+
-+	/* release the wol_list */
-+	if(S_ISDIR(inode->i_mode)) {
-+		__meta_put_lists(inode);
-+	}
-+
-+	/* mk: fan out fun */
-+	if(itohi(inode))
-+		iput(itohi(inode));
-+	if(itohi2(inode))
-+		iput(itohi2(inode));
-+
-+	// XXX: why this assertion fails?
-+	// because it doesn't like us
-+	// ASSERT((inode->i_state & I_DIRTY) == 0);
-+	kfree(itopd(inode));
-+	__itopd(inode) = NULL;
-+}
-+
-+
-+/*
-+ * Called in do_umount() if the MNT_FORCE flag was used and this
-+ * function is defined.  See comment in linux/fs/super.c:do_umount().
-+ * Used only in nfs, to kill any pending RPC tasks, so that subsequent
-+ * code can actually succeed and won't leave tasks that need handling.
-+ *
-+ * PS. I wonder if this is somehow useful to undo damage that was
-+ * left in the kernel after a user level file server (such as amd)
-+ * dies.
-+ */
-+STATIC void
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
-+mini_fo_umount_begin(struct vfsmount *mnt, int flags)
-+{
-+	struct vfsmount *hidden_mnt;
-+
-+	hidden_mnt = stopd(mnt->mnt_sb)->hidden_mnt;
-+
-+	if (hidden_mnt->mnt_sb->s_op->umount_begin)
-+		hidden_mnt->mnt_sb->s_op->umount_begin(hidden_mnt, flags);
-+
-+}
-+#else
-+mini_fo_umount_begin(super_block_t *sb)
-+{
-+	super_block_t *hidden_sb;
-+
-+	hidden_sb = stohs(sb);
-+
-+	if (hidden_sb->s_op->umount_begin)
-+		hidden_sb->s_op->umount_begin(hidden_sb);
-+
-+}
-+#endif
-+
-+
-+struct super_operations mini_fo_sops =
-+{
-+	read_inode:		mini_fo_read_inode,
-+#if defined(FIST_DEBUG) || defined(FIST_FILTER_SCA)
-+	write_inode:	mini_fo_write_inode,
-+#endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */
-+	put_inode:		mini_fo_put_inode,
-+#if defined(FIST_DEBUG) || defined(FIST_FILTER_SCA)
-+	delete_inode:	mini_fo_delete_inode,
-+#endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */
-+	put_super:		mini_fo_put_super,
-+	statfs:		mini_fo_statfs,
-+	remount_fs:		mini_fo_remount_fs,
-+	clear_inode:	mini_fo_clear_inode,
-+	umount_begin:	mini_fo_umount_begin,
-+};

+ 0 - 11
target/linux/generic-2.6/patches-2.6.21/210-d80211_compat.patch

@@ -1,11 +0,0 @@
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -532,6 +532,8 @@ struct net_device
- 	struct device		dev;
- 	/* space for optional statistics and wireless sysfs groups */
- 	struct attribute_group  *sysfs_groups[3];
-+	
-+	void *ieee80211_ptr;
- };
- #define to_net_dev(d) container_of(d, struct net_device, dev)
- 

+ 0 - 11
target/linux/generic-2.6/patches-2.6.21/211-no_block2mtd_readahead.patch

@@ -1,11 +0,0 @@
---- a/drivers/mtd/devices/block2mtd.c
-+++ b/drivers/mtd/devices/block2mtd.c
-@@ -41,7 +41,7 @@ struct block2mtd_dev {
- static LIST_HEAD(blkmtd_device_list);
- 
- 
--#define PAGE_READAHEAD 64
-+#define PAGE_READAHEAD 0
- static void cache_readahead(struct address_space *mapping, int index)
- {
- 	filler_t *filler = (filler_t*)mapping->a_ops->readpage;

+ 0 - 11
target/linux/generic-2.6/patches-2.6.21/212-block2mtd_erase_scan.patch

@@ -1,11 +0,0 @@
---- a/drivers/mtd/devices/block2mtd.c
-+++ b/drivers/mtd/devices/block2mtd.c
-@@ -112,7 +112,7 @@ static int _block2mtd_erase(struct block
- 		if (IS_ERR(page))
- 			return PTR_ERR(page);
- 
--		max = (u_long*)page_address(page) + PAGE_SIZE;
-+		max = (u_long*) ((u8 *) page_address(page) + PAGE_SIZE);
- 		for (p=(u_long*)page_address(page); p<max; p++)
- 			if (*p != -1UL) {
- 				lock_page(page);

+ 0 - 37
target/linux/generic-2.6/patches-2.6.21/213-kobject_uevent.patch

@@ -1,37 +0,0 @@
---- a/lib/kobject_uevent.c
-+++ b/lib/kobject_uevent.c
-@@ -30,9 +30,22 @@ u64 uevent_seqnum;
- char uevent_helper[UEVENT_HELPER_PATH_LEN] = "/sbin/hotplug";
- static DEFINE_SPINLOCK(sequence_lock);
- #if defined(CONFIG_NET)
--static struct sock *uevent_sock;
-+struct sock *uevent_sock = NULL;
-+EXPORT_SYMBOL_GPL(uevent_sock);
- #endif
- 
-+u64 uevent_next_seqnum(void)
-+{
-+	u64 seq;
-+
-+	spin_lock(&sequence_lock);
-+	seq = ++uevent_seqnum;
-+	spin_unlock(&sequence_lock);
-+	
-+	return seq;
-+}
-+EXPORT_SYMBOL_GPL(uevent_next_seqnum);
-+
- static char *action_to_string(enum kobject_action action)
- {
- 	switch (action) {
-@@ -171,9 +184,7 @@ int kobject_uevent_env(struct kobject *k
- 	}
- 
- 	/* we will send an event, request a new sequence number */
--	spin_lock(&sequence_lock);
--	seq = ++uevent_seqnum;
--	spin_unlock(&sequence_lock);
-+	seq = uevent_next_seqnum();
- 	sprintf(seq_buff, "SEQNUM=%llu", (unsigned long long)seq);
- 
- #if defined(CONFIG_NET)

+ 0 - 29
target/linux/generic-2.6/patches-2.6.21/30-fix_conflicting_getline.patch

@@ -1,29 +0,0 @@
---- a/scripts/unifdef.c
-+++ b/scripts/unifdef.c
-@@ -206,7 +206,7 @@ static void             done(void);
- static void             error(const char *);
- static int              findsym(const char *);
- static void             flushline(bool);
--static Linetype         getline(void);
-+static Linetype         get_line(void);
- static Linetype         ifeval(const char **);
- static void             ignoreoff(void);
- static void             ignoreon(void);
-@@ -512,7 +512,7 @@ process(void)
- 
- 	for (;;) {
- 		linenum++;
--		lineval = getline();
-+		lineval = get_line();
- 		trans_table[ifstate[depth]][lineval]();
- 		debug("process %s -> %s depth %d",
- 		    linetype_name[lineval],
-@@ -526,7 +526,7 @@ process(void)
-  * help from skipcomment().
-  */
- static Linetype
--getline(void)
-+get_line(void)
- {
- 	const char *cp;
- 	int cursym;

+ 0 - 21
target/linux/generic-2.6/patches-2.6.21/31-use_kbuild.h.patch

@@ -1,21 +0,0 @@
-[MIPS] Fix computation of {PGD,PMD,PTE}_T_LOG2.
-
-For the generation of asm-offset.h to work these need to be evaulatable
-by gcc as a constant expression.  This issue did exist for a while but
-didn't bite because they're only in asm-offset.h for debugging purposes.
-
---- a/include/asm-mips/pgtable.h
-+++ b/include/asm-mips/pgtable.h
-@@ -168,9 +168,9 @@ static inline void pte_clear(struct mm_s
- #define set_pud(pudptr, pudval) do { *(pudptr) = (pudval); } while(0)
- #endif
- 
--#define PGD_T_LOG2	ffz(~sizeof(pgd_t))
--#define PMD_T_LOG2	ffz(~sizeof(pmd_t))
--#define PTE_T_LOG2	ffz(~sizeof(pte_t))
-+#define PGD_T_LOG2	(__builtin_ffs(sizeof(pgd_t)) - 1)
-+#define PMD_T_LOG2	(__builtin_ffs(sizeof(pmd_t)) - 1)
-+#define PTE_T_LOG2	(__builtin_ffs(sizeof(pte_t)) - 1)
- 
- extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
- 

+ 0 - 17
target/linux/generic-2.6/patches-2.6.21/32-time_fix_timespec_add_ns.patch

@@ -1,17 +0,0 @@
-time: prevent the loop in timespec_add_ns() from being optimised away
-
-Since some architectures don't support __udivdi3().
-
---- a/include/linux/time.h
-+++ b/include/linux/time.h
-@@ -170,6 +170,10 @@ static inline void timespec_add_ns(struc
- {
- 	ns += a->tv_nsec;
- 	while(unlikely(ns >= NSEC_PER_SEC)) {
-+		/* The following asm() prevents the compiler from
-+		 * optimising this loop into a modulo operation.  */
-+		asm("" : "+r"(ns));
-+
- 		ns -= NSEC_PER_SEC;
- 		a->tv_sec++;
- 	}

+ 0 - 26
target/linux/generic-2.6/patches-2.6.21/420-gpiodev.patch

@@ -1,26 +0,0 @@
---- a/drivers/char/Kconfig
-+++ b/drivers/char/Kconfig
-@@ -984,6 +984,13 @@ config CS5535_GPIO
- 
- 	  If compiled as a module, it will be called cs5535_gpio.
- 
-+config GPIO_DEVICE
-+	tristate "GPIO device support"
-+	depends on GENERIC_GPIO
-+	help
-+	  Say Y to enable Linux GPIO device support.  This allows control of
-+	  GPIO pins using a character device
-+
- config GPIO_VR41XX
- 	tristate "NEC VR4100 series General-purpose I/O Unit support"
- 	depends on CPU_VR41XX
---- a/drivers/char/Makefile
-+++ b/drivers/char/Makefile
-@@ -90,6 +90,7 @@ obj-$(CONFIG_SCx200_GPIO)	+= scx200_gpio
- obj-$(CONFIG_PC8736x_GPIO)	+= pc8736x_gpio.o
- obj-$(CONFIG_NSC_GPIO)		+= nsc_gpio.o
- obj-$(CONFIG_CS5535_GPIO)	+= cs5535_gpio.o
-+obj-$(CONFIG_GPIO_DEVICE)	+= gpio_dev.o
- obj-$(CONFIG_GPIO_VR41XX)	+= vr41xx_giu.o
- obj-$(CONFIG_TANBAC_TB0219)	+= tb0219.o
- obj-$(CONFIG_TELCLOCK)		+= tlclk.o

+ 0 - 17
target/linux/generic-2.6/patches-2.6.21/510-yaffs_support.patch

@@ -1,17 +0,0 @@
---- a/fs/Kconfig
-+++ b/fs/Kconfig
-@@ -419,6 +419,7 @@ config FS_POSIX_ACL
- 
- source "fs/xfs/Kconfig"
- source "fs/gfs2/Kconfig"
-+source "fs/yaffs2/Kconfig"
- 
- config OCFS2_FS
- 	tristate "OCFS2 file system support"
---- a/fs/Makefile
-+++ b/fs/Makefile
-@@ -116,3 +116,4 @@ obj-$(CONFIG_HPPFS)		+= hppfs/
- obj-$(CONFIG_DEBUG_FS)		+= debugfs/
- obj-$(CONFIG_OCFS2_FS)		+= ocfs2/
- obj-$(CONFIG_GFS2_FS)           += gfs2/
-+obj-$(CONFIG_YAFFS_FS)		+= yaffs2/

+ 0 - 80
target/linux/generic-2.6/patches-2.6.21/511-yaffs_reduce_compiler_warnings.patch

@@ -1,80 +0,0 @@
---- a/fs/yaffs2/yaffs_fs.c
-+++ b/fs/yaffs2/yaffs_fs.c
-@@ -965,7 +965,7 @@ static int yaffs_readdir(struct file *f,
- 		f->f_version = inode->i_version;
- 	}
- 
--	list_for_each(i, &obj->variant.directoryVariant.children) {
-+	list_for_each(i, (struct list_head *)&obj->variant.directoryVariant.children) {
- 		curoffs++;
- 		if (curoffs >= offset) {
- 			l = list_entry(i, yaffs_Object, siblings);
-@@ -1269,7 +1269,7 @@ static int yaffs_rename(struct inode *ol
- 
- 	if (target &&
- 	    target->variantType == YAFFS_OBJECT_TYPE_DIRECTORY &&
--	    !list_empty(&target->variant.directoryVariant.children)) {
-+	    !list_empty((struct list_head *)&target->variant.directoryVariant.children)) {
- 
- 	        T(YAFFS_TRACE_OS, (KERN_DEBUG "target is non-empty dir\n"));
- 
-@@ -1503,7 +1503,7 @@ static void yaffs_put_super(struct super
- 	yaffs_GrossUnlock(dev);
- 
- 	/* we assume this is protected by lock_kernel() in mount/umount */
--	list_del(&dev->devList);
-+	list_del((struct list_head *)&dev->devList);
- 
- 	if(dev->spareBuffer){
- 		YFREE(dev->spareBuffer);
-@@ -1847,7 +1847,7 @@ static struct super_block *yaffs_interna
- 	dev->skipCheckpointWrite = options.skip_checkpoint_write;
- 
- 	/* we assume this is protected by lock_kernel() in mount/umount */
--	list_add_tail(&dev->devList, &yaffs_dev_list);
-+	list_add_tail((struct list_head *)&dev->devList, &yaffs_dev_list);
- 
- 	init_MUTEX(&dev->grossLock);
- 
---- a/fs/yaffs2/yaffs_mtdif1.c
-+++ b/fs/yaffs2/yaffs_mtdif1.c
-@@ -323,7 +323,7 @@ static int nandmtd1_TestPrerequists(stru
-  * Always returns YAFFS_OK.
-  */
- int nandmtd1_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
--	yaffs_BlockState * pState, int *pSequenceNumber)
-+	yaffs_BlockState * pState, __u32 *pSequenceNumber)
- {
- 	struct mtd_info * mtd = dev->genericDevice;
- 	int chunkNo = blockNo * dev->nChunksPerBlock;
---- a/fs/yaffs2/yaffs_mtdif1.h
-+++ b/fs/yaffs2/yaffs_mtdif1.h
-@@ -23,6 +23,6 @@ int nandmtd1_ReadChunkWithTagsFromNAND(y
- int nandmtd1_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo);
- 
- int nandmtd1_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
--	yaffs_BlockState * state, int *sequenceNumber);
-+	yaffs_BlockState * state, __u32 *sequenceNumber);
- 
- #endif
---- a/fs/yaffs2/yaffs_mtdif2.c
-+++ b/fs/yaffs2/yaffs_mtdif2.c
-@@ -188,7 +188,7 @@ int nandmtd2_MarkNANDBlockBad(struct yaf
- }
- 
- int nandmtd2_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
--			    yaffs_BlockState * state, int *sequenceNumber)
-+			    yaffs_BlockState * state, __u32 *sequenceNumber)
- {
- 	struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
- 	int retval;
---- a/fs/yaffs2/yaffs_mtdif2.h
-+++ b/fs/yaffs2/yaffs_mtdif2.h
-@@ -24,6 +24,6 @@ int nandmtd2_ReadChunkWithTagsFromNAND(y
- 				       __u8 * data, yaffs_ExtendedTags * tags);
- int nandmtd2_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo);
- int nandmtd2_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
--			    yaffs_BlockState * state, int *sequenceNumber);
-+			    yaffs_BlockState * state, __u32 *sequenceNumber);
- 
- #endif

+ 0 - 46
target/linux/generic-2.6/patches-2.6.21/900-headers_type_and_time.patch

@@ -1,46 +0,0 @@
---- a/include/linux/time.h
-+++ b/include/linux/time.h
-@@ -1,6 +1,10 @@
- #ifndef _LINUX_TIME_H
- #define _LINUX_TIME_H
- 
-+#ifndef __KERNEL__
-+#include <time.h>
-+#else
-+
- #include <linux/types.h>
- 
- #ifdef __KERNEL__
-@@ -228,4 +232,6 @@ struct itimerval {
-  */
- #define TIMER_ABSTIME			0x01
- 
-+#endif /* __KERNEL__ DEBIAN */
-+
- #endif
---- a/include/linux/types.h
-+++ b/include/linux/types.h
-@@ -1,6 +1,14 @@
- #ifndef _LINUX_TYPES_H
- #define _LINUX_TYPES_H
- 
-+/* Debian: Use userland types instead.  */
-+#ifndef __KERNEL__
-+# include <sys/types.h>
-+/* For other kernel headers.  */
-+# include <linux/posix_types.h>
-+# include <asm/types.h>
-+#else
-+
- #ifdef	__KERNEL__
- 
- #define BITS_TO_LONGS(bits) \
-@@ -162,6 +170,8 @@ typedef unsigned long blkcnt_t;
- 
- #endif /* __KERNEL_STRICT_NAMES */
- 
-+#endif /* __KERNEL__ DEBIAN */
-+
- /*
-  * Below are truly Linux-specific types that should never collide with
-  * any application/library that wants linux/types.h.

+ 0 - 138
target/linux/generic-2.6/patches-2.6.21/902-darwin_scripts_include.patch

@@ -1,138 +0,0 @@
---- a/scripts/genksyms/parse.c_shipped
-+++ b/scripts/genksyms/parse.c_shipped
-@@ -144,7 +144,9 @@
- 
- 
- #include <assert.h>
-+#ifndef __APPLE__
- #include <malloc.h>
-+#endif
- #include "genksyms.h"
- 
- static int is_typedef;
---- a/scripts/genksyms/parse.y
-+++ b/scripts/genksyms/parse.y
-@@ -24,7 +24,9 @@
- %{
- 
- #include <assert.h>
-+#ifndef __APPLE__
- #include <malloc.h>
-+#endif
- #include "genksyms.h"
- 
- static int is_typedef;
---- a/scripts/kallsyms.c
-+++ b/scripts/kallsyms.c
-@@ -30,6 +30,35 @@
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
-+#ifdef __APPLE__
-+/* Darwin has no memmem implementation, this one is ripped of the uClibc-0.9.28 source */
-+void *memmem (const void *haystack, size_t haystack_len,
-+                          const void *needle,  size_t needle_len)
-+{
-+  const char *begin;
-+  const char *const last_possible
-+    = (const char *) haystack + haystack_len - needle_len;
-+
-+  if (needle_len == 0)
-+    /* The first occurrence of the empty string is deemed to occur at
-+       the beginning of the string.  */
-+    return (void *) haystack;
-+
-+  /* Sanity check, otherwise the loop might search through the whole
-+     memory.  */
-+  if (__builtin_expect (haystack_len < needle_len, 0))
-+    return NULL;
-+
-+  for (begin = (const char *) haystack; begin <= last_possible; ++begin)
-+    if (begin[0] == ((const char *) needle)[0] &&
-+        !memcmp ((const void *) &begin[1],
-+                 (const void *) ((const char *) needle + 1),
-+                 needle_len - 1))
-+      return (void *) begin;
-+
-+  return NULL;
-+}
-+#endif
- 
- #define KSYM_NAME_LEN		127
- 
---- a/scripts/kconfig/Makefile
-+++ b/scripts/kconfig/Makefile
-@@ -87,6 +87,9 @@ check-lxdialog  := $(srctree)/$(src)/lxd
- # we really need to do so. (Do not call gcc as part of make mrproper)
- HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags)
- HOST_LOADLIBES   = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
-+ifeq ($(shell uname -s),Darwin)
-+HOST_LOADLIBES  += -lncurses
-+endif
- 
- HOST_EXTRACFLAGS += -DLOCALE
- 
---- a/scripts/mod/file2alias.c
-+++ b/scripts/mod/file2alias.c
-@@ -37,7 +37,21 @@ typedef unsigned char	__u8;
-  * even potentially has different endianness and word sizes, since
-  * we handle those differences explicitly below */
- #include "../../include/linux/mod_devicetable.h"
-+#ifndef __APPLE__
- #include "../../include/linux/input.h"
-+#else
-+#define EV_MAX                  0x1f
-+#define KEY_MUTE                113
-+#define KEY_MIN_INTERESTING     KEY_MUTE
-+#define KEY_MAX                 0x1ff
-+#define REL_MAX                 0x0f
-+#define ABS_MAX                 0x3f
-+#define MSC_MAX                 0x07
-+#define LED_MAX                 0x0f
-+#define SND_MAX                 0x07
-+#define FF_MAX          	0x7f
-+#define SW_MAX                  0x0f
-+#endif
- 
- #define ADD(str, sep, cond, field)                              \
- do {                                                            \
---- a/scripts/mod/mk_elfconfig.c
-+++ b/scripts/mod/mk_elfconfig.c
-@@ -1,7 +1,11 @@
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-+#ifndef __APPLE__
- #include <elf.h>
-+#else
-+#include "../../../../../tools/sstrip/include/elf.h"
-+#endif
- 
- int
- main(int argc, char **argv)
---- a/scripts/mod/modpost.h
-+++ b/scripts/mod/modpost.h
-@@ -7,7 +7,11 @@
- #include <sys/mman.h>
- #include <fcntl.h>
- #include <unistd.h>
-+#if !(defined(__APPLE__) || defined(__CYGWIN__))
- #include <elf.h>
-+#else
-+#include "../../../../../tools/sstrip/include/elf.h"
-+#endif
- 
- #include "elfconfig.h"
- 
---- a/scripts/mod/sumversion.c
-+++ b/scripts/mod/sumversion.c
-@@ -8,6 +8,9 @@
- #include <errno.h>
- #include <string.h>
- #include "modpost.h"
-+#ifdef __APPLE__
-+#include <limits.h>
-+#endif
- 
- /*
-  * Stolen form Cryptographic API.

+ 0 - 154
target/linux/generic-2.6/patches-2.6.21/903-hostap_txpower.patch

@@ -1,154 +0,0 @@
---- a/drivers/net/wireless/hostap/hostap_ap.c
-+++ b/drivers/net/wireless/hostap/hostap_ap.c
-@@ -2346,13 +2346,13 @@ int prism2_ap_get_sta_qual(local_info_t 
- 		addr[count].sa_family = ARPHRD_ETHER;
- 		memcpy(addr[count].sa_data, sta->addr, ETH_ALEN);
- 		if (sta->last_rx_silence == 0)
--			qual[count].qual = sta->last_rx_signal < 27 ?
--				0 : (sta->last_rx_signal - 27) * 92 / 127;
-+                        qual[count].qual = (sta->last_rx_signal - 156) == 0 ?
-+                                0 : (sta->last_rx_signal - 156) * 92 / 64;
- 		else
--			qual[count].qual = sta->last_rx_signal -
--				sta->last_rx_silence - 35;
--		qual[count].level = HFA384X_LEVEL_TO_dBm(sta->last_rx_signal);
--		qual[count].noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
-+                        qual[count].qual = (sta->last_rx_signal -
-+                                sta->last_rx_silence) * 92 / 64;
-+                qual[count].level = sta->last_rx_signal;
-+                qual[count].noise = sta->last_rx_silence;
- 		qual[count].updated = sta->last_rx_updated;
- 
- 		sta->last_rx_updated = IW_QUAL_DBM;
-@@ -2417,13 +2417,13 @@ int prism2_ap_translate_scan(struct net_
- 		memset(&iwe, 0, sizeof(iwe));
- 		iwe.cmd = IWEVQUAL;
- 		if (sta->last_rx_silence == 0)
--			iwe.u.qual.qual = sta->last_rx_signal < 27 ?
--				0 : (sta->last_rx_signal - 27) * 92 / 127;
-+	                iwe.u.qual.qual = (sta->last_rx_signal -156) == 0 ?
-+	                        0 : (sta->last_rx_signal - 156) * 92 / 64;
- 		else
--			iwe.u.qual.qual = sta->last_rx_signal -
--				sta->last_rx_silence - 35;
--		iwe.u.qual.level = HFA384X_LEVEL_TO_dBm(sta->last_rx_signal);
--		iwe.u.qual.noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
-+                        iwe.u.qual.qual = (sta->last_rx_signal -
-+                                sta->last_rx_silence) * 92 / 64;
-+                iwe.u.qual.level = sta->last_rx_signal;
-+                iwe.u.qual.noise = sta->last_rx_silence;
- 		iwe.u.qual.updated = sta->last_rx_updated;
- 		iwe.len = IW_EV_QUAL_LEN;
- 		current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
---- a/drivers/net/wireless/hostap/hostap_config.h
-+++ b/drivers/net/wireless/hostap/hostap_config.h
-@@ -47,4 +47,9 @@
-  */
- /* #define PRISM2_NO_STATION_MODES */
- 
-+/* Enable TX power Setting functions
-+ * (min att = -128 , max att =  127)
-+ */
-+#define RAW_TXPOWER_SETTING
-+
- #endif /* HOSTAP_CONFIG_H */
---- a/drivers/net/wireless/hostap/hostap.h
-+++ b/drivers/net/wireless/hostap/hostap.h
-@@ -90,6 +90,7 @@ extern const struct iw_handler_def hosta
- extern const struct ethtool_ops prism2_ethtool_ops;
- 
- int hostap_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
-+int hostap_restore_power(struct net_device *dev);
- 
- 
- #endif /* HOSTAP_H */
---- a/drivers/net/wireless/hostap/hostap_hw.c
-+++ b/drivers/net/wireless/hostap/hostap_hw.c
-@@ -933,6 +933,7 @@ static int hfa384x_set_rid(struct net_de
- 			prism2_hw_reset(dev);
- 	}
- 
-+	hostap_restore_power(dev);
- 	return res;
- }
- 
---- a/drivers/net/wireless/hostap/hostap_info.c
-+++ b/drivers/net/wireless/hostap/hostap_info.c
-@@ -428,6 +428,11 @@ static void handle_info_queue_linkstatus
- 	}
- 
- 	/* Get BSSID if we have a valid AP address */
-+
-+	if ( val == HFA384X_LINKSTATUS_CONNECTED ||
-+	     val == HFA384X_LINKSTATUS_DISCONNECTED ) 
-+			hostap_restore_power(local->dev);
-+
- 	if (connected) {
- 		netif_carrier_on(local->dev);
- 		netif_carrier_on(local->ddev);
---- a/drivers/net/wireless/hostap/hostap_ioctl.c
-+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
-@@ -1504,23 +1504,20 @@ static int prism2_txpower_hfa386x_to_dBm
- 		val = 255;
- 
- 	tmp = val;
--	tmp >>= 2;
- 
--	return -12 - tmp;
-+	return tmp;
- }
- 
- static u16 prism2_txpower_dBm_to_hfa386x(int val)
- {
- 	signed char tmp;
- 
--	if (val > 20)
--		return 128;
--	else if (val < -43)
-+	if (val > 127)
- 		return 127;
-+	else if (val < -128)
-+		return 128;
- 
- 	tmp = val;
--	tmp = -12 - tmp;
--	tmp <<= 2;
- 
- 	return (unsigned char) tmp;
- }
-@@ -4080,3 +4077,35 @@ int hostap_ioctl(struct net_device *dev,
- 
- 	return ret;
- }
-+
-+/* BUG FIX: Restore power setting value when lost due to F/W bug */
-+
-+int hostap_restore_power(struct net_device *dev)
-+{
-+        struct hostap_interface *iface = dev->priv;
-+       local_info_t *local = iface->local;
-+               
-+       u16 val;
-+       int ret = 0;
-+
-+       if (local->txpower_type == PRISM2_TXPOWER_OFF) {
-+                       val = 0xff; /* use all standby and sleep modes */
-+                       ret = local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF,
-+                                              HFA386X_CR_A_D_TEST_MODES2,
-+                                              &val, NULL);
-+       }
-+
-+#ifdef RAW_TXPOWER_SETTING
-+       if (local->txpower_type == PRISM2_TXPOWER_FIXED) {
-+               val = HFA384X_TEST_CFG_BIT_ALC;
-+               local->func->cmd(dev, HFA384X_CMDCODE_TEST |
-+                                (HFA384X_TEST_CFG_BITS << 8), 0, &val, NULL);
-+               val = prism2_txpower_dBm_to_hfa386x(local->txpower);
-+               ret = (local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF,
-+                            HFA386X_CR_MANUAL_TX_POWER, &val, NULL));
-+       }
-+#endif /* RAW_TXPOWER_SETTING */
-+       return (ret ? -EOPNOTSUPP : 0);
-+}
-+
-+EXPORT_SYMBOL(hostap_restore_power);

+ 0 - 17
target/linux/generic-2.6/patches-2.6.21/903-stddef_include.patch

@@ -1,17 +0,0 @@
---- a/include/linux/stddef.h
-+++ b/include/linux/stddef.h
-@@ -16,6 +16,7 @@ enum {
- 	false	= 0,
- 	true	= 1
- };
-+#endif /* __KERNEL__ */
- 
- #undef offsetof
- #ifdef __compiler_offsetof
-@@ -23,6 +24,5 @@ enum {
- #else
- #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
- #endif
--#endif /* __KERNEL__ */
- 
- #endif

+ 0 - 20
target/linux/generic-2.6/patches-2.6.21/904-ls_time_locale.patch

@@ -1,20 +0,0 @@
---- a/scripts/gen_initramfs_list.sh
-+++ b/scripts/gen_initramfs_list.sh
-@@ -125,7 +125,7 @@ parse() {
- 			str="${ftype} ${name} ${location} ${str}"
- 			;;
- 		"nod")
--			local dev=`LC_ALL=C ls -l "${location}"`
-+			local dev=`LC_ALL=C ls -l --time-style=locale "${location}"`
- 			local maj=`field 5 ${dev}`
- 			local min=`field 6 ${dev}`
- 			maj=${maj%,}
-@@ -135,7 +135,7 @@ parse() {
- 			str="${ftype} ${name} ${str} ${dev} ${maj} ${min}"
- 			;;
- 		"slink")
--			local target=`field 11 $(LC_ALL=C ls -l "${location}")`
-+			local target=`field 11 $(LC_ALL=C ls -l --time-style=locale "${location}")`
- 			str="${ftype} ${name} ${target} ${str}"
- 			;;
- 		*)

+ 0 - 7
target/linux/generic-2.6/patches-2.6.21/990-buildfix.patch

@@ -1,7 +0,0 @@
---- a/scripts/mod/sumversion.c
-+++ b/scripts/mod/sumversion.c
-@@ -1,3 +1,4 @@
-+#include <linux/limits.h>
- #include <netinet/in.h>
- #ifdef __sun__
- #include <inttypes.h>

+ 0 - 52
target/linux/generic-2.6/patches-2.6.21/999-backport_ip_hdr_and_friends.patch

@@ -1,52 +0,0 @@
---- a/include/linux/ip.h
-+++ b/include/linux/ip.h
-@@ -104,6 +104,16 @@ struct iphdr {
- 	/*The options start here. */
- };
- 
-+#ifdef __KERNEL__
-+#include <linux/skbuff.h>
-+
-+static inline struct iphdr *ip_hdr(const struct sk_buff *skb)
-+{
-+	return (struct iphdr *)skb_network_header(skb);
-+}
-+
-+#endif
-+
- struct ip_auth_hdr {
- 	__u8  nexthdr;
- 	__u8  hdrlen;		/* This one is measured in 32 bit units! */
---- a/include/linux/skbuff.h
-+++ b/include/linux/skbuff.h
-@@ -966,6 +966,16 @@ static inline void skb_reserve(struct sk
- 	skb->tail += len;
- }
- 
-+static inline unsigned char *skb_network_header(const struct sk_buff *skb)
-+{
-+	return skb->nh.raw;
-+}
-+
-+static inline unsigned char *skb_tail_pointer(const struct sk_buff *skb)
-+{
-+	return skb->tail;
-+}
-+
- /*
-  * CPUs often take a performance hit when accessing unaligned memory
-  * locations. The actual performance hit varies, it can be small if the
---- a/include/net/ip.h
-+++ b/include/net/ip.h
-@@ -43,6 +43,11 @@ struct inet_skb_parm
- #define IPSKB_REROUTED		16
- };
- 
-+static inline unsigned int ip_hdrlen(const struct sk_buff *skb)
-+{
-+	return ip_hdr(skb)->ihl * 4;
-+}
-+
- struct ipcm_cookie
- {
- 	__be32			addr;

+ 0 - 14
target/linux/generic-2.6/patches-2.6.21/999-use_preinit_as_init.patch

@@ -1,14 +0,0 @@
---- a/init/main.c
-+++ b/init/main.c
-@@ -764,10 +764,7 @@ static int noinline init_post(void)
- 		printk(KERN_WARNING "Failed to execute %s.  Attempting "
- 					"defaults...\n", execute_command);
- 	}
--	run_init_process("/sbin/init");
--	run_init_process("/etc/init");
--	run_init_process("/bin/init");
--	run_init_process("/bin/sh");
-+	run_init_process("/etc/preinit");
- 
- 	panic("No init found.  Try passing init= option to kernel.");
- }