summaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
Diffstat (limited to 'packages')
-rw-r--r--packages/alsa/alsa-fpu.inc6
-rw-r--r--packages/alsa/alsa-lib_1.0.14.bb5
-rw-r--r--packages/alsa/alsa-state.bb2
-rw-r--r--packages/alsa/alsa-state/akita/.mtn2git_empty0
-rw-r--r--packages/alsa/alsa-state/akita/asound.state619
-rw-r--r--packages/alsa/alsa-state/c7x0/asound.state27
-rw-r--r--packages/bluez/bluez-cups-backend_3.18.bb26
-rw-r--r--packages/bluez/bluez-cups-backend_3.19.bb26
-rw-r--r--packages/bluez/bluez-libs_3.18.bb1
-rw-r--r--packages/bluez/bluez-libs_3.19.bb1
-rw-r--r--packages/bluez/bluez-utils-alsa_3.18.bb24
-rw-r--r--packages/bluez/bluez-utils-alsa_3.19.bb24
-rw-r--r--packages/bluez/bluez-utils3.inc143
-rw-r--r--packages/bluez/bluez-utils_3.18.bb23
-rw-r--r--packages/bluez/bluez-utils_3.19.bb23
-rw-r--r--packages/gnome/epiphany_2.19.6.bb2
-rw-r--r--packages/gnome/libwnck_2.10.2.bb9
-rw-r--r--packages/gnome/libwnck_2.12.1.bb10
-rw-r--r--packages/gnome/libwnck_2.13.5.bb7
-rw-r--r--packages/gnome/libwnck_2.8.1.bb11
-rw-r--r--packages/gtk+/gdk-pixbuf-csource-native_2.10.14.bb4
-rw-r--r--packages/gtk+/gtk+.inc2
-rw-r--r--packages/gtk+/gtk+_2.12.0.bb4
-rw-r--r--packages/libetpan/libetpan_0.52.bb22
-rw-r--r--packages/libglade/libglade-2.6.2/.mtn2git_empty0
-rw-r--r--packages/libglade/libglade-2.6.2/glade-cruft.patch100
-rw-r--r--packages/libglade/libglade-2.6.2/no-xml2.patch499
-rw-r--r--packages/libglade/libglade_2.6.2.bb32
-rw-r--r--packages/links/links-x11_2.0+2.1pre30.bb (renamed from packages/links/links-x11_2.0+2.1pre26.bb)0
-rw-r--r--packages/links/links_2.0+2.1pre30.bb (renamed from packages/links/links_2.0+2.1pre26.bb)0
-rw-r--r--packages/linux/linux-openmoko-devel/defconfig4
-rw-r--r--packages/linux/linux-openmoko-devel/printascii.patch12
-rw-r--r--packages/linux/linux-openmoko-devel/squashfs.patch4386
-rw-r--r--packages/linux/linux-openmoko-devel_svn.bb20
-rw-r--r--packages/matchbox-keyboard/files/matchbox-keyboard-hide-delay.patch99
-rw-r--r--packages/matchbox-keyboard/matchbox-keyboard-inputmethod_svn.bb5
-rw-r--r--packages/navit/.mtn2git_empty0
-rw-r--r--packages/navit/files/.mtn2git_empty0
-rw-r--r--packages/navit/files/compile-fix.patch8
-rw-r--r--packages/navit/navit_0.0.1.bb14
-rw-r--r--packages/openmoko2/openmoko-browser2_svn.bb7
-rw-r--r--packages/openmoko2/openmoko-sound-system2_0.1.0.bb4
-rw-r--r--packages/openmoko2/openmoko-sound-theme-standard2_svn.bb4
-rw-r--r--packages/pkgconfig/pkgconfig-0.22/sysroot-support.patch102
-rw-r--r--packages/pkgconfig/pkgconfig.inc3
-rw-r--r--packages/poppler/poppler_0.6.bb6
-rw-r--r--packages/python/python-pybluez_0.13.bb10
-rw-r--r--packages/sylpheed/claws-mail_3.0.1.bb43
-rw-r--r--packages/uboot/uboot-openmoko_1.2.0+gitf34024d4a328e6edd906456da98d2c537155c4f7+svn2943.bb15
-rw-r--r--packages/uboot/uboot-openmoko_svn.bb15
50 files changed, 6328 insertions, 81 deletions
diff --git a/packages/alsa/alsa-fpu.inc b/packages/alsa/alsa-fpu.inc
new file mode 100644
index 0000000000..ebd3493e6c
--- /dev/null
+++ b/packages/alsa/alsa-fpu.inc
@@ -0,0 +1,6 @@
+
+def get_alsa_fpu_setting(bb, d):
+ if bb.data.getVar('TARGET_FPU', d, 1) in [ 'soft' ]:
+ return "--with-softfloat"
+ return ""
+
diff --git a/packages/alsa/alsa-lib_1.0.14.bb b/packages/alsa/alsa-lib_1.0.14.bb
index de805b9a4b..ba46342ae7 100644
--- a/packages/alsa/alsa-lib_1.0.14.bb
+++ b/packages/alsa/alsa-lib_1.0.14.bb
@@ -3,7 +3,7 @@ HOMEPAGE = "http://www.alsa-project.org"
SECTION = "libs/multimedia"
LICENSE = "GPL"
-PR = "r1"
+PR = "r2"
# configure.in sets -D__arm__ on the command line for any arm system
# (not just those with the ARM instruction set), this should be removed,
@@ -17,6 +17,9 @@ SRC_URI = "ftp://ftp.alsa-project.org/pub/lib/alsa-lib-${PV}.tar.bz2 \
inherit autotools pkgconfig
+require alsa-fpu.inc
+EXTRA_OECONF += "${@get_alsa_fpu_setting(bb, d)} "
+
EXTRA_OECONF = "--with-cards=pdaudiocf --with-oss=yes"
do_stage () {
diff --git a/packages/alsa/alsa-state.bb b/packages/alsa/alsa-state.bb
index 55541872fa..e2a92dcfc8 100644
--- a/packages/alsa/alsa-state.bb
+++ b/packages/alsa/alsa-state.bb
@@ -8,7 +8,7 @@ DESCRIPTION = "Default ALSA configuration"
LICENSE = "GPL"
RRECOMMENDS_alsa-state = "alsa-states"
PV = "0.1.0"
-PR = "r0"
+PR = "r1"
SRC_URI = " \
file://asoundrc \
diff --git a/packages/alsa/alsa-state/akita/.mtn2git_empty b/packages/alsa/alsa-state/akita/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/alsa/alsa-state/akita/.mtn2git_empty
diff --git a/packages/alsa/alsa-state/akita/asound.state b/packages/alsa/alsa-state/akita/asound.state
new file mode 100644
index 0000000000..ee5ef519c3
--- /dev/null
+++ b/packages/alsa/alsa-state/akita/asound.state
@@ -0,0 +1,619 @@
+state.Spitz {
+ control.1 {
+ comment.access 'read write'
+ comment.type INTEGER
+ comment.count 2
+ comment.range '0 - 63'
+ iface MIXER
+ name 'Capture Volume'
+ value.0 23
+ value.1 23
+ }
+ control.2 {
+ comment.access 'read write'
+ comment.type BOOLEAN
+ comment.count 2
+ iface MIXER
+ name 'Capture ZC Switch'
+ value.0 false
+ value.1 false
+ }
+ control.3 {
+ comment.access 'read write'
+ comment.type BOOLEAN
+ comment.count 2
+ iface MIXER
+ name 'Capture Switch'
+ value.0 false
+ value.1 false
+ }
+ control.4 {
+ comment.access 'read write'
+ comment.type BOOLEAN
+ comment.count 2
+ iface MIXER
+ name 'Headphone Playback ZC Switch'
+ value.0 false
+ value.1 false
+ }
+ control.5 {
+ comment.access 'read write'
+ comment.type BOOLEAN
+ comment.count 2
+ iface MIXER
+ name 'Speaker Playback ZC Switch'
+ value.0 false
+ value.1 false
+ }
+ control.6 {
+ comment.access 'read write'
+ comment.type ENUMERATED
+ comment.count 1
+ comment.item.0 None
+ comment.item.1 '32Khz'
+ comment.item.2 '44.1Khz'
+ comment.item.3 '48Khz'
+ iface MIXER
+ name 'Playback De-emphasis'
+ value None
+ }
+ control.7 {
+ comment.access 'read write'
+ comment.type ENUMERATED
+ comment.count 1
+ comment.item.0 Normal
+ comment.item.1 'L Invert'
+ comment.item.2 'R Invert'
+ comment.item.3 'L + R Invert'
+ iface MIXER
+ name 'Capture Polarity'
+ value Normal
+ }
+ control.8 {
+ comment.access 'read write'
+ comment.type BOOLEAN
+ comment.count 1
+ iface MIXER
+ name 'Playback 6dB Attenuate'
+ value false
+ }
+ control.9 {
+ comment.access 'read write'
+ comment.type BOOLEAN
+ comment.count 1
+ iface MIXER
+ name 'Capture 6dB Attenuate'
+ value false
+ }
+ control.10 {
+ comment.access 'read write'
+ comment.type INTEGER
+ comment.count 2
+ comment.range '0 - 255'
+ iface MIXER
+ name 'PCM Volume'
+ value.0 255
+ value.1 255
+ }
+ control.11 {
+ comment.access 'read write'
+ comment.type ENUMERATED
+ comment.count 1
+ comment.item.0 'Linear Control'
+ comment.item.1 'Adaptive Boost'
+ iface MIXER
+ name 'Bass Boost'
+ value 'Linear Control'
+ }
+ control.12 {
+ comment.access 'read write'
+ comment.type ENUMERATED
+ comment.count 1
+ comment.item.0 '130Hz @ 48kHz'
+ comment.item.1 '200Hz @ 48kHz'
+ iface MIXER
+ name 'Bass Filter'
+ value '130Hz @ 48kHz'
+ }
+ control.13 {
+ comment.access 'read write'
+ comment.type INTEGER
+ comment.count 1
+ comment.range '0 - 15'
+ iface MIXER
+ name 'Bass Volume'
+ value 11
+ }
+ control.14 {
+ comment.access 'read write'
+ comment.type INTEGER
+ comment.count 1
+ comment.range '0 - 15'
+ iface MIXER
+ name 'Treble Volume'
+ value 11
+ }
+ control.15 {
+ comment.access 'read write'
+ comment.type ENUMERATED
+ comment.count 1
+ comment.item.0 '8kHz'
+ comment.item.1 '4kHz'
+ iface MIXER
+ name 'Treble Cut-off'
+ value '8kHz'
+ }
+ control.16 {
+ comment.access 'read write'
+ comment.type BOOLEAN
+ comment.count 1
+ iface MIXER
+ name '3D Switch'
+ value false
+ }
+ control.17 {
+ comment.access 'read write'
+ comment.type INTEGER
+ comment.count 1
+ comment.range '0 - 15'
+ iface MIXER
+ name '3D Volume'
+ value 9
+ }
+ control.18 {
+ comment.access 'read write'
+ comment.type ENUMERATED
+ comment.count 1
+ comment.item.0 '200Hz'
+ comment.item.1 '500Hz'
+ iface MIXER
+ name '3D Lower Cut-off'
+ value '200Hz'
+ }
+ control.19 {
+ comment.access 'read write'
+ comment.type ENUMERATED
+ comment.count 1
+ comment.item.0 '2.2kHz'
+ comment.item.1 '1.5kHz'
+ iface MIXER
+ name '3D Upper Cut-off'
+ value '2.2kHz'
+ }
+ control.20 {
+ comment.access 'read write'
+ comment.type ENUMERATED
+ comment.count 1
+ comment.item.0 Capture
+ comment.item.1 Playback
+ iface MIXER
+ name '3D Mode'
+ value Playback
+ }
+ control.21 {
+ comment.access 'read write'
+ comment.type INTEGER
+ comment.count 1
+ comment.range '0 - 7'
+ iface MIXER
+ name 'ALC Capture Target Volume'
+ value 3
+ }
+ control.22 {
+ comment.access 'read write'
+ comment.type INTEGER
+ comment.count 1
+ comment.range '0 - 7'
+ iface MIXER
+ name 'ALC Capture Max Volume'
+ value 7
+ }
+ control.23 {
+ comment.access 'read write'
+ comment.type ENUMERATED
+ comment.count 1
+ comment.item.0 Off
+ comment.item.1 Right
+ comment.item.2 Left
+ comment.item.3 Stereo
+ iface MIXER
+ name 'ALC Capture Function'
+ value Left
+ }
+ control.24 {
+ comment.access 'read write'
+ comment.type BOOLEAN
+ comment.count 1
+ iface MIXER
+ name 'ALC Capture ZC Switch'
+ value false
+ }
+ control.25 {
+ comment.access 'read write'
+ comment.type INTEGER
+ comment.count 1
+ comment.range '0 - 15'
+ iface MIXER
+ name 'ALC Capture Hold Time'
+ value 0
+ }
+ control.26 {
+ comment.access 'read write'
+ comment.type INTEGER
+ comment.count 1
+ comment.range '0 - 15'
+ iface MIXER
+ name 'ALC Capture Decay Time'
+ value 3
+ }
+ control.27 {
+ comment.access 'read write'
+ comment.type INTEGER
+ comment.count 1
+ comment.range '0 - 15'
+ iface MIXER
+ name 'ALC Capture Attack Time'
+ value 2
+ }
+ control.28 {
+ comment.access 'read write'
+ comment.type INTEGER
+ comment.count 1
+ comment.range '0 - 31'
+ iface MIXER
+ name 'ALC Capture NG Threshold'
+ value 0
+ }
+ control.29 {
+ comment.access 'read write'
+ comment.type ENUMERATED
+ comment.count 1
+ comment.item.0 '2.2kHz'
+ comment.item.1 '1.5kHz'
+ iface MIXER
+ name 'ALC Capture NG Type'
+ value '2.2kHz'
+ }
+ control.30 {
+ comment.access 'read write'
+ comment.type BOOLEAN
+ comment.count 1
+ iface MIXER
+ name 'ALC Capture NG Switch'
+ value false
+ }
+ control.31 {
+ comment.access 'read write'
+ comment.type INTEGER
+ comment.count 1
+ comment.range '0 - 255'
+ iface MIXER
+ name 'Left ADC Capture Volume'
+ value 195
+ }
+ control.32 {
+ comment.access 'read write'
+ comment.type INTEGER
+ comment.count 1
+ comment.range '0 - 255'
+ iface MIXER
+ name 'Right ADC Capture Volume'
+ value 0
+ }
+ control.33 {
+ comment.access 'read write'
+ comment.type BOOLEAN
+ comment.count 1
+ iface MIXER
+ name 'ZC Timeout Switch'
+ value false
+ }
+ control.34 {
+ comment.access 'read write'
+ comment.type BOOLEAN
+ comment.count 1
+ iface MIXER
+ name 'Playback Invert Switch'
+ value false
+ }
+ control.35 {
+ comment.access 'read write'
+ comment.type BOOLEAN
+ comment.count 1
+ iface MIXER
+ name 'Right Speaker Playback Invert Switch'
+ value true
+ }
+ control.36 {
+ comment.access 'read write'
+ comment.type INTEGER
+ comment.count 2
+ comment.range '0 - 3'
+ iface MIXER
+ name 'Mic Boost'
+ value.0 0
+ value.1 0
+ }
+ control.37 {
+ comment.access 'read write'
+ comment.type INTEGER
+ comment.count 2
+ comment.range '0 - 7'
+ iface MIXER
+ name 'Bypass Left Playback Volume'
+ value.0 0
+ value.1 0
+ }
+ control.38 {
+ comment.access 'read write'
+ comment.type INTEGER
+ comment.count 2
+ comment.range '0 - 7'
+ iface MIXER
+ name 'Bypass Right Playback Volume'
+ value.0 0
+ value.1 0
+ }
+ control.39 {
+ comment.access 'read write'
+ comment.type INTEGER
+ comment.count 2
+ comment.range '0 - 7'
+ iface MIXER
+ name 'Bypass Mono Playback Volume'
+ value.0 0
+ value.1 0
+ }
+ control.40 {
+ comment.access 'read write'
+ comment.type BOOLEAN
+ comment.count 1
+ iface MIXER
+ name 'Mono Playback ZC Switch'
+ value false
+ }
+ control.41 {
+ comment.access 'read write'
+ comment.type INTEGER
+ comment.count 2
+ comment.range '0 - 127'
+ iface MIXER
+ name 'Headphone Playback Volume'
+ value.0 121
+ value.1 121
+ }
+ control.42 {
+ comment.access 'read write'
+ comment.type INTEGER
+ comment.count 2
+ comment.range '0 - 127'
+ iface MIXER
+ name 'Speaker Playback Volume'
+ value.0 121
+ value.1 121
+ }
+ control.43 {
+ comment.access 'read write'
+ comment.type INTEGER
+ comment.count 1
+ comment.range '0 - 127'
+ iface MIXER
+ name 'Mono Playback Volume'
+ value 0
+ }
+ control.44 {
+ comment.access 'read write'
+ comment.type ENUMERATED
+ comment.count 1
+ comment.item.0 Stereo
+ comment.item.1 'Mono (Left)'
+ comment.item.2 'Mono (Right)'
+ comment.item.3 'Digital Mono'
+ iface MIXER
+ name 'Right ADC Mux'
+ value 'Mono (Left)'
+ }
+ control.45 {
+ comment.access 'read write'
+ comment.type ENUMERATED
+ comment.count 1
+ comment.item.0 Stereo
+ comment.item.1 'Mono (Left)'
+ comment.item.2 'Mono (Right)'
+ comment.item.3 'Digital Mono'
+ iface MIXER
+ name 'Left ADC Mux'
+ value 'Mono (Left)'
+ }
+ control.46 {
+ comment.access 'read write'
+ comment.type ENUMERATED
+ comment.count 1
+ comment.item.0 'Line 1'
+ comment.item.1 'Line 2'
+ iface MIXER
+ name 'Differential Mux'
+ value 'Line 1'
+ }
+ control.47 {
+ comment.access 'read write'
+ comment.type ENUMERATED
+ comment.count 1
+ comment.item.0 VREF
+ comment.item.1 'ROUT1 + Vol'
+ comment.item.2 MonoOut
+ comment.item.3 ROUT1
+ iface MIXER
+ name 'Out3 Mux'
+ value VREF
+ }
+ control.48 {
+ comment.access 'read write'
+ comment.type ENUMERATED
+ comment.count 1
+ comment.item.0 'Line 1'
+ comment.item.1 'Line 2'
+ comment.item.2 'Line 3'
+ comment.item.3 PGA
+ comment.item.4 Differential
+ iface MIXER
+ name 'Right Line Mux'
+ value 'Line 2'
+ }
+ control.49 {
+ comment.access 'read write'
+ comment.type ENUMERATED
+ comment.count 1
+ comment.item.0 'Line 1'
+ comment.item.1 'Line 2'
+ comment.item.2 'Line 3'
+ comment.item.3 PGA
+ comment.item.4 Differential
+ iface MIXER
+ name 'Left Line Mux'
+ value 'Line 1'
+ }
+ control.50 {
+ comment.access 'read write'
+ comment.type ENUMERATED
+ comment.count 1
+ comment.item.0 'Line 1'
+ comment.item.1 'Line 2'
+ comment.item.2 'Line 3'
+ comment.item.3 Differential
+ iface MIXER
+ name 'Right PGA Mux'
+ value 'Line 2'
+ }
+ control.51 {
+ comment.access 'read write'
+ comment.type ENUMERATED
+ comment.count 1
+ comment.item.0 'Line 1'
+ comment.item.1 'Line 2'
+ comment.item.2 'Line 3'
+ comment.item.3 Differential
+ iface MIXER
+ name 'Left PGA Mux'
+ value 'Line 1'
+ }
+ control.52 {
+ comment.access 'read write'
+ comment.type BOOLEAN
+ comment.count 1
+ iface MIXER
+ name 'Mono Mixer Left Playback Switch'
+ value false
+ }
+ control.53 {
+ comment.access 'read write'
+ comment.type BOOLEAN
+ comment.count 1
+ iface MIXER
+ name 'Mono Mixer Left Bypass Switch'
+ value false
+ }
+ control.54 {
+ comment.access 'read write'
+ comment.type BOOLEAN
+ comment.count 1
+ iface MIXER
+ name 'Mono Mixer Right Playback Switc'
+ value false
+ }
+ control.55 {
+ comment.access 'read write'
+ comment.type BOOLEAN
+ comment.count 1
+ iface MIXER
+ name 'Mono Mixer Right Bypass Switch'
+ value false
+ }
+ control.56 {
+ comment.access 'read write'
+ comment.type BOOLEAN
+ comment.count 1
+ iface MIXER
+ name 'Right Mixer Left Playback Switc'
+ value false
+ }
+ control.57 {
+ comment.access 'read write'
+ comment.type BOOLEAN
+ comment.count 1
+ iface MIXER
+ name 'Right Mixer Left Bypass Switch'
+ value false
+ }
+ control.58 {
+ comment.access 'read write'
+ comment.type BOOLEAN
+ comment.count 1
+ iface MIXER
+ name 'Right Mixer Playback Switch'
+ value true
+ }
+ control.59 {
+ comment.access 'read write'
+ comment.type BOOLEAN
+ comment.count 1
+ iface MIXER
+ name 'Right Mixer Right Bypass Switch'
+ value false
+ }
+ control.60 {
+ comment.access 'read write'
+ comment.type BOOLEAN
+ comment.count 1
+ iface MIXER
+ name 'Left Mixer Playback Switch'
+ value true
+ }
+ control.61 {
+ comment.access 'read write'
+ comment.type BOOLEAN
+ comment.count 1
+ iface MIXER
+ name 'Left Mixer Left Bypass Switch'
+ value false
+ }
+ control.62 {
+ comment.access 'read write'
+ comment.type BOOLEAN
+ comment.count 1
+ iface MIXER
+ name 'Left Mixer Right Playback Switc'
+ value false
+ }
+ control.63 {
+ comment.access 'read write'
+ comment.type BOOLEAN
+ comment.count 1
+ iface MIXER
+ name 'Left Mixer Right Bypass Switch'
+ value false
+ }
+ control.64 {
+ comment.access 'read write'
+ comment.type ENUMERATED
+ comment.count 1
+ comment.item.0 Headphone
+ comment.item.1 Mic
+ comment.item.2 Line
+ comment.item.3 Headset
+ comment.item.4 Off
+ iface MIXER
+ name 'Jack Function'
+ value Off
+ }
+ control.65 {
+ comment.access 'read write'
+ comment.type ENUMERATED
+ comment.count 1
+ comment.item.0 On
+ comment.item.1 Off
+ iface MIXER
+ name 'Speaker Function'
+ value On
+ }
+}
diff --git a/packages/alsa/alsa-state/c7x0/asound.state b/packages/alsa/alsa-state/c7x0/asound.state
index 7fd648fcf6..caef65c120 100644
--- a/packages/alsa/alsa-state/c7x0/asound.state
+++ b/packages/alsa/alsa-state/c7x0/asound.state
@@ -5,16 +5,16 @@ state.Corgi {
comment.count 2
comment.range '0 - 127'
iface MIXER
- name 'Playback Volume'
- value.0 103
- value.1 103
+ name 'Master Playback Volume'
+ value.0 98
+ value.1 98
}
control.2 {
comment.access 'read write'
comment.type BOOLEAN
comment.count 2
iface MIXER
- name 'Playback Switch'
+ name 'Master Playback ZC Switch'
value.0 false
value.1 false
}
@@ -25,15 +25,15 @@ state.Corgi {
comment.range '0 - 31'
iface MIXER
name 'Capture Volume'
- value.0 23
- value.1 23
+ value.0 31
+ value.1 31
}
control.4 {
comment.access 'read write'
comment.type BOOLEAN
comment.count 2
iface MIXER
- name 'Capture Switch'
+ name 'Line Capture Switch'
value.0 false
value.1 false
}
@@ -51,7 +51,7 @@ state.Corgi {
comment.count 1
iface MIXER
name 'Capture Mic Switch'
- value true
+ value false
}
control.7 {
comment.access 'read write'
@@ -106,7 +106,7 @@ state.Corgi {
comment.count 1
iface MIXER
name 'Output Mixer Line Bypass Switch'
- value true
+ value false
}
control.13 {
comment.access 'read write'
@@ -122,7 +122,7 @@ state.Corgi {
comment.count 1
iface MIXER
name 'Output Mixer HiFi Playback Swit'
- value false
+ value true
}
control.15 {
comment.access 'read write'
@@ -141,11 +141,10 @@ state.Corgi {
comment.access 'read write'
comment.type ENUMERATED
comment.count 1
- comment.item.0 Auto
- comment.item.1 On
- comment.item.2 Off
+ comment.item.0 On
+ comment.item.1 Off
iface MIXER
name 'Speaker Function'
- value On
+ value Off
}
}
diff --git a/packages/bluez/bluez-cups-backend_3.18.bb b/packages/bluez/bluez-cups-backend_3.18.bb
new file mode 100644
index 0000000000..64884fa904
--- /dev/null
+++ b/packages/bluez/bluez-cups-backend_3.18.bb
@@ -0,0 +1,26 @@
+require bluez-utils3.inc
+
+DEPENDS += "cups"
+
+# see bluez-utils3.inc for the explanation of these option
+EXTRA_OECONF = " \
+ --enable-bccmd \
+ --enable-hid2hci \
+ --disable-alsa \
+ --enable-cups \
+ --enable-glib \
+ --disable-sdpd \
+ --enable-network \
+ --enable-serial \
+ --enable-input \
+ --enable-audio \
+ --enable-echo \
+ --enable-configfile \
+ --enable-initscripts \
+ --enable-test \
+ "
+
+PACKAGES = "${PN}"
+
+FILES_${PN} = "${libdir}/cups/backend/bluetooth"
+RDEPENDS_${PN} = "cups" \ No newline at end of file
diff --git a/packages/bluez/bluez-cups-backend_3.19.bb b/packages/bluez/bluez-cups-backend_3.19.bb
new file mode 100644
index 0000000000..64884fa904
--- /dev/null
+++ b/packages/bluez/bluez-cups-backend_3.19.bb
@@ -0,0 +1,26 @@
+require bluez-utils3.inc
+
+DEPENDS += "cups"
+
+# see bluez-utils3.inc for the explanation of these option
+EXTRA_OECONF = " \
+ --enable-bccmd \
+ --enable-hid2hci \
+ --disable-alsa \
+ --enable-cups \
+ --enable-glib \
+ --disable-sdpd \
+ --enable-network \
+ --enable-serial \
+ --enable-input \
+ --enable-audio \
+ --enable-echo \
+ --enable-configfile \
+ --enable-initscripts \
+ --enable-test \
+ "
+
+PACKAGES = "${PN}"
+
+FILES_${PN} = "${libdir}/cups/backend/bluetooth"
+RDEPENDS_${PN} = "cups" \ No newline at end of file
diff --git a/packages/bluez/bluez-libs_3.18.bb b/packages/bluez/bluez-libs_3.18.bb
new file mode 100644
index 0000000000..6ddf62a4fb
--- /dev/null
+++ b/packages/bluez/bluez-libs_3.18.bb
@@ -0,0 +1 @@
+require bluez-libs.inc
diff --git a/packages/bluez/bluez-libs_3.19.bb b/packages/bluez/bluez-libs_3.19.bb
new file mode 100644
index 0000000000..6ddf62a4fb
--- /dev/null
+++ b/packages/bluez/bluez-libs_3.19.bb
@@ -0,0 +1 @@
+require bluez-libs.inc
diff --git a/packages/bluez/bluez-utils-alsa_3.18.bb b/packages/bluez/bluez-utils-alsa_3.18.bb
new file mode 100644
index 0000000000..e2f48fba49
--- /dev/null
+++ b/packages/bluez/bluez-utils-alsa_3.18.bb
@@ -0,0 +1,24 @@
+require bluez-utils3.inc
+
+DEPENDS += "alsa-lib"
+
+# see bluez-utils3.inc for the explanation of these option
+EXTRA_OECONF = " \
+ --enable-bccmd \
+ --disable-hid2hci \
+ --enable-alsa \
+ --disable-cups \
+ --enable-glib \
+ --disable-sdpd \
+ --enable-network \
+ --enable-serial \
+ --enable-input \
+ --enable-audio \
+ --enable-echo \
+ --enable-configfile \
+ --enable-initscripts \
+ --enable-test \
+ "
+
+PACKAGES = "${PN}"
+FILES_${PN} = "${libdir}/alsa-lib/libasound*"
diff --git a/packages/bluez/bluez-utils-alsa_3.19.bb b/packages/bluez/bluez-utils-alsa_3.19.bb
new file mode 100644
index 0000000000..e2f48fba49
--- /dev/null
+++ b/packages/bluez/bluez-utils-alsa_3.19.bb
@@ -0,0 +1,24 @@
+require bluez-utils3.inc
+
+DEPENDS += "alsa-lib"
+
+# see bluez-utils3.inc for the explanation of these option
+EXTRA_OECONF = " \
+ --enable-bccmd \
+ --disable-hid2hci \
+ --enable-alsa \
+ --disable-cups \
+ --enable-glib \
+ --disable-sdpd \
+ --enable-network \
+ --enable-serial \
+ --enable-input \
+ --enable-audio \
+ --enable-echo \
+ --enable-configfile \
+ --enable-initscripts \
+ --enable-test \
+ "
+
+PACKAGES = "${PN}"
+FILES_${PN} = "${libdir}/alsa-lib/libasound*"
diff --git a/packages/bluez/bluez-utils3.inc b/packages/bluez/bluez-utils3.inc
new file mode 100644
index 0000000000..ddf90a2248
--- /dev/null
+++ b/packages/bluez/bluez-utils3.inc
@@ -0,0 +1,143 @@
+DESCRIPTION = "Linux Bluetooth Stack Userland Utilities."
+SECTION = "console"
+PRIORITY = "optional"
+DEPENDS = "gstreamer gst-plugins-base bluez-libs-${PV} libusb dbus glib-2.0"
+PROVIDES = "bluez-utils-dbus"
+RPROVIDES_${PN} = "bluez-pan bluez-sdp bluez-utils-dbus"
+RREPLACES = "bluez-utils-dbus"
+RCONFLICTS_${PN} = "bluez-utils-nodbus"
+LICENSE = "GPL"
+
+# ti patch doesn't apply, people using it should rediff it and send it upstream
+SRC_URI = "http://bluez.sourceforge.net/download/bluez-utils-${PV}.tar.gz \
+ file://hcid.conf "
+# file://hciattach-ti-bts.patch;patch=1 \
+
+S = "${WORKDIR}/bluez-utils-${PV}"
+
+inherit autotools update-rc.d
+
+EXTRA_OECONF = " \
+ --enable-bccmd \
+ --enable-hid2hci \
+ --enable-alsa \
+ --enable-cups \
+ --enable-glib \
+ --disable-sdpd \
+ --enable-network \
+ --enable-serial \
+ --enable-input \
+ --enable-audio \
+ --enable-echo \
+ --enable-configfile \
+ --enable-initscripts \
+ --enable-test \
+ "
+
+# The config options are explained below:
+
+# --enable-obex enable OBEX support
+# --enable-alsa enable ALSA support, not needed for nokia770, nokia800 and fic-gtao1
+# --enable-cups install CUPS backend support
+# --enable-bccmd install BCCMD interface utility
+# --enable-avctrl install Audio/Video control utility
+# --enable-hid2hci install HID mode switching utility
+# --enable-dfutool install DFU firmware upgrade utility
+
+# --enable-glib For systems that use and install GLib anyway
+# --disable-sdpd The sdpd is obsolete and should no longer be used. This of course requires that hcid will be started with -s to enable the SDP server
+
+#Following services can be enabled so far:
+# --enable-network
+# --enable-serial
+# --enable-input
+# --enable-audio
+# --enable-echo
+
+#There is no need to modify any init script. They will be started
+#automatically or on demand. Only /etc/bluetooth/*.service files should
+#be patched to change name or the autostart value.
+# --enable-configfile
+# --enable-initscripts
+
+#For even smaller -doc packages
+# --disable-manpages
+# --disable-pcmciarules
+
+#I haven't seen any embedded device with HID proxy support. So simply
+#disable it:
+# --disable-hid2hci
+
+
+do_install_append() {
+ install -d ${D}${base_sbindir} ${D}${base_bindir}/ ${D}${sysconfdir}/apm/event.d/
+ mv ${D}${sbindir}/* ${D}${base_sbindir}/
+ mv ${D}${bindir}/* ${D}${base_bindir}/
+ rmdir ${D}${bindir} ${D}${sbindir}
+ chmod u+s ${D}${base_sbindir}/hciattach ${D}${base_sbindir}/hciconfig
+ install -m 0644 ${WORKDIR}/hcid.conf ${D}${sysconfdir}/bluetooth/
+ install -m 0755 ${S}/daemon/.libs/passkey-agent ${D}${base_bindir}/
+}
+
+
+INITSCRIPT_NAME = "bluetooth"
+INITSCRIPT_PARAMS = "defaults 23 19"
+
+
+PACKAGES =+ "${PN}-compat"
+
+CONFFILES_${PN} = " \
+ ${sysconfdir}/bluetooth/hcid.conf \
+ ${sysconfdir}/default/bluetooth \
+ "
+
+CONFFILES_${PN}-compat = " \
+ ${sysconfdir}/bluetooth/rfcomm.conf \
+ "
+
+FILES_${PN} = " \
+ ${base_sbindir}/hcid \
+ ${libdir}/bluetooth \
+ ${sysconfdir}/init.d/bluetooth \
+ ${sysconfdir}/bluetooth/*.service \
+ ${sysconfdir}/bluetooth/hcid.conf \
+ ${sysconfdir}/default \
+ ${sysconfdir}/dbus-1 \
+ ${base_sbindir}/hciattach \
+ "
+
+FILES_${PN}-dbg += " \
+ ${libdir}/bluetooth/.debug \
+ ${libdir}/cups/backend/.debug \
+ ${libdir}/alsa-lib/.debug \
+ "
+
+FILES_${PN}-compat = " \
+ ${base_bindir}/sdptool \
+ ${base_bindir}/dund \
+ ${base_bindir}/rctest \
+ ${base_bindir}/ciptool \
+ ${base_bindir}/l2test \
+ ${base_bindir}/rfcomm \
+ ${base_bindir}/hcitool \
+ ${base_bindir}/pand \
+ ${base_bindir}/hidd \
+ ${base_bindir}/l2ping \
+ ${base_sbindir}/hciconfig \
+ ${base_sbindir}/bccmd \
+ ${base_sbindir}/hciemu \
+ ${base_sbindir}/hid2hci \
+ ${base_bindir}/passkey-agent \
+ ${sysconfdir}/bluetooth/rfcomm.conf \
+ "
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/bluez/bluez-utils_3.18.bb b/packages/bluez/bluez-utils_3.18.bb
new file mode 100644
index 0000000000..c0a4f460ba
--- /dev/null
+++ b/packages/bluez/bluez-utils_3.18.bb
@@ -0,0 +1,23 @@
+require bluez-utils3.inc
+
+# see bluez-utils3.inc for the explanation of these option
+EXTRA_OECONF = " \
+ --enable-bccmd \
+ --enable-hid2hci \
+ --disable-alsa \
+ --disable-cups \
+ --enable-glib \
+ --disable-sdpd \
+ --enable-network \
+ --enable-serial \
+ --enable-input \
+ --enable-audio \
+ --enable-echo \
+ --enable-configfile \
+ --enable-initscripts \
+ --enable-test \
+ "
+
+
+CONFFILES_${PN} = "${sysconfdir}/bluetooth/hcid.conf ${sysconfdir}/bluetooth/rfcomm.conf \
+ ${sysconfdir}/default/bluetooth" \ No newline at end of file
diff --git a/packages/bluez/bluez-utils_3.19.bb b/packages/bluez/bluez-utils_3.19.bb
new file mode 100644
index 0000000000..c0a4f460ba
--- /dev/null
+++ b/packages/bluez/bluez-utils_3.19.bb
@@ -0,0 +1,23 @@
+require bluez-utils3.inc
+
+# see bluez-utils3.inc for the explanation of these option
+EXTRA_OECONF = " \
+ --enable-bccmd \
+ --enable-hid2hci \
+ --disable-alsa \
+ --disable-cups \
+ --enable-glib \
+ --disable-sdpd \
+ --enable-network \
+ --enable-serial \
+ --enable-input \
+ --enable-audio \
+ --enable-echo \
+ --enable-configfile \
+ --enable-initscripts \
+ --enable-test \
+ "
+
+
+CONFFILES_${PN} = "${sysconfdir}/bluetooth/hcid.conf ${sysconfdir}/bluetooth/rfcomm.conf \
+ ${sysconfdir}/default/bluetooth" \ No newline at end of file
diff --git a/packages/gnome/epiphany_2.19.6.bb b/packages/gnome/epiphany_2.19.6.bb
index 8d405628ae..cebd39637d 100644
--- a/packages/gnome/epiphany_2.19.6.bb
+++ b/packages/gnome/epiphany_2.19.6.bb
@@ -1,5 +1,5 @@
DESCRIPTION = "GNOME default webbrowser"
-DEPENDS = "gnome-desktop gnome-vfs libgnomeui webkit-gtk"
+DEPENDS = "gnome-desktop gnome-vfs libgnomeui webkit-gtk iso-codes"
RDEPENDS = "gnome-vfs-plugin-http"
PR = "r1"
diff --git a/packages/gnome/libwnck_2.10.2.bb b/packages/gnome/libwnck_2.10.2.bb
deleted file mode 100644
index 17f5c673d6..0000000000
--- a/packages/gnome/libwnck_2.10.2.bb
+++ /dev/null
@@ -1,9 +0,0 @@
-LICENSE = "LGPL"
-DESCRIPTION = "Window navigation construction toolkit"
-HOMEPAGE = ""
-
-inherit gnome
-
-do_stage() {
- autotools_stage_all
-}
diff --git a/packages/gnome/libwnck_2.12.1.bb b/packages/gnome/libwnck_2.12.1.bb
deleted file mode 100644
index 1830a7540a..0000000000
--- a/packages/gnome/libwnck_2.12.1.bb
+++ /dev/null
@@ -1,10 +0,0 @@
-LICENSE = "LGPL"
-DEPENDS = "gtk+"
-DESCRIPTION = "Window navigation construction toolkit"
-HOMEPAGE = ""
-
-inherit gnome
-
-do_stage() {
- autotools_stage_all
-}
diff --git a/packages/gnome/libwnck_2.13.5.bb b/packages/gnome/libwnck_2.13.5.bb
index 5ad3e00cbf..b176493b93 100644
--- a/packages/gnome/libwnck_2.13.5.bb
+++ b/packages/gnome/libwnck_2.13.5.bb
@@ -1,6 +1,7 @@
-LICENSE = "LGPL"
-DEPENDS = "gtk+"
-DESCRIPTION = "Window navigation construction toolkit"
+DESCRIPTION = "Window navigation construction toolkit"
+LICENSE = "LGPL"
+SECTION = "x11/libs"
+DEPENDS = "gtk+ gdk-pixbuf-csource-native"
inherit gnome
diff --git a/packages/gnome/libwnck_2.8.1.bb b/packages/gnome/libwnck_2.8.1.bb
deleted file mode 100644
index 052e20fe32..0000000000
--- a/packages/gnome/libwnck_2.8.1.bb
+++ /dev/null
@@ -1,11 +0,0 @@
-LICENSE = "LGPL"
-DESCRIPTION = "Window navigation construction toolkit"
-HOMEPAGE = ""
-
-inherit gnome
-
-do_stage() {
- autotools_stage_includes
- install -d ${STAGING_LIBDIR}
- install -m 755 libwnck/.libs/libwnck-1.so.4.9.0 ${STAGING_LIBDIR}/libwnck-1.so
-}
diff --git a/packages/gtk+/gdk-pixbuf-csource-native_2.10.14.bb b/packages/gtk+/gdk-pixbuf-csource-native_2.10.14.bb
index 51fb846ce9..6fbc7d936f 100644
--- a/packages/gtk+/gdk-pixbuf-csource-native_2.10.14.bb
+++ b/packages/gtk+/gdk-pixbuf-csource-native_2.10.14.bb
@@ -1,6 +1,6 @@
require gtk+_${PV}.bb
inherit native
-DEPENDS = ""
+DEPENDS = "jpeg-native libpng-native"
S = "${WORKDIR}/gtk+-${PV}"
FILESPATH = "${FILE_DIRNAME}/gdk-pixbuf-csource:${FILE_DIRNAME}/gtk+-${PV}:${FILE_DIRNAME}/files"
SRC_URI += "file://reduce-dependencies.patch;patch=1"
@@ -14,6 +14,8 @@ EXTRA_OECONF = "\
--without-x \
--with-gdktarget=linux-fb \
--without-libtiff \
+ --with-libjpeg \
+ --with-libpng \
"
do_compile() {
diff --git a/packages/gtk+/gtk+.inc b/packages/gtk+/gtk+.inc
index 0805b99f39..14b5026cc6 100644
--- a/packages/gtk+/gtk+.inc
+++ b/packages/gtk+/gtk+.inc
@@ -4,7 +4,7 @@ HOMEPAGE = "http://www.gtk.org"
SECTION = "libs"
LICENSE = "LGPL"
PRIORITY = "optional"
-DEPENDS = "glib-2.0 pango atk jpeg libpng libxext libxcursor gtk-doc libgcrypt"
+DEPENDS = "glib-2.0 tiff pango atk jpeg libpng libxext libxcursor gtk-doc libgcrypt"
inherit autotools pkgconfig
diff --git a/packages/gtk+/gtk+_2.12.0.bb b/packages/gtk+/gtk+_2.12.0.bb
index 6b724bab80..57ba24e796 100644
--- a/packages/gtk+/gtk+_2.12.0.bb
+++ b/packages/gtk+/gtk+_2.12.0.bb
@@ -1,5 +1,7 @@
require gtk+.inc
+PR = "r1"
+
DEPENDS += "cairo"
# disable per default - untested and not all patches included.
@@ -22,7 +24,7 @@ SRC_URI = "http://download.gnome.org/sources/gtk+/2.12/gtk+-${PV}.tar.bz2 \
# die die die
# file://pangoxft2.10.6.diff;patch=1"
-EXTRA_OECONF = "--without-libtiff --disable-xkb --disable-glibtest --enable-display-migration"
+EXTRA_OECONF = "--with-libtiff --disable-xkb --disable-glibtest --enable-display-migration"
LIBV = "2.10.0"
diff --git a/packages/libetpan/libetpan_0.52.bb b/packages/libetpan/libetpan_0.52.bb
new file mode 100644
index 0000000000..77b2cca39b
--- /dev/null
+++ b/packages/libetpan/libetpan_0.52.bb
@@ -0,0 +1,22 @@
+DESCRIPTION = "libetpan is a library for communicating with mail and news servers. \
+It supports the protocols SMTP, POP3, IMAP and NNTP."
+HOMEPAGE = "http://www.etpan.org"
+SECTION = "libs"
+DEPENDS = "gnutls"
+LICENSE = "BSD"
+PR = "r0"
+
+SRC_URI = "${SOURCEFORGE_MIRROR}/libetpan/libetpan-${PV}.tar.gz"
+
+inherit autotools pkgconfig gettext binconfig
+
+EXTRA_OECONF = "--without-openssl --with-gnutls --disable-db"
+
+PARALLEL_MAKE = ""
+
+do_stage() {
+ autotools_stage_all
+}
+
+FILES_${PN} = "${libdir}/lib*.so.*"
+FILES_${PN}-dev = "${bindir} ${includedir} ${libdir}/lib*.so ${libdir}/*.la ${libdir}/*.a ${libdir}/pkgconfig"
diff --git a/packages/libglade/libglade-2.6.2/.mtn2git_empty b/packages/libglade/libglade-2.6.2/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/libglade/libglade-2.6.2/.mtn2git_empty
diff --git a/packages/libglade/libglade-2.6.2/glade-cruft.patch b/packages/libglade/libglade-2.6.2/glade-cruft.patch
new file mode 100644
index 0000000000..0fceccf0c4
--- /dev/null
+++ b/packages/libglade/libglade-2.6.2/glade-cruft.patch
@@ -0,0 +1,100 @@
+diff -ur libglade-2.4.0~/configure.in libglade-2.4.0/configure.in
+--- libglade-2.4.0~/configure.in 2004-05-17 12:38:31.000000000 +0100
++++ libglade-2.4.0/configure.in 2004-07-28 16:53:09.000000000 +0100
+@@ -147,6 +147,18 @@
+ AM_CONDITIONAL(HAVE_PYTHON, $have_python)
+ AC_SUBST(PYTHON)
+
++AC_MSG_CHECKING([for cruft in libgtk])
++AC_TRY_LINK([
++#include <gtk/gtk.h>
++#include <stdio.h>
++], [ gtk_tree_get_type (); return 0; ],
++ [ AC_MSG_RESULT(yes)
++ have_cruft=yes ],
++ [ AC_MSG_RESULT(no)
++ AC_DEFINE(DISABLE_CRUFT,,[leave out support for old, broken widgets])
++ have_cruft=no ])
++AC_SUBST(DISABLE_CRUFT)
++
+ dnl add debugging options ...
+ changequote(,)dnl
+ if test "x$GCC" = xyes; then
+Only in libglade-2.4.0: configure.in.orig
+diff -ur libglade-2.4.0~/glade/glade-gtk.c libglade-2.4.0/glade/glade-gtk.c
+--- libglade-2.4.0~/glade/glade-gtk.c 2004-03-13 13:47:35.000000000 +0000
++++ libglade-2.4.0/glade/glade-gtk.c 2004-07-28 16:53:52.000000000 +0100
+@@ -213,6 +213,8 @@
+ gtk_clist_column_titles_hide (GTK_CLIST (w));
+ }
+
++#ifndef DISABLE_CRUFT
++
+ static void
+ tree_set_selection_mode (GladeXML *xml, GtkWidget *w,
+ const char *name, const char *value)
+@@ -238,6 +240,8 @@
+ gtk_tree_set_view_lines (GTK_TREE (w), BOOL (value));
+ }
+
++#endif
++
+ static void
+ list_set_selection_mode (GladeXML *xml, GtkWidget *w,
+ const char *name, const char *value)
+@@ -254,6 +258,7 @@
+ gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (w), BOOL (value));
+ }
+
++#ifndef DISABLE_CRUFT
+ static void
+ text_set_text (GladeXML *xml, GtkWidget *w,
+ const char *name, const char *value)
+@@ -262,6 +267,7 @@
+
+ gtk_editable_insert_text (GTK_EDITABLE (w), value, -1, &pos);
+ }
++#endif
+
+ static void
+ radio_menu_item_set_group (GladeXML *xml, GtkWidget *w,
+@@ -1125,13 +1131,17 @@
+ glade_register_custom_prop (GTK_TYPE_CLIST, "selection_mode", clist_set_selection_mode);
+ glade_register_custom_prop (GTK_TYPE_CLIST, "shadow_type", clist_set_shadow_type);
+ glade_register_custom_prop (GTK_TYPE_CLIST, "show_titles", clist_set_show_titles);
++#ifndef DISABLE_CRUFT
+ glade_register_custom_prop (GTK_TYPE_TREE, "selection_mode", tree_set_selection_mode);
+ glade_register_custom_prop (GTK_TYPE_TREE, "view_mode", tree_set_view_mode);
+ glade_register_custom_prop (GTK_TYPE_TREE, "view_line", tree_set_view_line);
++#endif
+ glade_register_custom_prop (GTK_TYPE_LIST, "selection_mode", list_set_selection_mode);
+ glade_register_custom_prop (GTK_TYPE_CHECK_MENU_ITEM, "always_show_toggle",
+ check_menu_item_set_always_show_toggle);
++#ifndef DISABLE_CRUFT
+ glade_register_custom_prop (GTK_TYPE_TEXT, "text", text_set_text);
++#endif
+ glade_register_custom_prop (GTK_TYPE_RADIO_MENU_ITEM, "group",
+ radio_menu_item_set_group);
+ glade_register_custom_prop (GTK_TYPE_TOOLBAR, "tooltips", toolbar_set_tooltips);
+@@ -1288,8 +1298,10 @@
+ glade_standard_build_children, NULL);
+ glade_register_widget (GTK_TYPE_TEAROFF_MENU_ITEM, glade_standard_build_widget,
+ NULL, NULL);
++#ifndef DISABLE_CRUFT
+ glade_register_widget (GTK_TYPE_TEXT, glade_standard_build_widget,
+ NULL, NULL);
++#endif
+ glade_register_widget (GTK_TYPE_TEXT_VIEW, glade_standard_build_widget,
+ NULL, NULL);
+ glade_register_widget (GTK_TYPE_TIPS_QUERY, glade_standard_build_widget,
+@@ -1304,8 +1316,10 @@
+ glade_standard_build_children, NULL);
+ glade_register_widget (GTK_TYPE_TOOL_BUTTON, glade_standard_build_widget,
+ NULL, NULL);
++#ifndef DISABLE_CRUFT
+ glade_register_widget (GTK_TYPE_TREE, glade_standard_build_widget,
+ NULL, NULL);
++#endif
+ glade_register_widget (GTK_TYPE_TREE_VIEW, glade_standard_build_widget,
+ NULL, NULL);
+ glade_register_widget (GTK_TYPE_VBUTTON_BOX, glade_standard_build_widget,
diff --git a/packages/libglade/libglade-2.6.2/no-xml2.patch b/packages/libglade/libglade-2.6.2/no-xml2.patch
new file mode 100644
index 0000000000..1c2e215b8d
--- /dev/null
+++ b/packages/libglade/libglade-2.6.2/no-xml2.patch
@@ -0,0 +1,499 @@
+diff -urN libglade-2.4.2.orig/configure.in libglade-2.4.2/configure.in
+--- libglade-2.4.2.orig/configure.in 2005-02-11 12:42:58.000000000 +0100
++++ libglade-2.4.2/configure.in 2005-03-22 01:22:00.000000000 +0100
+@@ -52,11 +52,33 @@
+ AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
+
+ PKG_CHECK_MODULES(LIBGLADE, [dnl
+- libxml-2.0 >= required_libxml_version dnl
+ atk >= required_atk_version dnl
+ gtk+-2.0 >= required_gtk_version dnl
+ glib-2.0 >= required_glib_version])
+
++disable_xml2=no
++AC_ARG_WITH([libxml2],
++ AC_HELP_STRING([--without-libxml2], [Don't use libxml2, use Glib's GMarkupParser instead]),
++ [disable_xml2=yes],
++ [disable_xml2=no])
++
++AC_MSG_CHECKING([if we are using libxml2])
++if test "x$disable_xml2" == "xno"; then
++ AC_MSG_RESULT(yes)
++ PKG_CHECK_MODULES(XML2, libxml-2.0 >= 2.4.10)
++ PKGCFG_REQUIRE_LIBXML2="libxml-2.0"
++ LIBGLADE_CFLAGS="$LIBGLADE_CFLAGS $XML2_CFLAGS"
++ LIBGLADE_LIBS="$LIBGLADE_LIBS $XML2_LIBS"
++else
++ LIBGLADE_CFLAGS="$LIBGLADE_CFLAGS -DUSE_GMARKUP_PARSER"
++ PKGCFG_REQUIRE_LIBXML2=""
++ AC_MSG_RESULT(no)
++fi
++
++AC_SUBST(XML2_LIBS)
++AC_SUBST(XML2_CFLAGS)
++AC_SUBST(PKGCFG_REQUIRE_LIBXML2)
++
+ AC_MSG_CHECKING([for native Win32])
+ case "$host" in
+ *-*-mingw*)
+@@ -116,6 +138,21 @@
+ fi
+ fi
+
++if test "x$disable_xml2" == "xyes"; then
++ echo "*****************************************************"
++ echo " You chose to disable libxml2 and use Glib's"
++ echo " GMarkupParser instead."
++ echo
++ echo " Please bear in mind that using libglade with"
++ echo " GMarkupParser is an experimental feature only."
++ echo
++ echo " Please post problems or success stories to"
++ echo " the glade-devel mailing list. Thank you."
++ echo "*****************************************************"
++fi
++
++
++
+ GTK_DOC_CHECK(1.0)
+
+ dnl gettext stuff ... there is no message catalog for libglade -- libglade
+diff -urN libglade-2.4.2.orig/glade/glade-parser.c libglade-2.4.2/glade/glade-parser.c
+--- libglade-2.4.2.orig/glade/glade-parser.c 2004-11-11 11:56:13.000000000 +0100
++++ libglade-2.4.2/glade/glade-parser.c 2005-03-22 01:20:00.000000000 +0100
+@@ -34,7 +34,15 @@
+ # define dgettext(Domain, String) (String)
+ #endif
+
+-#include <libxml/parser.h>
++#ifdef USE_GMARKUP_PARSER
++# include <zlib.h>
++#else
++# include <libxml/parser.h>
++#endif
++
++#ifdef USE_GMARKUP_PARSER
++# define xmlChar gchar
++#endif
+
+ #include "glade-parser.h"
+ #include "glade-private.h"
+@@ -508,7 +516,9 @@
+ case PARSER_START:
+ if (!strcmp(name, "glade-interface")) {
+ state->state = PARSER_GLADE_INTERFACE;
+-#if 0
++
++#ifndef USE_GMARKUP_PARSER
++ #if 0
+ /* check for correct XML namespace */
+ for (i = 0; attrs && attrs[i] != NULL; i += 2) {
+ if (!strcmp(attrs[i], "xmlns") &&
+@@ -518,7 +528,9 @@
+ g_warning("unknown attribute `%s' for <glade-interface>",
+ attrs[i]);
+ }
++ #endif
+ #endif
++
+ } else {
+ g_warning("Expected <glade-interface>. Got <%s>.", name);
+ state->prev_state = state->state;
+@@ -1063,12 +1075,18 @@
+ }
+ }
+
++#ifndef USE_GMARKUP_PARSER
++
+ static xmlEntityPtr
+ glade_parser_get_entity(GladeParseState *state, const xmlChar *name)
+ {
+ return xmlGetPredefinedEntity(name);
+ }
+
++#endif /* !defined(USE_GMARKUP_PARSER) */
++
++#ifndef USE_GMARKUP_PARSER
++
+ static void
+ glade_parser_warning(GladeParseState *state, const char *msg, ...)
+ {
+@@ -1079,6 +1097,10 @@
+ va_end(args);
+ }
+
++#endif /* !defined(USE_GMARKUP_PARSER) */
++
++#ifndef USE_GMARKUP_PARSER
++
+ static void
+ glade_parser_error(GladeParseState *state, const char *msg, ...)
+ {
+@@ -1089,6 +1111,10 @@
+ va_end(args);
+ }
+
++#endif /* !defined(USE_GMARKUP_PARSER) */
++
++#ifndef USE_GMARKUP_PARSER
++
+ static void
+ glade_parser_fatal_error(GladeParseState *state, const char *msg, ...)
+ {
+@@ -1099,6 +1125,10 @@
+ va_end(args);
+ }
+
++#endif /* !defined(USE_GMARKUP_PARSER) */
++
++#ifndef USE_GMARKUP_PARSER
++
+ static xmlSAXHandler glade_parser = {
+ (internalSubsetSAXFunc)NULL, /* internalSubset */
+ (isStandaloneSAXFunc)NULL, /* isStandalone */
+@@ -1126,6 +1156,82 @@
+ (fatalErrorSAXFunc)glade_parser_fatal_error, /* fatalError */
+ };
+
++#else /* USE_GMARKUP_PARSER */
++
++static void
++glade_parser_start_element_wrapper(GMarkupParseContext *context,
++ const gchar *name,
++ const gchar **attr_names,
++ const gchar **attr_values,
++ gpointer state,
++ GError **error)
++{
++ guint i = 0;
++
++ /* Pack attribute names/values from two separate
++ * arrays (GMarkupParser style) into one single
++ * array (libxml SAXParser style). This is not
++ * very efficient, but we do it to make the
++ * GMarkupParser code as little invasive as
++ * possible. */
++
++ while (attr_names[i] != NULL) {
++ ++i;
++ }
++
++ if (1)
++ {
++ const gchar *attr[(i*2)+1];
++ guint j, k;
++
++ for (j=0, k=0; k < i; j += 2)
++ {
++ attr[j] = attr_names[k];
++ attr[j+1] = attr_values[k];
++ ++k;
++ }
++ attr[i*2] = NULL;
++
++ glade_parser_start_element((GladeParseState*)state, name, attr);
++ }
++}
++
++static void
++glade_parser_end_element_wrapper(GMarkupParseContext *context,
++ const gchar *name,
++ gpointer state,
++ GError **err)
++{
++ glade_parser_end_element((GladeParseState*)state, name);
++}
++
++static void
++glade_parser_characters_wrapper(GMarkupParseContext *context,
++ const gchar *chars,
++ gsize len,
++ gpointer state,
++ GError **err)
++{
++ glade_parser_characters((GladeParseState*)state, chars, (int) len);
++}
++
++static void
++glade_parser_error(GMarkupParseContext *context, GError *err, gpointer data)
++{
++ g_log("Glade-Parser", G_LOG_LEVEL_CRITICAL, "%s", err->message);
++}
++
++static const GMarkupParser glade_parser = {
++ glade_parser_start_element_wrapper, /* element open */
++ glade_parser_end_element_wrapper, /* element close */
++ glade_parser_characters_wrapper, /* text content */
++ NULL, /* passthrough */
++ glade_parser_error, /* parse error */
++};
++
++#endif /* USE_GMARKUP_PARSER */
++
++
+ static void
+ widget_info_free(GladeWidgetInfo *info)
+ {
+@@ -1191,6 +1297,9 @@
+ *
+ * Returns: the GladeInterface structure for the XML file.
+ */
++
++#ifndef USE_GMARKUP_PARSER
++
+ GladeInterface *
+ glade_parser_parse_file(const gchar *file, const gchar *domain)
+ {
+@@ -1222,6 +1331,31 @@
+ return state.interface;
+ }
+
++#else /* defined(USE_GMARKUP_PARSER) */
++
++GladeInterface *
++glade_parser_parse_file(const gchar *file, const gchar *domain)
++{
++ GladeInterface *interface;
++ GError *err = NULL;
++ gchar *content = NULL;
++ gsize clen;
++
++ if (!g_file_get_contents(file, &content, &clen, &err)) {
++ g_warning("could not load glade file: %s", err->message);
++ g_error_free(err);
++ return NULL;
++ }
++
++ interface = glade_parser_parse_buffer(content, (gint) clen, domain);
++
++ g_free(content);
++
++ return interface;
++}
++
++#endif /* USE_GMARKUP_PARSER */
++
+ /**
+ * glade_parser_parse_buffer
+ * @buffer: a buffer in memory containing XML data.
+@@ -1237,6 +1371,9 @@
+ *
+ * Returns: the GladeInterface structure for the XML buffer.
+ */
++
++#ifndef USE_GMARKUP_PARSER
++
+ GladeInterface *
+ glade_parser_parse_buffer(const gchar *buffer, gint len, const gchar *domain)
+ {
+@@ -1263,6 +1400,161 @@
+ return state.interface;
+ }
+
++#else /* defined(USE_GMARKUP_PARSER) */
++
++
++static GladeInterface *
++glade_parser_parse_buffer_internal(const gchar *buffer, gint len, const gchar *domain)
++{
++ GMarkupParseContext *context;
++ GladeParseState state = { 0 };
++ GError *err = NULL;
++
++ state.interface = NULL;
++ if (domain)
++ state.domain = domain;
++ else
++ state.domain = textdomain(NULL);
++
++ /* FIXME: This strstr() is not safe, as it ignores the len
++ * argument and assumes the buffer is NUL-terminated */
++ if (strstr(buffer, "<?xml") == NULL) {
++ g_warning("No XML header found in document!");
++ return NULL;
++ }
++
++ context = g_markup_parse_context_new(&glade_parser, (GMarkupParseFlags) 0, &state, NULL);
++
++ glade_parser_start_document(&state);
++
++ if (!g_markup_parse_context_parse(context, buffer, (gssize) len, &err)) {
++ g_warning("document not well formed: %s", err->message);
++ g_error_free(err);
++ if (state.interface)
++ glade_interface_destroy (state.interface);
++ return NULL;
++ }
++
++ glade_parser_end_document(&state);
++
++ if (state.state != PARSER_FINISH) {
++ g_warning("did not finish in PARSER_FINISH state!");
++
++ if (state.interface)
++ glade_interface_destroy(state.interface);
++
++ return NULL;
++ }
++
++ return state.interface;
++}
++
++struct _gzip_rfc1952_hdr
++{
++ guint8 id1, id2, cm, flags;
++ guint32 mtime;
++ guint8 xflags;
++ guint8 os;
++};
++
++static GladeInterface *
++glade_parser_parse_gzipped_buffer(const gchar *buffer, gint len, const gchar *domain)
++{
++ struct _gzip_rfc1952_hdr *hdr = (struct _gzip_rfc1952_hdr*)buffer;
++ struct z_stream_s zstream;
++ GladeInterface *interface;
++ const guint8 *cbuf; /* start of compressed data */
++ guint8 *decompress_buf;
++ gulong decompress_len = 0;
++ gint ret;
++
++ g_assert(hdr != NULL && hdr->id1 == 0x1f && hdr->id2 == 0x8b);
++
++ if (hdr->cm != Z_DEFLATED) {
++ g_warning("Unknown decompression method %u", (guint) hdr->cm);
++ return NULL;
++ }
++
++ /* Uncompressed size (modulo 2^32) is last
++ * 4 bytes of gzipped file, and little endian.
++ * See RFC 1952 */
++ decompress_len = GUINT32_FROM_LE(*((guint32*)(((guint8*)buffer) + len - 4)));
++
++ /* paranoid mode: glade files > 5MB are unlikely */
++ g_return_val_if_fail(decompress_len < 5*1024*1024, NULL);
++
++ decompress_buf = g_malloc0(decompress_len + 1); /* +1 for NUL-terminator */
++
++ /* find start of compressed data, skipping header stuff */
++ cbuf = (guint8*)buffer + 10;
++ if (hdr->flags & 0x04) {
++ guint16 xlen = GUINT16_FROM_LE(*((guint16*)cbuf));
++ cbuf += xlen + 2;
++ }
++ if (hdr->flags & 0x08) {
++ guint16 onamelen = strlen(cbuf);
++ cbuf += onamelen + 1;
++ }
++ if (hdr->flags & 0x10) {
++ guint16 commentlen = strlen(cbuf);
++ cbuf += commentlen + 1;
++ }
++ if (hdr->flags & 0x02)
++ {
++ cbuf += 2; /* skip header CRC16 */
++ }
++
++ zstream.next_in = (void*)cbuf;
++ zstream.avail_in = (uLongf) len - ((void*)cbuf-(void*)buffer) - 4 - 4 +1;
++ zstream.next_out = decompress_buf;
++ zstream.avail_out= decompress_len;
++ zstream.zalloc = Z_NULL;
++ zstream.zfree = Z_NULL;
++ zstream.opaque = Z_NULL;
++
++ ret = inflateInit2(&zstream, -MAX_WBITS);
++
++ if (ret != Z_OK) {
++ g_warning("inflateInit2() failed. zlib error code: %d", ret);
++ g_free(decompress_buf);
++ return NULL;
++ }
++
++ ret = inflate(&zstream, Z_FINISH);
++
++ if (ret != Z_STREAM_END) {
++ g_warning("zlib decompression failed. zlib error code: %d", ret);
++ g_free(decompress_buf);
++ return NULL;
++ }
++
++ interface = glade_parser_parse_buffer_internal(decompress_buf, decompress_len, domain);
++
++ g_free(decompress_buf);
++
++ return interface;
++}
++
++GladeInterface *
++glade_parser_parse_buffer(const gchar *buffer, gint len, const gchar *domain)
++{
++ g_return_val_if_fail(buffer != NULL, NULL);
++ g_return_val_if_fail(len > 0, NULL);
++
++ /* Check if buffer is gzipped */
++ if (buffer[0] == 0x1f && buffer[1] == (gchar)0x8b) {
++ return glade_parser_parse_gzipped_buffer(buffer, len, domain);
++ }
++
++ /* Buffer is cleartext. */
++ return glade_parser_parse_buffer_internal(buffer, len, domain);
++}
++
++#endif /* USE_GMARKUP_PARSER */
++
++
++#ifndef USE_GMARKUP_PARSER
++
+ static void
+ dump_widget(xmlNode *parent, GladeWidgetInfo *info, gint indent)
+ {
+@@ -1382,6 +1674,8 @@
+ xmlNodeAddContent(widget, " ");
+ }
+
++#endif /* !defined(USE_GMARKUP_PARSER) */
++
+ /**
+ * glade_interface_dump
+ * @interface: the GladeInterface
+@@ -1390,6 +1684,9 @@
+ * This function dumps the contents of a GladeInterface into a file as
+ * XML. It is intended mainly as a debugging tool.
+ */
++
++#ifndef USE_GMARKUP_PARSER
++
+ void
+ glade_interface_dump(GladeInterface *interface, const gchar *filename)
+ {
+@@ -1428,6 +1725,17 @@
+ xmlFreeDoc(doc);
+ }
+
++#else /* defined(USE_GMARKUP_PARSER) */
++
++void
++glade_interface_dump(GladeInterface *interface, const gchar *filename)
++{
++ g_warning("glade_interface_dump() is only available with libxml2.");
++}
++
++#endif /* USE_GMARKUP_PARSER */
++
++
+ #if 0
+ int
+ main(int argc, char **argv) {
+diff -urN libglade-2.4.2.orig/libglade-2.0.pc.in libglade-2.4.2/libglade-2.0.pc.in
+--- libglade-2.4.2.orig/libglade-2.0.pc.in 2001-12-12 15:28:23.000000000 +0100
++++ libglade-2.4.2/libglade-2.0.pc.in 2005-03-22 01:20:00.000000000 +0100
+@@ -11,7 +11,7 @@
+ Name: Libglade
+ Description: a library for dynamically loading GLADE interface files
+ Version: @VERSION@
+-Requires: gtk+-2.0 libxml-2.0
++Requires: gtk+-2.0 @PKGCFG_REQUIRE_LIBXML2@
+ Libs: -L${libdir} -lglade-2.0
+ Cflags: -I${includedir}/libglade-2.0
+
diff --git a/packages/libglade/libglade_2.6.2.bb b/packages/libglade/libglade_2.6.2.bb
new file mode 100644
index 0000000000..f0450e644d
--- /dev/null
+++ b/packages/libglade/libglade_2.6.2.bb
@@ -0,0 +1,32 @@
+LICENSE = "LGPL"
+DESCRIPTION = "Runtime support for GTK interface builder"
+SECTION = "libs"
+PRIORITY = "optional"
+DEPENDS = "gtk+ gtk-doc"
+
+inherit autotools pkgconfig gnome
+
+PR = "r1"
+
+SRC_URI += "file://glade-cruft.patch;patch=1 file://no-xml2.patch;patch=1"
+
+EXTRA_OECONF += "--without-libxml2"
+
+LDFLAGS += "-lz"
+
+PACKAGES += " ${PN}-data"
+FILES_${PN} = "${libdir}/lib*.so.*"
+FILES_${PN}-data = "${datadir}/xml/libglade/glade-2.0.dtd"
+FILES_${PN}-dev += "${bindir}/libglade-convert"
+#RDEPENDS_${PN} = "${PN}-data"
+
+headers = "glade-build.h glade-init.h glade-parser.h glade-xml.h glade.h"
+
+do_stage () {
+ oe_libinstall -a -so -C glade libglade-2.0 ${STAGING_LIBDIR}
+
+ mkdir -p ${STAGING_INCDIR}/libglade-2.0/glade
+ for i in ${headers}; do
+ install -m 0644 ${S}/glade/$i ${STAGING_INCDIR}/libglade-2.0/glade/$i
+ done
+}
diff --git a/packages/links/links-x11_2.0+2.1pre26.bb b/packages/links/links-x11_2.0+2.1pre30.bb
index 9ee70d9ad4..9ee70d9ad4 100644
--- a/packages/links/links-x11_2.0+2.1pre26.bb
+++ b/packages/links/links-x11_2.0+2.1pre30.bb
diff --git a/packages/links/links_2.0+2.1pre26.bb b/packages/links/links_2.0+2.1pre30.bb
index c46a64f380..c46a64f380 100644
--- a/packages/links/links_2.0+2.1pre26.bb
+++ b/packages/links/links_2.0+2.1pre30.bb
diff --git a/packages/linux/linux-openmoko-devel/defconfig b/packages/linux/linux-openmoko-devel/defconfig
index 1d12b6ec36..f7274016c8 100644
--- a/packages/linux/linux-openmoko-devel/defconfig
+++ b/packages/linux/linux-openmoko-devel/defconfig
@@ -1604,6 +1604,10 @@ CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
CONFIG_CRAMFS=y
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
diff --git a/packages/linux/linux-openmoko-devel/printascii.patch b/packages/linux/linux-openmoko-devel/printascii.patch
new file mode 100644
index 0000000000..13a014db39
--- /dev/null
+++ b/packages/linux/linux-openmoko-devel/printascii.patch
@@ -0,0 +1,12 @@
+Index: linux-2.6.22.5/kernel/printk.c
+===================================================================
+--- linux-2.6.22.5.orig/kernel/printk.c
++++ linux-2.6.22.5/kernel/printk.c
+@@ -535,6 +535,7 @@ asmlinkage int vprintk(const char *fmt,
+
+ /* Emit the output into the temporary buffer */
+ printed_len = vscnprintf(printk_buf, sizeof(printk_buf), fmt, args);
++ printascii(printk_buf);
+
+ /*
+ * Copy the output into log_buf. If the caller didn't provide
diff --git a/packages/linux/linux-openmoko-devel/squashfs.patch b/packages/linux/linux-openmoko-devel/squashfs.patch
new file mode 100644
index 0000000000..51efd6b3c9
--- /dev/null
+++ b/packages/linux/linux-openmoko-devel/squashfs.patch
@@ -0,0 +1,4386 @@
+diff -x .gitignore -Nurp linux-2.6.20/fs/Kconfig linux-2.6.20-squashfs3.2-r2/fs/Kconfig
+--- linux-2.6.20/fs/Kconfig 2006-12-25 01:13:12.000000000 +0000
++++ linux-2.6.20-squashfs3.2-r2/fs/Kconfig 2007-01-16 02:06:03.000000000 +0000
+@@ -1404,6 +1404,71 @@ config CRAMFS
+
+ If unsure, say N.
+
++config SQUASHFS
++ tristate "SquashFS 3.2 - Squashed file system support"
++ select ZLIB_INFLATE
++ help
++ Saying Y here includes support for SquashFS 3.2 (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.1 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
+diff -x .gitignore -Nurp linux-2.6.20/fs/Makefile linux-2.6.20-squashfs3.2-r2/fs/Makefile
+--- linux-2.6.20/fs/Makefile 2006-12-25 01:13:12.000000000 +0000
++++ linux-2.6.20-squashfs3.2-r2/fs/Makefile 2007-01-16 02:06:03.000000000 +0000
+@@ -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/
+diff -x .gitignore -Nurp linux-2.6.20/fs/squashfs/inode.c linux-2.6.20-squashfs3.2-r2/fs/squashfs/inode.c
+--- linux-2.6.20/fs/squashfs/inode.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.20-squashfs3.2-r2/fs/squashfs/inode.c 2007-01-16 02:28:36.000000000 +0000
+@@ -0,0 +1,2329 @@
++/*
++ * Squashfs - a compressed read only filesystem for Linux
++ *
++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007
++ * Phillip Lougher <phillip@lougher.org.uk>
++ *
++ * 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/squashfs_fs.h>
++#include <linux/module.h>
++#include <linux/zlib.h>
++#include <linux/fs.h>
++#include <linux/squashfs_fs_sb.h>
++#include <linux/squashfs_fs_i.h>
++#include <linux/buffer_head.h>
++#include <linux/vfs.h>
++#include <linux/vmalloc.h>
++#include <linux/smp_lock.h>
++
++#include "squashfs.h"
++
++static void vfs_read_inode(struct inode *i);
++static struct dentry *squashfs_get_parent(struct dentry *child);
++static int squashfs_read_inode(struct inode *i, squashfs_inode_t inode);
++static int squashfs_statfs(struct dentry *, struct kstatfs *);
++static int squashfs_symlink_readpage(struct file *file, struct page *page);
++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_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 dentry *squashfs_lookup(struct inode *, struct dentry *,
++ struct nameidata *);
++static int squashfs_remount(struct super_block *s, int *flags, char *data);
++static void squashfs_put_super(struct super_block *);
++static int squashfs_get_sb(struct file_system_type *,int, const char *, void *,
++ struct vfsmount *);
++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 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 const 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_super_ops = {
++ .alloc_inode = squashfs_alloc_inode,
++ .destroy_inode = squashfs_destroy_inode,
++ .statfs = squashfs_statfs,
++ .put_super = squashfs_put_super,
++ .remount_fs = squashfs_remount
++};
++
++static struct super_operations squashfs_export_super_ops = {
++ .alloc_inode = squashfs_alloc_inode,
++ .destroy_inode = squashfs_destroy_inode,
++ .statfs = squashfs_statfs,
++ .put_super = squashfs_put_super,
++ .read_inode = vfs_read_inode
++};
++
++static struct export_operations squashfs_export_ops = {
++ .get_parent = squashfs_get_parent
++};
++
++SQSH_EXTERN const struct address_space_operations squashfs_symlink_aops = {
++ .readpage = squashfs_symlink_readpage
++};
++
++SQSH_EXTERN const struct address_space_operations squashfs_aops = {
++ .readpage = squashfs_readpage
++};
++
++SQSH_EXTERN const struct address_space_operations squashfs_aops_4K = {
++ .readpage = squashfs_readpage4K
++};
++
++static const 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, int srclength)
++{
++ struct squashfs_sb_info *msblk = s->s_fs_info;
++ struct squashfs_super_block *sblk = &msblk->sblk;
++ 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 = 0;
++ unsigned int compressed;
++ unsigned int c_byte = length;
++
++ if (c_byte) {
++ bytes = msblk->devblksize - offset;
++ compressed = SQUASHFS_COMPRESSED_BLOCK(c_byte);
++ c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte);
++
++ TRACE("Block @ 0x%llx, %scompressed size %d, src size %d\n", index, compressed
++ ? "" : "un", (unsigned int) c_byte, srclength);
++
++ if (c_byte > srclength || index < 0 || (index + c_byte) > sblk->bytes_used)
++ goto read_failure;
++
++ 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 (index < 0 || (index + 2) > sblk->bytes_used)
++ goto read_failure;
++
++ 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_byte = SQUASHFS_COMPRESSED_SIZE(c_byte);
++
++ TRACE("Block @ 0x%llx, %scompressed size %d\n", index, compressed
++ ? "" : "un", (unsigned int) c_byte);
++
++ if (c_byte > srclength || (index + c_byte) > sblk->bytes_used)
++ goto read_failure;
++
++ 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) {
++ int zlib_err = 0;
++
++ /*
++ * uncompress block
++ */
++
++ mutex_lock(&msblk->read_data_mutex);
++
++ msblk->stream.next_out = buffer;
++ msblk->stream.avail_out = srclength;
++
++ for (bytes = 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 release_mutex;
++
++ msblk->stream.next_in = bh[k]->b_data + offset;
++ msblk->stream.avail_in = avail_bytes;
++
++ if (k == 0) {
++ zlib_err = zlib_inflateInit(&msblk->stream);
++ if (zlib_err != Z_OK) {
++ ERROR("zlib_inflateInit returned unexpected result 0x%x, srclength %d\n",
++ zlib_err, srclength);
++ goto release_mutex;
++ }
++
++ if (avail_bytes == 0) {
++ offset = 0;
++ brelse(bh[k]);
++ continue;
++ }
++ }
++
++ zlib_err = zlib_inflate(&msblk->stream, Z_NO_FLUSH);
++ if (zlib_err != Z_OK && zlib_err != Z_STREAM_END) {
++ ERROR("zlib_inflate returned unexpected result 0x%x, srclength %d, avail_in %d, avail_out %d\n",
++ zlib_err, srclength, msblk->stream.avail_in, msblk->stream.avail_out);
++ goto release_mutex;
++ }
++
++ bytes += avail_bytes;
++ offset = 0;
++ brelse(bh[k]);
++ }
++
++ if (zlib_err != Z_STREAM_END)
++ goto release_mutex;
++
++ zlib_err = zlib_inflateEnd(&msblk->stream);
++ if (zlib_err != Z_OK) {
++ ERROR("zlib_inflateEnd returned unexpected result 0x%x, srclength %d\n",
++ zlib_err, srclength);
++ goto release_mutex;
++ }
++ bytes = msblk->stream.total_out;
++ mutex_unlock(&msblk->read_data_mutex);
++ } else {
++ int i;
++
++ for(i = 0; i < b; i++) {
++ wait_on_buffer(bh[i]);
++ if(!buffer_uptodate(bh[i]))
++ goto block_release;
++ }
++
++ for (bytes = 0; k < b; k++) {
++ avail_bytes = (c_byte - bytes) > (msblk->devblksize - offset) ?
++ msblk->devblksize - offset :
++ c_byte - bytes;
++ memcpy(buffer + bytes, bh[k]->b_data + offset, avail_bytes);
++ bytes += avail_bytes;
++ offset = 0;
++ brelse(bh[k]);
++ }
++ }
++
++ if (next_index)
++ *next_index = index + c_byte + (length ? 0 :
++ (SQUASHFS_CHECK_DATA(msblk->sblk.flags)
++ ? 3 : 2));
++ return bytes;
++
++release_mutex:
++ mutex_unlock(&msblk->read_data_mutex);
++
++block_release:
++ for (; k < b; k++)
++ brelse(bh[k]);
++
++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;
++
++ mutex_lock(&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);
++ mutex_unlock(&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");
++ mutex_unlock(&msblk->block_cache_mutex);
++ goto out;
++ }
++ }
++
++ msblk->block_cache[i].block = SQUASHFS_USED_BLK;
++ mutex_unlock(&msblk->block_cache_mutex);
++
++ msblk->block_cache[i].length = squashfs_read_data(s,
++ msblk->block_cache[i].data, block, 0, &next_index, SQUASHFS_METADATA_SIZE);
++ if (msblk->block_cache[i].length == 0) {
++ ERROR("Unable to read cache block [%llx:%x]\n",
++ block, offset);
++ mutex_lock(&msblk->block_cache_mutex);
++ msblk->block_cache[i].block = SQUASHFS_INVALID_BLK;
++ kfree(msblk->block_cache[i].data);
++ wake_up(&msblk->waitq);
++ mutex_unlock(&msblk->block_cache_mutex);
++ goto out;
++ }
++
++ mutex_lock(&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) {
++ mutex_unlock(&msblk->block_cache_mutex);
++ continue;
++ }
++
++ bytes = msblk->block_cache[i].length - offset;
++
++ if (bytes < 1) {
++ mutex_unlock(&msblk->block_cache_mutex);
++ goto out;
++ } else if (bytes >= 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;
++ }
++ mutex_unlock(&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;
++ mutex_unlock(&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)
++{
++ mutex_lock(&msblk->fragment_mutex);
++ fragment->locked --;
++ wake_up(&msblk->fragment_wait_queue);
++ mutex_unlock(&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;
++ struct squashfs_super_block *sblk = &msblk->sblk;
++
++ while ( 1 ) {
++ mutex_lock(&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);
++ mutex_unlock(&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");
++ mutex_unlock(&msblk->fragment_mutex);
++ goto out;
++ }
++
++ msblk->fragment[i].block = SQUASHFS_INVALID_BLK;
++ msblk->fragment[i].locked = 1;
++ mutex_unlock(&msblk->fragment_mutex);
++
++ if (!(msblk->fragment[i].length = squashfs_read_data(s,
++ msblk->fragment[i].data,
++ start_block, length, NULL, sblk->block_size))) {
++ ERROR("Unable to read fragment cache block "
++ "[%llx]\n", start_block);
++ msblk->fragment[i].locked = 0;
++ smp_mb();
++ goto out;
++ }
++
++ mutex_lock(&msblk->fragment_mutex);
++ 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);
++ mutex_unlock(&msblk->fragment_mutex);
++ break;
++ }
++
++ msblk->fragment[i].locked++;
++ mutex_unlock(&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 void squashfs_new_inode(struct squashfs_sb_info *msblk, struct inode *i,
++ struct squashfs_base_inode_header *inodeb)
++{
++ 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];
++}
++
++
++static squashfs_inode_t squashfs_inode_lookup(struct super_block *s, int ino)
++{
++ struct squashfs_sb_info *msblk = s->s_fs_info;
++ long long start = msblk->inode_lookup_table[SQUASHFS_LOOKUP_BLOCK(ino - 1)];
++ int offset = SQUASHFS_LOOKUP_BLOCK_OFFSET(ino - 1);
++ squashfs_inode_t inode;
++
++ TRACE("Entered squashfs_inode_lookup, inode_number = %d\n", ino);
++
++ if (msblk->swap) {
++ squashfs_inode_t sinode;
++
++ if (!squashfs_get_cached_block(s, (char *) &sinode, start, offset,
++ sizeof(sinode), &start, &offset))
++ goto out;
++ SQUASHFS_SWAP_INODE_T((&inode), &sinode);
++ } else if (!squashfs_get_cached_block(s, (char *) &inode, start, offset,
++ sizeof(inode), &start, &offset))
++ goto out;
++
++ TRACE("squashfs_inode_lookup, inode = 0x%llx\n", inode);
++
++ return inode;
++
++out:
++ return SQUASHFS_INVALID_BLK;
++}
++
++
++static void vfs_read_inode(struct inode *i)
++{
++ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
++ squashfs_inode_t inode = squashfs_inode_lookup(i->i_sb, i->i_ino);
++
++ TRACE("Entered vfs_read_inode\n");
++
++ if(inode != SQUASHFS_INVALID_BLK)
++ (msblk->read_inode)(i, inode);
++}
++
++
++static struct dentry *squashfs_get_parent(struct dentry *child)
++{
++ struct inode *i = child->d_inode;
++ struct inode *parent = iget(i->i_sb, SQUASHFS_I(i)->u.s2.parent_inode);
++ struct dentry *rv;
++
++ TRACE("Entered squashfs_get_parent\n");
++
++ if(parent == NULL) {
++ rv = ERR_PTR(-EACCES);
++ goto out;
++ }
++
++ rv = d_alloc_anon(parent);
++ if(rv == NULL)
++ rv = ERR_PTR(-ENOMEM);
++
++out:
++ return rv;
++}
++
++
++SQSH_EXTERN struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode, unsigned int inode_number)
++{
++ struct squashfs_sb_info *msblk = s->s_fs_info;
++ struct inode *i = iget_locked(s, inode_number);
++
++ TRACE("Entered squashfs_iget\n");
++
++ if(i && (i->i_state & I_NEW)) {
++ (msblk->read_inode)(i, inode);
++ unlock_new_inode(i);
++ }
++
++ return i;
++}
++
++
++static int squashfs_read_inode(struct inode *i, squashfs_inode_t inode)
++{
++ struct super_block *s = i->i_sb;
++ 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_read_inode\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;
++
++ squashfs_new_inode(msblk, i, inodeb);
++
++ 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;
++
++ 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;
++
++ 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;
++
++ 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;
++
++ 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;
++
++ 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;
++
++ 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;
++
++ 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;
++ }
++
++ return 1;
++
++failed_read:
++ ERROR("Unable to read inode [%llx:%x]\n", block, offset);
++
++failed_read1:
++ make_bad_inode(i);
++ return 0;
++}
++
++
++static int read_inode_lookup_table(struct super_block *s)
++{
++ struct squashfs_sb_info *msblk = s->s_fs_info;
++ struct squashfs_super_block *sblk = &msblk->sblk;
++ unsigned int length = SQUASHFS_LOOKUP_BLOCK_BYTES(sblk->inodes);
++
++ TRACE("In read_inode_lookup_table, length %d\n", length);
++
++ /* Allocate inode lookup table */
++ if (!(msblk->inode_lookup_table = kmalloc(length, GFP_KERNEL))) {
++ ERROR("Failed to allocate inode lookup table\n");
++ return 0;
++ }
++
++ if (!squashfs_read_data(s, (char *) msblk->inode_lookup_table,
++ sblk->lookup_table_start, length |
++ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length)) {
++ ERROR("unable to read inode lookup table\n");
++ return 0;
++ }
++
++ if (msblk->swap) {
++ int i;
++ long long block;
++
++ for (i = 0; i < SQUASHFS_LOOKUP_BLOCKS(sblk->inodes); i++) {
++ SQUASHFS_SWAP_LOOKUP_BLOCKS((&block),
++ &msblk->inode_lookup_table[i], 1);
++ msblk->inode_lookup_table[i] = block;
++ }
++ }
++
++ return 1;
++}
++
++
++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;
++ unsigned int length = SQUASHFS_FRAGMENT_INDEX_BYTES(sblk->fragments);
++
++ if(length == 0)
++ return 1;
++
++ /* Allocate fragment index table */
++ if (!(msblk->fragment_index = kmalloc(length, GFP_KERNEL))) {
++ ERROR("Failed to allocate fragment index table\n");
++ return 0;
++ }
++
++ if (!squashfs_read_data(s, (char *) msblk->fragment_index,
++ sblk->fragment_table_start, length |
++ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length)) {
++ 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->read_inode = squashfs_read_inode;
++ 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;
++ if (!(msblk->stream.workspace = vmalloc(zlib_inflate_workspacesize()))) {
++ ERROR("Failed to allocate zlib workspace\n");
++ goto failure;
++ }
++ sblk = &msblk->sblk;
++
++ msblk->devblksize = sb_min_blocksize(s, BLOCK_SIZE);
++ msblk->devblksize_log2 = ffz(~msblk->devblksize);
++
++ mutex_init(&msblk->read_data_mutex);
++ mutex_init(&msblk->read_page_mutex);
++ mutex_init(&msblk->block_cache_mutex);
++ mutex_init(&msblk->fragment_mutex);
++ mutex_init(&msblk->meta_index_mutex);
++
++ init_waitqueue_head(&msblk->waitq);
++ init_waitqueue_head(&msblk->fragment_wait_queue);
++
++ sblk->bytes_used = sizeof(struct squashfs_super_block);
++ if (!squashfs_read_data(s, (char *) sblk, SQUASHFS_START,
++ sizeof(struct squashfs_super_block) |
++ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, sizeof(struct squashfs_super_block))) {
++ 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;
++
++ /* Check the filesystem does not extend beyond the end of the
++ block device */
++ if(sblk->bytes_used < 0 || sblk->bytes_used > i_size_read(s->s_bdev->bd_inode))
++ goto failed_mount;
++
++ /* Check the root inode for sanity */
++ if (SQUASHFS_INODE_OFFSET(sblk->root_inode) > SQUASHFS_METADATA_SIZE)
++ 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_super_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_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, (sblk->no_uids + sblk->no_guids) * sizeof(unsigned int))) {
++ 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, (sblk->no_uids + sblk->no_guids) * sizeof(unsigned int))) {
++ 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 and read fragment index table */
++ if (msblk->read_fragment_index_table(s) == 0)
++ goto failed_mount;
++
++ if(sblk->s_major < 3 || sblk->lookup_table_start == SQUASHFS_INVALID_BLK)
++ goto allocate_root;
++
++ /* Allocate and read inode lookup table */
++ if (read_inode_lookup_table(s) == 0)
++ goto failed_mount;
++
++ s->s_op = &squashfs_export_super_ops;
++ s->s_export_op = &squashfs_export_ops;
++
++allocate_root:
++ root = new_inode(s);
++ if ((msblk->read_inode)(root, sblk->root_inode) == 0)
++ goto failed_mount;
++ insert_inode_hash(root);
++
++ 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->inode_lookup_table);
++ kfree(msblk->fragment_index);
++ kfree(msblk->fragment);
++ kfree(msblk->uid);
++ kfree(msblk->read_page);
++ kfree(msblk->block_cache);
++ kfree(msblk->fragment_index_2);
++ vfree(msblk->stream.workspace);
++ 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_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);
++ flush_dcache_page(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;
++
++ mutex_lock(&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:
++ mutex_unlock(&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;
++
++ mutex_lock(&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:
++ mutex_unlock(&msblk->meta_index_mutex);
++ return meta;
++}
++
++
++void release_meta_index(struct inode *inode, struct meta_index *meta)
++{
++ meta->locked = 0;
++ smp_mb();
++}
++
++
++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 {
++ if(meta->entries == 0)
++ goto failed;
++ 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;
++ 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 (!(block_list = kmalloc(SIZE, GFP_KERNEL))) {
++ ERROR("Failed to allocate block_list\n");
++ goto skip_read;
++ }
++
++ 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;
++
++ mutex_lock(&msblk->read_page_mutex);
++
++ if (!(bytes = squashfs_read_data(inode->i_sb, msblk->read_page,
++ block, bsize, NULL, sblk->block_size))) {
++ ERROR("Unable to read page, block %llx, size %x\n", block,
++ bsize);
++ mutex_unlock(&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 avail = (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, avail);
++
++ push_page = (i == page->index) ? page :
++ grab_cache_page_nowait(page->mapping, i);
++
++ if (!push_page)
++ continue;
++
++ if (PageUptodate(push_page))
++ goto skip_page;
++
++ pageaddr = kmap_atomic(push_page, KM_USER0);
++ memcpy(pageaddr, data_ptr + byte_offset, avail);
++ memset(pageaddr + avail, 0, PAGE_CACHE_SIZE - avail);
++ kunmap_atomic(pageaddr, KM_USER0);
++ flush_dcache_page(push_page);
++ SetPageUptodate(push_page);
++skip_page:
++ unlock_page(push_page);
++ if(i != page->index)
++ 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))
++ mutex_unlock(&msblk->read_page_mutex);
++ else
++ release_cached_fragment(msblk, fragment);
++
++ kfree(block_list);
++ 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);
++
++ kfree(block_list);
++ 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;
++ 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)) {
++ block_list = NULL;
++ goto skip_read;
++ }
++
++ if (!(block_list = kmalloc(SIZE, GFP_KERNEL))) {
++ ERROR("Failed to allocate block_list\n");
++ 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);
++ if(block == 0)
++ goto skip_read;
++
++ mutex_lock(&msblk->read_page_mutex);
++ bytes = squashfs_read_data(inode->i_sb, msblk->read_page, block,
++ bsize, NULL, sblk->block_size);
++ if (bytes) {
++ pageaddr = kmap_atomic(page, KM_USER0);
++ memcpy(pageaddr, msblk->read_page, bytes);
++ kunmap_atomic(pageaddr, KM_USER0);
++ } else
++ ERROR("Unable to read page, block %llx, size %x\n",
++ block, bsize);
++ mutex_unlock(&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);
++ if (fragment) {
++ bytes = i_size_read(inode) & (sblk->block_size - 1);
++ pageaddr = kmap_atomic(page, KM_USER0);
++ memcpy(pageaddr, fragment->data + SQUASHFS_I(inode)->
++ u.s1.fragment_offset, bytes);
++ kunmap_atomic(pageaddr, KM_USER0);
++ 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:
++ 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);
++
++ kfree(block_list);
++ 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;
++ struct squashfs_dir_index *index;
++ char *str;
++
++ TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count);
++
++ if (!(str = kmalloc(sizeof(struct squashfs_dir_index) +
++ (SQUASHFS_NAME_LEN + 1) * 2, GFP_KERNEL))) {
++ ERROR("Failed to allocate squashfs_dir_index\n");
++ goto failure;
++ }
++
++ index = (struct squashfs_dir_index *) (str + SQUASHFS_NAME_LEN + 1);
++ 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;
++ kfree(str);
++failure:
++ 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,
++ dir_count;
++ struct squashfs_dir_header dirh;
++ struct squashfs_dir_entry *dire;
++
++ TRACE("Entered squashfs_readdir [%llx:%x]\n", next_block, next_offset);
++
++ if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) +
++ SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) {
++ ERROR("Failed to allocate squashfs_dir_entry\n");
++ goto finish;
++ }
++
++ 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;
++ }
++
++ 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;
++ }
++ }
++
++finish:
++ kfree(dire);
++ return 0;
++
++failed_read:
++ ERROR("Unable to read directory block [%llx:%x]\n", next_block,
++ next_offset);
++ kfree(dire);
++ 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;
++ struct squashfs_dir_entry *dire;
++
++ TRACE("Entered squashfs_lookup [%llx:%x]\n", next_block, next_offset);
++
++ if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) +
++ SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) {
++ ERROR("Failed to allocate squashfs_dir_entry\n");
++ goto exit_lookup;
++ }
++
++ if (len > SQUASHFS_NAME_LEN)
++ goto exit_lookup;
++
++ 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_lookup;
++
++ 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 = squashfs_iget(i->i_sb, ino, dirh.inode_number + dire->inode_number);
++
++ goto exit_lookup;
++ }
++ }
++ }
++
++exit_lookup:
++ kfree(dire);
++ if (inode)
++ return d_splice_alias(inode, dentry);
++ 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_lookup;
++}
++
++
++static int squashfs_remount(struct super_block *s, int *flags, char *data)
++{
++ *flags |= MS_RDONLY;
++ return 0;
++}
++
++
++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_page);
++ kfree(sbi->uid);
++ kfree(sbi->fragment_index);
++ kfree(sbi->fragment_index_2);
++ kfree(sbi->meta_index);
++ vfree(sbi->stream.workspace);
++ 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.2-r2 (2007/01/15) "
++ "Phillip Lougher\n");
++
++ if ((err = register_filesystem(&squashfs_fs_type)))
++ destroy_inodecache();
++
++out:
++ return err;
++}
++
++
++static void __exit exit_squashfs_fs(void)
++{
++ 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;
++
++
++
++ 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 3.2-r2, a compressed read-only filesystem");
++MODULE_AUTHOR("Phillip Lougher <phillip@lougher.org.uk>");
++MODULE_LICENSE("GPL");
+diff -x .gitignore -Nurp linux-2.6.20/fs/squashfs/Makefile linux-2.6.20-squashfs3.2-r2/fs/squashfs/Makefile
+--- linux-2.6.20/fs/squashfs/Makefile 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.20-squashfs3.2-r2/fs/squashfs/Makefile 2007-01-12 00:06:09.000000000 +0000
+@@ -0,0 +1,7 @@
++#
++# Makefile for the linux squashfs routines.
++#
++
++obj-$(CONFIG_SQUASHFS) += squashfs.o
++squashfs-y += inode.o
++squashfs-y += squashfs2_0.o
+diff -x .gitignore -Nurp linux-2.6.20/fs/squashfs/squashfs2_0.c linux-2.6.20-squashfs3.2-r2/fs/squashfs/squashfs2_0.c
+--- linux-2.6.20/fs/squashfs/squashfs2_0.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.20-squashfs3.2-r2/fs/squashfs/squashfs2_0.c 2007-01-12 02:27:20.000000000 +0000
+@@ -0,0 +1,742 @@
++/*
++ * Squashfs - a compressed read only filesystem for Linux
++ *
++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007
++ * Phillip Lougher <phillip@lougher.org.uk>
++ *
++ * 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/squashfs_fs.h>
++#include <linux/module.h>
++#include <linux/zlib.h>
++#include <linux/fs.h>
++#include <linux/squashfs_fs_sb.h>
++#include <linux/squashfs_fs_i.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, SQUASHFS_FRAGMENT_INDEX_BYTES_2(sblk->fragments))) {
++ 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 void squashfs_new_inode(struct squashfs_sb_info *msblk, struct inode *i,
++ struct squashfs_base_inode_header_2 *inodeb, unsigned int ino)
++{
++ struct squashfs_super_block *sblk = &msblk->sblk;
++
++ 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];
++}
++
++
++static int squashfs_read_inode_2(struct inode *i, squashfs_inode_t inode)
++{
++ struct super_block *s = i->i_sb;
++ 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 = i->i_ino;
++ 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;
++
++ squashfs_new_inode(msblk, i, inodeb, ino);
++
++ 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 = 0;
++
++ 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;
++
++ 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;
++ 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;
++
++ 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;
++
++ 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;
++
++ 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;
++
++ 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: {
++
++ 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;
++ }
++
++ return 1;
++
++failed_read:
++ ERROR("Unable to read inode [%x:%x]\n", block, offset);
++
++failed_read1:
++ 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_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;
++ struct squashfs_dir_index_2 *index;
++ char *str;
++
++ TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count);
++
++ if (!(str = kmalloc(sizeof(struct squashfs_dir_index) +
++ (SQUASHFS_NAME_LEN + 1) * 2, GFP_KERNEL))) {
++ ERROR("Failed to allocate squashfs_dir_index\n");
++ goto failure;
++ }
++
++ index = (struct squashfs_dir_index_2 *) (str + SQUASHFS_NAME_LEN + 1);
++ 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;
++ kfree(str);
++failure:
++ 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,
++ dir_count;
++ struct squashfs_dir_header_2 dirh;
++ struct squashfs_dir_entry_2 *dire;
++
++ TRACE("Entered squashfs_readdir_2 [%llx:%x]\n", next_block, next_offset);
++
++ if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) +
++ SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) {
++ ERROR("Failed to allocate squashfs_dir_entry\n");
++ goto finish;
++ }
++
++ 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;
++ }
++ }
++
++finish:
++ kfree(dire);
++ return 0;
++
++failed_read:
++ ERROR("Unable to read directory block [%llx:%x]\n", next_block,
++ next_offset);
++ kfree(dire);
++ 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;
++ struct squashfs_dir_entry_2 *dire;
++ int sorted = sblk->s_major == 2 && sblk->s_minor >= 1;
++
++ TRACE("Entered squashfs_lookup_2 [%llx:%x]\n", next_block, next_offset);
++
++ if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) +
++ SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) {
++ ERROR("Failed to allocate squashfs_dir_entry\n");
++ goto exit_loop;
++ }
++
++ 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);
++ unsigned int inode_number = SQUASHFS_MK_VFS_INODE(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 = squashfs_iget(i->i_sb, ino, inode_number);
++
++ goto exit_loop;
++ }
++ }
++ }
++
++exit_loop:
++ kfree(dire);
++ 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->read_inode = squashfs_read_inode_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;
++}
+diff -x .gitignore -Nurp linux-2.6.20/fs/squashfs/squashfs.h linux-2.6.20-squashfs3.2-r2/fs/squashfs/squashfs.h
+--- linux-2.6.20/fs/squashfs/squashfs.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.20-squashfs3.2-r2/fs/squashfs/squashfs.h 2007-01-12 01:42:11.000000000 +0000
+@@ -0,0 +1,87 @@
++/*
++ * Squashfs - a compressed read only filesystem for Linux
++ *
++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007
++ * Phillip Lougher <phillip@lougher.org.uk>
++ *
++ * 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, int srclength);
++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 inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode, unsigned int inode_number);
++extern const struct address_space_operations squashfs_symlink_aops;
++extern const struct address_space_operations squashfs_aops;
++extern const 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
+diff -x .gitignore -Nurp linux-2.6.20/include/linux/squashfs_fs.h linux-2.6.20-squashfs3.2-r2/include/linux/squashfs_fs.h
+--- linux-2.6.20/include/linux/squashfs_fs.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.20-squashfs3.2-r2/include/linux/squashfs_fs.h 2007-01-12 00:06:09.000000000 +0000
+@@ -0,0 +1,934 @@
++#ifndef SQUASHFS_FS
++#define SQUASHFS_FS
++
++/*
++ * Squashfs
++ *
++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007
++ * Phillip Lougher <phillip@lougher.org.uk>
++ *
++ * 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_EXPORT 7
++
++#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_EXPORTABLE(flags) SQUASHFS_BIT(flags, \
++ SQUASHFS_EXPORT)
++
++#define SQUASHFS_CHECK_DATA(flags) SQUASHFS_BIT(flags, \
++ SQUASHFS_CHECK)
++
++#define SQUASHFS_MKFLAGS(noi, nod, check_data, nof, no_frag, always_frag, \
++ duplicate_checking, exortable) (noi | (nod << 1) | (check_data << 2) \
++ | (nof << 3) | (no_frag << 4) | (always_frag << 5) | \
++ (duplicate_checking << 6) | (exportable << 7))
++
++/* 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))
++
++/* inode lookup table defines */
++#define SQUASHFS_LOOKUP_BYTES(A) ((A) * sizeof(squashfs_inode_t))
++
++#define SQUASHFS_LOOKUP_BLOCK(A) (SQUASHFS_LOOKUP_BYTES(A) / \
++ SQUASHFS_METADATA_SIZE)
++
++#define SQUASHFS_LOOKUP_BLOCK_OFFSET(A) (SQUASHFS_LOOKUP_BYTES(A) % \
++ SQUASHFS_METADATA_SIZE)
++
++#define SQUASHFS_LOOKUP_BLOCKS(A) ((SQUASHFS_LOOKUP_BYTES(A) + \
++ SQUASHFS_METADATA_SIZE - 1) / \
++ SQUASHFS_METADATA_SIZE)
++
++#define SQUASHFS_LOOKUP_BLOCK_BYTES(A) (SQUASHFS_LOOKUP_BLOCKS(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 lookup_table_start;
++} __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 pending;
++} __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)->lookup_table_start, 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_INODE_T(s, d) SQUASHFS_SWAP_LONG_LONGS(s, d, 1)
++
++#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)
++#define SQUASHFS_SWAP_LOOKUP_BLOCKS(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
+diff -x .gitignore -Nurp linux-2.6.20/include/linux/squashfs_fs_i.h linux-2.6.20-squashfs3.2-r2/include/linux/squashfs_fs_i.h
+--- linux-2.6.20/include/linux/squashfs_fs_i.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.20-squashfs3.2-r2/include/linux/squashfs_fs_i.h 2007-01-12 00:06:09.000000000 +0000
+@@ -0,0 +1,45 @@
++#ifndef SQUASHFS_FS_I
++#define SQUASHFS_FS_I
++/*
++ * Squashfs
++ *
++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007
++ * Phillip Lougher <phillip@lougher.org.uk>
++ *
++ * 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
+diff -x .gitignore -Nurp linux-2.6.20/include/linux/squashfs_fs_sb.h linux-2.6.20-squashfs3.2-r2/include/linux/squashfs_fs_sb.h
+--- linux-2.6.20/include/linux/squashfs_fs_sb.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.20-squashfs3.2-r2/include/linux/squashfs_fs_sb.h 2007-01-12 01:23:47.000000000 +0000
+@@ -0,0 +1,74 @@
++#ifndef SQUASHFS_FS_SB
++#define SQUASHFS_FS_SB
++/*
++ * Squashfs
++ *
++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007
++ * Phillip Lougher <phillip@lougher.org.uk>
++ *
++ * 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;
++ char *read_page;
++ struct mutex read_data_mutex;
++ struct mutex read_page_mutex;
++ struct mutex block_cache_mutex;
++ struct mutex fragment_mutex;
++ struct mutex meta_index_mutex;
++ wait_queue_head_t waitq;
++ wait_queue_head_t fragment_wait_queue;
++ struct meta_index *meta_index;
++ z_stream stream;
++ long long *inode_lookup_table;
++ int (*read_inode)(struct inode *i, 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
+diff -x .gitignore -Nurp linux-2.6.20/init/do_mounts_rd.c linux-2.6.20-squashfs3.2-r2/init/do_mounts_rd.c
+--- linux-2.6.20/init/do_mounts_rd.c 2006-11-29 21:57:37.000000000 +0000
++++ linux-2.6.20-squashfs3.2-r2/init/do_mounts_rd.c 2007-01-16 02:06:03.000000000 +0000
+@@ -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,18 @@ 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);
++ if (squashfsb->s_major < 3)
++ nblocks = (squashfsb->bytes_used_2+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
++ else
++ nblocks = (squashfsb->bytes_used+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
++ goto done;
++ }
++
+ /*
+ * Read block 1 to test for minix and ext2 superblock
+ */
diff --git a/packages/linux/linux-openmoko-devel_svn.bb b/packages/linux/linux-openmoko-devel_svn.bb
index f93f11f082..6fae5da9ef 100644
--- a/packages/linux/linux-openmoko-devel_svn.bb
+++ b/packages/linux/linux-openmoko-devel_svn.bb
@@ -1,7 +1,7 @@
DESCRIPTION = "Linux 2.6.x (development) kernel for FIC SmartPhones shipping w/ OpenMoko"
VANILLA_VERSION = "2.6.22.5"
PV = "${VANILLA_VERSION}-moko11+svnr${SRCREV}"
-PR = "r0"
+PR = "r1"
KERNEL_IMAGETYPE = "uImage"
UBOOT_ENTRYPOINT = "30008000"
@@ -15,7 +15,9 @@ SRCREV_FORMAT = "patches"
SRC_URI = "${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/linux-${VANILLA_VERSION}.tar.bz2 \
svn://svn.openmoko.org/trunk/src/target/kernel;module=patches;proto=http;name=patches \
+ file://squashfs.patch;patch=1 \
file://fix-EVIOCGRAB-semantics-2.6.22.5.patch;patch=1 \
+# file://printascii.patch;patch=1 \
file://defconfig \
file://logo_linux_clut224.ppm"
S = "${WORKDIR}/linux-${VANILLA_VERSION}"
@@ -52,3 +54,19 @@ do_prepatch() {
addtask prepatch after do_unpack before do_patch
+###############################################################
+# put into deploy directory and append u-boot header
+#
+do_deploy() {
+ install -d ${DEPLOY_DIR_IMAGE}
+ install -m 0644 arch/${ARCH}/boot/${KERNEL_IMAGETYPE} ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}-${PV}-${PR}-${MACHINE}.bin
+ tar -cvzf ${DEPLOY_DIR_IMAGE}/modules-${KERNEL_RELEASE}-${PR}-${MACHINE}.tgz -C ${D} lib
+ ${OBJCOPY} -O binary -R .note -R .comment -S vmlinux linux.bin
+ rm -f linux.bin.gz
+ gzip -9 linux.bin
+ ${STAGING_BINDIR_NATIVE}/uboot-mkimage -A arm -O linux -T kernel -C gzip -a 30008000 -e 30008000 -n "OpenMoko Kernel Image Neo1973" \
+ -d linux.bin.gz ${DEPLOY_DIR_IMAGE}/uImage-${PV}-${PR}-${MACHINE}.bin
+ ln -sf ${DEPLOY_DIR_IMAGE}/uImage-${PV}-${PR}-${MACHINE}.bin ${DEPLOY_DIR_IMAGE}/uImage-${MACHINE}-latest.bin
+ rm -f linux.bin.gz
+}
+
diff --git a/packages/matchbox-keyboard/files/matchbox-keyboard-hide-delay.patch b/packages/matchbox-keyboard/files/matchbox-keyboard-hide-delay.patch
new file mode 100644
index 0000000000..c8cb76d99e
--- /dev/null
+++ b/packages/matchbox-keyboard/files/matchbox-keyboard-hide-delay.patch
@@ -0,0 +1,99 @@
+Index: matchbox-keyboard/src/matchbox-keyboard.h
+===================================================================
+--- matchbox-keyboard/src/matchbox-keyboard.h (revision 1669)
++++ matchbox-keyboard/src/matchbox-keyboard.h (working copy)
+@@ -285,7 +285,7 @@
+ void
+ mb_kbd_remote_init (MBKeyboardUI *ui);
+
+-void
++int
+ mb_kbd_remote_process_xevents (MBKeyboardUI *ui, XEvent *xevent);
+
+ /**** Keyboard ****/
+Index: matchbox-keyboard/src/matchbox-keyboard-ui.c
+===================================================================
+--- matchbox-keyboard/src/matchbox-keyboard-ui.c (revision 1669)
++++ matchbox-keyboard/src/matchbox-keyboard-ui.c (working copy)
+@@ -1096,6 +1096,8 @@
+ /* Key repeat - values for standard xorg install ( xset q) */
+ int repeat_delay = 100 * 10000;
+ int repeat_rate = 30 * 1000;
++ int hide_delay = 100 * 1000;
++ int to_hide = 0;
+
+ int press_x = 0, press_y = 0;
+
+@@ -1182,11 +1184,42 @@
+ mb_kbd_xembed_process_xevents (ui, &xev);
+
+ if (ui->is_daemon)
+- mb_kbd_remote_process_xevents (ui, &xev);
+-
++ {
++ switch (mb_kbd_remote_process_xevents (ui, &xev))
++ {
++ case 0:
++ if (to_hide == 1) {
++ mb_kbd_ui_hide(ui);
++ }
++ tvt.tv_usec = hide_delay;
++ to_hide = 1;
++ break;
++ case 1:
++ mb_kbd_ui_show(ui);
++ tvt.tv_usec = repeat_delay;
++ to_hide = 0;
++ break;
++ default:
++ if (to_hide == 1) {
++ mb_kbd_ui_hide(ui);
++ tvt.tv_usec = repeat_delay;
++ to_hide = 0;
++ }
++ break;
++ }
++ }
+ }
+ else
+ {
++ /* Hide timed out */
++ if (to_hide == 1)
++ {
++ DBG("Hide timed out, calling mb_kbd_ui_hide");
++ mb_kbd_ui_hide(ui);
++ tvt.tv_usec = repeat_delay;
++ to_hide = 0;
++ }
++
+ /* Keyrepeat */
+ if (mb_kbd_get_held_key(ui->kbd) != NULL)
+ {
+Index: matchbox-keyboard/src/matchbox-keyboard-remote.c
+===================================================================
+--- matchbox-keyboard/src/matchbox-keyboard-remote.c (revision 1669)
++++ matchbox-keyboard/src/matchbox-keyboard-remote.c (working copy)
+@@ -28,7 +28,7 @@
+ "_MB_IM_INVOKER_COMMAND", False);
+ }
+
+-void
++int
+ mb_kbd_remote_process_xevents (MBKeyboardUI *ui, XEvent *xevent)
+ {
+ DBG("got a message\n");
+@@ -42,9 +42,12 @@
+ DBG("got a message of type _MB_IM_INVOKER_COMMAND, val %i\n",
+ xevent->xclient.data.l[0]);
+ if (xevent->xclient.data.l[0] == 1)
+- mb_kbd_ui_show (ui);
++ {
++ return 1;
++ }
+ else
+- mb_kbd_ui_hide (ui);
++ return 0;
+ }
+ }
++ return -1;
+ }
diff --git a/packages/matchbox-keyboard/matchbox-keyboard-inputmethod_svn.bb b/packages/matchbox-keyboard/matchbox-keyboard-inputmethod_svn.bb
index b7ef698938..16d5f0e2e6 100644
--- a/packages/matchbox-keyboard/matchbox-keyboard-inputmethod_svn.bb
+++ b/packages/matchbox-keyboard/matchbox-keyboard-inputmethod_svn.bb
@@ -6,11 +6,12 @@ RPROVIDES_${PN} = matchbox-keyboard
#DEFAULT_PREFERENCE = "-1"
SECTION = "x11"
PV = "0.0+svnr${SRCREV}"
-PR = "r4"
+PR = "r5"
SRC_URI = "svn://svn.o-hand.com/repos/matchbox/trunk;module=matchbox-keyboard;proto=http \
file://matchbox-keyboard-applet.patch;patch=1;pnum=0 \
- file://80matchboxkeyboard"
+ file://80matchboxkeyboard \
+ file://matchbox-keyboard-hide-delay.patch;patch=1"
SRC_URI_append_fic-gta01 = " file://fic-gta01-font-size.patch;patch=1"
diff --git a/packages/navit/.mtn2git_empty b/packages/navit/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/navit/.mtn2git_empty
diff --git a/packages/navit/files/.mtn2git_empty b/packages/navit/files/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/navit/files/.mtn2git_empty
diff --git a/packages/navit/files/compile-fix.patch b/packages/navit/files/compile-fix.patch
new file mode 100644
index 0000000000..86274d8aa8
--- /dev/null
+++ b/packages/navit/files/compile-fix.patch
@@ -0,0 +1,8 @@
+diff -Naur navit-0.0.1.old/src/fib-1.1/Makefile.am navit-0.0.1/src/fib-1.1/Makefile.am
+--- navit-0.0.1.old/src/fib-1.1/Makefile.am 2007-07-05 19:16:20.000000000 +0200
++++ navit-0.0.1/src/fib-1.1/Makefile.am 2007-09-18 00:48:08.000000000 +0200
+@@ -1,4 +1,3 @@
+ noinst_LTLIBRARIES = libfib.la
+ libfib_la_SOURCES = fib.c fib.h fibpriv.h
+-libfib_la_LDFLAGS = -static
+ EXTRA_DIST=README configure.in fh_extractmin.3 fh_makeheap.3 fh_makekeyheap.3 fibtest.c fibtest2.c tt.c use.c
diff --git a/packages/navit/navit_0.0.1.bb b/packages/navit/navit_0.0.1.bb
new file mode 100644
index 0000000000..947d2b3ba8
--- /dev/null
+++ b/packages/navit/navit_0.0.1.bb
@@ -0,0 +1,14 @@
+DESCRIPTION = "Navit is a car navigation system with routing engine."
+LICENSE = "GPL"
+DEPENDS = "glib-2.0 gtk+"
+PV = "0.0.1"
+PR = "r1"
+
+inherit autotools
+
+SRC_URI = "${SOURCEFORGE_MIRROR}/navit/navit-${PV}.tar.gz \
+ file://compile-fix.patch;patch=1"
+
+EXTRA_OECONF = "--disable-gui-sdl --disable-binding-python"
+
+FILES_${PN}-dbg += "${libdir}/${PN}/*/.debug"
diff --git a/packages/openmoko2/openmoko-browser2_svn.bb b/packages/openmoko2/openmoko-browser2_svn.bb
new file mode 100644
index 0000000000..edfeca7702
--- /dev/null
+++ b/packages/openmoko2/openmoko-browser2_svn.bb
@@ -0,0 +1,7 @@
+DESCRIPTION = "The OpenMoko Webbrowser"
+SECTION = "openmoko/apps"
+DEPENDS += "intltool libmokoui2 check webkit-gtk"
+PV = "0.0.1+svn${SVNREV}"
+PR = "r0"
+
+inherit openmoko2
diff --git a/packages/openmoko2/openmoko-sound-system2_0.1.0.bb b/packages/openmoko2/openmoko-sound-system2_0.1.0.bb
index 46397afa9b..35bfe66318 100644
--- a/packages/openmoko2/openmoko-sound-system2_0.1.0.bb
+++ b/packages/openmoko2/openmoko-sound-system2_0.1.0.bb
@@ -10,7 +10,9 @@ RDEPENDS = "\
pulseaudio-module-native-protocol-unix \
pulseaudio-module-cli-protocol-unix \
"
-PR = "r0"
+RREPLACES = "openmoko-sound-system"
+RPROVIDES = "openmoko-sound-system"
+PR = "r1"
inherit openmoko-base update-rc.d
diff --git a/packages/openmoko2/openmoko-sound-theme-standard2_svn.bb b/packages/openmoko2/openmoko-sound-theme-standard2_svn.bb
index a8b41ed318..0693b9bb8a 100644
--- a/packages/openmoko2/openmoko-sound-theme-standard2_svn.bb
+++ b/packages/openmoko2/openmoko-sound-theme-standard2_svn.bb
@@ -1,7 +1,9 @@
DESCRIPTION = "Standard sound theme for the OpenMoko distribution"
SECTION = "openmoko/base"
+RREPLACES = "openmoko-sound-theme-standard"
+RPROVIDES = "openmoko-sound-theme-standard"
PV = "0.1+svnr${SRCREV}"
-PR = "r0"
+PR = "r1"
inherit openmoko2 autotools
diff --git a/packages/pkgconfig/pkgconfig-0.22/sysroot-support.patch b/packages/pkgconfig/pkgconfig-0.22/sysroot-support.patch
new file mode 100644
index 0000000000..2e4f796cc9
--- /dev/null
+++ b/packages/pkgconfig/pkgconfig-0.22/sysroot-support.patch
@@ -0,0 +1,102 @@
+Add support for PKG_CONFIG_SYSROOT_DIR to pkgconfig
+
+---
+ main.c | 5 ++++-
+ pkg-config.1 | 9 +++++++++
+ pkg.c | 14 +++++++++++++-
+ pkg.h | 3 +++
+ 4 files changed, 29 insertions(+), 2 deletions(-)
+
+Index: pkg-config-0.22/main.c
+===================================================================
+--- pkg-config-0.22.orig/main.c 2007-09-14 10:20:15.000000000 +0100
++++ pkg-config-0.22/main.c 2007-09-14 10:22:41.000000000 +0100
+@@ -46,6 +46,8 @@
+ static int want_debug_spew = 0;
+ static int want_verbose_errors = 0;
+ static int want_stdout_errors = 0;
++char *pcsysrootdir = NULL;
++
+
+ void
+ debug_spew (const char *format, ...)
+@@ -196,7 +198,7 @@ main (int argc, char **argv)
+ GString *str;
+ GSList *packages = NULL;
+ char *search_path;
+- char *pcbuilddir;
++ char *pcbuilddir;
+ const char *pkglibdir;
+ char **search_dirs;
+ char **iter;
+@@ -345,6 +347,7 @@ main (int argc, char **argv)
+ }
+ }
+ #endif
++ pcsysrootdir = getenv ("PKG_CONFIG_SYSROOT_DIR");
+
+ pcbuilddir = getenv ("PKG_CONFIG_TOP_BUILD_DIR");
+ if (pcbuilddir)
+Index: pkg-config-0.22/pkg.c
+===================================================================
+--- pkg-config-0.22.orig/pkg.c 2007-09-14 10:20:15.000000000 +0100
++++ pkg-config-0.22/pkg.c 2007-09-14 10:22:41.000000000 +0100
+@@ -479,11 +479,23 @@ string_list_to_string (GSList *list)
+ GSList *tmp;
+ GString *str = g_string_new ("");
+ char *retval;
++ int offset=0;
+
+ tmp = list;
+ while (tmp != NULL)
+ {
+- g_string_append (str, tmp->data);
++ if (pcsysrootdir != NULL)
++ {
++ if (!strncmp(tmp->data,"-I",2) ||
++ !strncmp(tmp->data,"-L",2))
++ {
++ offset=2;
++ g_string_append_c (str,((char*)tmp->data)[0]);
++ g_string_append_c (str,((char*)tmp->data)[1]);
++ g_string_append (str,pcsysrootdir);
++ }
++ }
++ g_string_append (str, tmp->data+offset);
+ g_string_append_c (str, ' ');
+
+ tmp = g_slist_next (tmp);
+Index: pkg-config-0.22/pkg-config.1
+===================================================================
+--- pkg-config-0.22.orig/pkg-config.1 2007-09-14 10:20:15.000000000 +0100
++++ pkg-config-0.22/pkg-config.1 2007-09-14 10:23:08.000000000 +0100
+@@ -260,6 +260,15 @@ Don't strip -I/usr/include out of cflags
+ Don't strip -L/usr/lib out of libs
+
+ .TP
++.I "PKG_CONFIG_SYSROOT_DIR"
++Modify -I and -L to use the directories located in target sysroot.
++this option is usefull when crosscompiling package that use pkg-config
++to determine CFLAGS anf LDFLAGS. -I and -L are modified to point to
++the new system root. this means that a -I/usr/include/libfoo will
++become -I/var/target/usr/include/libfoo with a PKG_CONFIG_SYSROOT_DIR
++equal to /var/target (same rule apply to -L)
++
++.TP
+ .I "PKG_CONFIG_LIBDIR"
+ Replaces the default \fIpkg-config\fP search directory.
+
+Index: pkg-config-0.22/pkg.h
+===================================================================
+--- pkg-config-0.22.orig/pkg.h 2007-09-14 10:20:15.000000000 +0100
++++ pkg-config-0.22/pkg.h 2007-09-14 10:22:41.000000000 +0100
+@@ -123,6 +123,9 @@ void disable_private_libs(void);
+ /* If TRUE, do not automatically prefer uninstalled versions */
+ extern gboolean disable_uninstalled;
+
++/* string that contain environment */
++extern char* pcsysrootdir;
++
+ #ifdef G_OS_WIN32
+ /* If TRUE, do not automatically define "prefix" while
+ * parsing each .pc file */
diff --git a/packages/pkgconfig/pkgconfig.inc b/packages/pkgconfig/pkgconfig.inc
index 47c077a8d3..ed9e7e69af 100644
--- a/packages/pkgconfig/pkgconfig.inc
+++ b/packages/pkgconfig/pkgconfig.inc
@@ -5,9 +5,10 @@ It replaces the ubiquitous *-config scripts you may have \
seen with a single tool."
HOMEPAGE = "http://pkg-config.freedesktop.org/wiki/"
LICENSE = "GPL"
-PR = "r1"
+PR = "r2"
SRC_URI = "http://pkgconfig.freedesktop.org/releases/pkg-config-${PV}.tar.gz \
+ file://sysroot-support.patch;patch=1 \
file://glibconfig-sysdefs.h"
S = "${WORKDIR}/pkg-config-${PV}/"
diff --git a/packages/poppler/poppler_0.6.bb b/packages/poppler/poppler_0.6.bb
new file mode 100644
index 0000000000..3c1ec00183
--- /dev/null
+++ b/packages/poppler/poppler_0.6.bb
@@ -0,0 +1,6 @@
+require poppler.inc
+
+PR = "r0"
+
+EXTRA_OECONF_append = " --disable-abiword-output "
+
diff --git a/packages/python/python-pybluez_0.13.bb b/packages/python/python-pybluez_0.13.bb
new file mode 100644
index 0000000000..2e7e282ddc
--- /dev/null
+++ b/packages/python/python-pybluez_0.13.bb
@@ -0,0 +1,10 @@
+DESCRIPTION = "Python bindings for the Linux Bluetooth stack"
+SECTION = "devel/python"
+DEPENDS = "bluez-libs"
+LICENSE = "GPL"
+PR = "ml0"
+
+SRC_URI = "http://org.csail.mit.edu/pybluez/release/pybluez-src-${PV}.tar.gz"
+S = "${WORKDIR}/pybluez-${PV}"
+
+inherit distutils
diff --git a/packages/sylpheed/claws-mail_3.0.1.bb b/packages/sylpheed/claws-mail_3.0.1.bb
new file mode 100644
index 0000000000..29e7a5bc63
--- /dev/null
+++ b/packages/sylpheed/claws-mail_3.0.1.bb
@@ -0,0 +1,43 @@
+SECTION = "x11/network"
+DESCRIPTION = "Mail user agent"
+DEPENDS = "gtk+ libetpan openssl aspell"
+LICENSE = "GPL"
+PR = "r0"
+
+SRC_URI = "\
+ ${SOURCEFORGE_MIRROR}/sylpheed-claws/claws-mail-${PV}.tar.bz2 \
+ file://desktop.patch;patch=1 \
+ "
+
+FILES_${PN} = "${bindir} ${datadir}/pixmaps ${datadir}/applications"
+
+EXTRA_OECONF = "--disable-aspell-test \
+ --enable--aspell \
+ --disable-manual \
+ --disable-crash-dialog \
+ --disable-jpilot \
+ --disable-trayicon-plugin \
+ --disable-spamassassin-plugin \
+ --disable-bogofilter-plugin \
+ --disable-pgpcore-plugin \
+ --disable-pgpmime-plugin \
+ --disable-pgpinline-plugin \
+ --disable-dillo-viewer-plugin \
+ --disable-clamav-plugin \
+ --disable-gnomeprint \
+ --disable-valgrind \
+ "
+
+inherit autotools pkgconfig
+
+do_install_append() {
+ install -d ${D}${datadir}/applications
+ install -m 0644 claws-mail.desktop ${D}${datadir}/applications/
+ install -d ${D}${datadir}/pixmaps
+ install -m 0644 claws-mail.png ${D}${datadir}/pixmaps/
+}
+
+do_stage () {
+ autotools_stage_all
+}
+
diff --git a/packages/uboot/uboot-openmoko_1.2.0+gitf34024d4a328e6edd906456da98d2c537155c4f7+svn2943.bb b/packages/uboot/uboot-openmoko_1.2.0+gitf34024d4a328e6edd906456da98d2c537155c4f7+svn2943.bb
index 6256363500..2a09c76f09 100644
--- a/packages/uboot/uboot-openmoko_1.2.0+gitf34024d4a328e6edd906456da98d2c537155c4f7+svn2943.bb
+++ b/packages/uboot/uboot-openmoko_1.2.0+gitf34024d4a328e6edd906456da98d2c537155c4f7+svn2943.bb
@@ -9,7 +9,7 @@ UBOOT_OPENMOKO_REV = "2943"
UBOOT_MACHINES = "gta01bv2 gta01bv3 gta01bv4"
PV = "1.2.0+git${UBOOT_UPSTREAM_REV}+svn${UBOOT_OPENMOKO_REV}"
-PR = "r0"
+PR = "r1"
PROVIDES = "virtual/bootloader"
S = "${WORKDIR}/git"
@@ -30,16 +30,9 @@ do_quilt() {
}
do_svnrev() {
- FILE=${S}/tools/setlocalversion
- OLDFILE=$FILE.old
- NEWFILE=$FILE.new
- cp $FILE $OLDFILE
- LINES=`cat $OLDFILE | wc -l`
- LINES_WE_WANT=$(($LINES-1))
- LASTLINE=`cat $OLDFILE | tail -n 1`
- cat $OLDFILE | head -n $LINES_WE_WANT > $NEWFILE
- echo ${LASTLINE}_${PR} >> $NEWFILE
- rm $FILE && mv $NEWFILE $FILE
+ mv -f tools/setlocalversion tools/setlocalversion.old
+ echo -n "echo " >>tools/setlocalversion
+ echo ${PV} >>tools/setlocalversion
}
do_configure_prepend() {
diff --git a/packages/uboot/uboot-openmoko_svn.bb b/packages/uboot/uboot-openmoko_svn.bb
index e1575884c2..3669b409da 100644
--- a/packages/uboot/uboot-openmoko_svn.bb
+++ b/packages/uboot/uboot-openmoko_svn.bb
@@ -5,7 +5,7 @@ SECTION = "bootloader"
PRIORITY = "optional"
PROVIDES = "virtual/bootloader"
PV = "1.2.0+git${SRCDATE}+svnr${SRCREV}"
-PR = "r0"
+PR = "r1"
SRCREV_FORMAT = "patches"
@@ -30,16 +30,9 @@ do_quilt() {
}
do_svnrev() {
- FILE=${S}/tools/setlocalversion
- OLDFILE=$FILE.old
- NEWFILE=$FILE.new
- cp $FILE $OLDFILE
- LINES=`cat $OLDFILE | wc -l`
- LINES_WE_WANT=$(($LINES-1))
- LASTLINE=`cat $OLDFILE | tail -n 1`
- cat $OLDFILE | head -n $LINES_WE_WANT > $NEWFILE
- echo ${LASTLINE}_${PR} >> $NEWFILE
- rm $FILE && mv $NEWFILE $FILE
+ mv -f tools/setlocalversion tools/setlocalversion.old
+ echo -n "echo " >>tools/setlocalversion
+ echo ${PV} >>tools/setlocalversion
}
do_configure_prepend() {