mirror of
https://github.com/linux-sunxi/meta-sunxi.git
synced 2025-07-16 13:59:46 +02:00
Compare commits
161 Commits
Author | SHA1 | Date | |
---|---|---|---|
849a2266d5 | |||
e51d5cfdee | |||
d2ccb1d993 | |||
e238cc158a | |||
07c07fcd78 | |||
b05f2dbb8b | |||
b9acc14280 | |||
b5e93023fb | |||
4f75b81ab2 | |||
14da837096 | |||
b4357af03b | |||
888ddfd531 | |||
72ea1fe7df | |||
54d3993da4 | |||
2f8da55176 | |||
fe162b176d | |||
b660f3a9dc | |||
f6b855d948 | |||
43a6a5ecc8 | |||
17645719ad | |||
08c5a4bfb8 | |||
1cdd083d2b | |||
062c1477cf | |||
7372a11da5 | |||
318e9aa826 | |||
50b4227876 | |||
0a2034bb3c | |||
8f1c8f67cf | |||
9d864e2510 | |||
eac21d7734 | |||
d32866858f | |||
82672a440b | |||
0693369edc | |||
b66da9c3bb | |||
4e261ffb96 | |||
5127517a14 | |||
784e893ac5 | |||
92b8be8139 | |||
8a9c1d688c | |||
9ac263ebab | |||
4d45bd5262 | |||
012655af8d | |||
2df4c1b23d | |||
211d55b437 | |||
2e8a4b71cf | |||
08143b5735 | |||
25a65df5a3 | |||
7952eb7f17 | |||
9ae2eecab8 | |||
ef3a203e02 | |||
1ef92fd0d2 | |||
f3d9254f7f | |||
5a23591b24 | |||
bd263f945d | |||
05769afd3b | |||
08dfe98af6 | |||
6fd8f0e07a | |||
12db242d7e | |||
49ada71639 | |||
9f031779ca | |||
af112e2f1c | |||
dcb2166a1c | |||
31be4cf6ee | |||
79a65ac2a1 | |||
c5ee8d779f | |||
fab2a652d2 | |||
ec8d7afb9c | |||
f4ebd29a50 | |||
d8934807c6 | |||
6e6e7bdc45 | |||
73377c0bc6 | |||
b326149b1b | |||
966a7cf417 | |||
9125a7a903 | |||
c6b0194806 | |||
be0e113009 | |||
1092ae5117 | |||
bea5512317 | |||
32243d4dc9 | |||
207b25ecf1 | |||
d60ad7f615 | |||
8107abbdee | |||
4240612f21 | |||
cb66c3eafb | |||
c7adafe8ac | |||
dfb9413049 | |||
d5fa6bc501 | |||
46c2d5d4a1 | |||
55b9d9ae5e | |||
b10c844cb2 | |||
38edd14b04 | |||
5c7ffb35f2 | |||
82d0172433 | |||
d271c8130a | |||
59437d24b1 | |||
091001b76d | |||
90c7651e64 | |||
91a61a8de4 | |||
7b424b6ec9 | |||
4f66286422 | |||
eeb41f14c8 | |||
2de81b3de0 | |||
c27b5d3555 | |||
e8e6552b17 | |||
196f800f7d | |||
732bb19214 | |||
c663594470 | |||
5727515f10 | |||
9a8031a8c2 | |||
e25b18fd0b | |||
a27c9aa7e4 | |||
5b875e911c | |||
31b7c4c8e2 | |||
5699690a98 | |||
339dc8af45 | |||
0ed1eadb95 | |||
715f2ace5b | |||
56f00d5e20 | |||
2c587ebf73 | |||
62d877b9e9 | |||
998cbf3544 | |||
d5461fdab9 | |||
0dc2ccf234 | |||
edd823ca05 | |||
a743b7d5e5 | |||
049349756c | |||
2b7341d260 | |||
c8782fa7fd | |||
dc03e94587 | |||
dfe5e55274 | |||
e1969f71e9 | |||
537386dcfc | |||
d809a6ecdb | |||
bcc4283b09 | |||
b81aa265ed | |||
1eb006ed26 | |||
b918724761 | |||
6c0b99fce8 | |||
dfa712ea4b | |||
bb3a53941a | |||
dea1bac947 | |||
e408b5024f | |||
5900774287 | |||
4e2383470e | |||
05a803caac | |||
8c6f8c9392 | |||
620311104b | |||
8f1f5535ab | |||
969a4e6b0b | |||
00b9ae419e | |||
944e8111b8 | |||
ec4b40754e | |||
1d2299057b | |||
3867ea9cb3 | |||
1b5c971774 | |||
f1e777d552 | |||
070639d970 | |||
c59ae55bd0 | |||
9eb93456ae | |||
cafb3cec05 | |||
9bf053c15a |
24
README.md
24
README.md
@ -12,10 +12,32 @@ Tested with core-image-base.
|
||||
Maintainers:
|
||||
|
||||
* Nicolas Aguirre <aguirre.nicolas@gmail.com>
|
||||
* Enrico Butera <ebutera@users.berlios.de>
|
||||
* Enrico Butera <ebutera@users.sourceforge.net>
|
||||
* Sergey Lapin <slapin@ossfans.org>
|
||||
|
||||
Kernel / U-Boot Version
|
||||
===========
|
||||
Most Allwinner devices and hardware are supported in mainline kernel and U-Boot, so this layer builds mainline by default.
|
||||
There is a custom U-Boot and Kernel version for sunxi devices which includes some special drivers not mainlined.
|
||||
These versions are rather old (3.4 for kernel and 2014.04 for U-Boot), but may support more functions and devices than current mainline
|
||||
|
||||
If you want to switch back to sunxi versions for some reasons (no device tree available, unsupported hardware), either:
|
||||
- change the file conf/machine/include/sunxi.inc to include the following block
|
||||
- edit your conf/local.conf to add the following block
|
||||
|
||||
PREFERRED_PROVIDER_u-boot="u-boot-sunxi"
|
||||
PREFERRED_PROVIDER_virtual/bootloader="u-boot-sunxi"
|
||||
PREFERRED_PROVIDER_virtual/kernel="linux-sunxi"
|
||||
|
||||
If you already have built the mainline versions it might be necessary to reset the build directories with:
|
||||
|
||||
bitbake -c clean linux
|
||||
bitbake -c clean u-boot
|
||||
|
||||
Also, older kernel versions such as this don't build successfully with any gcc version 5.0 or newer. Since gcc-5.2 is the current
|
||||
default compiler on master, if you wish to build this kernel with master you'll need to add the following to your conf/local.conf:
|
||||
|
||||
GCCVERSION = "4.9%"
|
||||
|
||||
Performance
|
||||
===========
|
||||
|
@ -26,7 +26,7 @@ BOOT_SPACE ?= "20480"
|
||||
IMAGE_ROOTFS_ALIGNMENT = "2048"
|
||||
|
||||
# Use an uncompressed ext3 by default as rootfs
|
||||
SDIMG_ROOTFS_TYPE ?= "ext3"
|
||||
SDIMG_ROOTFS_TYPE ?= "ext4"
|
||||
SDIMG_ROOTFS = "${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.${SDIMG_ROOTFS_TYPE}"
|
||||
|
||||
IMAGE_DEPENDS_sunxi-sdimg += " \
|
||||
@ -35,10 +35,9 @@ IMAGE_DEPENDS_sunxi-sdimg += " \
|
||||
dosfstools-native \
|
||||
virtual/kernel \
|
||||
virtual/bootloader \
|
||||
sunxi-board-fex \
|
||||
"
|
||||
|
||||
rootfs[depends] += "sunxi-board-fex:do_deploy"
|
||||
rootfs[depends] += "virtual/kernel:do_deploy"
|
||||
|
||||
# SD card image name
|
||||
SDIMG = "${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.sunxi-sdimg"
|
||||
@ -66,12 +65,34 @@ IMAGE_CMD_sunxi-sdimg () {
|
||||
|
||||
# Create a vfat image with boot files
|
||||
BOOT_BLOCKS=$(LC_ALL=C parted -s ${SDIMG} unit b print | awk '/ 1 / { print substr($4, 1, length($4 -1)) / 512 /2 }')
|
||||
rm -f ${WORKDIR}/boot.img
|
||||
mkfs.vfat -n "${BOOTDD_VOLUME_ID}" -S 512 -C ${WORKDIR}/boot.img $BOOT_BLOCKS
|
||||
mcopy -i ${WORKDIR}/boot.img -s ${STAGING_DIR_HOST}/usr/src/kernel/${KERNEL_IMAGETYPE} ::uImage
|
||||
|
||||
mcopy -i ${WORKDIR}/boot.img -s ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}-${MACHINE}.bin ::uImage
|
||||
|
||||
# Copy device tree file
|
||||
if test -n "${KERNEL_DEVICETREE}"; then
|
||||
for DTS_FILE in ${KERNEL_DEVICETREE}; do
|
||||
DTS_BASE_NAME=`basename ${DTS_FILE} | awk -F "." '{print $1}'`
|
||||
if [ -e "${KERNEL_IMAGETYPE}-${DTS_BASE_NAME}.dtb" ]; then
|
||||
kernel_bin="`readlink ${KERNEL_IMAGETYPE}-${MACHINE}.bin`"
|
||||
kernel_bin_for_dtb="`readlink ${KERNEL_IMAGETYPE}-${DTS_BASE_NAME}.dtb | sed "s,$DTS_BASE_NAME,${MACHINE},g;s,\.dtb$,.bin,g"`"
|
||||
if [ $kernel_bin = $kernel_bin_for_dtb ]; then
|
||||
mcopy -i ${WORKDIR}/boot.img -s ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}-${DTS_BASE_NAME}.dtb ::/${DTS_BASE_NAME}.dtb
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -e "${DEPLOY_DIR_IMAGE}/fex.bin" ]
|
||||
then
|
||||
mcopy -i ${WORKDIR}/boot.img -s ${DEPLOY_DIR_IMAGE}/fex.bin ::script.bin
|
||||
fi
|
||||
if [ -e "${DEPLOY_DIR_IMAGE}/boot.scr" ]
|
||||
then
|
||||
mcopy -i ${WORKDIR}/boot.img -s ${DEPLOY_DIR_IMAGE}/boot.scr ::boot.scr
|
||||
fi
|
||||
|
||||
|
||||
# Add stamp file
|
||||
echo "${IMAGE_NAME}-${IMAGEDATESTAMP}" > ${WORKDIR}/image-version-info
|
||||
|
9
conf/machine/bananapi.conf
Normal file
9
conf/machine/bananapi.conf
Normal file
@ -0,0 +1,9 @@
|
||||
#@TYPE: Machine
|
||||
#@NAME: Bananapi
|
||||
#@DESCRIPTION: Machine configuration for the bananapi, based on allwinner A20 CPU http://bananapi.org/
|
||||
|
||||
require conf/machine/include/sun7i.inc
|
||||
|
||||
KERNEL_DEVICETREE = "sun7i-a20-bananapi.dtb"
|
||||
UBOOT_MACHINE = "Bananapi_config"
|
||||
SUNXI_FEX_FILE = "sys_config/a20/Bananapi.fex"
|
@ -2,17 +2,8 @@
|
||||
#@NAME: CubieBoard
|
||||
#@DESCRIPTION: Machine configuration for the cubieboard, based on allwinner a10 CPU http://cubieboard.org/
|
||||
|
||||
# Only has DVI connector for external screen
|
||||
GUI_MACHINE_CLASS = "bigscreen"
|
||||
require conf/machine/include/sun4i.inc
|
||||
|
||||
require conf/machine/include/tune-cortexa8.inc
|
||||
require conf/machine/include/sunxi.inc
|
||||
require conf/machine/include/sunxi-mali.inc
|
||||
|
||||
UBOOT_MACHINE = "cubieboard"
|
||||
UBOOT_ENTRYPOINT = "0x40008000"
|
||||
UBOOT_LOADADDRESS = "0x40008000"
|
||||
|
||||
SERIAL_CONSOLE = "115200 ttyS0"
|
||||
|
||||
MACHINE_FEATURES = "kernel26 screen apm usbgadget usbhost vfat alsa"
|
||||
KERNEL_DEVICETREE = "sun4i-a10-cubieboard.dtb"
|
||||
UBOOT_MACHINE = "Cubieboard_config"
|
||||
SUNXI_FEX_FILE = "sys_config/a10/cubieboard.fex"
|
||||
|
@ -2,17 +2,8 @@
|
||||
#@NAME: CubieBoard2
|
||||
#@DESCRIPTION: Machine configuration for the cubieboard2, based on allwinner A20 CPU http://cubieboard.org/
|
||||
|
||||
# Only has DVI connector for external screen
|
||||
GUI_MACHINE_CLASS = "bigscreen"
|
||||
require conf/machine/include/sun7i.inc
|
||||
|
||||
require conf/machine/include/tune-cortexa7.inc
|
||||
require conf/machine/include/sunxi.inc
|
||||
require conf/machine/include/sunxi-mali.inc
|
||||
|
||||
UBOOT_MACHINE = "cubieboard2"
|
||||
UBOOT_ENTRYPOINT = "0x40008000"
|
||||
UBOOT_LOADADDRESS = "0x40008000"
|
||||
|
||||
SERIAL_CONSOLE = "115200 ttyS0"
|
||||
|
||||
MACHINE_FEATURES = "screen apm usbgadget usbhost vfat"
|
||||
KERNEL_DEVICETREE = "sun7i-a20-cubieboard2.dtb"
|
||||
UBOOT_MACHINE = "Cubieboard2_config"
|
||||
SUNXI_FEX_FILE = "sys_config/a20/cubieboard2.fex"
|
||||
|
@ -2,17 +2,8 @@
|
||||
#@NAME: Cubietruck
|
||||
#@DESCRIPTION: Machine configuration for the Cubietruck, based on allwinner A20 CPU http://cubieboard.org/
|
||||
|
||||
# Only has DVI connector for external screen
|
||||
GUI_MACHINE_CLASS = "bigscreen"
|
||||
require conf/machine/include/sun7i.inc
|
||||
|
||||
require conf/machine/include/tune-cortexa7.inc
|
||||
require conf/machine/include/sunxi.inc
|
||||
require conf/machine/include/sunxi-mali.inc
|
||||
|
||||
UBOOT_MACHINE = "cubietruck"
|
||||
UBOOT_ENTRYPOINT = "0x40008000"
|
||||
UBOOT_LOADADDRESS = "0x40008000"
|
||||
|
||||
SERIAL_CONSOLE = "115200 ttyS0"
|
||||
|
||||
MACHINE_FEATURES = "screen apm usbgadget usbhost vfat"
|
||||
KERNEL_DEVICETREE = "sun7i-a20-cubietruck.dtb"
|
||||
UBOOT_MACHINE = "Cubietruck_config"
|
||||
SUNXI_FEX_FILE = "sys_config/a20/cubietruck.fex"
|
9
conf/machine/forfun-q88db.conf
Normal file
9
conf/machine/forfun-q88db.conf
Normal file
@ -0,0 +1,9 @@
|
||||
#@TYPE: Machine
|
||||
#@NAME: Forfun Q88DB
|
||||
#@DESCRIPTION: Machine configuration for the Forfun Q88DB Tablet with A13 CPU
|
||||
#http://linux-sunxi.org/Forfun_Q88DB
|
||||
|
||||
require conf/machine/include/sun5i.inc
|
||||
|
||||
UBOOT_MACHINE = "forfun_q88db_defconfig"
|
||||
SUNXI_FEX_FILE = "sys_config/a13/forfun_q88db.fex"
|
5
conf/machine/include/sun4i.inc
Normal file
5
conf/machine/include/sun4i.inc
Normal file
@ -0,0 +1,5 @@
|
||||
require conf/machine/include/sunxi.inc
|
||||
require conf/machine/include/sunxi-mali.inc
|
||||
require conf/machine/include/tune-cortexa8.inc
|
||||
|
||||
SOC_FAMILY = "sun4i"
|
5
conf/machine/include/sun5i.inc
Normal file
5
conf/machine/include/sun5i.inc
Normal file
@ -0,0 +1,5 @@
|
||||
require conf/machine/include/sunxi.inc
|
||||
require conf/machine/include/sunxi-mali.inc
|
||||
require conf/machine/include/tune-cortexa8.inc
|
||||
|
||||
SOC_FAMILY = "sun5i"
|
5
conf/machine/include/sun7i.inc
Normal file
5
conf/machine/include/sun7i.inc
Normal file
@ -0,0 +1,5 @@
|
||||
require conf/machine/include/sunxi.inc
|
||||
require conf/machine/include/sunxi-mali.inc
|
||||
require conf/machine/include/tune-cortexa7.inc
|
||||
|
||||
SOC_FAMILY = "sun7i"
|
@ -1,3 +1,10 @@
|
||||
SOC_FAMILY ??= ""
|
||||
include conf/machine/include/soc-family.inc
|
||||
|
||||
# Sub-architecture support
|
||||
MACHINE_SOCARCH_SUFFIX ?= ""
|
||||
MACHINE_SOCARCH_SUFFIX_sun4i = "-sun4i"
|
||||
|
||||
PREFERRED_PROVIDER_virtual/xserver = "xserver-xorg"
|
||||
XSERVER = "xserver-xorg \
|
||||
xf86-video-fbturbo \
|
||||
@ -5,12 +12,21 @@ XSERVER = "xserver-xorg \
|
||||
xf86-input-mouse \
|
||||
xf86-input-keyboard"
|
||||
|
||||
PREFERRED_PROVIDER_virtual/kernel = "linux"
|
||||
PREFERRED_VERSION_linux-libc-headers = "3.4.61"
|
||||
PREFERRED_PROVIDER_virtual/kernel ?= "linux"
|
||||
PREFERRED_PROVIDER_u-boot ?= "u-boot"
|
||||
PREFERRED_PROVIDER_virtual/bootloader ?= "u-boot"
|
||||
|
||||
KERNEL_IMAGETYPE = "uImage"
|
||||
KERNEL_IMAGETYPE ?= "uImage"
|
||||
|
||||
IMAGE_CLASSES += "sdcard_image-sunxi"
|
||||
IMAGE_FSTYPES += "ext3 tar.gz sunxi-sdimg"
|
||||
|
||||
MACHINE_EXTRA_RRECOMMENDS = "kernel-modules"
|
||||
|
||||
UBOOT_LOCALVERSION = "-g${@d.getVar('SRCPV', True).partition('+')[2][0:7]}"
|
||||
|
||||
UBOOT_ENTRYPOINT ?= "0x40008000"
|
||||
UBOOT_LOADADDRESS ?= "0x400080OB00"
|
||||
|
||||
SERIAL_CONSOLE ?= "115200 ttyS0"
|
||||
MACHINE_FEATURES ?= "alsa apm keyboard rtc serial screen usbgadget usbhost vfat"
|
||||
|
@ -2,17 +2,8 @@
|
||||
#@NAME: Mele a1000/a2000
|
||||
#@DESCRIPTION: Machine configuration for the Mele a1000 and a2000, base on allwinner a10 CPU
|
||||
|
||||
# Only has DVI connector for external screen
|
||||
GUI_MACHINE_CLASS = "bigscreen"
|
||||
require conf/machine/include/sun4i.inc
|
||||
|
||||
require conf/machine/include/tune-cortexa8.inc
|
||||
require conf/machine/include/sunxi.inc
|
||||
require conf/machine/include/sunxi-mali.inc
|
||||
|
||||
UBOOT_MACHINE = "mele_a1000"
|
||||
UBOOT_ENTRYPOINT = "0x40008000"
|
||||
UBOOT_LOADADDRESS = "0x40008000"
|
||||
|
||||
SERIAL_CONSOLE = "115200 ttyS0"
|
||||
|
||||
MACHINE_FEATURES = "kernel26 screen apm usbgadget usbhost vfat alsa"
|
||||
KERNEL_DEVICETREE = "sun4i-a10-a1000.dtb"
|
||||
UBOOT_MACHINE = "Mele_A1000_config"
|
||||
SUNXI_FEX_FILE = "sys_config/a10/mele_a1000.fex"
|
@ -2,17 +2,7 @@
|
||||
#@NAME: Mele a1000g/a2000g
|
||||
#@DESCRIPTION: Machine configuration for the Mele a1000g and a2000g, base on allwinner a10 CPU
|
||||
|
||||
# Only has DVI connector for external screen
|
||||
GUI_MACHINE_CLASS = "bigscreen"
|
||||
require conf/machine/include/sun4i.inc
|
||||
|
||||
require conf/machine/include/tune-cortexa8.inc
|
||||
require conf/machine/include/sunxi.inc
|
||||
require conf/machine/include/sunxi-mali.inc
|
||||
|
||||
UBOOT_MACHINE = "mele_a1000g"
|
||||
UBOOT_ENTRYPOINT = "0x40008000"
|
||||
UBOOT_LOADADDRESS = "0x40008000"
|
||||
|
||||
SERIAL_CONSOLE = "115200 ttyS0"
|
||||
|
||||
MACHINE_FEATURES = "kernel26 screen apm usbgadget usbhost vfat alsa"
|
||||
UBOOT_MACHINE = "Mele_A1000G_quad_config"
|
||||
SUNXI_FEX_FILE = "sys_config/a10/mele_a1000g.fex"
|
@ -1,24 +0,0 @@
|
||||
#@TYPE: Machine
|
||||
#@NAME: Olimex A10-OLinuXino-LIME Board
|
||||
#@DESCRIPTION: Machine configuration for Olimex A10-OLinuXino-LIME Board, based on Allwinner A10 CPU
|
||||
#https://github.com/OLIMEX/OLINUXINO
|
||||
|
||||
# There are also LCD possibilities
|
||||
GUI_MACHINE_CLASS = "bigscreen"
|
||||
|
||||
require conf/machine/include/tune-cortexa8.inc
|
||||
require conf/machine/include/sunxi.inc
|
||||
require conf/machine/include/sunxi-mali.inc
|
||||
|
||||
|
||||
UBOOT_MACHINE = "a10-olinuxino-lime"
|
||||
UBOOT_ENTRYPOINT = "0x40008000"
|
||||
UBOOT_LOADADDRESS = "0x40008000"
|
||||
|
||||
SERIAL_CONSOLE = "115200 ttyS0"
|
||||
|
||||
MACHINE_EXTRA_RRECOMMENDS += "\
|
||||
kernel-module-sw-ahci-platform \
|
||||
"
|
||||
|
||||
MACHINE_FEATURES = "kernel26 screen apm usbgadget usbhost vfat alsa"
|
10
conf/machine/olinuxino-a10lime.conf
Normal file
10
conf/machine/olinuxino-a10lime.conf
Normal file
@ -0,0 +1,10 @@
|
||||
#@TYPE: Machine
|
||||
#@NAME: Olimex A10-OLinuXino Lime (4GB) Board
|
||||
#@DESCRIPTION: Machine configuration for the Olimex A10-OLinuXino Lime Board, based on Allwinner A10 CPU
|
||||
#https://github.com/OLIMEX/OLINUXINO
|
||||
|
||||
require conf/machine/include/sun4i.inc
|
||||
|
||||
KERNEL_DEVICETREE = "sun4i-a10-olinuxino-lime.dtb"
|
||||
UBOOT_MACHINE = "A10-OLinuXino-Lime_config"
|
||||
SUNXI_FEX_FILE = "sys_config/a10/a10-olinuxino-lime.fex"
|
@ -3,17 +3,8 @@
|
||||
#@DESCRIPTION: Machine configuration for Olimex A10S-OLinuXino-MICRO Board, based on Allwinner A10s CPU
|
||||
#https://github.com/OLIMEX/OLINUXINO
|
||||
|
||||
# There are also LCD possibilities
|
||||
GUI_MACHINE_CLASS = "bigscreen"
|
||||
require conf/machine/include/sun5i.inc
|
||||
|
||||
require conf/machine/include/tune-cortexa8.inc
|
||||
require conf/machine/include/sunxi.inc
|
||||
|
||||
|
||||
UBOOT_MACHINE = "a10s-olinuxino-m"
|
||||
UBOOT_ENTRYPOINT = "0x40008000"
|
||||
UBOOT_LOADADDRESS = "0x40008000"
|
||||
|
||||
SERIAL_CONSOLE = "115200 ttyS0"
|
||||
|
||||
MACHINE_FEATURES = "kernel26 screen apm usbgadget usbhost vfat alsa"
|
||||
KERNEL_DEVICETREE = "sun5i-a10s-olinuxino-micro.dtb"
|
||||
UBOOT_MACHINE = "A10s-OLinuXino-M_config"
|
||||
SUNXI_FEX_FILE = "sys_config/a10s/a10s-olinuxino-m.fex"
|
@ -3,17 +3,8 @@
|
||||
#@DESCRIPTION: Machine configuration for the Olime A13-OLinuXino Board, base on allwinner a13 CPU
|
||||
#https://github.com/OLIMEX/OLINUXINO
|
||||
|
||||
# Only has DVI connector for external screen
|
||||
GUI_MACHINE_CLASS = "bigscreen"
|
||||
require conf/machine/include/sun5i.inc
|
||||
|
||||
require conf/machine/include/tune-cortexa8.inc
|
||||
require conf/machine/include/sunxi.inc
|
||||
require conf/machine/include/sunxi-mali.inc
|
||||
|
||||
UBOOT_MACHINE = "a13-olinuxino"
|
||||
UBOOT_ENTRYPOINT = "0x40008000"
|
||||
UBOOT_LOADADDRESS = "0x40008000"
|
||||
|
||||
SERIAL_CONSOLE = "115200 ttyS0"
|
||||
|
||||
MACHINE_FEATURES = "kernel26 screen apm usbgadget usbhost vfat alsa"
|
||||
KERNEL_DEVICETREE = "sun5i-a13-olinuxino.dtb"
|
||||
UBOOT_MACHINE = "A13-OLinuXino_config"
|
||||
SUNXI_FEX_FILE = "sys_config/a13/a13-olinuxino.fex"
|
9
conf/machine/olinuxino-a13som.conf
Normal file
9
conf/machine/olinuxino-a13som.conf
Normal file
@ -0,0 +1,9 @@
|
||||
#@TYPE: Machine
|
||||
#@NAME: Olimex A13-SOM
|
||||
#@DESCRIPTION: Machine configuration for the Olimex A13-SOM Evaluation Board, based on Allwinner A13 CPU
|
||||
#https://github.com/OLIMEX/SOM
|
||||
|
||||
require conf/machine/include/sun5i.inc
|
||||
|
||||
UBOOT_MACHINE = "OLIMEX-A13-SOM_config"
|
||||
SUNXI_FEX_FILE = "sys_config/a13/olimex_a13_som.fex"
|
@ -3,14 +3,8 @@
|
||||
#@DESCRIPTION: Machine configuration for the Olimex A20-OLinuXino Board, based on Allwinner A20 CPU
|
||||
#https://github.com/OLIMEX/OLINUXINO
|
||||
|
||||
require conf/machine/include/tune-cortexa7.inc
|
||||
require conf/machine/include/sunxi.inc
|
||||
require conf/machine/include/sunxi-mali.inc
|
||||
require conf/machine/include/sun7i.inc
|
||||
|
||||
UBOOT_MACHINE = "a20-olinuxino_micro"
|
||||
UBOOT_ENTRYPOINT = "0x40008000"
|
||||
UBOOT_LOADADDRESS = "0x40008000"
|
||||
|
||||
SERIAL_CONSOLE = "115200 ttyS0"
|
||||
|
||||
MACHINE_FEATURES = "kernel26 screen apm usbgadget usbhost vfat alsa"
|
||||
KERNEL_DEVICETREE = "sun7i-a20-olinuxino-micro.dtb"
|
||||
UBOOT_MACHINE = "A20-OLinuXino_MICRO_config"
|
||||
SUNXI_FEX_FILE = "sys_config/a20/a20-olinuxino_micro.fex"
|
10
conf/machine/olinuxino-a20lime.conf
Normal file
10
conf/machine/olinuxino-a20lime.conf
Normal file
@ -0,0 +1,10 @@
|
||||
#@TYPE: Machine
|
||||
#@NAME: Olimex A20-OLinuXino Lime (4GB) Board
|
||||
#@DESCRIPTION: Machine configuration for the Olimex A20-OLinuXino Lime Board, based on Allwinner A20 CPU
|
||||
#https://github.com/OLIMEX/OLINUXINO
|
||||
|
||||
require conf/machine/include/sun7i.inc
|
||||
|
||||
KERNEL_DEVICETREE = "sun7i-a20-olinuxino-lime.dtb"
|
||||
UBOOT_MACHINE = "A20-OLinuXino-Lime_config"
|
||||
SUNXI_FEX_FILE = "sys_config/a20/a20-olinuxino_lime.fex"
|
10
conf/machine/olinuxino-a20lime2.conf
Normal file
10
conf/machine/olinuxino-a20lime2.conf
Normal file
@ -0,0 +1,10 @@
|
||||
#@TYPE: Machine
|
||||
#@NAME: Olimex A20-OLinuXino Lime2 (4GB) Board
|
||||
#@DESCRIPTION: Machine configuration for the Olimex A20-OLinuXino Lime2 Board, based on Allwinner A20 CPU
|
||||
#https://github.com/OLIMEX/OLINUXINO
|
||||
|
||||
require conf/machine/include/sun7i.inc
|
||||
|
||||
KERNEL_DEVICETREE = "sun7i-a20-olinuxino-lime2.dtb"
|
||||
UBOOT_MACHINE = "A20-OLinuXino-Lime2_config"
|
||||
SUNXI_FEX_FILE = "sys_config/a20/a20-olinuxino_lime2.fex"
|
9
conf/machine/olinuxino-a20som.conf
Normal file
9
conf/machine/olinuxino-a20som.conf
Normal file
@ -0,0 +1,9 @@
|
||||
#@TYPE: Machine
|
||||
#@NAME: Olimex A20-SOM
|
||||
#@DESCRIPTION: Machine configuration for the Olimex A20-SOM Evaluation Board, based on Allwinner A20 CPU
|
||||
#https://github.com/OLIMEX/SOM
|
||||
|
||||
require conf/machine/include/sun7i.inc
|
||||
|
||||
UBOOT_MACHINE = "Olimex_A20-SOM_config"
|
||||
SUNXI_FEX_FILE = "sys_config/a20/olimex_a20_som.fex"
|
@ -4,22 +4,16 @@ DESCRIPTION = "Handler for Allwinner's FEX files"
|
||||
LICENSE = "CC0-1.0"
|
||||
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/${LICENSE};md5=0ceb3372c9595f0a8067e55da801e4a1"
|
||||
DEPENDS = "sunxi-tools-native"
|
||||
PV = "1.0"
|
||||
PR = "r6"
|
||||
PV = "1.1+git${SRCPV}"
|
||||
PR = "r0"
|
||||
|
||||
COMPATIBLE_MACHINE = "(sun4i|sun5i|sun7i)"
|
||||
|
||||
SRC_URI = "git://github.com/linux-sunxi/sunxi-boards.git;protocol=git"
|
||||
SRCREV = "5e63e3da42254d3c23eb6436a03ed1d32fb11e98"
|
||||
# Increase PV with SRCREV change
|
||||
SRCREV = "496ef0fbd166cc2395daa76dd3c359357420963d"
|
||||
|
||||
S = "${WORKDIR}/git"
|
||||
SUNXI_FEX_FILE_mele = "sys_config/a10/mele_a1000.fex"
|
||||
SUNXI_FEX_FILE_meleg = "sys_config/a10/mele_a1000g.fex"
|
||||
SUNXI_FEX_FILE_olinuxino-a10s = "sys_config/a10s/a10s-olinuxino-m.fex"
|
||||
SUNXI_FEX_FILE_olinuxino-a10 = "sys_config/a10/a10-olinuxino-lime.fex"
|
||||
SUNXI_FEX_FILE_olinuxino-a13 = "sys_config/a13/a13-olinuxino.fex"
|
||||
SUNXI_FEX_FILE_olinuxino-a20 = "sys_config/a20/a20-olinuxino_micro.fex"
|
||||
SUNXI_FEX_FILE_cubieboard = "sys_config/a10/cubieboard.fex"
|
||||
SUNXI_FEX_FILE_cubieboard2 = "sys_config/a20/cubieboard2.fex"
|
||||
SUNXI_FEX_FILE_cubietruck= "sys_config/a20/cubietruck.fex"
|
||||
|
||||
SUNXI_FEX_BIN_IMAGE = "fex-${MACHINE}-${PV}-${PR}.bin"
|
||||
SUNXI_FEX_BIN_IMAGE_SYMLINK = "fex-${MACHINE}.bin"
|
||||
@ -51,7 +45,3 @@ do_package_write_ipk[noexec] = "1"
|
||||
do_package_write_rpm[noexec] = "1"
|
||||
do_package_write_deb[noexec] = "1"
|
||||
do_populate_sysroot[noexec] = "1"
|
||||
|
||||
# Remember to add machine entry to IMAGE_DEPENDS in sdcard_image-a10.bbclass
|
||||
# when adding new machines.
|
||||
COMPATIBLE_MACHINE = "(mele|meleg|olinuxino-a10s|olinuxino-a10|olinuxino-a13|olinuxino-a20|cubieboard|cubieboard2|cubietruck)"
|
||||
|
4
recipes-bsp/u-boot/files/boot.cmd
Normal file
4
recipes-bsp/u-boot/files/boot.cmd
Normal file
@ -0,0 +1,4 @@
|
||||
setenv bootargs console=${console} console=tty1 root=/dev/mmcblk0p2 rootwait panic=10 ${extra}
|
||||
load mmc 0:1 ${fdt_addr_r} ${fdtfile} || load mmc 0:1 ${fdt_addr_r} boot/${fdtfile}
|
||||
load mmc 0:1 ${kernel_addr_r} zImage || load mmc 0:1 ${kernel_addr_r} boot/zImage || load mmc 0:1 ${kernel_addr_r} uImage || load mmc 0:1 ${kernel_addr_r} boot/uImage
|
||||
bootz ${kernel_addr_r} - ${fdt_addr_r} || bootm ${kernel_addr_r} - ${fdt_addr_r}
|
36
recipes-bsp/u-boot/u-boot-sunxi.bb
Normal file
36
recipes-bsp/u-boot/u-boot-sunxi.bb
Normal file
@ -0,0 +1,36 @@
|
||||
DESCRIPTION = "U-Boot port for sunxi"
|
||||
|
||||
require recipes-bsp/u-boot/u-boot.inc
|
||||
|
||||
LICENSE = "GPLv2"
|
||||
LIC_FILES_CHKSUM = "file://Licenses/gpl-2.0.txt;md5=b234ee4d69f5fce4486a80fdaf4a4263"
|
||||
|
||||
# No patches for other machines yet
|
||||
|
||||
COMPATIBLE_MACHINE = "(sun4i|sun5i|sun7i)"
|
||||
|
||||
DEFAULT_PREFERENCE_sun4i="1"
|
||||
DEFAULT_PREFERENCE_sun5i="1"
|
||||
DEFAULT_PREFERENCE_sun7i="1"
|
||||
|
||||
# Sunxi U-Boot uses different names for some boards
|
||||
UBOOT_MACHINE_olinuxino-a20 = "A20-OLinuXino-Micro_config"
|
||||
UBOOT_MACHINE_olinuxino-a10s = "A10s-OLinuXino-Micro_config"
|
||||
UBOOT_MACHINE_meleg = "Mele_A1000G_config"
|
||||
|
||||
SRC_URI = " \
|
||||
git://github.com/linux-sunxi/u-boot-sunxi.git;protocol=git;branch=sunxi \
|
||||
file://0002-gcc5-fixes.patch \
|
||||
"
|
||||
|
||||
PE = "1"
|
||||
|
||||
PV = "v2014.04+git${SRCPV}"
|
||||
# Corresponds 2014.04 in Makefile
|
||||
SRCREV = "ea1ac32bf76eb60baef474c2516fc431b381d952"
|
||||
|
||||
S = "${WORKDIR}/git"
|
||||
|
||||
PACKAGE_ARCH = "${MACHINE_ARCH}"
|
||||
|
||||
SPL_BINARY="u-boot-sunxi-with-spl.bin"
|
197
recipes-bsp/u-boot/u-boot-sunxi/0002-gcc5-fixes.patch
Normal file
197
recipes-bsp/u-boot/u-boot-sunxi/0002-gcc5-fixes.patch
Normal file
@ -0,0 +1,197 @@
|
||||
From a5e50d6fd7321d0bc60fda2db938c170d09f9dee Mon Sep 17 00:00:00 2001
|
||||
From: Trevor Woerner <twoerner@gmail.com>
|
||||
Date: Thu, 24 Sep 2015 22:36:02 -0400
|
||||
Subject: [PATCH] gcc5 fixes
|
||||
|
||||
gcc5 is pickier about inline functions defined in headers.
|
||||
|
||||
Signed-off-by: Trevor Woerner <twoerner@gmail.com>
|
||||
---
|
||||
arch/arm/include/asm/io.h | 12 ++++----
|
||||
common/board_f.c | 18 ++++++------
|
||||
common/main.c | 2 +-
|
||||
include/linux/compiler-gcc5.h | 65 +++++++++++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 81 insertions(+), 16 deletions(-)
|
||||
create mode 100644 include/linux/compiler-gcc5.h
|
||||
|
||||
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
|
||||
index 6a1f05a..2f6925b 100644
|
||||
--- a/arch/arm/include/asm/io.h
|
||||
+++ b/arch/arm/include/asm/io.h
|
||||
@@ -75,7 +75,7 @@ static inline phys_addr_t virt_to_phys(void * vaddr)
|
||||
#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v))
|
||||
#define __arch_putl(v,a) (*(volatile unsigned int *)(a) = (v))
|
||||
|
||||
-extern inline void __raw_writesb(unsigned long addr, const void *data,
|
||||
+static inline void __raw_writesb(unsigned long addr, const void *data,
|
||||
int bytelen)
|
||||
{
|
||||
uint8_t *buf = (uint8_t *)data;
|
||||
@@ -83,7 +83,7 @@ extern inline void __raw_writesb(unsigned long addr, const void *data,
|
||||
__arch_putb(*buf++, addr);
|
||||
}
|
||||
|
||||
-extern inline void __raw_writesw(unsigned long addr, const void *data,
|
||||
+static inline void __raw_writesw(unsigned long addr, const void *data,
|
||||
int wordlen)
|
||||
{
|
||||
uint16_t *buf = (uint16_t *)data;
|
||||
@@ -91,7 +91,7 @@ extern inline void __raw_writesw(unsigned long addr, const void *data,
|
||||
__arch_putw(*buf++, addr);
|
||||
}
|
||||
|
||||
-extern inline void __raw_writesl(unsigned long addr, const void *data,
|
||||
+static inline void __raw_writesl(unsigned long addr, const void *data,
|
||||
int longlen)
|
||||
{
|
||||
uint32_t *buf = (uint32_t *)data;
|
||||
@@ -99,21 +99,21 @@ extern inline void __raw_writesl(unsigned long addr, const void *data,
|
||||
__arch_putl(*buf++, addr);
|
||||
}
|
||||
|
||||
-extern inline void __raw_readsb(unsigned long addr, void *data, int bytelen)
|
||||
+static inline void __raw_readsb(unsigned long addr, void *data, int bytelen)
|
||||
{
|
||||
uint8_t *buf = (uint8_t *)data;
|
||||
while(bytelen--)
|
||||
*buf++ = __arch_getb(addr);
|
||||
}
|
||||
|
||||
-extern inline void __raw_readsw(unsigned long addr, void *data, int wordlen)
|
||||
+static inline void __raw_readsw(unsigned long addr, void *data, int wordlen)
|
||||
{
|
||||
uint16_t *buf = (uint16_t *)data;
|
||||
while(wordlen--)
|
||||
*buf++ = __arch_getw(addr);
|
||||
}
|
||||
|
||||
-extern inline void __raw_readsl(unsigned long addr, void *data, int longlen)
|
||||
+static inline void __raw_readsl(unsigned long addr, void *data, int longlen)
|
||||
{
|
||||
uint32_t *buf = (uint32_t *)data;
|
||||
while(longlen--)
|
||||
diff --git a/common/board_f.c b/common/board_f.c
|
||||
index f285bad..72b421c 100644
|
||||
--- a/common/board_f.c
|
||||
+++ b/common/board_f.c
|
||||
@@ -78,24 +78,24 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||
************************************************************************
|
||||
* May be supplied by boards if desired
|
||||
*/
|
||||
-inline void __coloured_LED_init(void) {}
|
||||
+void __coloured_LED_init(void) {}
|
||||
void coloured_LED_init(void)
|
||||
__attribute__((weak, alias("__coloured_LED_init")));
|
||||
-inline void __red_led_on(void) {}
|
||||
+void __red_led_on(void) {}
|
||||
void red_led_on(void) __attribute__((weak, alias("__red_led_on")));
|
||||
-inline void __red_led_off(void) {}
|
||||
+void __red_led_off(void) {}
|
||||
void red_led_off(void) __attribute__((weak, alias("__red_led_off")));
|
||||
-inline void __green_led_on(void) {}
|
||||
+void __green_led_on(void) {}
|
||||
void green_led_on(void) __attribute__((weak, alias("__green_led_on")));
|
||||
-inline void __green_led_off(void) {}
|
||||
+void __green_led_off(void) {}
|
||||
void green_led_off(void) __attribute__((weak, alias("__green_led_off")));
|
||||
-inline void __yellow_led_on(void) {}
|
||||
+void __yellow_led_on(void) {}
|
||||
void yellow_led_on(void) __attribute__((weak, alias("__yellow_led_on")));
|
||||
-inline void __yellow_led_off(void) {}
|
||||
+void __yellow_led_off(void) {}
|
||||
void yellow_led_off(void) __attribute__((weak, alias("__yellow_led_off")));
|
||||
-inline void __blue_led_on(void) {}
|
||||
+void __blue_led_on(void) {}
|
||||
void blue_led_on(void) __attribute__((weak, alias("__blue_led_on")));
|
||||
-inline void __blue_led_off(void) {}
|
||||
+void __blue_led_off(void) {}
|
||||
void blue_led_off(void) __attribute__((weak, alias("__blue_led_off")));
|
||||
|
||||
/*
|
||||
diff --git a/common/main.c b/common/main.c
|
||||
index 8b6f274..3312b90 100644
|
||||
--- a/common/main.c
|
||||
+++ b/common/main.c
|
||||
@@ -27,7 +27,7 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||
/*
|
||||
* Board-specific Platform code can reimplement show_boot_progress () if needed
|
||||
*/
|
||||
-void inline __show_boot_progress (int val) {}
|
||||
+void __show_boot_progress (int val) {}
|
||||
void show_boot_progress (int val) __attribute__((weak, alias("__show_boot_progress")));
|
||||
|
||||
#define MAX_DELAY_STOP_STR 32
|
||||
diff --git a/include/linux/compiler-gcc5.h b/include/linux/compiler-gcc5.h
|
||||
new file mode 100644
|
||||
index 0000000..c8c5659
|
||||
--- /dev/null
|
||||
+++ b/include/linux/compiler-gcc5.h
|
||||
@@ -0,0 +1,65 @@
|
||||
+#ifndef __LINUX_COMPILER_H
|
||||
+#error "Please don't include <linux/compiler-gcc5.h> directly, include <linux/compiler.h> instead."
|
||||
+#endif
|
||||
+
|
||||
+#define __used __attribute__((__used__))
|
||||
+#define __must_check __attribute__((warn_unused_result))
|
||||
+#define __compiler_offsetof(a, b) __builtin_offsetof(a, b)
|
||||
+
|
||||
+/* Mark functions as cold. gcc will assume any path leading to a call
|
||||
+ to them will be unlikely. This means a lot of manual unlikely()s
|
||||
+ are unnecessary now for any paths leading to the usual suspects
|
||||
+ like BUG(), printk(), panic() etc. [but let's keep them for now for
|
||||
+ older compilers]
|
||||
+
|
||||
+ Early snapshots of gcc 4.3 don't support this and we can't detect this
|
||||
+ in the preprocessor, but we can live with this because they're unreleased.
|
||||
+ Maketime probing would be overkill here.
|
||||
+
|
||||
+ gcc also has a __attribute__((__hot__)) to move hot functions into
|
||||
+ a special section, but I don't see any sense in this right now in
|
||||
+ the kernel context */
|
||||
+#define __cold __attribute__((__cold__))
|
||||
+
|
||||
+#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
|
||||
+
|
||||
+#ifndef __CHECKER__
|
||||
+# define __compiletime_warning(message) __attribute__((warning(message)))
|
||||
+# define __compiletime_error(message) __attribute__((error(message)))
|
||||
+#endif /* __CHECKER__ */
|
||||
+
|
||||
+/*
|
||||
+ * Mark a position in code as unreachable. This can be used to
|
||||
+ * suppress control flow warnings after asm blocks that transfer
|
||||
+ * control elsewhere.
|
||||
+ *
|
||||
+ * Early snapshots of gcc 4.5 don't support this and we can't detect
|
||||
+ * this in the preprocessor, but we can live with this because they're
|
||||
+ * unreleased. Really, we need to have autoconf for the kernel.
|
||||
+ */
|
||||
+#define unreachable() __builtin_unreachable()
|
||||
+
|
||||
+/* Mark a function definition as prohibited from being cloned. */
|
||||
+#define __noclone __attribute__((__noclone__))
|
||||
+
|
||||
+/*
|
||||
+ * Tell the optimizer that something else uses this function or variable.
|
||||
+ */
|
||||
+#define __visible __attribute__((externally_visible))
|
||||
+
|
||||
+/*
|
||||
+ * GCC 'asm goto' miscompiles certain code sequences:
|
||||
+ *
|
||||
+ * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
|
||||
+ *
|
||||
+ * Work it around via a compiler barrier quirk suggested by Jakub Jelinek.
|
||||
+ *
|
||||
+ * (asm goto is automatically volatile - the naming reflects this.)
|
||||
+ */
|
||||
+#define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0)
|
||||
+
|
||||
+#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP
|
||||
+#define __HAVE_BUILTIN_BSWAP32__
|
||||
+#define __HAVE_BUILTIN_BSWAP64__
|
||||
+#define __HAVE_BUILTIN_BSWAP16__
|
||||
+#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */
|
||||
--
|
||||
2.6.0.rc3
|
||||
|
@ -1,97 +0,0 @@
|
||||
DESCRIPTION = "U-Boot - the Universal Boot Loader"
|
||||
HOMEPAGE = "http://www.denx.de/wiki/U-Boot/WebHome"
|
||||
SECTION = "bootloaders"
|
||||
PROVIDES = "virtual/bootloader"
|
||||
|
||||
inherit deploy
|
||||
|
||||
EXTRA_OEMAKE = 'CROSS_COMPILE=${TARGET_PREFIX} CC="${TARGET_PREFIX}gcc ${TOOLCHAIN_OPTIONS}"'
|
||||
|
||||
python () {
|
||||
if not d.getVar("UBOOT_MACHINE", True):
|
||||
PN = d.getVar("PN", True)
|
||||
FILE = os.path.basename(d.getVar("FILE", True))
|
||||
bb.debug(1, "To build %s, see %s for instructions on \
|
||||
setting up your machine config" % (PN, FILE))
|
||||
raise bb.parse.SkipPackage("because UBOOT_MACHINE is not set")
|
||||
}
|
||||
|
||||
# Allow setting an additional version string that will be picked up by the
|
||||
# u-boot build system and appended to the u-boot version. If the .scmversion
|
||||
# file already exists it will not be overwritten.
|
||||
UBOOT_LOCALVERSION ?= ""
|
||||
|
||||
# Some versions of u-boot use .bin and others use .img. By default use .bin
|
||||
# but enable individual recipes to change this value.
|
||||
UBOOT_SUFFIX ?= "bin"
|
||||
UBOOT_IMAGE ?= "u-boot-${MACHINE}-${PV}-${PR}.${UBOOT_SUFFIX}"
|
||||
UBOOT_BINARY ?= "u-boot.${UBOOT_SUFFIX}"
|
||||
UBOOT_SYMLINK ?= "u-boot-${MACHINE}.${UBOOT_SUFFIX}"
|
||||
UBOOT_MAKE_TARGET ?= "all"
|
||||
|
||||
# Some versions of u-boot build an SPL (Second Program Loader) image that
|
||||
# should be packaged along with the u-boot binary as well as placed in the
|
||||
# deploy directory. For those versions they can set the following variables
|
||||
# to allow packaging the SPL.
|
||||
SPL_BINARY ?= ""
|
||||
SPL_IMAGE ?= "${SPL_BINARY}-${MACHINE}-${PV}-${PR}"
|
||||
SPL_SYMLINK ?= "${SPL_BINARY}-${MACHINE}"
|
||||
|
||||
do_compile () {
|
||||
if [ "${@base_contains('DISTRO_FEATURES', 'ld-is-gold', 'ld-is-gold', '', d)}" = "ld-is-gold" ] ; then
|
||||
sed -i 's/$(CROSS_COMPILE)ld$/$(CROSS_COMPILE)ld.bfd/g' config.mk
|
||||
fi
|
||||
|
||||
unset LDFLAGS
|
||||
unset CFLAGS
|
||||
unset CPPFLAGS
|
||||
|
||||
if [ ! -e ${B}/.scmversion -a ! -e ${S}/.scmversion ]
|
||||
then
|
||||
echo ${UBOOT_LOCALVERSION} > ${B}/.scmversion
|
||||
echo ${UBOOT_LOCALVERSION} > ${S}/.scmversion
|
||||
fi
|
||||
|
||||
oe_runmake ${UBOOT_MACHINE}
|
||||
oe_runmake ${UBOOT_MAKE_TARGET}
|
||||
}
|
||||
|
||||
do_install () {
|
||||
install -d ${D}/boot
|
||||
install ${S}/${UBOOT_BINARY} ${D}/boot/${UBOOT_IMAGE}
|
||||
ln -sf ${UBOOT_IMAGE} ${D}/boot/${UBOOT_BINARY}
|
||||
|
||||
if [ -e ${WORKDIR}/fw_env.config ] ; then
|
||||
install -d ${D}${sysconfdir}
|
||||
install -m 644 ${WORKDIR}/fw_env.config ${D}${sysconfdir}/fw_env.config
|
||||
fi
|
||||
|
||||
if [ "x${SPL_BINARY}" != "x" ]
|
||||
then
|
||||
install ${S}/${SPL_BINARY} ${D}/boot/${SPL_IMAGE}
|
||||
ln -sf ${SPL_IMAGE} ${D}/boot/${SPL_BINARY}
|
||||
fi
|
||||
}
|
||||
|
||||
FILES_${PN} = "/boot ${sysconfdir}"
|
||||
FILESPATH =. "${FILE_DIRNAME}/u-boot-git/${MACHINE}:"
|
||||
|
||||
do_deploy () {
|
||||
install -d ${DEPLOYDIR}
|
||||
install ${S}/${UBOOT_BINARY} ${DEPLOYDIR}/${UBOOT_IMAGE}
|
||||
|
||||
cd ${DEPLOYDIR}
|
||||
rm -f ${UBOOT_BINARY} ${UBOOT_SYMLINK}
|
||||
ln -sf ${UBOOT_IMAGE} ${UBOOT_SYMLINK}
|
||||
ln -sf ${UBOOT_IMAGE} ${UBOOT_BINARY}
|
||||
|
||||
if [ "x${SPL_BINARY}" != "x" ]
|
||||
then
|
||||
install ${S}/${SPL_BINARY} ${DEPLOYDIR}/${SPL_IMAGE}
|
||||
rm -f ${DEPLOYDIR}/${SPL_BINARY} ${DEPLOYDIR}/${SPL_SYMLINK}
|
||||
ln -sf ${SPL_IMAGE} ${DEPLOYDIR}/${SPL_BINARY}
|
||||
ln -sf ${SPL_IMAGE} ${DEPLOYDIR}/${SPL_SYMLINK}
|
||||
fi
|
||||
}
|
||||
|
||||
addtask deploy before do_build after do_compile
|
44
recipes-bsp/u-boot/u-boot_2015.10.bb
Normal file
44
recipes-bsp/u-boot/u-boot_2015.10.bb
Normal file
@ -0,0 +1,44 @@
|
||||
DESCRIPTION="Upstream's U-boot configured for sunxi devices"
|
||||
|
||||
require recipes-bsp/u-boot/u-boot.inc
|
||||
|
||||
DEPENDS += "dtc-native"
|
||||
|
||||
LICENSE = "GPLv2"
|
||||
|
||||
LIC_FILES_CHKSUM = "\
|
||||
file://Licenses/Exceptions;md5=338a7cb1e52d0d1951f83e15319a3fe7 \
|
||||
file://Licenses/bsd-2-clause.txt;md5=6a31f076f5773aabd8ff86191ad6fdd5 \
|
||||
file://Licenses/bsd-3-clause.txt;md5=4a1190eac56a9db675d58ebe86eaf50c \
|
||||
file://Licenses/eCos-2.0.txt;md5=b338cb12196b5175acd3aa63b0a0805c \
|
||||
file://Licenses/gpl-2.0.txt;md5=b234ee4d69f5fce4486a80fdaf4a4263 \
|
||||
file://Licenses/ibm-pibs.txt;md5=c49502a55e35e0a8a1dc271d944d6dba \
|
||||
file://Licenses/isc.txt;md5=ec65f921308235311f34b79d844587eb \
|
||||
file://Licenses/lgpl-2.0.txt;md5=5f30f0716dfdd0d91eb439ebec522ec2 \
|
||||
file://Licenses/lgpl-2.1.txt;md5=4fbd65380cdd255951079008b364516c \
|
||||
file://Licenses/x11.txt;md5=b46f176c847b8742db02126fb8af92e2 \
|
||||
"
|
||||
|
||||
COMPATIBLE_MACHINE = "(sun4i|sun5i|sun7i)"
|
||||
|
||||
DEFAULT_PREFERENCE_sun4i="1"
|
||||
DEFAULT_PREFERENCE_sun5i="1"
|
||||
DEFAULT_PREFERENCE_sun7i="1"
|
||||
|
||||
SRC_URI += "file://boot.cmd \
|
||||
"
|
||||
|
||||
SRCREV = "5ec0003b19cbdf06ccd6941237cbc0d1c3468e2d"
|
||||
|
||||
PV = "v2015.10${SRCPV}"
|
||||
|
||||
PE = "1"
|
||||
|
||||
SPL_BINARY="u-boot-sunxi-with-spl.bin"
|
||||
|
||||
UBOOT_ENV_SUFFIX = "scr"
|
||||
UBOOT_ENV = "boot"
|
||||
|
||||
do_compile_append() {
|
||||
${S}/tools/mkimage -C none -A arm -T script -d ${WORKDIR}/boot.cmd ${WORKDIR}/${UBOOT_ENV_BINARY}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
require u-boot.inc
|
||||
|
||||
LICENSE = "GPLv2"
|
||||
LIC_FILES_CHKSUM = "file://Licenses/gpl-2.0.txt;md5=b234ee4d69f5fce4486a80fdaf4a4263"
|
||||
|
||||
# No patches for other machines yet
|
||||
COMPATIBLE_MACHINE = "(mele|meleg|olinuxino-a13|olinuxino-a10s|olinuxino-a10|olinuxino-a20|cubieboard|cubieboard2|cubietruck)"
|
||||
|
||||
DEFAULT_PREFERENCE_mele= "1"
|
||||
DEFAULT_PREFERENCE_meleg= "1"
|
||||
DEFAULT_PREFERENCE_olinuxino-a13= "1"
|
||||
DEFAULT_PREFERENCE_olinuxino-a10s= "1"
|
||||
DEFAULT_PREFERENCE_olinuxino-a10= "1"
|
||||
DEFAULT_PREFERENCE_olinuxino-a20= "1"
|
||||
DEFAULT_PREFERENCE_cubieboard="1"
|
||||
DEFAULT_PREFERENCE_cubieboard2="1"
|
||||
DEFAULT_PREFERENCE_cubietruck="1"
|
||||
|
||||
SRC_URI = "git://github.com/linux-sunxi/u-boot-sunxi.git;protocol=git;branch=sunxi"
|
||||
|
||||
PE = "1"
|
||||
PV = "v2013.10+v2014.01-rc1"
|
||||
SRCREV = "d854c4de2f57107e35893c591f856f8f6d0ccc5d"
|
||||
|
||||
|
||||
S = "${WORKDIR}/git"
|
||||
|
||||
PACKAGE_ARCH = "${MACHINE_ARCH}"
|
||||
|
||||
SPL_BINARY="u-boot-sunxi-with-spl.bin"
|
||||
|
221
recipes-devtools/python/files/olinuxino-a10/mapping.h
Normal file
221
recipes-devtools/python/files/olinuxino-a10/mapping.h
Normal file
@ -0,0 +1,221 @@
|
||||
/*
|
||||
*
|
||||
* This file is part of pyA10Lime.
|
||||
* mapping.h is python GPIO extension.
|
||||
*
|
||||
* Copyright (c) 2014 Stefan Mavrodiev @ OLIMEX LTD, <support@olimex.com>
|
||||
*
|
||||
* pyA10Lime is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MAPPING_H
|
||||
#define __MAPPING_H
|
||||
|
||||
#include "gpio_lib.h"
|
||||
|
||||
/**
|
||||
Structure that describe all gpio
|
||||
*/
|
||||
typedef struct _pin {
|
||||
char name[10]; // The processor pin
|
||||
int offset; // Memory offset for the pin
|
||||
int pin_number; // Number on the connector
|
||||
}pin_t;
|
||||
|
||||
typedef struct _gpio {
|
||||
char connector_name[10];
|
||||
pin_t pins[41];
|
||||
}gpio_t;
|
||||
|
||||
|
||||
gpio_t gpio[] = {
|
||||
{"lcd",
|
||||
{
|
||||
{ "PD16", SUNXI_GPD(16), 5 },
|
||||
{ "PD17", SUNXI_GPD(17), 6 },
|
||||
{ "PD18", SUNXI_GPD(18), 7 },
|
||||
{ "PD19", SUNXI_GPD(19), 8 },
|
||||
{ "PD20", SUNXI_GPD(20), 9 },
|
||||
{ "PD21", SUNXI_GPD(21), 10 },
|
||||
{ "PD22", SUNXI_GPD(22), 11 },
|
||||
{ "PD23", SUNXI_GPD(23), 12 },
|
||||
{ "PD8", SUNXI_GPD(8), 13 },
|
||||
{ "PD9", SUNXI_GPD(9), 14 },
|
||||
{ "PD10", SUNXI_GPD(10), 15 },
|
||||
{ "PD11", SUNXI_GPD(11), 16 },
|
||||
{ "PD12", SUNXI_GPD(12), 17 },
|
||||
{ "PD13", SUNXI_GPD(13), 18 },
|
||||
{ "PD14", SUNXI_GPD(14), 19 },
|
||||
{ "PD15", SUNXI_GPD(15), 20 },
|
||||
{ "PD0", SUNXI_GPD(0), 21 },
|
||||
{ "PD1", SUNXI_GPD(1), 22 },
|
||||
{ "PD2", SUNXI_GPD(2), 23 },
|
||||
{ "PD3", SUNXI_GPD(3), 24 },
|
||||
{ "PD4", SUNXI_GPD(4), 25 },
|
||||
{ "PD5", SUNXI_GPD(5), 26 },
|
||||
{ "PD6", SUNXI_GPD(6), 27 },
|
||||
{ "PD7", SUNXI_GPD(7), 28 },
|
||||
{ "PD26", SUNXI_GPD(26), 29 },
|
||||
{ "PD27", SUNXI_GPD(27), 30 },
|
||||
{ "PD24", SUNXI_GPD(24), 31 },
|
||||
{ "PD25", SUNXI_GPD(25), 32 },
|
||||
{ "PH8", SUNXI_GPH(8), 35 },
|
||||
{ "PB2", SUNXI_GPB(2), 36 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
{"gpio1",
|
||||
{
|
||||
{ "PG0", SUNXI_GPG(0), 5 },
|
||||
{ "PG1", SUNXI_GPG(1), 7 },
|
||||
{ "PG2", SUNXI_GPG(2), 9 },
|
||||
{ "PG3", SUNXI_GPG(3), 11 },
|
||||
{ "PG4", SUNXI_GPG(4), 13 },
|
||||
{ "PG5", SUNXI_GPG(5), 15 },
|
||||
{ "PG6", SUNXI_GPG(6), 17 },
|
||||
{ "PG7", SUNXI_GPG(7), 19 },
|
||||
{ "PG8", SUNXI_GPG(8), 21 },
|
||||
{ "PG9", SUNXI_GPG(9), 23 },
|
||||
{ "PG10", SUNXI_GPG(10), 25 },
|
||||
{ "PG11", SUNXI_GPG(11), 27 },
|
||||
{ "PC3", SUNXI_GPC(3), 29 },
|
||||
{ "PC18", SUNXI_GPC(18), 31 },
|
||||
{ "PC19", SUNXI_GPC(19), 33 },
|
||||
{ "PC20", SUNXI_GPC(20), 35 },
|
||||
{ "PC21", SUNXI_GPC(21), 37 },
|
||||
{ "PC22", SUNXI_GPC(22), 39 },
|
||||
{ "PC23", SUNXI_GPC(23), 40 },
|
||||
{ "PC24", SUNXI_GPC(24), 38 },
|
||||
{ "PB18", SUNXI_GPB(18), 36 },
|
||||
{ "PB19", SUNXI_GPB(19), 34 },
|
||||
{ "PB20", SUNXI_GPB(20), 32 },
|
||||
{ "PB21", SUNXI_GPB(21), 30 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
{"gpio2",
|
||||
{
|
||||
{ "PI0", SUNXI_GPI(0), 9 },
|
||||
{ "PI1", SUNXI_GPI(1), 11 },
|
||||
{ "PI2", SUNXI_GPI(2), 13 },
|
||||
{ "PI3", SUNXI_GPI(3), 15 },
|
||||
{ "PI4", SUNXI_GPI(4), 17 },
|
||||
{ "PI5", SUNXI_GPI(5), 19 },
|
||||
{ "PI6", SUNXI_GPI(6), 21 },
|
||||
{ "PI7", SUNXI_GPI(7), 23 },
|
||||
{ "PI8", SUNXI_GPI(8), 25 },
|
||||
{ "PI9", SUNXI_GPI(9), 27 },
|
||||
{ "PI10", SUNXI_GPI(10), 29 },
|
||||
{ "PI11", SUNXI_GPI(11), 31 },
|
||||
{ "PI12", SUNXI_GPI(12), 33 },
|
||||
{ "PI13", SUNXI_GPI(13), 35 },
|
||||
{ "PI14", SUNXI_GPI(14), 37 },
|
||||
{ "PI15", SUNXI_GPI(15), 39 },
|
||||
{ "PI16", SUNXI_GPI(16), 40 },
|
||||
{ "PI17", SUNXI_GPI(17), 38 },
|
||||
{ "PI18", SUNXI_GPI(18), 36 },
|
||||
{ "PI19", SUNXI_GPI(19), 34 },
|
||||
{ "PI20", SUNXI_GPI(20), 32 },
|
||||
{ "PI21", SUNXI_GPI(21), 30 },
|
||||
{ "PE0", SUNXI_GPE(0), 6 },
|
||||
{ "PE1", SUNXI_GPE(1), 8 },
|
||||
{ "PE2", SUNXI_GPE(2), 10 },
|
||||
{ "PE3", SUNXI_GPE(3), 12 },
|
||||
{ "PE4", SUNXI_GPE(4), 14 },
|
||||
{ "PE5", SUNXI_GPE(5), 16 },
|
||||
{ "PE6", SUNXI_GPE(6), 18 },
|
||||
{ "PE7", SUNXI_GPE(7), 20 },
|
||||
{ "PE8", SUNXI_GPE(8), 22 },
|
||||
{ "PE9", SUNXI_GPE(9), 24 },
|
||||
{ "PE10", SUNXI_GPE(10), 26 },
|
||||
{ "PE11", SUNXI_GPE(11), 28 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
{"gpio3",
|
||||
{
|
||||
{ "PH0", SUNXI_GPH(0), 7 },
|
||||
{ "PH7", SUNXI_GPH(7), 9 },
|
||||
{ "PH9", SUNXI_GPH(9), 11 },
|
||||
{ "PH10", SUNXI_GPH(10), 13 },
|
||||
{ "PH11", SUNXI_GPH(11), 15 },
|
||||
{ "PH12", SUNXI_GPH(12), 17 },
|
||||
{ "PH13", SUNXI_GPH(13), 19 },
|
||||
{ "PH14", SUNXI_GPH(14), 21 },
|
||||
{ "PH15", SUNXI_GPH(15), 23 },
|
||||
{ "PH16", SUNXI_GPH(16), 25 },
|
||||
{ "PH17", SUNXI_GPH(17), 27 },
|
||||
{ "PH18", SUNXI_GPH(18), 29 },
|
||||
{ "PH19", SUNXI_GPH(19), 31 },
|
||||
{ "PH20", SUNXI_GPH(20), 33 },
|
||||
{ "PH21", SUNXI_GPH(21), 35 },
|
||||
{ "PH22", SUNXI_GPH(22), 37 },
|
||||
{ "PH23", SUNXI_GPH(23), 39 },
|
||||
{ "PH24", SUNXI_GPH(24), 34 },
|
||||
{ "PH25", SUNXI_GPH(25), 36 },
|
||||
{ "PH26", SUNXI_GPH(26), 38 },
|
||||
{ "PH27", SUNXI_GPH(27), 40 },
|
||||
{ "PB3", SUNXI_GPB(3), 6 },
|
||||
{ "PB4", SUNXI_GPB(4), 8 },
|
||||
{ "PB5", SUNXI_GPB(5), 10 },
|
||||
{ "PB6", SUNXI_GPB(6), 12 },
|
||||
{ "PB7", SUNXI_GPB(7), 14 },
|
||||
{ "PB8", SUNXI_GPB(8), 16 },
|
||||
{ "PB10", SUNXI_GPB(10), 18 },
|
||||
{ "PB11", SUNXI_GPB(11), 20 },
|
||||
{ "PB12", SUNXI_GPB(12), 22 },
|
||||
{ "PB13", SUNXI_GPB(13), 24 },
|
||||
{ "PB14", SUNXI_GPB(14), 26 },
|
||||
{ "PB15", SUNXI_GPB(15), 28 },
|
||||
{ "PB16", SUNXI_GPB(16), 30 },
|
||||
{ "PB17", SUNXI_GPB(17), 32 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
{"gpio4",
|
||||
{
|
||||
{ "PC7", SUNXI_GPC(7), 16 },
|
||||
{ "PC16", SUNXI_GPC(16), 18 },
|
||||
{ "PC17", SUNXI_GPC(17), 20 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
{"led",
|
||||
{
|
||||
{ "PH2", SUNXI_GPH(2), 1},
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
#endif
|
221
recipes-devtools/python/files/olinuxino-a10lime/mapping.h
Normal file
221
recipes-devtools/python/files/olinuxino-a10lime/mapping.h
Normal file
@ -0,0 +1,221 @@
|
||||
/*
|
||||
*
|
||||
* This file is part of pyA10Lime.
|
||||
* mapping.h is python GPIO extension.
|
||||
*
|
||||
* Copyright (c) 2014 Stefan Mavrodiev @ OLIMEX LTD, <support@olimex.com>
|
||||
*
|
||||
* pyA10Lime is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MAPPING_H
|
||||
#define __MAPPING_H
|
||||
|
||||
#include "gpio_lib.h"
|
||||
|
||||
/**
|
||||
Structure that describe all gpio
|
||||
*/
|
||||
typedef struct _pin {
|
||||
char name[10]; // The processor pin
|
||||
int offset; // Memory offset for the pin
|
||||
int pin_number; // Number on the connector
|
||||
}pin_t;
|
||||
|
||||
typedef struct _gpio {
|
||||
char connector_name[10];
|
||||
pin_t pins[41];
|
||||
}gpio_t;
|
||||
|
||||
|
||||
gpio_t gpio[] = {
|
||||
{"lcd",
|
||||
{
|
||||
{ "PD16", SUNXI_GPD(16), 5 },
|
||||
{ "PD17", SUNXI_GPD(17), 6 },
|
||||
{ "PD18", SUNXI_GPD(18), 7 },
|
||||
{ "PD19", SUNXI_GPD(19), 8 },
|
||||
{ "PD20", SUNXI_GPD(20), 9 },
|
||||
{ "PD21", SUNXI_GPD(21), 10 },
|
||||
{ "PD22", SUNXI_GPD(22), 11 },
|
||||
{ "PD23", SUNXI_GPD(23), 12 },
|
||||
{ "PD8", SUNXI_GPD(8), 13 },
|
||||
{ "PD9", SUNXI_GPD(9), 14 },
|
||||
{ "PD10", SUNXI_GPD(10), 15 },
|
||||
{ "PD11", SUNXI_GPD(11), 16 },
|
||||
{ "PD12", SUNXI_GPD(12), 17 },
|
||||
{ "PD13", SUNXI_GPD(13), 18 },
|
||||
{ "PD14", SUNXI_GPD(14), 19 },
|
||||
{ "PD15", SUNXI_GPD(15), 20 },
|
||||
{ "PD0", SUNXI_GPD(0), 21 },
|
||||
{ "PD1", SUNXI_GPD(1), 22 },
|
||||
{ "PD2", SUNXI_GPD(2), 23 },
|
||||
{ "PD3", SUNXI_GPD(3), 24 },
|
||||
{ "PD4", SUNXI_GPD(4), 25 },
|
||||
{ "PD5", SUNXI_GPD(5), 26 },
|
||||
{ "PD6", SUNXI_GPD(6), 27 },
|
||||
{ "PD7", SUNXI_GPD(7), 28 },
|
||||
{ "PD26", SUNXI_GPD(26), 29 },
|
||||
{ "PD27", SUNXI_GPD(27), 30 },
|
||||
{ "PD24", SUNXI_GPD(24), 31 },
|
||||
{ "PD25", SUNXI_GPD(25), 32 },
|
||||
{ "PH8", SUNXI_GPH(8), 35 },
|
||||
{ "PB2", SUNXI_GPB(2), 36 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
{"gpio1",
|
||||
{
|
||||
{ "PG0", SUNXI_GPG(0), 5 },
|
||||
{ "PG1", SUNXI_GPG(1), 7 },
|
||||
{ "PG2", SUNXI_GPG(2), 9 },
|
||||
{ "PG3", SUNXI_GPG(3), 11 },
|
||||
{ "PG4", SUNXI_GPG(4), 13 },
|
||||
{ "PG5", SUNXI_GPG(5), 15 },
|
||||
{ "PG6", SUNXI_GPG(6), 17 },
|
||||
{ "PG7", SUNXI_GPG(7), 19 },
|
||||
{ "PG8", SUNXI_GPG(8), 21 },
|
||||
{ "PG9", SUNXI_GPG(9), 23 },
|
||||
{ "PG10", SUNXI_GPG(10), 25 },
|
||||
{ "PG11", SUNXI_GPG(11), 27 },
|
||||
{ "PC3", SUNXI_GPC(3), 29 },
|
||||
{ "PC18", SUNXI_GPC(18), 31 },
|
||||
{ "PC19", SUNXI_GPC(19), 33 },
|
||||
{ "PC20", SUNXI_GPC(20), 35 },
|
||||
{ "PC21", SUNXI_GPC(21), 37 },
|
||||
{ "PC22", SUNXI_GPC(22), 39 },
|
||||
{ "PC23", SUNXI_GPC(23), 40 },
|
||||
{ "PC24", SUNXI_GPC(24), 38 },
|
||||
{ "PB18", SUNXI_GPB(18), 36 },
|
||||
{ "PB19", SUNXI_GPB(19), 34 },
|
||||
{ "PB20", SUNXI_GPB(20), 32 },
|
||||
{ "PB21", SUNXI_GPB(21), 30 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
{"gpio2",
|
||||
{
|
||||
{ "PI0", SUNXI_GPI(0), 9 },
|
||||
{ "PI1", SUNXI_GPI(1), 11 },
|
||||
{ "PI2", SUNXI_GPI(2), 13 },
|
||||
{ "PI3", SUNXI_GPI(3), 15 },
|
||||
{ "PI4", SUNXI_GPI(4), 17 },
|
||||
{ "PI5", SUNXI_GPI(5), 19 },
|
||||
{ "PI6", SUNXI_GPI(6), 21 },
|
||||
{ "PI7", SUNXI_GPI(7), 23 },
|
||||
{ "PI8", SUNXI_GPI(8), 25 },
|
||||
{ "PI9", SUNXI_GPI(9), 27 },
|
||||
{ "PI10", SUNXI_GPI(10), 29 },
|
||||
{ "PI11", SUNXI_GPI(11), 31 },
|
||||
{ "PI12", SUNXI_GPI(12), 33 },
|
||||
{ "PI13", SUNXI_GPI(13), 35 },
|
||||
{ "PI14", SUNXI_GPI(14), 37 },
|
||||
{ "PI15", SUNXI_GPI(15), 39 },
|
||||
{ "PI16", SUNXI_GPI(16), 40 },
|
||||
{ "PI17", SUNXI_GPI(17), 38 },
|
||||
{ "PI18", SUNXI_GPI(18), 36 },
|
||||
{ "PI19", SUNXI_GPI(19), 34 },
|
||||
{ "PI20", SUNXI_GPI(20), 32 },
|
||||
{ "PI21", SUNXI_GPI(21), 30 },
|
||||
{ "PE0", SUNXI_GPE(0), 6 },
|
||||
{ "PE1", SUNXI_GPE(1), 8 },
|
||||
{ "PE2", SUNXI_GPE(2), 10 },
|
||||
{ "PE3", SUNXI_GPE(3), 12 },
|
||||
{ "PE4", SUNXI_GPE(4), 14 },
|
||||
{ "PE5", SUNXI_GPE(5), 16 },
|
||||
{ "PE6", SUNXI_GPE(6), 18 },
|
||||
{ "PE7", SUNXI_GPE(7), 20 },
|
||||
{ "PE8", SUNXI_GPE(8), 22 },
|
||||
{ "PE9", SUNXI_GPE(9), 24 },
|
||||
{ "PE10", SUNXI_GPE(10), 26 },
|
||||
{ "PE11", SUNXI_GPE(11), 28 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
{"gpio3",
|
||||
{
|
||||
{ "PH0", SUNXI_GPH(0), 7 },
|
||||
{ "PH7", SUNXI_GPH(7), 9 },
|
||||
{ "PH9", SUNXI_GPH(9), 11 },
|
||||
{ "PH10", SUNXI_GPH(10), 13 },
|
||||
{ "PH11", SUNXI_GPH(11), 15 },
|
||||
{ "PH12", SUNXI_GPH(12), 17 },
|
||||
{ "PH13", SUNXI_GPH(13), 19 },
|
||||
{ "PH14", SUNXI_GPH(14), 21 },
|
||||
{ "PH15", SUNXI_GPH(15), 23 },
|
||||
{ "PH16", SUNXI_GPH(16), 25 },
|
||||
{ "PH17", SUNXI_GPH(17), 27 },
|
||||
{ "PH18", SUNXI_GPH(18), 29 },
|
||||
{ "PH19", SUNXI_GPH(19), 31 },
|
||||
{ "PH20", SUNXI_GPH(20), 33 },
|
||||
{ "PH21", SUNXI_GPH(21), 35 },
|
||||
{ "PH22", SUNXI_GPH(22), 37 },
|
||||
{ "PH23", SUNXI_GPH(23), 39 },
|
||||
{ "PH24", SUNXI_GPH(24), 34 },
|
||||
{ "PH25", SUNXI_GPH(25), 36 },
|
||||
{ "PH26", SUNXI_GPH(26), 38 },
|
||||
{ "PH27", SUNXI_GPH(27), 40 },
|
||||
{ "PB3", SUNXI_GPB(3), 6 },
|
||||
{ "PB4", SUNXI_GPB(4), 8 },
|
||||
{ "PB5", SUNXI_GPB(5), 10 },
|
||||
{ "PB6", SUNXI_GPB(6), 12 },
|
||||
{ "PB7", SUNXI_GPB(7), 14 },
|
||||
{ "PB8", SUNXI_GPB(8), 16 },
|
||||
{ "PB10", SUNXI_GPB(10), 18 },
|
||||
{ "PB11", SUNXI_GPB(11), 20 },
|
||||
{ "PB12", SUNXI_GPB(12), 22 },
|
||||
{ "PB13", SUNXI_GPB(13), 24 },
|
||||
{ "PB14", SUNXI_GPB(14), 26 },
|
||||
{ "PB15", SUNXI_GPB(15), 28 },
|
||||
{ "PB16", SUNXI_GPB(16), 30 },
|
||||
{ "PB17", SUNXI_GPB(17), 32 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
{"gpio4",
|
||||
{
|
||||
{ "PC7", SUNXI_GPC(7), 16 },
|
||||
{ "PC16", SUNXI_GPC(16), 18 },
|
||||
{ "PC17", SUNXI_GPC(17), 20 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
{"led",
|
||||
{
|
||||
{ "PH2", SUNXI_GPH(2), 1},
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
#endif
|
146
recipes-devtools/python/files/olinuxino-a13/mapping.h
Normal file
146
recipes-devtools/python/files/olinuxino-a13/mapping.h
Normal file
@ -0,0 +1,146 @@
|
||||
/*
|
||||
*
|
||||
* This file is part of pyA13.
|
||||
* mapping.h is python GPIO extension.
|
||||
*
|
||||
* Copyright (c) 2014 Stefan Mavrodiev @ OLIMEX LTD, <support@olimex.com>
|
||||
*
|
||||
* pyA13 is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MAPPING_H
|
||||
#define __MAPPING_H
|
||||
|
||||
#include "gpio_lib.h"
|
||||
|
||||
/**
|
||||
Structure that describe all gpio
|
||||
*/
|
||||
typedef struct _pin {
|
||||
char name[10]; // The processor pin
|
||||
int offset; // Memory offset for the pin
|
||||
int pin_number; // Number on the connector
|
||||
}pin_t;
|
||||
|
||||
typedef struct _gpio {
|
||||
char connector_name[10];
|
||||
pin_t pins[41];
|
||||
}gpio_t;
|
||||
|
||||
|
||||
gpio_t gpio[] = {
|
||||
{"lcd",
|
||||
{
|
||||
{ "PD18", SUNXI_GPD(18), 5 },
|
||||
{ "PD18", SUNXI_GPD(18), 6 },
|
||||
{ "PD18", SUNXI_GPD(18), 7 },
|
||||
{ "PD19", SUNXI_GPD(19), 8 },
|
||||
{ "PD20", SUNXI_GPD(20), 9 },
|
||||
{ "PD21", SUNXI_GPD(21), 10 },
|
||||
{ "PD22", SUNXI_GPD(22), 11 },
|
||||
{ "PD23", SUNXI_GPD(23), 12 },
|
||||
{ "PD10", SUNXI_GPD(10), 13 },
|
||||
{ "PD10", SUNXI_GPD(10), 14 },
|
||||
{ "PD10", SUNXI_GPD(10), 15 },
|
||||
{ "PD11", SUNXI_GPD(11), 16 },
|
||||
{ "PD12", SUNXI_GPD(12), 17 },
|
||||
{ "PD13", SUNXI_GPD(13), 18 },
|
||||
{ "PD14", SUNXI_GPD(14), 19 },
|
||||
{ "PD15", SUNXI_GPD(15), 20 },
|
||||
{ "PD2", SUNXI_GPD(2), 21 },
|
||||
{ "PD2", SUNXI_GPD(2), 22 },
|
||||
{ "PD2", SUNXI_GPD(2), 23 },
|
||||
{ "PD3", SUNXI_GPD(3), 24 },
|
||||
{ "PD4", SUNXI_GPD(4), 25 },
|
||||
{ "PD5", SUNXI_GPD(5), 26 },
|
||||
{ "PD6", SUNXI_GPD(6), 27 },
|
||||
{ "PD7", SUNXI_GPD(7), 28 },
|
||||
{ "PD26", SUNXI_GPD(26), 29 },
|
||||
{ "PD27", SUNXI_GPD(27), 30 },
|
||||
{ "PD24", SUNXI_GPD(24), 31 },
|
||||
{ "PD25", SUNXI_GPD(25), 32 },
|
||||
{ "PB3", SUNXI_GPB(3), 33 },
|
||||
{ "PB4", SUNXI_GPB(4), 34 },
|
||||
{ "PB10", SUNXI_GPB(10), 35 },
|
||||
{ "PB2", SUNXI_GPB(2), 36 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
{"gpio2",
|
||||
{
|
||||
{ "PB0", SUNXI_GPB(0), 5 },
|
||||
{ "PG11", SUNXI_GPG(11), 6 },
|
||||
{ "PB1", SUNXI_GPB(1), 7 },
|
||||
{ "PG10", SUNXI_GPG(10), 8 },
|
||||
{ "PB2", SUNXI_GPB(2), 9 },
|
||||
{ "PG9", SUNXI_GPG(9), 10 },
|
||||
{ "PB3", SUNXI_GPB(3), 11 },
|
||||
{ "PE11", SUNXI_GPE(11), 12 },
|
||||
{ "PB4", SUNXI_GPB(4), 13 },
|
||||
{ "PE10", SUNXI_GPE(10), 14 },
|
||||
{ "PB10", SUNXI_GPB(10), 15 },
|
||||
{ "PE9", SUNXI_GPE(9), 16 },
|
||||
{ "PB15", SUNXI_GPB(15), 17 },
|
||||
{ "PE8", SUNXI_GPE(8), 18 },
|
||||
{ "PB16", SUNXI_GPB(16), 19 },
|
||||
{ "PE7", SUNXI_GPE(7), 20 },
|
||||
{ "PC0", SUNXI_GPC(0), 21 },
|
||||
{ "PE6", SUNXI_GPE(6), 22 },
|
||||
{ "PC1", SUNXI_GPC(1), 23 },
|
||||
{ "PE5", SUNXI_GPE(5), 24 },
|
||||
{ "PC2", SUNXI_GPC(2), 25 },
|
||||
{ "PE4", SUNXI_GPE(4), 26 },
|
||||
{ "PC3", SUNXI_GPC(3), 27 },
|
||||
{ "PC19", SUNXI_GPC(19), 28 },
|
||||
{ "PC4", SUNXI_GPC(4), 29 },
|
||||
{ "PC15", SUNXI_GPC(15), 30 },
|
||||
{ "PC5", SUNXI_GPC(5), 31 },
|
||||
{ "PC14", SUNXI_GPC(14), 32 },
|
||||
{ "PC6", SUNXI_GPC(6), 33 },
|
||||
{ "PC13", SUNXI_GPC(13), 34 },
|
||||
{ "PC7", SUNXI_GPC(7), 35 },
|
||||
{ "PC12", SUNXI_GPC(12), 36 },
|
||||
{ "PC8", SUNXI_GPC(8), 37 },
|
||||
{ "PC11", SUNXI_GPC(11), 38 },
|
||||
{ "PC9", SUNXI_GPC(9), 39 },
|
||||
{ "PC10", SUNXI_GPC(10), 40 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
{"uext",
|
||||
{
|
||||
{ "PG3", SUNXI_GPG(3), 3 },
|
||||
{ "PG3", SUNXI_GPG(4), 4 },
|
||||
{ "PB17", SUNXI_GPB(17), 5 },
|
||||
{ "PB18", SUNXI_GPB(18), 6 },
|
||||
{ "PE3", SUNXI_GPE(3), 7 },
|
||||
{ "PE2", SUNXI_GPE(2), 8 },
|
||||
{ "PE1", SUNXI_GPE(1), 9 },
|
||||
{ "PE0", SUNXI_GPE(0), 10 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
147
recipes-devtools/python/files/olinuxino-a13som/mapping.h
Normal file
147
recipes-devtools/python/files/olinuxino-a13som/mapping.h
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
*
|
||||
* This file is part of pyA13SOM.
|
||||
* mapping.h is python GPIO extension.
|
||||
*
|
||||
* Copyright (c) 2014 Stefan Mavrodiev @ OLIMEX LTD, <support@olimex.com>
|
||||
*
|
||||
* pyA13SOM is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MAPPING_H
|
||||
#define __MAPPING_H
|
||||
|
||||
#include "gpio_lib.h"
|
||||
|
||||
/**
|
||||
Structure that describe all gpio
|
||||
*/
|
||||
typedef struct _pin {
|
||||
char name[10]; // The processor pin
|
||||
int offset; // Memory offset for the pin
|
||||
int pin_number; // Number on the connector
|
||||
}pin_t;
|
||||
|
||||
typedef struct _gpio {
|
||||
char connector_name[10];
|
||||
pin_t pins[41];
|
||||
}gpio_t;
|
||||
|
||||
|
||||
gpio_t gpio[] = {
|
||||
{"lcd",
|
||||
{
|
||||
{ "PD18", SUNXI_GPD(18), 5 },
|
||||
{ "PD18", SUNXI_GPD(18), 6 },
|
||||
{ "PD18", SUNXI_GPD(18), 7 },
|
||||
{ "PD19", SUNXI_GPD(19), 8 },
|
||||
{ "PD20", SUNXI_GPD(20), 9 },
|
||||
{ "PD21", SUNXI_GPD(21), 10 },
|
||||
{ "PD22", SUNXI_GPD(22), 11 },
|
||||
{ "PD23", SUNXI_GPD(23), 12 },
|
||||
{ "PD10", SUNXI_GPD(10), 13 },
|
||||
{ "PD10", SUNXI_GPD(10), 14 },
|
||||
{ "PD10", SUNXI_GPD(10), 15 },
|
||||
{ "PD11", SUNXI_GPD(11), 16 },
|
||||
{ "PD12", SUNXI_GPD(12), 17 },
|
||||
{ "PD13", SUNXI_GPD(13), 18 },
|
||||
{ "PD14", SUNXI_GPD(14), 19 },
|
||||
{ "PD15", SUNXI_GPD(15), 20 },
|
||||
{ "PD2", SUNXI_GPD(2), 21 },
|
||||
{ "PD2", SUNXI_GPD(2), 22 },
|
||||
{ "PD2", SUNXI_GPD(2), 23 },
|
||||
{ "PD3", SUNXI_GPD(3), 24 },
|
||||
{ "PD4", SUNXI_GPD(4), 25 },
|
||||
{ "PD5", SUNXI_GPD(5), 26 },
|
||||
{ "PD6", SUNXI_GPD(6), 27 },
|
||||
{ "PD7", SUNXI_GPD(7), 28 },
|
||||
{ "PD26", SUNXI_GPD(26), 29 },
|
||||
{ "PD27", SUNXI_GPD(27), 30 },
|
||||
{ "PD24", SUNXI_GPD(24), 31 },
|
||||
{ "PD25", SUNXI_GPD(25), 32 },
|
||||
{ "PB3", SUNXI_GPB(3), 33 },
|
||||
{ "PB4", SUNXI_GPB(4), 34 },
|
||||
{ "PB10", SUNXI_GPB(10), 35 },
|
||||
{ "PB2", SUNXI_GPB(2), 36 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
{"gpio1",
|
||||
{
|
||||
{ "PB0", SUNXI_GPB(0), 5 },
|
||||
{ "PG11", SUNXI_GPG(11), 6 },
|
||||
{ "PB1", SUNXI_GPB(1), 7 },
|
||||
{ "PG10", SUNXI_GPG(10), 8 },
|
||||
{ "PB2", SUNXI_GPB(2), 9 },
|
||||
{ "PG9", SUNXI_GPG(9), 10 },
|
||||
{ "PB3", SUNXI_GPB(3), 11 },
|
||||
{ "PE11", SUNXI_GPE(11), 12 },
|
||||
{ "PB4", SUNXI_GPB(4), 13 },
|
||||
{ "PE10", SUNXI_GPE(10), 14 },
|
||||
{ "PB10", SUNXI_GPB(10), 15 },
|
||||
{ "PE9", SUNXI_GPE(9), 16 },
|
||||
{ "PB15", SUNXI_GPB(15), 17 },
|
||||
{ "PE8", SUNXI_GPE(8), 18 },
|
||||
{ "PB16", SUNXI_GPB(16), 19 },
|
||||
{ "PE7", SUNXI_GPE(7), 20 },
|
||||
{ "PC0", SUNXI_GPC(0), 21 },
|
||||
{ "PE6", SUNXI_GPE(6), 22 },
|
||||
{ "PC1", SUNXI_GPC(1), 23 },
|
||||
{ "PE5", SUNXI_GPE(5), 24 },
|
||||
{ "PC2", SUNXI_GPC(2), 25 },
|
||||
{ "PE4", SUNXI_GPE(4), 26 },
|
||||
{ "PC3", SUNXI_GPC(3), 27 },
|
||||
{ "PC19", SUNXI_GPC(19), 28 },
|
||||
{ "PC4", SUNXI_GPC(4), 29 },
|
||||
{ "PC15", SUNXI_GPC(15), 30 },
|
||||
{ "PC5", SUNXI_GPC(5), 31 },
|
||||
{ "PC14", SUNXI_GPC(14), 32 },
|
||||
{ "PC6", SUNXI_GPC(6), 33 },
|
||||
{ "PC13", SUNXI_GPC(13), 34 },
|
||||
{ "PC7", SUNXI_GPC(7), 35 },
|
||||
{ "PC12", SUNXI_GPC(12), 36 },
|
||||
{ "PC8", SUNXI_GPC(8), 37 },
|
||||
{ "PC11", SUNXI_GPC(11), 38 },
|
||||
{ "PC9", SUNXI_GPC(9), 39 },
|
||||
{ "PC10", SUNXI_GPC(10), 40 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
{"gpio3",
|
||||
{
|
||||
{ "PE0", SUNXI_GPE(0), 1 },
|
||||
{ "PG1", SUNXI_GPG(1), 2 },
|
||||
{ "PE1", SUNXI_GPE(1), 3 },
|
||||
{ "PG2", SUNXI_GPG(2), 4 },
|
||||
{ "PE2", SUNXI_GPE(2), 5 },
|
||||
{ "PG12", SUNXI_GPG(12), 6 },
|
||||
{ "PE3", SUNXI_GPE(3), 7 },
|
||||
{ "PB17", SUNXI_GPB(17), 8 },
|
||||
{ "PB18", SUNXI_GPB(18), 10 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
303
recipes-devtools/python/files/olinuxino-a20/mapping.h
Normal file
303
recipes-devtools/python/files/olinuxino-a20/mapping.h
Normal file
@ -0,0 +1,303 @@
|
||||
/*
|
||||
*
|
||||
* This file is part of pyA20.
|
||||
* mapping.h is python GPIO extension.
|
||||
*
|
||||
* Copyright (c) 2014 Stefan Mavrodiev @ OLIMEX LTD, <support@olimex.com>
|
||||
*
|
||||
* pyA20 is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MAPPING_H
|
||||
#define __MAPPING_H
|
||||
|
||||
#include "gpio_lib.h"
|
||||
|
||||
/**
|
||||
Structure that describe all gpio
|
||||
*/
|
||||
typedef struct _pin {
|
||||
char name[10]; // The processor pin
|
||||
int offset; // Memory offset for the pin
|
||||
int pin_number; // Number on the connector
|
||||
}pin_t;
|
||||
|
||||
typedef struct _gpio {
|
||||
char connector_name[10];
|
||||
pin_t pins[41];
|
||||
}gpio_t;
|
||||
|
||||
|
||||
gpio_t gpio[] = {
|
||||
{"lcd",
|
||||
{
|
||||
{ "PD16", SUNXI_GPD(16), 5 },
|
||||
{ "PD17", SUNXI_GPD(17), 6 },
|
||||
{ "PD18", SUNXI_GPD(18), 7 },
|
||||
{ "PD19", SUNXI_GPD(19), 8 },
|
||||
{ "PD20", SUNXI_GPD(20), 9 },
|
||||
{ "PD21", SUNXI_GPD(21), 10 },
|
||||
{ "PD22", SUNXI_GPD(22), 11 },
|
||||
{ "PD23", SUNXI_GPD(23), 12 },
|
||||
{ "PD8", SUNXI_GPD(8), 13 },
|
||||
{ "PD9", SUNXI_GPD(9), 14 },
|
||||
{ "PD10", SUNXI_GPD(10), 15 },
|
||||
{ "PD11", SUNXI_GPD(11), 16 },
|
||||
{ "PD12", SUNXI_GPD(12), 17 },
|
||||
{ "PD13", SUNXI_GPD(13), 18 },
|
||||
{ "PD14", SUNXI_GPD(14), 19 },
|
||||
{ "PD15", SUNXI_GPD(15), 20 },
|
||||
{ "PD0", SUNXI_GPD(0), 21 },
|
||||
{ "PD1", SUNXI_GPD(1), 22 },
|
||||
{ "PD2", SUNXI_GPD(2), 23 },
|
||||
{ "PD3", SUNXI_GPD(3), 24 },
|
||||
{ "PD4", SUNXI_GPD(4), 25 },
|
||||
{ "PD5", SUNXI_GPD(5), 26 },
|
||||
{ "PD6", SUNXI_GPD(6), 27 },
|
||||
{ "PD7", SUNXI_GPD(7), 28 },
|
||||
{ "PD26", SUNXI_GPD(26), 29 },
|
||||
{ "PD27", SUNXI_GPD(27), 30 },
|
||||
{ "PD24", SUNXI_GPD(24), 31 },
|
||||
{ "PD25", SUNXI_GPD(25), 32 },
|
||||
{ "PH8", SUNXI_GPH(8), 35 },
|
||||
{ "PB2", SUNXI_GPB(2), 36 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
/*
|
||||
#define PIN_PG0 SUNXI_GPG(0)
|
||||
#define PIN_PG1 SUNXI_GPG(1)
|
||||
#define PIN_PG2 SUNXI_GPG(2)
|
||||
#define PIN_PG3 SUNXI_GPG(3)
|
||||
#define PIN_PG4 SUNXI_GPG(4)
|
||||
#define PIN_PG5 SUNXI_GPG(5)
|
||||
#define PIN_PG6 SUNXI_GPG(6)
|
||||
#define PIN_PG7 SUNXI_GPG(7)
|
||||
#define PIN_PG8 SUNXI_GPG(8)
|
||||
#define PIN_PG9 SUNXI_GPG(9)
|
||||
#define PIN_PG10 SUNXI_GPG(10)
|
||||
#define PIN_PG11 SUNXI_GPG(11)
|
||||
*/ {"gpio1",
|
||||
{
|
||||
{ "PG0", SUNXI_GPG(0), 5 },
|
||||
{ "PG1", SUNXI_GPG(0), 7 },
|
||||
{ "PG2", SUNXI_GPG(0), 9 },
|
||||
{ "PG3", SUNXI_GPG(0), 11 },
|
||||
{ "PG4", SUNXI_GPG(0), 13 },
|
||||
{ "PG5", SUNXI_GPG(0), 15 },
|
||||
{ "PG6", SUNXI_GPG(0), 17 },
|
||||
{ "PG7", SUNXI_GPG(0), 19 },
|
||||
{ "PG8", SUNXI_GPG(0), 21 },
|
||||
{ "PG9", SUNXI_GPG(0), 23 },
|
||||
{ "PG10", SUNXI_GPG(0), 25 },
|
||||
{ "PG11", SUNXI_GPG(0), 27 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
//GPIO 2
|
||||
#define PIN_PE0 SUNXI_GPE(0)
|
||||
#define PIN_PE1 SUNXI_GPE(1)
|
||||
#define PIN_PI0 SUNXI_GPI(0)
|
||||
#define PIN_PE2 SUNXI_GPE(2)
|
||||
#define PIN_PI1 SUNXI_GPI(1)
|
||||
#define PIN_PE3 SUNXI_GPE(3)
|
||||
#define PIN_PI2 SUNXI_GPI(2)
|
||||
#define PIN_PE4 SUNXI_GPE(4)
|
||||
#define PIN_PI3 SUNXI_GPI(3)
|
||||
#define PIN_PE5 SUNXI_GPE(5)
|
||||
#define PIN_PI10 SUNXI_GPI(10)
|
||||
#define PIN_PE6 SUNXI_GPE(6)
|
||||
#define PIN_PI11 SUNXI_GPI(11)
|
||||
#define PIN_PE7 SUNXI_GPE(7)
|
||||
#define PIN_PC3 SUNXI_GPC(3)
|
||||
#define PIN_PE8 SUNXI_GPE(8)
|
||||
#define PIN_PC7 SUNXI_GPC(7)
|
||||
#define PIN_PE9 SUNXI_GPE(9)
|
||||
#define PIN_PC16 SUNXI_GPC(16)
|
||||
#define PIN_PE10 SUNXI_GPE(10)
|
||||
#define PIN_PC17 SUNXI_GPC(17)
|
||||
#define PIN_PE11 SUNXI_GPE(11)
|
||||
#define PIN_PC18 SUNXI_GPC(18)
|
||||
#define PIN_PI14 SUNXI_GPI(14)
|
||||
#define PIN_PC23 SUNXI_GPC(23)
|
||||
#define PIN_PI15 SUNXI_GPI(15)
|
||||
#define PIN_PC24 SUNXI_GPC(24)
|
||||
#define PIN_PB23 SUNXI_GPB(23)
|
||||
#define PIN_PB22 SUNXI_GPB(22)
|
||||
*/
|
||||
{"gpio2",
|
||||
{
|
||||
{ "PE0", SUNXI_GPE(0), 6 },
|
||||
{ "PE1", SUNXI_GPE(1), 8 },
|
||||
{ "PI0", SUNXI_GPI(0), 9 },
|
||||
{ "PE2", SUNXI_GPE(2), 10 },
|
||||
{ "PI1", SUNXI_GPI(1), 11 },
|
||||
{ "PE3", SUNXI_GPE(3), 12 },
|
||||
{ "PI2", SUNXI_GPI(2), 13 },
|
||||
{ "PE4", SUNXI_GPE(4), 14 },
|
||||
{ "PI3", SUNXI_GPI(3), 15 },
|
||||
{ "PE5", SUNXI_GPE(5), 16 },
|
||||
{ "PI10", SUNXI_GPI(10), 17 },
|
||||
{ "PE6", SUNXI_GPE(6), 18 },
|
||||
{ "PI11", SUNXI_GPI(11), 19 },
|
||||
{ "PE7", SUNXI_GPE(7), 20 },
|
||||
{ "PC3", SUNXI_GPC(3), 21 },
|
||||
{ "PE8", SUNXI_GPE(8), 22 },
|
||||
{ "PC7", SUNXI_GPC(7), 23 },
|
||||
{ "PE9", SUNXI_GPE(9), 24 },
|
||||
{ "PC16", SUNXI_GPC(16), 25 },
|
||||
{ "PE10", SUNXI_GPE(10), 26 },
|
||||
{ "PC17", SUNXI_GPC(17), 27 },
|
||||
{ "PE11", SUNXI_GPE(11), 28 },
|
||||
{ "PC18", SUNXI_GPC(18), 29 },
|
||||
{ "PI14", SUNXI_GPI(14), 30 },
|
||||
{ "PC23", SUNXI_GPC(23), 31 },
|
||||
{ "PI15", SUNXI_GPI(15), 32 },
|
||||
{ "PC24", SUNXI_GPC(24), 33 },
|
||||
{ "PB23", SUNXI_GPB(23), 34 },
|
||||
{ "PB22", SUNXI_GPB(22), 36 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
//GPIO 3
|
||||
#define PIN_PH0 SUNXI_GPH(0)
|
||||
#define PIN_PB3 SUNXI_GPB(3)
|
||||
#define PIN_PH2 SUNXI_GPH(2)
|
||||
#define PIN_PB4 SUNXI_GPB(4)
|
||||
#define PIN_PH7 SUNXI_GPH(7)
|
||||
#define PIN_PB5 SUNXI_GPB(5)
|
||||
#define PIN_PH9 SUNXI_GPH(9)
|
||||
#define PIN_PB6 SUNXI_GPB(6)
|
||||
#define PIN_PH10 SUNXI_GPH(10)
|
||||
#define PIN_PB7 SUNXI_GPB(7)
|
||||
#define PIN_PH11 SUNXI_GPH(11)
|
||||
#define PIN_PB8 SUNXI_GPB(8)
|
||||
#define PIN_PH12 SUNXI_GPH(12)
|
||||
#define PIN_PB10 SUNXI_GPB(10)
|
||||
#define PIN_PH13 SUNXI_GPH(13)
|
||||
#define PIN_PB11 SUNXI_GPB(11)
|
||||
#define PIN_PH14 SUNXI_GPH(14)
|
||||
#define PIN_PB12 SUNXI_GPB(12)
|
||||
#define PIN_PH15 SUNXI_GPH(15)
|
||||
#define PIN_PB13 SUNXI_GPB(13)
|
||||
#define PIN_PH16 SUNXI_GPH(16)
|
||||
#define PIN_PB14 SUNXI_GPB(14)
|
||||
#define PIN_PH17 SUNXI_GPH(17)
|
||||
#define PIN_PB15 SUNXI_GPB(15)
|
||||
#define PIN_PH18 SUNXI_GPH(18)
|
||||
#define PIN_PB16 SUNXI_GPB(16)
|
||||
#define PIN_PH19 SUNXI_GPH(19)
|
||||
#define PIN_PB17 SUNXI_GPB(17)
|
||||
#define PIN_PH20 SUNXI_GPH(20)
|
||||
#define PIN_PH24 SUNXI_GPH(24)
|
||||
#define PIN_PH21 SUNXI_GPH(21)
|
||||
#define PIN_PH25 SUNXI_GPH(25)
|
||||
#define PIN_PH22 SUNXI_GPH(22)
|
||||
#define PIN_PH26 SUNXI_GPH(26)
|
||||
#define PIN_PH23 SUNXI_GPH(23)
|
||||
#define PIN_PH27 SUNXI_GPH(27)
|
||||
*/
|
||||
{"gpio3",
|
||||
{
|
||||
{ "PH0", SUNXI_GPH(0), 5 },
|
||||
{ "PB3", SUNXI_GPB(3), 6 },
|
||||
{ "PH2", SUNXI_GPH(2), 7 },
|
||||
{ "PB4", SUNXI_GPB(4), 8 },
|
||||
{ "PH7", SUNXI_GPH(7), 9 },
|
||||
{ "PB5", SUNXI_GPB(5), 10 },
|
||||
{ "PH9", SUNXI_GPH(9), 11 },
|
||||
{ "PB6", SUNXI_GPB(6), 12 },
|
||||
{ "PH10", SUNXI_GPH(10), 13 },
|
||||
{ "PB7", SUNXI_GPB(7), 14 },
|
||||
{ "PH11", SUNXI_GPH(11), 15 },
|
||||
{ "PB8", SUNXI_GPB(8), 16 },
|
||||
{ "PH12", SUNXI_GPH(12), 17 },
|
||||
{ "PB10", SUNXI_GPB(10), 18 },
|
||||
{ "PH13", SUNXI_GPH(13), 19 },
|
||||
{ "PB11", SUNXI_GPB(11), 20 },
|
||||
{ "PH14", SUNXI_GPH(14), 21 },
|
||||
{ "PB12", SUNXI_GPB(12), 22 },
|
||||
{ "PH15", SUNXI_GPH(15), 23 },
|
||||
{ "PB13", SUNXI_GPB(13), 24 },
|
||||
{ "PH16", SUNXI_GPH(16), 25 },
|
||||
{ "PB14", SUNXI_GPB(14), 26 },
|
||||
{ "PH17", SUNXI_GPH(17), 27 },
|
||||
{ "PB15", SUNXI_GPB(15), 28 },
|
||||
{ "PH18", SUNXI_GPH(18), 29 },
|
||||
{ "PB16", SUNXI_GPB(16), 30 },
|
||||
{ "PH19", SUNXI_GPH(19), 31 },
|
||||
{ "PB17", SUNXI_GPB(17), 32 },
|
||||
{ "PH20", SUNXI_GPH(20), 33 },
|
||||
{ "PH24", SUNXI_GPH(24), 34 },
|
||||
{ "PH21", SUNXI_GPH(21), 35 },
|
||||
{ "PH25", SUNXI_GPH(25), 36 },
|
||||
{ "PH22", SUNXI_GPH(22), 37 },
|
||||
{ "PH26", SUNXI_GPH(26), 38 },
|
||||
{ "PH23", SUNXI_GPH(23), 39 },
|
||||
{ "PH27", SUNXI_GPH(27), 40 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
{"uext1",
|
||||
{
|
||||
{ "PI12", SUNXI_GPI(12), 3 },
|
||||
{ "PI13", SUNXI_GPI(13), 4 },
|
||||
{ "PB20", SUNXI_GPB(20), 5 },
|
||||
{ "PB21", SUNXI_GPB(21), 6 },
|
||||
{ "PC22", SUNXI_GPC(22), 7 },
|
||||
{ "PC21", SUNXI_GPC(21), 8 },
|
||||
{ "PC20", SUNXI_GPC(20), 9 },
|
||||
{ "PC19", SUNXI_GPC(19), 10 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
{"uext2",
|
||||
{
|
||||
{ "PI20", SUNXI_GPI(20), 3 },
|
||||
{ "PI21", SUNXI_GPI(21), 4 },
|
||||
{ "PB18", SUNXI_GPB(18), 5 },
|
||||
{ "PB19", SUNXI_GPB(19), 6 },
|
||||
{ "PI19", SUNXI_GPI(19), 7 },
|
||||
{ "PI18", SUNXI_GPI(18), 8 },
|
||||
{ "PI17", SUNXI_GPI(17), 9 },
|
||||
{ "PI16", SUNXI_GPI(16), 10 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
221
recipes-devtools/python/files/olinuxino-a20lime/mapping.h
Normal file
221
recipes-devtools/python/files/olinuxino-a20lime/mapping.h
Normal file
@ -0,0 +1,221 @@
|
||||
/*
|
||||
*
|
||||
* This file is part of pyA20Lime.
|
||||
* mapping.h is python GPIO extension.
|
||||
*
|
||||
* Copyright (c) 2014 Stefan Mavrodiev @ OLIMEX LTD, <support@olimex.com>
|
||||
*
|
||||
* pyA20Lime is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MAPPING_H
|
||||
#define __MAPPING_H
|
||||
|
||||
#include "gpio_lib.h"
|
||||
|
||||
/**
|
||||
Structure that describe all gpio
|
||||
*/
|
||||
typedef struct _pin {
|
||||
char name[10]; // The processor pin
|
||||
int offset; // Memory offset for the pin
|
||||
int pin_number; // Number on the connector
|
||||
}pin_t;
|
||||
|
||||
typedef struct _gpio {
|
||||
char connector_name[10];
|
||||
pin_t pins[41];
|
||||
}gpio_t;
|
||||
|
||||
|
||||
gpio_t gpio[] = {
|
||||
{"lcd",
|
||||
{
|
||||
{ "PD16", SUNXI_GPD(16), 5 },
|
||||
{ "PD17", SUNXI_GPD(17), 6 },
|
||||
{ "PD18", SUNXI_GPD(18), 7 },
|
||||
{ "PD19", SUNXI_GPD(19), 8 },
|
||||
{ "PD20", SUNXI_GPD(20), 9 },
|
||||
{ "PD21", SUNXI_GPD(21), 10 },
|
||||
{ "PD22", SUNXI_GPD(22), 11 },
|
||||
{ "PD23", SUNXI_GPD(23), 12 },
|
||||
{ "PD8", SUNXI_GPD(8), 13 },
|
||||
{ "PD9", SUNXI_GPD(9), 14 },
|
||||
{ "PD10", SUNXI_GPD(10), 15 },
|
||||
{ "PD11", SUNXI_GPD(11), 16 },
|
||||
{ "PD12", SUNXI_GPD(12), 17 },
|
||||
{ "PD13", SUNXI_GPD(13), 18 },
|
||||
{ "PD14", SUNXI_GPD(14), 19 },
|
||||
{ "PD15", SUNXI_GPD(15), 20 },
|
||||
{ "PD0", SUNXI_GPD(0), 21 },
|
||||
{ "PD1", SUNXI_GPD(1), 22 },
|
||||
{ "PD2", SUNXI_GPD(2), 23 },
|
||||
{ "PD3", SUNXI_GPD(3), 24 },
|
||||
{ "PD4", SUNXI_GPD(4), 25 },
|
||||
{ "PD5", SUNXI_GPD(5), 26 },
|
||||
{ "PD6", SUNXI_GPD(6), 27 },
|
||||
{ "PD7", SUNXI_GPD(7), 28 },
|
||||
{ "PD26", SUNXI_GPD(26), 29 },
|
||||
{ "PD27", SUNXI_GPD(27), 30 },
|
||||
{ "PD24", SUNXI_GPD(24), 31 },
|
||||
{ "PD25", SUNXI_GPD(25), 32 },
|
||||
{ "PH8", SUNXI_GPH(8), 35 },
|
||||
{ "PB2", SUNXI_GPB(2), 36 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
{"gpio1",
|
||||
{
|
||||
{ "PG0", SUNXI_GPG(0), 5 },
|
||||
{ "PG1", SUNXI_GPG(1), 7 },
|
||||
{ "PG2", SUNXI_GPG(2), 9 },
|
||||
{ "PG3", SUNXI_GPG(3), 11 },
|
||||
{ "PG4", SUNXI_GPG(4), 13 },
|
||||
{ "PG5", SUNXI_GPG(5), 15 },
|
||||
{ "PG6", SUNXI_GPG(6), 17 },
|
||||
{ "PG7", SUNXI_GPG(7), 19 },
|
||||
{ "PG8", SUNXI_GPG(8), 21 },
|
||||
{ "PG9", SUNXI_GPG(9), 23 },
|
||||
{ "PG10", SUNXI_GPG(10), 25 },
|
||||
{ "PG11", SUNXI_GPG(11), 27 },
|
||||
{ "PC3", SUNXI_GPC(3), 29 },
|
||||
{ "PC18", SUNXI_GPC(18), 31 },
|
||||
{ "PC19", SUNXI_GPC(19), 33 },
|
||||
{ "PC20", SUNXI_GPC(20), 35 },
|
||||
{ "PC21", SUNXI_GPC(21), 37 },
|
||||
{ "PC22", SUNXI_GPC(22), 39 },
|
||||
{ "PC23", SUNXI_GPC(23), 40 },
|
||||
{ "PC24", SUNXI_GPC(24), 38 },
|
||||
{ "PB18", SUNXI_GPB(18), 36 },
|
||||
{ "PB19", SUNXI_GPB(19), 34 },
|
||||
{ "PB20", SUNXI_GPB(20), 32 },
|
||||
{ "PB21", SUNXI_GPB(21), 30 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
{"gpio2",
|
||||
{
|
||||
{ "PI0", SUNXI_GPI(0), 9 },
|
||||
{ "PI1", SUNXI_GPI(1), 11 },
|
||||
{ "PI2", SUNXI_GPI(2), 13 },
|
||||
{ "PI3", SUNXI_GPI(3), 15 },
|
||||
{ "PI4", SUNXI_GPI(4), 17 },
|
||||
{ "PI5", SUNXI_GPI(5), 19 },
|
||||
{ "PI6", SUNXI_GPI(6), 21 },
|
||||
{ "PI7", SUNXI_GPI(7), 23 },
|
||||
{ "PI8", SUNXI_GPI(8), 25 },
|
||||
{ "PI9", SUNXI_GPI(9), 27 },
|
||||
{ "PI10", SUNXI_GPI(10), 29 },
|
||||
{ "PI11", SUNXI_GPI(11), 31 },
|
||||
{ "PI12", SUNXI_GPI(12), 33 },
|
||||
{ "PI13", SUNXI_GPI(13), 35 },
|
||||
{ "PI14", SUNXI_GPI(14), 37 },
|
||||
{ "PI15", SUNXI_GPI(15), 39 },
|
||||
{ "PI16", SUNXI_GPI(16), 40 },
|
||||
{ "PI17", SUNXI_GPI(17), 38 },
|
||||
{ "PI18", SUNXI_GPI(18), 36 },
|
||||
{ "PI19", SUNXI_GPI(19), 34 },
|
||||
{ "PI20", SUNXI_GPI(20), 32 },
|
||||
{ "PI21", SUNXI_GPI(21), 30 },
|
||||
{ "PE0", SUNXI_GPE(0), 6 },
|
||||
{ "PE1", SUNXI_GPE(1), 8 },
|
||||
{ "PE2", SUNXI_GPE(2), 10 },
|
||||
{ "PE3", SUNXI_GPE(3), 12 },
|
||||
{ "PE4", SUNXI_GPE(4), 14 },
|
||||
{ "PE5", SUNXI_GPE(5), 16 },
|
||||
{ "PE6", SUNXI_GPE(6), 18 },
|
||||
{ "PE7", SUNXI_GPE(7), 20 },
|
||||
{ "PE8", SUNXI_GPE(8), 22 },
|
||||
{ "PE9", SUNXI_GPE(9), 24 },
|
||||
{ "PE10", SUNXI_GPE(10), 26 },
|
||||
{ "PE11", SUNXI_GPE(11), 28 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
{"gpio3",
|
||||
{
|
||||
{ "PH0", SUNXI_GPH(0), 7 },
|
||||
{ "PH7", SUNXI_GPH(7), 9 },
|
||||
{ "PH9", SUNXI_GPH(9), 11 },
|
||||
{ "PH10", SUNXI_GPH(10), 13 },
|
||||
{ "PH11", SUNXI_GPH(11), 15 },
|
||||
{ "PH12", SUNXI_GPH(12), 17 },
|
||||
{ "PH13", SUNXI_GPH(13), 19 },
|
||||
{ "PH14", SUNXI_GPH(14), 21 },
|
||||
{ "PH15", SUNXI_GPH(15), 23 },
|
||||
{ "PH16", SUNXI_GPH(16), 25 },
|
||||
{ "PH17", SUNXI_GPH(17), 27 },
|
||||
{ "PH18", SUNXI_GPH(18), 29 },
|
||||
{ "PH19", SUNXI_GPH(19), 31 },
|
||||
{ "PH20", SUNXI_GPH(20), 33 },
|
||||
{ "PH21", SUNXI_GPH(21), 35 },
|
||||
{ "PH22", SUNXI_GPH(22), 37 },
|
||||
{ "PH23", SUNXI_GPH(23), 39 },
|
||||
{ "PH24", SUNXI_GPH(24), 34 },
|
||||
{ "PH25", SUNXI_GPH(25), 36 },
|
||||
{ "PH26", SUNXI_GPH(26), 38 },
|
||||
{ "PH27", SUNXI_GPH(27), 40 },
|
||||
{ "PB3", SUNXI_GPB(3), 6 },
|
||||
{ "PB4", SUNXI_GPB(4), 8 },
|
||||
{ "PB5", SUNXI_GPB(5), 10 },
|
||||
{ "PB6", SUNXI_GPB(6), 12 },
|
||||
{ "PB7", SUNXI_GPB(7), 14 },
|
||||
{ "PB8", SUNXI_GPB(8), 16 },
|
||||
{ "PB10", SUNXI_GPB(10), 18 },
|
||||
{ "PB11", SUNXI_GPB(11), 20 },
|
||||
{ "PB12", SUNXI_GPB(12), 22 },
|
||||
{ "PB13", SUNXI_GPB(13), 24 },
|
||||
{ "PB14", SUNXI_GPB(14), 26 },
|
||||
{ "PB15", SUNXI_GPB(15), 28 },
|
||||
{ "PB16", SUNXI_GPB(16), 30 },
|
||||
{ "PB17", SUNXI_GPB(17), 32 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
{"gpio4",
|
||||
{
|
||||
{ "PC7", SUNXI_GPC(7), 16 },
|
||||
{ "PC16", SUNXI_GPC(16), 18 },
|
||||
{ "PC17", SUNXI_GPC(17), 20 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
{"led",
|
||||
{
|
||||
{ "PH2", SUNXI_GPH(2), 1},
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
#endif
|
224
recipes-devtools/python/files/olinuxino-a20lime2/mapping.h
Normal file
224
recipes-devtools/python/files/olinuxino-a20lime2/mapping.h
Normal file
@ -0,0 +1,224 @@
|
||||
/*
|
||||
*
|
||||
* This file is part of pyA20Lime2.
|
||||
* mapping.h is python GPIO extension.
|
||||
*
|
||||
* Copyright (c) 2014 Stefan Mavrodiev @ OLIMEX LTD, <support@olimex.com>
|
||||
*
|
||||
* pyA20Lime2 is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MAPPING_H
|
||||
#define __MAPPING_H
|
||||
|
||||
#include "gpio_lib.h"
|
||||
|
||||
/**
|
||||
Structure that describe all gpio
|
||||
*/
|
||||
typedef struct _pin {
|
||||
char name[10]; // The processor pin
|
||||
int offset; // Memory offset for the pin
|
||||
int pin_number; // Number on the connector
|
||||
}pin_t;
|
||||
|
||||
typedef struct _gpio {
|
||||
char connector_name[10];
|
||||
pin_t pins[41];
|
||||
}gpio_t;
|
||||
|
||||
|
||||
gpio_t gpio[] = {
|
||||
{"lcd",
|
||||
{
|
||||
{ "PD16", SUNXI_GPD(16), 5 },
|
||||
{ "PD17", SUNXI_GPD(17), 6 },
|
||||
{ "PD18", SUNXI_GPD(18), 7 },
|
||||
{ "PD19", SUNXI_GPD(19), 8 },
|
||||
{ "PD20", SUNXI_GPD(20), 9 },
|
||||
{ "PD21", SUNXI_GPD(21), 10 },
|
||||
{ "PD22", SUNXI_GPD(22), 11 },
|
||||
{ "PD23", SUNXI_GPD(23), 12 },
|
||||
{ "PD8", SUNXI_GPD(8), 13 },
|
||||
{ "PD9", SUNXI_GPD(9), 14 },
|
||||
{ "PD10", SUNXI_GPD(10), 15 },
|
||||
{ "PD11", SUNXI_GPD(11), 16 },
|
||||
{ "PD12", SUNXI_GPD(12), 17 },
|
||||
{ "PD13", SUNXI_GPD(13), 18 },
|
||||
{ "PD14", SUNXI_GPD(14), 19 },
|
||||
{ "PD15", SUNXI_GPD(15), 20 },
|
||||
{ "PD0", SUNXI_GPD(0), 21 },
|
||||
{ "PD1", SUNXI_GPD(1), 22 },
|
||||
{ "PD2", SUNXI_GPD(2), 23 },
|
||||
{ "PD3", SUNXI_GPD(3), 24 },
|
||||
{ "PD4", SUNXI_GPD(4), 25 },
|
||||
{ "PD5", SUNXI_GPD(5), 26 },
|
||||
{ "PD6", SUNXI_GPD(6), 27 },
|
||||
{ "PD7", SUNXI_GPD(7), 28 },
|
||||
{ "PD26", SUNXI_GPD(26), 29 },
|
||||
{ "PD27", SUNXI_GPD(27), 30 },
|
||||
{ "PD24", SUNXI_GPD(24), 31 },
|
||||
{ "PD25", SUNXI_GPD(25), 32 },
|
||||
{ "PH8", SUNXI_GPH(8), 35 },
|
||||
{ "PB2", SUNXI_GPB(2), 36 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
{"gpio1",
|
||||
{
|
||||
{ "PG0", SUNXI_GPG(0), 5 },
|
||||
{ "PG1", SUNXI_GPG(1), 7 },
|
||||
{ "PG2", SUNXI_GPG(2), 9 },
|
||||
{ "PG3", SUNXI_GPG(3), 11 },
|
||||
{ "PG4", SUNXI_GPG(4), 13 },
|
||||
{ "PG5", SUNXI_GPG(5), 15 },
|
||||
{ "PG6", SUNXI_GPG(6), 17 },
|
||||
{ "PG7", SUNXI_GPG(7), 19 },
|
||||
{ "PG8", SUNXI_GPG(8), 21 },
|
||||
{ "PG9", SUNXI_GPG(9), 23 },
|
||||
{ "PG10", SUNXI_GPG(10), 25 },
|
||||
{ "PG11", SUNXI_GPG(11), 27 },
|
||||
{ "PC3", SUNXI_GPC(3), 29 },
|
||||
{ "PC18", SUNXI_GPC(18), 31 },
|
||||
{ "PC19", SUNXI_GPC(19), 33 },
|
||||
{ "PC20", SUNXI_GPC(20), 35 },
|
||||
{ "PC21", SUNXI_GPC(21), 37 },
|
||||
{ "PC22", SUNXI_GPC(22), 39 },
|
||||
{ "PC23", SUNXI_GPC(23), 40 },
|
||||
{ "PC24", SUNXI_GPC(24), 38 },
|
||||
{ "PB18", SUNXI_GPB(18), 36 },
|
||||
{ "PB19", SUNXI_GPB(19), 34 },
|
||||
{ "PB20", SUNXI_GPB(20), 32 },
|
||||
{ "PB21", SUNXI_GPB(21), 30 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
{"gpio2",
|
||||
{
|
||||
{ "PI0", SUNXI_GPI(0), 9 },
|
||||
{ "PI1", SUNXI_GPI(1), 11 },
|
||||
{ "PI2", SUNXI_GPI(2), 13 },
|
||||
{ "PI3", SUNXI_GPI(3), 15 },
|
||||
{ "PI4", SUNXI_GPI(4), 17 },
|
||||
{ "PI5", SUNXI_GPI(5), 19 },
|
||||
{ "PI6", SUNXI_GPI(6), 21 },
|
||||
{ "PI7", SUNXI_GPI(7), 23 },
|
||||
{ "PI8", SUNXI_GPI(8), 25 },
|
||||
{ "PI9", SUNXI_GPI(9), 27 },
|
||||
{ "PI10", SUNXI_GPI(10), 29 },
|
||||
{ "PI11", SUNXI_GPI(11), 31 },
|
||||
{ "PI12", SUNXI_GPI(12), 33 },
|
||||
{ "PI13", SUNXI_GPI(13), 35 },
|
||||
{ "PI14", SUNXI_GPI(14), 37 },
|
||||
{ "PI15", SUNXI_GPI(15), 39 },
|
||||
{ "PI16", SUNXI_GPI(16), 40 },
|
||||
{ "PI17", SUNXI_GPI(17), 38 },
|
||||
{ "PI18", SUNXI_GPI(18), 36 },
|
||||
{ "PI19", SUNXI_GPI(19), 34 },
|
||||
{ "PI20", SUNXI_GPI(20), 32 },
|
||||
{ "PI21", SUNXI_GPI(21), 30 },
|
||||
{ "PE0", SUNXI_GPE(0), 6 },
|
||||
{ "PE1", SUNXI_GPE(1), 8 },
|
||||
{ "PE2", SUNXI_GPE(2), 10 },
|
||||
{ "PE3", SUNXI_GPE(3), 12 },
|
||||
{ "PE4", SUNXI_GPE(4), 14 },
|
||||
{ "PE5", SUNXI_GPE(5), 16 },
|
||||
{ "PE6", SUNXI_GPE(6), 18 },
|
||||
{ "PE7", SUNXI_GPE(7), 20 },
|
||||
{ "PE8", SUNXI_GPE(8), 22 },
|
||||
{ "PE9", SUNXI_GPE(9), 24 },
|
||||
{ "PE10", SUNXI_GPE(10), 26 },
|
||||
{ "PE11", SUNXI_GPE(11), 28 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
{"gpio3",
|
||||
{
|
||||
{ "PH0", SUNXI_GPH(0), 7 },
|
||||
{ "PH7", SUNXI_GPH(7), 9 },
|
||||
{ "PH9", SUNXI_GPH(9), 11 },
|
||||
{ "PH10", SUNXI_GPH(10), 13 },
|
||||
{ "PH11", SUNXI_GPH(11), 15 },
|
||||
{ "PH12", SUNXI_GPH(12), 17 },
|
||||
{ "PH13", SUNXI_GPH(13), 19 },
|
||||
{ "PH14", SUNXI_GPH(14), 21 },
|
||||
{ "PH15", SUNXI_GPH(15), 23 },
|
||||
{ "PH16", SUNXI_GPH(16), 25 },
|
||||
{ "PH17", SUNXI_GPH(17), 27 },
|
||||
{ "PH18", SUNXI_GPH(18), 29 },
|
||||
{ "PH19", SUNXI_GPH(19), 31 },
|
||||
{ "PH20", SUNXI_GPH(20), 33 },
|
||||
{ "PH21", SUNXI_GPH(21), 35 },
|
||||
{ "PH22", SUNXI_GPH(22), 37 },
|
||||
{ "PH23", SUNXI_GPH(23), 39 },
|
||||
{ "PH24", SUNXI_GPH(24), 34 },
|
||||
{ "PH25", SUNXI_GPH(25), 36 },
|
||||
{ "PH26", SUNXI_GPH(26), 38 },
|
||||
{ "PH27", SUNXI_GPH(27), 40 },
|
||||
{ "PB3", SUNXI_GPB(3), 4 },
|
||||
{ "PB4", SUNXI_GPB(4), 6 },
|
||||
{ "PB5", SUNXI_GPB(5), 8 },
|
||||
{ "PB6", SUNXI_GPB(6), 10 },
|
||||
{ "PB7", SUNXI_GPB(7), 12 },
|
||||
{ "PB8", SUNXI_GPB(8), 14 },
|
||||
{ "PB9", SUNXI_GPB(8), 16 },
|
||||
{ "PB10", SUNXI_GPB(10), 18 },
|
||||
{ "PB11", SUNXI_GPB(11), 20 },
|
||||
{ "PB12", SUNXI_GPB(12), 22 },
|
||||
{ "PB13", SUNXI_GPB(13), 24 },
|
||||
{ "PB14", SUNXI_GPB(14), 26 },
|
||||
{ "PB15", SUNXI_GPB(15), 28 },
|
||||
{ "PB16", SUNXI_GPB(16), 30 },
|
||||
{ "PB17", SUNXI_GPB(17), 32 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
{"gpio4",
|
||||
{
|
||||
{ "PA9", SUNXI_GPA(9), 12 },
|
||||
{ "PA14", SUNXI_GPA(14), 14 },
|
||||
{ "PC7", SUNXI_GPC(7), 16 },
|
||||
{ "PC16", SUNXI_GPC(16), 18 },
|
||||
{ "PC17", SUNXI_GPC(17), 20 },
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
{"led",
|
||||
{
|
||||
{ "PH2", SUNXI_GPH(2), 1},
|
||||
{
|
||||
{ 0, 0, 0}
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
#endif
|
51
recipes-devtools/python/files/setup.py.patch
Normal file
51
recipes-devtools/python/files/setup.py.patch
Normal file
@ -0,0 +1,51 @@
|
||||
--- pyA20-0.2.0/setup.py 2014-09-04 12:17:18.000000000 +0200
|
||||
+++ pyA20-0.2.0/setup.py 2014-11-24 17:44:37.000000000 +0100
|
||||
@@ -43,31 +43,31 @@
|
||||
Detect processor type
|
||||
:return:
|
||||
"""
|
||||
- cpuinfo = open("/proc/cpuinfo", 'r')
|
||||
- for line in cpuinfo:
|
||||
- if "Hardware" in line:
|
||||
- processor = line.split(":")[1].rstrip()
|
||||
+ #cpuinfo = open("/proc/cpuinfo", 'r')
|
||||
+ #for line in cpuinfo:
|
||||
+ # if "Hardware" in line:
|
||||
+ # processor = line.split(":")[1].rstrip()
|
||||
|
||||
- if "sun4i" in processor:
|
||||
- print ("Detected processor: " + print_color(processor) + " (Probably Allwinner A10)")
|
||||
+ # if "sun4i" in processor:
|
||||
+ # print ("Detected processor: " + print_color(processor) + " (Probably Allwinner A10)")
|
||||
|
||||
- elif "sun5i" in processor:
|
||||
- print ("Detected processor: " + print_color(processor) + " (Probably Allwinner A13)")
|
||||
+ # elif "sun5i" in processor:
|
||||
+ # print ("Detected processor: " + print_color(processor) + " (Probably Allwinner A13)")
|
||||
|
||||
- elif "sun7i" in processor:
|
||||
- print ("Detected processor: " + print_color(processor) + " (Probably Allwinner A20)")
|
||||
+ # elif "sun7i" in processor:
|
||||
+ # print ("Detected processor: " + print_color(processor) + " (Probably Allwinner A20)")
|
||||
|
||||
- else:
|
||||
- print ("Detected processor: " + print_color("unknown"))
|
||||
+ # else:
|
||||
+ # print ("Detected processor: " + print_color("unknown"))
|
||||
|
||||
|
||||
- if processor_type not in processor:
|
||||
- print_warning()
|
||||
+ # if processor_type not in processor:
|
||||
+ # print_warning()
|
||||
|
||||
- return
|
||||
+ return
|
||||
|
||||
- print ("No processor detected")
|
||||
- print_warning()
|
||||
+ #print ("No processor detected")
|
||||
+ #print_warning()
|
||||
|
||||
|
||||
class build_ext(_build_ext):
|
24
recipes-devtools/python/pyA20_0.2.0.bb
Normal file
24
recipes-devtools/python/pyA20_0.2.0.bb
Normal file
@ -0,0 +1,24 @@
|
||||
DESCRIPTION = "A module to control Allwinner GPIO,SPI and I2C channels"
|
||||
HOMEPAGE = "https://pypi.python.org/pypi/pyA20"
|
||||
SECTION = "devel/python"
|
||||
LICENSE = "MIT"
|
||||
LIC_FILES_CHKSUM = "file://PKG-INFO;md5=b4cb7d5da6f1efc1d0bf487169e83985"
|
||||
DEPENDS = "python"
|
||||
|
||||
# No GPIO mappings for other machines yet
|
||||
COMPATIBLE_MACHINE = "(olinuxino-a13|olinuxino-a10|olinuxino-a20|olinuxino-a10lime|olinuxino-a20lime|olinuxino-a20lime2|olinuxino-a13som)"
|
||||
|
||||
SRC_URI = "http://pypi.python.org/packages/source/p/pyA20/pyA20-${PV}.tar.gz \
|
||||
file://setup.py.patch \
|
||||
file://mapping.h \
|
||||
"
|
||||
S = "${WORKDIR}/pyA20-${PV}"
|
||||
|
||||
inherit distutils
|
||||
|
||||
do_compile_prepend() {
|
||||
cp ${WORKDIR}/mapping.h ${S}/pyA20/gpio/mapping.h
|
||||
}
|
||||
|
||||
SRC_URI[md5sum] = "b4115859834f09ebd389f810f2ffefb9"
|
||||
SRC_URI[sha256sum] = "9855747d9bbdfcce6b460fcd67d953155e39f4e002a9a4c573910248b451dad8"
|
@ -0,0 +1,47 @@
|
||||
From fcdde5440976bb2c204789e13313c4d77cb263b7 Mon Sep 17 00:00:00 2001
|
||||
From: Nicolas Aguirre <aguirre.nicolas@gmail.com>
|
||||
Date: Tue, 16 Jun 2015 23:06:29 +0200
|
||||
Subject: [PATCH] Add EGLSyncKHR EGLTimeKHR and GLChar definition
|
||||
|
||||
---
|
||||
include/EGL/eglext.h | 4 +++-
|
||||
include/GLES2/gl2.h | 1 +
|
||||
2 files changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/include/EGL/eglext.h b/include/EGL/eglext.h
|
||||
index 25cfcb8..ec482d8 100644
|
||||
--- a/include/EGL/eglext.h
|
||||
+++ b/include/EGL/eglext.h
|
||||
@@ -36,7 +36,6 @@ extern "C" {
|
||||
/* Current version at http://www.khronos.org/registry/egl/ */
|
||||
/* $Revision: 7244 $ on $Date: 2009-01-20 17:06:59 -0800 (Tue, 20 Jan 2009) $ */
|
||||
#define EGL_EGLEXT_VERSION 3
|
||||
-
|
||||
#ifndef EGL_KHR_config_attribs
|
||||
#define EGL_KHR_config_attribs 1
|
||||
#define EGL_CONFORMANT_KHR 0x3042 /* EGLConfig attribute */
|
||||
@@ -44,6 +43,9 @@ extern "C" {
|
||||
#define EGL_VG_ALPHA_FORMAT_PRE_BIT_KHR 0x0040 /* EGL_SURFACE_TYPE bitfield */
|
||||
#endif
|
||||
|
||||
+typedef void *EGLSyncKHR;
|
||||
+typedef uint64_t EGLTimeKHR;
|
||||
+
|
||||
#ifndef EGL_KHR_lock_surface
|
||||
#define EGL_KHR_lock_surface 1
|
||||
#define EGL_READ_SURFACE_BIT_KHR 0x0001 /* EGL_LOCK_USAGE_HINT_KHR bitfield */
|
||||
diff --git a/include/GLES2/gl2.h b/include/GLES2/gl2.h
|
||||
index 59e376c..90d96bb 100644
|
||||
--- a/include/GLES2/gl2.h
|
||||
+++ b/include/GLES2/gl2.h
|
||||
@@ -32,6 +32,7 @@ typedef unsigned int GLuint;
|
||||
typedef khronos_float_t GLfloat;
|
||||
typedef khronos_float_t GLclampf;
|
||||
typedef khronos_int32_t GLfixed;
|
||||
+typedef char GLchar;
|
||||
|
||||
/* GL types for handling large vertex buffer objects */
|
||||
typedef khronos_intptr_t GLintptr;
|
||||
--
|
||||
1.9.1
|
||||
|
@ -0,0 +1,28 @@
|
||||
From 054886253f4f559b351a94e1e6ebfd5eb504461f Mon Sep 17 00:00:00 2001
|
||||
From: Trevor Woerner <twoerner@gmail.com>
|
||||
Date: Thu, 24 Sep 2015 23:38:11 -0400
|
||||
Subject: [PATCH] fix test build
|
||||
|
||||
Allow the test application to build and link successfully.
|
||||
|
||||
Signed-off-by: Trevor Woerner <twoerner@gmail.com>
|
||||
---
|
||||
test/Makefile | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/test/Makefile b/test/Makefile
|
||||
index 700416e..51481c9 100644
|
||||
--- a/test/Makefile
|
||||
+++ b/test/Makefile
|
||||
@@ -5,7 +5,7 @@ CFLAGS ?= -Wall
|
||||
all: test
|
||||
|
||||
test: ../config.mk test.c
|
||||
- $(CC) $(CFLAGS) -o $@ test.c -lEGL -lGLESv2
|
||||
+ $(CC) $(CFLAGS) -I../include -L../../image/usr/lib -o $@ test.c -lEGL -lGLESv2 -lX11
|
||||
|
||||
clean:
|
||||
rm -f test
|
||||
--
|
||||
2.6.0.rc3
|
||||
|
@ -0,0 +1,136 @@
|
||||
From 15d91ef25234ff402f4288273989693f2d402d9d Mon Sep 17 00:00:00 2001
|
||||
From: Raoul Hecky <raoul.hecky@gmail.com>
|
||||
Date: Fri, 10 Jan 2014 14:44:53 +0100
|
||||
Subject: [PATCH] Add missing GLchar definition, some gl/gles apps needs that
|
||||
to compile correctly
|
||||
|
||||
Build pkg-config files for gles and egl and install them
|
||||
|
||||
Fix .pc creation
|
||||
|
||||
add correct driver version in .pc
|
||||
---
|
||||
.gitignore | 1 +
|
||||
Makefile | 1 +
|
||||
Makefile.pc | 21 +++++++++++++++++++++
|
||||
egl.pc.in | 11 +++++++++++
|
||||
gles_cm.pc.in | 11 +++++++++++
|
||||
glesv2.pc.in | 11 +++++++++++
|
||||
include/GLES/gl.h | 1 +
|
||||
include/GLES2/gl2.h | 1 +
|
||||
8 files changed, 58 insertions(+)
|
||||
create mode 100644 Makefile.pc
|
||||
create mode 100644 egl.pc.in
|
||||
create mode 100644 gles_cm.pc.in
|
||||
create mode 100644 glesv2.pc.in
|
||||
|
||||
diff --git a/.gitignore b/.gitignore
|
||||
index 6865abf..e8a3713 100644
|
||||
--- a/.gitignore
|
||||
+++ b/.gitignore
|
||||
@@ -1,2 +1,3 @@
|
||||
config.mk
|
||||
*~
|
||||
+*.pc
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 60d4a0f..94845ea 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -21,6 +21,7 @@ clean:
|
||||
install: config.mk
|
||||
$(MAKE) -C lib install
|
||||
$(MAKE) -C include install
|
||||
+ $(MAKE) -f Makefile.pc
|
||||
|
||||
test: config.mk
|
||||
$(MAKE) -C test test
|
||||
diff --git a/Makefile.pc b/Makefile.pc
|
||||
new file mode 100644
|
||||
index 0000000..01097fd
|
||||
--- /dev/null
|
||||
+++ b/Makefile.pc
|
||||
@@ -0,0 +1,21 @@
|
||||
+include Makefile.setup
|
||||
+include config.mk
|
||||
+
|
||||
+all:
|
||||
+ echo "prefix=$(prefix)" > egl.pc
|
||||
+ cat egl.pc.in >> egl.pc
|
||||
+ sed -i "s/MVERSION/$MALI_VERSION/g" egl.pc
|
||||
+ echo "prefix=$(prefix)" > gles_cm.pc
|
||||
+ cat gles_cm.pc.in >> gles_cm.pc
|
||||
+ sed -i "s/MVERSION/$MALI_VERSION/g" gles_cm.pc
|
||||
+ echo "prefix=$(prefix)" > glesv2.pc
|
||||
+ cat glesv2.pc.in >> glesv2.pc
|
||||
+ sed -i "s/MVERSION/$MALI_VERSION/g" glesv2.pc
|
||||
+
|
||||
+install: egl.pc gles_cm.pc glesv2.pc
|
||||
+ $(MKDIR) $(libdir)/pkgconfig
|
||||
+ $(INSTALL_DATA) $^ $(libdir)/pkgconfig
|
||||
+
|
||||
+clean:
|
||||
+ $(RM) egl.pc gles_cm.pc glesv2.pc
|
||||
+
|
||||
diff --git a/egl.pc.in b/egl.pc.in
|
||||
new file mode 100644
|
||||
index 0000000..0697183
|
||||
--- /dev/null
|
||||
+++ b/egl.pc.in
|
||||
@@ -0,0 +1,11 @@
|
||||
+exec_prefix=${prefix}
|
||||
+libdir=${prefix}/lib
|
||||
+includedir=${prefix}/include
|
||||
+
|
||||
+Name: egl
|
||||
+Description: Mali EGL library
|
||||
+Requires.private:
|
||||
+Version: MVERSION
|
||||
+Libs: -L${libdir} -lEGL
|
||||
+Libs.private: -lm -lpthread -ldl
|
||||
+Cflags: -I${includedir}
|
||||
diff --git a/gles_cm.pc.in b/gles_cm.pc.in
|
||||
new file mode 100644
|
||||
index 0000000..22bc348
|
||||
--- /dev/null
|
||||
+++ b/gles_cm.pc.in
|
||||
@@ -0,0 +1,11 @@
|
||||
+exec_prefix=${prefix}
|
||||
+libdir=${prefix}/lib
|
||||
+includedir=${prefix}/include
|
||||
+
|
||||
+Name: gles_cm
|
||||
+Description: Mali OpenGL ES 1.1 CM library
|
||||
+Requires.private:
|
||||
+Version: MVERSION
|
||||
+Libs: -L${libdir} -lGLES_CM
|
||||
+Libs.private: -lm -lpthread -ldl
|
||||
+Cflags: -I${includedir}
|
||||
diff --git a/glesv2.pc.in b/glesv2.pc.in
|
||||
new file mode 100644
|
||||
index 0000000..efef2ed
|
||||
--- /dev/null
|
||||
+++ b/glesv2.pc.in
|
||||
@@ -0,0 +1,11 @@
|
||||
+exec_prefix=${prefix}
|
||||
+libdir=${prefix}/lib
|
||||
+includedir=${prefix}/include
|
||||
+
|
||||
+Name: glesv2
|
||||
+Description: Mali OpenGL ES 2.0 library
|
||||
+Requires.private:
|
||||
+Version: MVERSION
|
||||
+Libs: -L${libdir} -lGLESv2
|
||||
+Libs.private: -lm -lpthread -ldl
|
||||
+Cflags: -I${includedir}
|
||||
diff --git a/include/GLES/gl.h b/include/GLES/gl.h
|
||||
index 858f394..a6bb591 100644
|
||||
--- a/include/GLES/gl.h
|
||||
+++ b/include/GLES/gl.h
|
||||
@@ -29,6 +29,7 @@ typedef float GLfloat;
|
||||
typedef float GLclampf;
|
||||
typedef signed int GLfixed;
|
||||
typedef signed int GLclampx;
|
||||
+typedef char GLchar;
|
||||
|
||||
typedef int * GLintptr;
|
||||
typedef int * GLsizeiptr;
|
@ -0,0 +1,30 @@
|
||||
From 95bbd40135f96b473d4c713317e485d0049580cd Mon Sep 17 00:00:00 2001
|
||||
From: Raoul Hecky <raoul.hecky@gmail.com>
|
||||
Date: Tue, 8 Apr 2014 08:10:12 +0200
|
||||
Subject: [PATCH] Fix sed to replace by the correct var
|
||||
|
||||
---
|
||||
Makefile.pc | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/Makefile.pc b/Makefile.pc
|
||||
index 01097fd..c51d18c 100644
|
||||
--- a/Makefile.pc
|
||||
+++ b/Makefile.pc
|
||||
@@ -4,13 +4,13 @@ include config.mk
|
||||
all:
|
||||
echo "prefix=$(prefix)" > egl.pc
|
||||
cat egl.pc.in >> egl.pc
|
||||
- sed -i "s/MVERSION/$MALI_VERSION/g" egl.pc
|
||||
+ sed -i "s/MVERSION/${MALI_VERSION}/g" egl.pc
|
||||
echo "prefix=$(prefix)" > gles_cm.pc
|
||||
cat gles_cm.pc.in >> gles_cm.pc
|
||||
- sed -i "s/MVERSION/$MALI_VERSION/g" gles_cm.pc
|
||||
+ sed -i "s/MVERSION/${MALI_VERSION}/g" gles_cm.pc
|
||||
echo "prefix=$(prefix)" > glesv2.pc
|
||||
cat glesv2.pc.in >> glesv2.pc
|
||||
- sed -i "s/MVERSION/$MALI_VERSION/g" glesv2.pc
|
||||
+ sed -i "s/MVERSION/${MALI_VERSION}/g" glesv2.pc
|
||||
|
||||
install: egl.pc gles_cm.pc glesv2.pc
|
||||
$(MKDIR) $(libdir)/pkgconfig
|
@ -1,33 +1,63 @@
|
||||
DESCRIPTION = "libGLES for the A10/A13 Allwinner processor with Mali 400 (X11)"
|
||||
|
||||
LICENSE = "proprietary-binary"
|
||||
LIC_FILES_CHKSUM = "file://README;md5=a103ac69c166fcd98a67a9917dd7affd"
|
||||
LICENSE = "Proprietary"
|
||||
LIC_FILES_CHKSUM = "file://README;md5=1b81a178e80ee888ee4571772699ab2c"
|
||||
|
||||
COMPATIBLE_MACHINE = "(mele|meleg|cubieboard|cubieboard2|cubietruck|olinuxino-a10|olinuxino-a13|olinuxino-a20)"
|
||||
|
||||
DEPENDS = "virtual/libx11 libxau libxdmcp libdrm dri2proto libdri2"
|
||||
COMPATIBLE_MACHINE = "(sun4i|sun5i|sun7i)"
|
||||
|
||||
# These libraries shouldn't get installed in world builds unless something
|
||||
# explicitly depends upon them.
|
||||
EXCLUDE_FROM_WORLD = "1"
|
||||
PROVIDES = "virtual/libgles1 virtual/libgles2 virtual/egl"
|
||||
RPROVIDES_${PN} += "libGLESv2.so libEGL.so libGLESv2.so libGLESv1_CM.so libMali.so"
|
||||
|
||||
inherit distro_features_check
|
||||
REQUIRED_DISTRO_FEATURES = "opengl"
|
||||
|
||||
SRCREV_pn-${PN} = "997139453d869b4dc2e7507b6a78f27d7f191e28"
|
||||
SRC_URI = "gitsm://github.com/linux-sunxi/sunxi-mali.git"
|
||||
SRCREV_pn-${PN} = "d343311efc8db166d8371b28494f0f27b6a58724"
|
||||
SRC_URI = "gitsm://github.com/linux-sunxi/sunxi-mali.git \
|
||||
file://0001-Add-EGLSyncKHR-EGLTimeKHR-and-GLChar-definition.patch \
|
||||
file://0002-Add-missing-GLchar-definition.patch \
|
||||
file://0003-Fix-sed-to-replace-by-the-correct-var.patch \
|
||||
file://0001-fix-test-build.patch \
|
||||
"
|
||||
|
||||
S = "${WORKDIR}/git"
|
||||
|
||||
DEPENDS = "libdrm dri2proto libump"
|
||||
|
||||
PACKAGECONFIG ??= "${@base_contains('DISTRO_FEATURES', 'x11', 'x11', '', d)} ${@base_contains('DISTRO_FEATURES', 'wayland', 'wayland', '', d)}"
|
||||
PACKAGECONFIG[wayland] = "EGL_TYPE=framebuffer,,,"
|
||||
PACKAGECONFIG[x11] = "EGL_TYPE=x11,,virtual/libx11 libxau libxdmcp libdri2,"
|
||||
|
||||
# Inhibit warnings about files being stripped, we can't do anything about it.
|
||||
INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
|
||||
INHIBIT_PACKAGE_STRIP = "1"
|
||||
INHIBIT_SYSROOT_STRIP = "1"
|
||||
|
||||
do_configure() {
|
||||
DESTDIR=${D}/ VERSION=r3p0 ABI=armhf EGL_TYPE=x11 make config
|
||||
DESTDIR=${D}/ VERSION=r3p0 ABI=armhf ${EXTRA_OECONF} make config
|
||||
}
|
||||
|
||||
do_install() {
|
||||
make -f Makefile.pc
|
||||
|
||||
# install headers
|
||||
install -d -m 0755 ${D}${includedir}/EGL
|
||||
install -m 0755 ${S}/include/EGL/*.h ${D}${includedir}/EGL/
|
||||
install -d -m 0755 ${D}${includedir}/GLES
|
||||
install -m 0755 ${S}/include/GLES/*.h ${D}${includedir}/GLES/
|
||||
install -d -m 0755 ${D}${includedir}/GLES2
|
||||
install -m 0755 ${S}/include/GLES2/*.h ${D}${includedir}/GLES2/
|
||||
install -d -m 0755 ${D}${includedir}/KHR
|
||||
install -m 0755 ${S}/include/KHR/*.h ${D}${includedir}/KHR/
|
||||
|
||||
# Copy the .pc files
|
||||
install -d -m 0755 ${D}${libdir}/pkgconfig
|
||||
install -m 0644 ${S}/egl.pc ${D}${libdir}/pkgconfig/
|
||||
install -m 0644 ${S}/gles_cm.pc ${D}${libdir}/pkgconfig/
|
||||
install -m 0644 ${S}/glesv2.pc ${D}${libdir}/pkgconfig/
|
||||
|
||||
install -d ${D}${libdir}
|
||||
install -d ${D}${includedir}
|
||||
|
||||
|
||||
make libdir=${D}${libdir}/ includedir=${D}${includedir}/ install
|
||||
make libdir=${D}${libdir}/ includedir=${D}${includedir}/ install -C include
|
||||
|
||||
@ -36,16 +66,21 @@ do_install() {
|
||||
|
||||
mv ${D}${libdir}/libMali.so ${D}${libdir}/libMali.so.3
|
||||
ln -sf libMali.so.3 ${D}${libdir}/libMali.so
|
||||
ln -sf libUMP.so.3 ${D}${libdir}/libUMP.so
|
||||
|
||||
for flib in libEGL.so.1.4 libGLESv1_CM.so.1.1 libGLESv2.so.2.0 ; do
|
||||
rm ${D}${libdir}/$flib
|
||||
ln -sf libMali.so.3 ${D}${libdir}/$flib
|
||||
done
|
||||
|
||||
DESTDIR=${D}/ VERSION=r3p0 ABI=armhf ${EXTRA_OECONF} make test
|
||||
install -d ${D}${bindir}
|
||||
install -m 0755 ${S}/test/test ${D}${bindir}/sunximali-test
|
||||
}
|
||||
|
||||
# Packages like xf86-video-fbturbo dlopen() libUMP.so, so we do need to ship the .so files in ${PN}
|
||||
PACKAGES =+ "${PN}-test"
|
||||
FILES_${PN} += "${libdir}/lib*.so"
|
||||
FILES_${PN}-dev = "${includedir}"
|
||||
FILES_${PN}-dev = "${includedir} ${libdir}/pkgconfig/*"
|
||||
FILES_${PN}-test = "${bindir}/sunximali-test"
|
||||
# These are closed binaries generated elsewhere so don't check ldflags & text relocations
|
||||
INSANE_SKIP_${PN} = "dev-so ldflags textrel"
|
||||
|
15
recipes-graphics/libump/libump_git.bb
Normal file
15
recipes-graphics/libump/libump_git.bb
Normal file
@ -0,0 +1,15 @@
|
||||
DESCRIPTION = "Unified Memory Provider userspace API source code needed for xf86-video-mali compilation"
|
||||
|
||||
LICENSE = "Apache-2"
|
||||
LIC_FILES_CHKSUM = "file://debian/copyright;md5=edf7fb6071cae7ec80d537a05ee17198"
|
||||
|
||||
inherit autotools
|
||||
|
||||
PV = "r4p0-00rel0+git${SRCPV}"
|
||||
SRCREV_pn-${PN} = "ec0680628744f30b8fac35e41a7bd8e23e59c39f"
|
||||
|
||||
SRC_URI = "git://github.com/linux-sunxi/libump.git"
|
||||
|
||||
S = "${WORKDIR}/git"
|
||||
|
||||
|
@ -1,6 +1,4 @@
|
||||
FILESEXTRAPATHS := "${THISDIR}/${PN}"
|
||||
|
||||
PRINC := "${@int(PRINC) + 1}"
|
||||
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
|
||||
|
||||
SRC_URI += "file://tslib.patch"
|
||||
|
||||
|
@ -13,5 +13,5 @@ SRCREV_pn-${PN} = "4f1eef3183df2b270c3d5cbef07343ee5127a6a4"
|
||||
|
||||
S = "${WORKDIR}/git"
|
||||
|
||||
inherit autotools
|
||||
inherit autotools pkgconfig
|
||||
|
||||
|
@ -5,11 +5,11 @@ DESCRIPTION = "X.Org X server -- A10/A13 display driver"
|
||||
LICENSE = "MIT-X"
|
||||
LIC_FILES_CHKSUM = "file://COPYING;md5=f91dc3ee5ce59eb4b528e67e98a31266"
|
||||
|
||||
DEPENDS += "sunxi-mali"
|
||||
DEPENDS += "sunxi-mali libump xf86driproto"
|
||||
|
||||
PE = "3"
|
||||
PV = "0.3.1+git${SRCPV}"
|
||||
SRCREV_pn-${PN} = "eed17d5586c3b4dfcf0b5976e8b947b171d4897c"
|
||||
PV = "0.5.1+git${SRCPV}"
|
||||
SRCREV_pn-${PN} = "e094e3c8f9004ca3347694bd05b99d136e8621b9"
|
||||
|
||||
SRC_URI = "git://github.com/ssvb/xf86-video-fbturbo.git;protocol=http;branch=master \
|
||||
file://20-fbturbo.conf"
|
||||
|
@ -1,4 +1 @@
|
||||
FILESEXTRAPATHS := "${THISDIR}/${PN}"
|
||||
|
||||
PRINC := "${@int(PRINC) + 1}"
|
||||
|
||||
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
|
||||
|
71
recipes-kernel/linux/linux-sunxi/0001-compiler-gcc5.patch
Normal file
71
recipes-kernel/linux/linux-sunxi/0001-compiler-gcc5.patch
Normal file
@ -0,0 +1,71 @@
|
||||
Index: git/include/linux/compiler-gcc5.h
|
||||
===================================================================
|
||||
--- git/include/linux/compiler-gcc5.h 2015-09-19 20:11:27.999423338 +0200
|
||||
+++ git/include/linux/compiler-gcc5.h 2015-09-23 10:26:05.000000000 +0200
|
||||
@@ -0,0 +1,66 @@
|
||||
+#ifndef __LINUX_COMPILER_H
|
||||
+#error "Please don't include <linux/compiler-gcc5.h> directly, include <linux/compiler.h> instead."
|
||||
+#endif
|
||||
+
|
||||
+#define __used __attribute__((__used__))
|
||||
+#define __must_check __attribute__((warn_unused_result))
|
||||
+#define __compiler_offsetof(a, b) __builtin_offsetof(a, b)
|
||||
+
|
||||
+/* Mark functions as cold. gcc will assume any path leading to a call
|
||||
+ to them will be unlikely. This means a lot of manual unlikely()s
|
||||
+ are unnecessary now for any paths leading to the usual suspects
|
||||
+ like BUG(), printk(), panic() etc. [but let's keep them for now for
|
||||
+ older compilers]
|
||||
+
|
||||
+ Early snapshots of gcc 4.3 don't support this and we can't detect this
|
||||
+ in the preprocessor, but we can live with this because they're unreleased.
|
||||
+ Maketime probing would be overkill here.
|
||||
+
|
||||
+ gcc also has a __attribute__((__hot__)) to move hot functions into
|
||||
+ a special section, but I don't see any sense in this right now in
|
||||
+ the kernel context */
|
||||
+#define __cold __attribute__((__cold__))
|
||||
+
|
||||
+#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
|
||||
+
|
||||
+#ifndef __CHECKER__
|
||||
+# define __compiletime_warning(message) __attribute__((warning(message)))
|
||||
+# define __compiletime_error(message) __attribute__((error(message)))
|
||||
+#endif /* __CHECKER__ */
|
||||
+
|
||||
+/*
|
||||
+ * Mark a position in code as unreachable. This can be used to
|
||||
+ * suppress control flow warnings after asm blocks that transfer
|
||||
+ * control elsewhere.
|
||||
+ *
|
||||
+ * Early snapshots of gcc 4.5 don't support this and we can't detect
|
||||
+ * this in the preprocessor, but we can live with this because they're
|
||||
+ * unreleased. Really, we need to have autoconf for the kernel.
|
||||
+ */
|
||||
+#define unreachable() __builtin_unreachable()
|
||||
+
|
||||
+/* Mark a function definition as prohibited from being cloned. */
|
||||
+#define __noclone __attribute__((__noclone__))
|
||||
+
|
||||
+/*
|
||||
+ * Tell the optimizer that something else uses this function or variable.
|
||||
+ */
|
||||
+#define __visible __attribute__((externally_visible))
|
||||
+
|
||||
+/*
|
||||
+ * GCC 'asm goto' miscompiles certain code sequences:
|
||||
+ *
|
||||
+ * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
|
||||
+ *
|
||||
+ * Work it around via a compiler barrier quirk suggested by Jakub Jelinek.
|
||||
+ * Fixed in GCC 4.8.2 and later versions.
|
||||
+ *
|
||||
+ * (asm goto is automatically volatile - the naming reflects this.)
|
||||
+ */
|
||||
+#define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0)
|
||||
+
|
||||
+#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP
|
||||
+#define __HAVE_BUILTIN_BSWAP32__
|
||||
+#define __HAVE_BUILTIN_BSWAP64__
|
||||
+#define __HAVE_BUILTIN_BSWAP16__
|
||||
+#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */
|
135
recipes-kernel/linux/linux-sunxi/0001-gcc5-fixes.patch
Normal file
135
recipes-kernel/linux/linux-sunxi/0001-gcc5-fixes.patch
Normal file
@ -0,0 +1,135 @@
|
||||
From 83b0b8a7b9cb658d3cc980b4fbcbb2cc8b257ccf Mon Sep 17 00:00:00 2001
|
||||
From: Trevor Woerner <twoerner@gmail.com>
|
||||
Date: Thu, 24 Sep 2015 17:07:26 -0400
|
||||
Subject: [PATCH] gcc5 fixes
|
||||
|
||||
gcc5 is pickier about inline functions defined in headers.
|
||||
|
||||
Signed-off-by: Trevor Woerner <twoerner@gmail.com>
|
||||
---
|
||||
drivers/net/wireless/rtl8188eu/include/ieee80211.h | 4 ++--
|
||||
drivers/net/wireless/rtl8189es/include/ieee80211.h | 4 ++--
|
||||
drivers/net/wireless/rtl8192cu/include/ieee80211.h | 8 ++++----
|
||||
drivers/net/wireless/rtl8723as/include/ieee80211.h | 4 ++--
|
||||
drivers/staging/rtl8712/ieee80211.h | 4 ++--
|
||||
5 files changed, 12 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/wireless/rtl8188eu/include/ieee80211.h b/drivers/net/wireless/rtl8188eu/include/ieee80211.h
|
||||
index 1ae96a5..7a301c5 100644
|
||||
--- a/drivers/net/wireless/rtl8188eu/include/ieee80211.h
|
||||
+++ b/drivers/net/wireless/rtl8188eu/include/ieee80211.h
|
||||
@@ -1188,12 +1188,12 @@ enum ieee80211_state {
|
||||
(((Addr[2]) & 0xff) == 0xff) && (((Addr[3]) & 0xff) == 0xff) && (((Addr[4]) & 0xff) == 0xff) && \
|
||||
(((Addr[5]) & 0xff) == 0xff))
|
||||
#else
|
||||
-extern __inline int is_multicast_mac_addr(const u8 *addr)
|
||||
+static __inline int is_multicast_mac_addr(const u8 *addr)
|
||||
{
|
||||
return ((addr[0] != 0xff) && (0x01 & addr[0]));
|
||||
}
|
||||
|
||||
-extern __inline int is_broadcast_mac_addr(const u8 *addr)
|
||||
+static __inline int is_broadcast_mac_addr(const u8 *addr)
|
||||
{
|
||||
return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \
|
||||
(addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
|
||||
diff --git a/drivers/net/wireless/rtl8189es/include/ieee80211.h b/drivers/net/wireless/rtl8189es/include/ieee80211.h
|
||||
index 1ae96a5..7a301c5 100644
|
||||
--- a/drivers/net/wireless/rtl8189es/include/ieee80211.h
|
||||
+++ b/drivers/net/wireless/rtl8189es/include/ieee80211.h
|
||||
@@ -1188,12 +1188,12 @@ enum ieee80211_state {
|
||||
(((Addr[2]) & 0xff) == 0xff) && (((Addr[3]) & 0xff) == 0xff) && (((Addr[4]) & 0xff) == 0xff) && \
|
||||
(((Addr[5]) & 0xff) == 0xff))
|
||||
#else
|
||||
-extern __inline int is_multicast_mac_addr(const u8 *addr)
|
||||
+static __inline int is_multicast_mac_addr(const u8 *addr)
|
||||
{
|
||||
return ((addr[0] != 0xff) && (0x01 & addr[0]));
|
||||
}
|
||||
|
||||
-extern __inline int is_broadcast_mac_addr(const u8 *addr)
|
||||
+static __inline int is_broadcast_mac_addr(const u8 *addr)
|
||||
{
|
||||
return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \
|
||||
(addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
|
||||
diff --git a/drivers/net/wireless/rtl8192cu/include/ieee80211.h b/drivers/net/wireless/rtl8192cu/include/ieee80211.h
|
||||
index 86e9726..950691d 100644
|
||||
--- a/drivers/net/wireless/rtl8192cu/include/ieee80211.h
|
||||
+++ b/drivers/net/wireless/rtl8192cu/include/ieee80211.h
|
||||
@@ -1149,12 +1149,12 @@ enum ieee80211_state {
|
||||
#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
|
||||
#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
|
||||
|
||||
-extern __inline int is_multicast_mac_addr(const u8 *addr)
|
||||
+static __inline int is_multicast_mac_addr(const u8 *addr)
|
||||
{
|
||||
return ((addr[0] != 0xff) && (0x01 & addr[0]));
|
||||
}
|
||||
|
||||
-extern __inline int is_broadcast_mac_addr(const u8 *addr)
|
||||
+static __inline int is_broadcast_mac_addr(const u8 *addr)
|
||||
{
|
||||
return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \
|
||||
(addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
|
||||
@@ -1177,7 +1177,7 @@ typedef struct tx_pending_t{
|
||||
#define IEEE_G (1<<2)
|
||||
#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G)
|
||||
|
||||
-extern __inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
|
||||
+static __inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
|
||||
{
|
||||
/* Single white space is for Linksys APs */
|
||||
if (essid_len == 1 && essid[0] == ' ')
|
||||
@@ -1193,7 +1193,7 @@ extern __inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
|
||||
return 1;
|
||||
}
|
||||
|
||||
-extern __inline int ieee80211_get_hdrlen(u16 fc)
|
||||
+static __inline int ieee80211_get_hdrlen(u16 fc)
|
||||
{
|
||||
int hdrlen = 24;
|
||||
|
||||
diff --git a/drivers/net/wireless/rtl8723as/include/ieee80211.h b/drivers/net/wireless/rtl8723as/include/ieee80211.h
|
||||
index bf24c3b..f8046ee 100644
|
||||
--- a/drivers/net/wireless/rtl8723as/include/ieee80211.h
|
||||
+++ b/drivers/net/wireless/rtl8723as/include/ieee80211.h
|
||||
@@ -1176,12 +1176,12 @@ enum ieee80211_state {
|
||||
(((Addr[2]) & 0xff) == 0xff) && (((Addr[3]) & 0xff) == 0xff) && (((Addr[4]) & 0xff) == 0xff) && \
|
||||
(((Addr[5]) & 0xff) == 0xff))
|
||||
#else
|
||||
-extern __inline int is_multicast_mac_addr(const u8 *addr)
|
||||
+static __inline int is_multicast_mac_addr(const u8 *addr)
|
||||
{
|
||||
return ((addr[0] != 0xff) && (0x01 & addr[0]));
|
||||
}
|
||||
|
||||
-extern __inline int is_broadcast_mac_addr(const u8 *addr)
|
||||
+static __inline int is_broadcast_mac_addr(const u8 *addr)
|
||||
{
|
||||
return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \
|
||||
(addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
|
||||
diff --git a/drivers/staging/rtl8712/ieee80211.h b/drivers/staging/rtl8712/ieee80211.h
|
||||
index 3c0092b..1e7b55b 100644
|
||||
--- a/drivers/staging/rtl8712/ieee80211.h
|
||||
+++ b/drivers/staging/rtl8712/ieee80211.h
|
||||
@@ -734,7 +734,7 @@ enum ieee80211_state {
|
||||
#define IEEE_G (1<<2)
|
||||
#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G)
|
||||
|
||||
-extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
|
||||
+static inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
|
||||
{
|
||||
/* Single white space is for Linksys APs */
|
||||
if (essid_len == 1 && essid[0] == ' ')
|
||||
@@ -748,7 +748,7 @@ extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
|
||||
return 1;
|
||||
}
|
||||
|
||||
-extern inline int ieee80211_get_hdrlen(u16 fc)
|
||||
+static inline int ieee80211_get_hdrlen(u16 fc)
|
||||
{
|
||||
int hdrlen = 24;
|
||||
|
||||
--
|
||||
2.6.0.rc3
|
||||
|
@ -0,0 +1,50 @@
|
||||
From ef4fea130eeb70eff4f3a549fd3f6e9b11437550 Mon Sep 17 00:00:00 2001
|
||||
From: ZaneZam <cyxman@yahoo.com>
|
||||
Date: Thu, 26 Mar 2015 14:50:10 +0100
|
||||
Subject: [PATCH] arm: LLVMLinux: use static inline in ARM ftrace.h
|
||||
|
||||
With compilers which follow the C99 standard (like modern versions of gcc and
|
||||
clang), "extern inline" does the wrong thing (emits code for an externally
|
||||
linkable version of the inline function). In this case using static inline
|
||||
and removing the NULL version of return_address in return_address.c does
|
||||
the right thing.
|
||||
|
||||
Signed-off-by: Behan Webster <behanw@converseincode.com>
|
||||
Reviewed-by: Mark Charlebois <charlebm@gmail.com>
|
||||
|
||||
source: http://www.serverphorums.com/read.php?12,880351,880351#msg-880351
|
||||
---
|
||||
arch/arm/include/asm/ftrace.h | 2 +-
|
||||
arch/arm/kernel/return_address.c | 2 ++
|
||||
2 files changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/arm/include/asm/ftrace.h b/arch/arm/include/asm/ftrace.h
|
||||
index f89515a..2bb8cac 100644
|
||||
--- a/arch/arm/include/asm/ftrace.h
|
||||
+++ b/arch/arm/include/asm/ftrace.h
|
||||
@@ -45,7 +45,7 @@ void *return_address(unsigned int);
|
||||
|
||||
#else
|
||||
|
||||
-extern inline void *return_address(unsigned int level)
|
||||
+static inline void *return_address(unsigned int level)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c
|
||||
index f1aef84..49477f0 100644
|
||||
--- a/arch/arm/kernel/return_address.c
|
||||
+++ b/arch/arm/kernel/return_address.c
|
||||
@@ -62,10 +62,12 @@ void *return_address(unsigned int level)
|
||||
/* #warning "TODO: return_address should use unwind tables" */
|
||||
#endif
|
||||
|
||||
+/*
|
||||
void *return_address(unsigned int level)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
+*/
|
||||
|
||||
#endif /* if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) / else */
|
||||
|
1218
recipes-kernel/linux/linux-sunxi/cubieboard2/defconfig
Normal file
1218
recipes-kernel/linux/linux-sunxi/cubieboard2/defconfig
Normal file
File diff suppressed because it is too large
Load Diff
327
recipes-kernel/linux/linux-sunxi/olinuxino-a10lime/defconfig
Normal file
327
recipes-kernel/linux/linux-sunxi/olinuxino-a10lime/defconfig
Normal file
@ -0,0 +1,327 @@
|
||||
CONFIG_EXPERIMENTAL=y
|
||||
# CONFIG_LOCALVERSION_AUTO is not set
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_BSD_PROCESS_ACCT=y
|
||||
CONFIG_BSD_PROCESS_ACCT_V3=y
|
||||
CONFIG_FHANDLE=y
|
||||
CONFIG_TASKSTATS=y
|
||||
CONFIG_TASK_DELAY_ACCT=y
|
||||
CONFIG_TASK_XACCT=y
|
||||
CONFIG_TASK_IO_ACCOUNTING=y
|
||||
CONFIG_AUDIT=y
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_LOG_BUF_SHIFT=19
|
||||
CONFIG_CGROUPS=y
|
||||
CONFIG_CGROUP_FREEZER=y
|
||||
CONFIG_CGROUP_DEVICE=y
|
||||
CONFIG_CPUSETS=y
|
||||
CONFIG_CGROUP_CPUACCT=y
|
||||
CONFIG_RESOURCE_COUNTERS=y
|
||||
CONFIG_BLK_CGROUP=y
|
||||
CONFIG_RELAY=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
CONFIG_KALLSYMS_ALL=y
|
||||
CONFIG_PERF_COUNTERS=y
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_FORCE_LOAD=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_MODVERSIONS=y
|
||||
CONFIG_MODULE_SRCVERSION_ALL=y
|
||||
CONFIG_BLK_DEV_INTEGRITY=y
|
||||
CONFIG_PARTITION_ADVANCED=y
|
||||
CONFIG_OSF_PARTITION=y
|
||||
CONFIG_AMIGA_PARTITION=y
|
||||
CONFIG_MAC_PARTITION=y
|
||||
CONFIG_BSD_DISKLABEL=y
|
||||
CONFIG_MINIX_SUBPARTITION=y
|
||||
CONFIG_SOLARIS_X86_PARTITION=y
|
||||
CONFIG_UNIXWARE_DISKLABEL=y
|
||||
CONFIG_SGI_PARTITION=y
|
||||
CONFIG_SUN_PARTITION=y
|
||||
CONFIG_KARMA_PARTITION=y
|
||||
CONFIG_EFI_PARTITION=y
|
||||
CONFIG_CFQ_GROUP_IOSCHED=y
|
||||
CONFIG_ARCH_SUN4I=y
|
||||
CONFIG_SWP_EMULATE=y
|
||||
CONFIG_NO_HZ=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_PREEMPT=y
|
||||
CONFIG_AEABI=y
|
||||
# CONFIG_OABI_COMPAT is not set
|
||||
CONFIG_HIGHMEM=y
|
||||
CONFIG_COMPACTION=y
|
||||
CONFIG_KSM=y
|
||||
CONFIG_ZBOOT_ROM_TEXT=0x0
|
||||
CONFIG_ZBOOT_ROM_BSS=0x0
|
||||
CONFIG_CMDLINE=" debug"
|
||||
CONFIG_CPU_FREQ=y
|
||||
CONFIG_CPU_FREQ_STAT=m
|
||||
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
|
||||
CONFIG_CPU_FREQ_GOV_FANTASY=y
|
||||
CONFIG_CPU_FREQ_DVFS=y
|
||||
CONFIG_CPU_IDLE=y
|
||||
CONFIG_VFP=y
|
||||
CONFIG_NEON=y
|
||||
CONFIG_BINFMT_MISC=y
|
||||
CONFIG_PM_RUNTIME=y
|
||||
CONFIG_PM_DEBUG=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_XFRM_USER=y
|
||||
CONFIG_NET_KEY=y
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
CONFIG_NET_IPIP=y
|
||||
CONFIG_IP_MROUTE=y
|
||||
CONFIG_IP_PIMSM_V1=y
|
||||
CONFIG_IP_PIMSM_V2=y
|
||||
CONFIG_SYN_COOKIES=y
|
||||
CONFIG_INET_AH=y
|
||||
CONFIG_INET_ESP=y
|
||||
CONFIG_INET_IPCOMP=y
|
||||
# CONFIG_INET_DIAG is not set
|
||||
CONFIG_IPV6=y
|
||||
CONFIG_INET6_XFRM_MODE_TRANSPORT=m
|
||||
CONFIG_INET6_XFRM_MODE_TUNNEL=m
|
||||
CONFIG_INET6_XFRM_MODE_BEET=m
|
||||
CONFIG_IPV6_SIT=m
|
||||
# CONFIG_ANDROID_PARANOID_NETWORK is not set
|
||||
CONFIG_NETWORK_SECMARK=y
|
||||
CONFIG_BRIDGE=m
|
||||
CONFIG_VLAN_8021Q=y
|
||||
CONFIG_VLAN_8021Q_GVRP=y
|
||||
CONFIG_NET_PKTGEN=m
|
||||
CONFIG_BT=y
|
||||
CONFIG_BT_RFCOMM=y
|
||||
CONFIG_BT_RFCOMM_TTY=y
|
||||
CONFIG_BT_BNEP=y
|
||||
CONFIG_BT_BNEP_MC_FILTER=y
|
||||
CONFIG_BT_BNEP_PROTO_FILTER=y
|
||||
CONFIG_BT_HCIUART=y
|
||||
CONFIG_BT_HCIUART_H4=y
|
||||
CONFIG_BT_HCIUART_BCSP=y
|
||||
CONFIG_BT_HCIUART_LL=y
|
||||
CONFIG_CFG80211=y
|
||||
CONFIG_RFKILL=y
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_DEVTMPFS_MOUNT=y
|
||||
# CONFIG_FIRMWARE_IN_KERNEL is not set
|
||||
CONFIG_CMA=y
|
||||
CONFIG_CMA_SIZE_MBYTES=192
|
||||
CONFIG_CONNECTOR=y
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
CONFIG_BLK_DEV_CRYPTOLOOP=y
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_COUNT=2
|
||||
CONFIG_SUNXI_DBGREG=m
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_BLK_DEV_SR=y
|
||||
CONFIG_BLK_DEV_SR_VENDOR=y
|
||||
CONFIG_SCSI_MULTI_LUN=y
|
||||
CONFIG_ATA=y
|
||||
CONFIG_SATA_AHCI_PLATFORM=y
|
||||
CONFIG_SW_SATA_AHCI_PLATFORM=m
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_TUN=m
|
||||
CONFIG_SUNXI_EMAC=y
|
||||
CONFIG_PHYLIB=y
|
||||
CONFIG_USB_KAWETH=m
|
||||
CONFIG_USB_PEGASUS=m
|
||||
CONFIG_USB_USBNET=m
|
||||
CONFIG_USB_HSO=m
|
||||
CONFIG_USB_IPHETH=m
|
||||
CONFIG_RTL8192CU_SW=m
|
||||
CONFIG_INPUT_FF_MEMLESS=y
|
||||
CONFIG_INPUT_POLLDEV=y
|
||||
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
|
||||
CONFIG_INPUT_JOYDEV=y
|
||||
CONFIG_INPUT_EVDEV=y
|
||||
CONFIG_INPUT_KEYRESET=y
|
||||
CONFIG_KEYBOARD_SUN4IKEYPAD=m
|
||||
CONFIG_KEYBOARD_SUN4I_KEYBOARD=m
|
||||
CONFIG_KEYBOARD_HV2605_KEYBOARD=m
|
||||
CONFIG_INPUT_JOYSTICK=y
|
||||
CONFIG_INPUT_TOUCHSCREEN=y
|
||||
CONFIG_TOUCHSCREEN_GT801=m
|
||||
CONFIG_TOUCHSCREEN_GT811=m
|
||||
CONFIG_TOUCHSCREEN_GT818=m
|
||||
CONFIG_TOUCHSCREEN_SUN4I_TS=m
|
||||
CONFIG_TOUCHSCREEN_FT5X_TS=m
|
||||
CONFIG_TOUCHSCREEN_ZT8031=m
|
||||
CONFIG_VT_HW_CONSOLE_BINDING=y
|
||||
CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
|
||||
CONFIG_SERIAL_NONSTANDARD=y
|
||||
# CONFIG_DEVKMEM is not set
|
||||
CONFIG_SERIAL_8250=y
|
||||
CONFIG_SERIAL_8250_CONSOLE=y
|
||||
CONFIG_SERIAL_8250_NR_UARTS=8
|
||||
CONFIG_SERIAL_8250_RUNTIME_UARTS=8
|
||||
# CONFIG_HW_RANDOM is not set
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2C_CHARDEV=y
|
||||
CONFIG_GPIOLIB=y
|
||||
CONFIG_GPIO_SYSFS=y
|
||||
CONFIG_GPIO_SUNXI=m
|
||||
CONFIG_W1=m
|
||||
CONFIG_W1_SUNXI=m
|
||||
CONFIG_W1_MASTER_GPIO=m
|
||||
CONFIG_POWER_SUPPLY=y
|
||||
CONFIG_AW_AXP=y
|
||||
CONFIG_REGULATOR=y
|
||||
CONFIG_MEDIA_SUPPORT=y
|
||||
CONFIG_VIDEO_DEV=y
|
||||
CONFIG_MEDIA_TUNER_CUSTOMISE=y
|
||||
# CONFIG_MEDIA_TUNER_SIMPLE is not set
|
||||
# CONFIG_MEDIA_TUNER_TDA8290 is not set
|
||||
# CONFIG_MEDIA_TUNER_TDA827X is not set
|
||||
# CONFIG_MEDIA_TUNER_TDA18271 is not set
|
||||
# CONFIG_MEDIA_TUNER_TDA9887 is not set
|
||||
# CONFIG_MEDIA_TUNER_TEA5767 is not set
|
||||
# CONFIG_MEDIA_TUNER_MT20XX is not set
|
||||
# CONFIG_MEDIA_TUNER_MT2060 is not set
|
||||
# CONFIG_MEDIA_TUNER_MT2266 is not set
|
||||
# CONFIG_MEDIA_TUNER_MT2131 is not set
|
||||
# CONFIG_MEDIA_TUNER_QT1010 is not set
|
||||
# CONFIG_MEDIA_TUNER_XC2028 is not set
|
||||
# CONFIG_MEDIA_TUNER_XC5000 is not set
|
||||
# CONFIG_MEDIA_TUNER_MXL5005S is not set
|
||||
# CONFIG_MEDIA_TUNER_MXL5007T is not set
|
||||
# CONFIG_MEDIA_TUNER_MC44S803 is not set
|
||||
# CONFIG_MEDIA_TUNER_MAX2165 is not set
|
||||
# CONFIG_MEDIA_TUNER_TDA18218 is not set
|
||||
# CONFIG_MEDIA_TUNER_TDA18212 is not set
|
||||
# CONFIG_VIDEO_CAPTURE_DRIVERS is not set
|
||||
CONFIG_CSI_OV7670=m
|
||||
CONFIG_CSI_GT2005=m
|
||||
CONFIG_CSI_GC0308=m
|
||||
CONFIG_CSI_HI704=m
|
||||
CONFIG_CSI_SP0838=m
|
||||
CONFIG_CSI_MT9M112=m
|
||||
CONFIG_CSI_MT9M113=m
|
||||
CONFIG_CSI_OV2655=m
|
||||
CONFIG_CSI_HI253=m
|
||||
CONFIG_CSI_MT9D112=m
|
||||
CONFIG_CSI_GC0307=m
|
||||
CONFIG_CSI_OV5640=m
|
||||
# CONFIG_RADIO_ADAPTERS is not set
|
||||
CONFIG_AUDIO_ENGINE=y
|
||||
CONFIG_PA_CONTROL=y
|
||||
CONFIG_DRM=m
|
||||
CONFIG_DRM_MALI=m
|
||||
CONFIG_MALI=m
|
||||
CONFIG_FB=y
|
||||
CONFIG_FB_SUNXI=y
|
||||
CONFIG_FB_SUNXI_LCD=y
|
||||
CONFIG_FB_SUNXI_HDMI=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
CONFIG_SOUND=y
|
||||
CONFIG_SND=y
|
||||
CONFIG_SND_SOC=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_EHCI_ROOT_HUB_TT=y
|
||||
CONFIG_USB_OHCI_HCD=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_USB_STORAGE_REALTEK=y
|
||||
CONFIG_USB_STORAGE_DATAFAB=y
|
||||
CONFIG_USB_STORAGE_FREECOM=y
|
||||
CONFIG_USB_STORAGE_ISD200=y
|
||||
CONFIG_USB_STORAGE_USBAT=y
|
||||
CONFIG_USB_STORAGE_SDDR09=y
|
||||
CONFIG_USB_STORAGE_SDDR55=y
|
||||
CONFIG_USB_STORAGE_JUMPSHOT=y
|
||||
CONFIG_USB_STORAGE_ALAUDA=y
|
||||
CONFIG_USB_STORAGE_ONETOUCH=y
|
||||
CONFIG_USB_STORAGE_KARMA=y
|
||||
CONFIG_USB_STORAGE_CYPRESS_ATACB=y
|
||||
CONFIG_USB_STORAGE_ENE_UB6250=y
|
||||
CONFIG_USB_GADGET=y
|
||||
CONFIG_USB_FILE_STORAGE=m
|
||||
CONFIG_USB_FILE_STORAGE_TEST=y
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MMC_UNSAFE_RESUME=y
|
||||
# CONFIG_MMC_BLOCK_BOUNCE is not set
|
||||
CONFIG_MMC_SUNXI_POWER_CONTROL=y
|
||||
CONFIG_MMC_SUNXI=y
|
||||
CONFIG_NEW_LEDS=y
|
||||
CONFIG_LEDS_CLASS=y
|
||||
CONFIG_LEDS_SUNXI=y
|
||||
CONFIG_LEDS_TRIGGERS=y
|
||||
CONFIG_LEDS_TRIGGER_TIMER=y
|
||||
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_SUN4I=y
|
||||
CONFIG_STAGING=y
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
CONFIG_QUOTA=y
|
||||
CONFIG_QUOTA_NETLINK_INTERFACE=y
|
||||
# CONFIG_PRINT_QUOTA_WARNING is not set
|
||||
CONFIG_QFMT_V2=y
|
||||
CONFIG_AUTOFS4_FS=y
|
||||
CONFIG_FUSE_FS=y
|
||||
CONFIG_CUSE=y
|
||||
CONFIG_FSCACHE=y
|
||||
CONFIG_FSCACHE_STATS=y
|
||||
CONFIG_CACHEFILES=y
|
||||
CONFIG_ISO9660_FS=y
|
||||
CONFIG_JOLIET=y
|
||||
CONFIG_ZISOFS=y
|
||||
CONFIG_UDF_FS=y
|
||||
CONFIG_MSDOS_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
|
||||
CONFIG_NTFS_FS=y
|
||||
CONFIG_NTFS_RW=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
CONFIG_CONFIGFS_FS=y
|
||||
# CONFIG_MISC_FILESYSTEMS is not set
|
||||
CONFIG_NFS_FS=y
|
||||
CONFIG_NFS_V3=y
|
||||
CONFIG_NFS_V4=y
|
||||
CONFIG_CIFS=y
|
||||
CONFIG_NLS_DEFAULT="utf8"
|
||||
CONFIG_NLS_CODEPAGE_437=y
|
||||
CONFIG_NLS_CODEPAGE_936=y
|
||||
CONFIG_NLS_CODEPAGE_950=y
|
||||
CONFIG_NLS_CODEPAGE_932=y
|
||||
CONFIG_NLS_CODEPAGE_949=y
|
||||
CONFIG_NLS_ASCII=y
|
||||
CONFIG_NLS_ISO8859_1=y
|
||||
CONFIG_NLS_UTF8=y
|
||||
CONFIG_PRINTK_TIME=y
|
||||
# CONFIG_ENABLE_WARN_DEPRECATED is not set
|
||||
CONFIG_FRAME_WARN=2048
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_STRIP_ASM_SYMS=y
|
||||
CONFIG_DEBUG_FS=y
|
||||
CONFIG_DEBUG_KERNEL=y
|
||||
CONFIG_DEBUG_SHIRQ=y
|
||||
CONFIG_DETECT_HUNG_TASK=y
|
||||
CONFIG_SCHEDSTATS=y
|
||||
CONFIG_TIMER_STATS=y
|
||||
CONFIG_DEBUG_LIST=y
|
||||
CONFIG_BOOT_PRINTK_DELAY=y
|
||||
CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
|
||||
# CONFIG_FTRACE is not set
|
||||
CONFIG_DYNAMIC_DEBUG=y
|
||||
CONFIG_STRICT_DEVMEM=y
|
||||
CONFIG_DEBUG_LL=y
|
||||
CONFIG_EARLY_PRINTK=y
|
||||
CONFIG_SECURITYFS=y
|
||||
# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
|
||||
CONFIG_CRYPTO_GF128MUL=y
|
||||
CONFIG_CRYPTO_SEQIV=y
|
||||
CONFIG_CRYPTO_ZLIB=y
|
||||
CONFIG_CRYPTO_LZO=y
|
||||
# CONFIG_CRYPTO_ANSI_CPRNG is not set
|
||||
# CONFIG_CRYPTO_HW is not set
|
||||
CONFIG_LIBCRC32C=y
|
||||
CONFIG_AVERAGE=y
|
330
recipes-kernel/linux/linux-sunxi/olinuxino-a13/defconfig
Normal file
330
recipes-kernel/linux/linux-sunxi/olinuxino-a13/defconfig
Normal file
@ -0,0 +1,330 @@
|
||||
CONFIG_EXPERIMENTAL=y
|
||||
# CONFIG_LOCALVERSION_AUTO is not set
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_BSD_PROCESS_ACCT=y
|
||||
CONFIG_BSD_PROCESS_ACCT_V3=y
|
||||
CONFIG_FHANDLE=y
|
||||
CONFIG_TASKSTATS=y
|
||||
CONFIG_TASK_DELAY_ACCT=y
|
||||
CONFIG_TASK_XACCT=y
|
||||
CONFIG_TASK_IO_ACCOUNTING=y
|
||||
CONFIG_AUDIT=y
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_LOG_BUF_SHIFT=19
|
||||
CONFIG_CGROUPS=y
|
||||
CONFIG_CGROUP_FREEZER=y
|
||||
CONFIG_CGROUP_DEVICE=y
|
||||
CONFIG_CPUSETS=y
|
||||
CONFIG_CGROUP_CPUACCT=y
|
||||
CONFIG_RESOURCE_COUNTERS=y
|
||||
CONFIG_BLK_CGROUP=y
|
||||
CONFIG_RELAY=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
CONFIG_KALLSYMS_ALL=y
|
||||
CONFIG_PERF_COUNTERS=y
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_FORCE_LOAD=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_MODVERSIONS=y
|
||||
CONFIG_MODULE_SRCVERSION_ALL=y
|
||||
CONFIG_BLK_DEV_INTEGRITY=y
|
||||
CONFIG_PARTITION_ADVANCED=y
|
||||
CONFIG_OSF_PARTITION=y
|
||||
CONFIG_AMIGA_PARTITION=y
|
||||
CONFIG_MAC_PARTITION=y
|
||||
CONFIG_BSD_DISKLABEL=y
|
||||
CONFIG_MINIX_SUBPARTITION=y
|
||||
CONFIG_SOLARIS_X86_PARTITION=y
|
||||
CONFIG_UNIXWARE_DISKLABEL=y
|
||||
CONFIG_SGI_PARTITION=y
|
||||
CONFIG_SUN_PARTITION=y
|
||||
CONFIG_KARMA_PARTITION=y
|
||||
CONFIG_EFI_PARTITION=y
|
||||
CONFIG_CFQ_GROUP_IOSCHED=y
|
||||
CONFIG_ARCH_SUN5I=y
|
||||
CONFIG_SW_DEBUG_UART=1
|
||||
CONFIG_SWP_EMULATE=y
|
||||
CONFIG_PREEMPT=y
|
||||
CONFIG_AEABI=y
|
||||
CONFIG_HIGHMEM=y
|
||||
CONFIG_COMPACTION=y
|
||||
CONFIG_KSM=y
|
||||
CONFIG_ZBOOT_ROM_TEXT=0x0
|
||||
CONFIG_ZBOOT_ROM_BSS=0x0
|
||||
CONFIG_CMDLINE=" debug"
|
||||
CONFIG_CPU_FREQ=y
|
||||
CONFIG_CPU_FREQ_STAT_DETAILS=y
|
||||
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
|
||||
CONFIG_CPU_FREQ_GOV_USERSPACE=y
|
||||
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
|
||||
CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
|
||||
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
|
||||
CONFIG_CPU_FREQ_USR_EVNT_NOTIFY=y
|
||||
CONFIG_CPU_FREQ_DVFS=y
|
||||
CONFIG_CPU_IDLE=y
|
||||
CONFIG_VFP=y
|
||||
CONFIG_NEON=y
|
||||
CONFIG_BINFMT_MISC=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_XFRM_USER=y
|
||||
CONFIG_NET_KEY=y
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
CONFIG_NET_IPIP=y
|
||||
CONFIG_IP_MROUTE=y
|
||||
CONFIG_IP_PIMSM_V1=y
|
||||
CONFIG_IP_PIMSM_V2=y
|
||||
CONFIG_SYN_COOKIES=y
|
||||
CONFIG_INET_AH=y
|
||||
CONFIG_INET_ESP=y
|
||||
CONFIG_INET_IPCOMP=y
|
||||
# CONFIG_INET_DIAG is not set
|
||||
CONFIG_IPV6=y
|
||||
CONFIG_IPV6_PRIVACY=y
|
||||
CONFIG_IPV6_ROUTER_PREF=y
|
||||
CONFIG_IPV6_ROUTE_INFO=y
|
||||
CONFIG_IPV6_OPTIMISTIC_DAD=y
|
||||
CONFIG_INET6_AH=m
|
||||
CONFIG_INET6_ESP=m
|
||||
CONFIG_INET6_IPCOMP=m
|
||||
CONFIG_IPV6_MIP6=m
|
||||
CONFIG_INET6_XFRM_MODE_TRANSPORT=m
|
||||
CONFIG_INET6_XFRM_MODE_TUNNEL=m
|
||||
CONFIG_INET6_XFRM_MODE_BEET=m
|
||||
CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
|
||||
CONFIG_IPV6_SIT=m
|
||||
CONFIG_IPV6_SIT_6RD=y
|
||||
CONFIG_IPV6_TUNNEL=m
|
||||
CONFIG_IPV6_MULTIPLE_TABLES=y
|
||||
CONFIG_IPV6_SUBTREES=y
|
||||
CONFIG_IPV6_MROUTE=y
|
||||
CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y
|
||||
CONFIG_IPV6_PIMSM_V2=y
|
||||
# CONFIG_ANDROID_PARANOID_NETWORK is not set
|
||||
CONFIG_NETWORK_SECMARK=y
|
||||
CONFIG_BRIDGE=y
|
||||
CONFIG_VLAN_8021Q=y
|
||||
CONFIG_VLAN_8021Q_GVRP=y
|
||||
CONFIG_NET_PKTGEN=m
|
||||
CONFIG_CFG80211=y
|
||||
CONFIG_MAC80211=y
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_DEVTMPFS_MOUNT=y
|
||||
# CONFIG_FIRMWARE_IN_KERNEL is not set
|
||||
CONFIG_CMA=y
|
||||
CONFIG_CMA_SIZE_MBYTES=192
|
||||
CONFIG_CONNECTOR=y
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
CONFIG_BLK_DEV_CRYPTOLOOP=y
|
||||
CONFIG_BLK_DEV_UB=y
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_COUNT=4
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_BLK_DEV_SR=y
|
||||
CONFIG_BLK_DEV_SR_VENDOR=y
|
||||
CONFIG_SCSI_MULTI_LUN=y
|
||||
CONFIG_MD=y
|
||||
CONFIG_BLK_DEV_MD=y
|
||||
CONFIG_MD_LINEAR=y
|
||||
CONFIG_MD_MULTIPATH=y
|
||||
CONFIG_MD_FAULTY=y
|
||||
CONFIG_BLK_DEV_DM=y
|
||||
CONFIG_DM_CRYPT=y
|
||||
CONFIG_DM_SNAPSHOT=y
|
||||
CONFIG_DM_MIRROR=y
|
||||
CONFIG_DM_ZERO=y
|
||||
CONFIG_DM_MULTIPATH=y
|
||||
CONFIG_DM_MULTIPATH_QL=y
|
||||
CONFIG_DM_MULTIPATH_ST=y
|
||||
CONFIG_NETDEVICES=y
|
||||
# CONFIG_NET_VENDOR_BROADCOM is not set
|
||||
# CONFIG_NET_VENDOR_CHELSIO is not set
|
||||
# CONFIG_NET_VENDOR_CIRRUS is not set
|
||||
# CONFIG_NET_VENDOR_FARADAY is not set
|
||||
# CONFIG_NET_VENDOR_INTEL is not set
|
||||
# CONFIG_NET_VENDOR_MARVELL is not set
|
||||
# CONFIG_NET_VENDOR_MICREL is not set
|
||||
# CONFIG_NET_VENDOR_MICROCHIP is not set
|
||||
# CONFIG_NET_VENDOR_NATSEMI is not set
|
||||
# CONFIG_NET_VENDOR_SEEQ is not set
|
||||
# CONFIG_NET_VENDOR_SMSC is not set
|
||||
# CONFIG_NET_VENDOR_STMICRO is not set
|
||||
CONFIG_PHYLIB=y
|
||||
CONFIG_USB_CATC=y
|
||||
CONFIG_USB_KAWETH=y
|
||||
CONFIG_USB_PEGASUS=y
|
||||
CONFIG_USB_RTL8150=y
|
||||
CONFIG_USB_USBNET=y
|
||||
CONFIG_USB_NET_CDC_EEM=y
|
||||
CONFIG_USB_NET_DM9601=y
|
||||
CONFIG_USB_NET_SMSC75XX=y
|
||||
CONFIG_USB_NET_SMSC95XX=y
|
||||
CONFIG_USB_NET_GL620A=y
|
||||
CONFIG_USB_NET_PLUSB=y
|
||||
CONFIG_USB_NET_MCS7830=y
|
||||
CONFIG_USB_NET_RNDIS_HOST=y
|
||||
CONFIG_USB_ALI_M5632=y
|
||||
CONFIG_USB_AN2720=y
|
||||
CONFIG_USB_EPSON2888=y
|
||||
CONFIG_USB_KC2190=y
|
||||
CONFIG_USB_NET_CX82310_ETH=y
|
||||
CONFIG_USB_NET_KALMIA=y
|
||||
CONFIG_USB_NET_QMI_WWAN=y
|
||||
CONFIG_USB_NET_INT51X1=y
|
||||
CONFIG_USB_IPHETH=y
|
||||
CONFIG_USB_SIERRA_NET=y
|
||||
CONFIG_USB_VL600=y
|
||||
CONFIG_RTL8192CU_SW=m
|
||||
CONFIG_INPUT_FF_MEMLESS=y
|
||||
CONFIG_INPUT_POLLDEV=y
|
||||
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
|
||||
CONFIG_INPUT_EVDEV=y
|
||||
CONFIG_KEYBOARD_SUN4IKEYPAD=m
|
||||
CONFIG_KEYBOARD_SUN4I_KEYBOARD=m
|
||||
CONFIG_KEYBOARD_HV2605_KEYBOARD=m
|
||||
# CONFIG_INPUT_MOUSE is not set
|
||||
CONFIG_INPUT_TOUCHSCREEN=y
|
||||
CONFIG_TOUCHSCREEN_GT801=m
|
||||
CONFIG_TOUCHSCREEN_GT811=m
|
||||
CONFIG_TOUCHSCREEN_GT818=m
|
||||
CONFIG_TOUCHSCREEN_SUN4I_TS=m
|
||||
CONFIG_TOUCHSCREEN_FT5X_TS=m
|
||||
CONFIG_TOUCHSCREEN_ZT8031=m
|
||||
CONFIG_VT_HW_CONSOLE_BINDING=y
|
||||
CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
|
||||
CONFIG_SERIAL_NONSTANDARD=y
|
||||
# CONFIG_DEVKMEM is not set
|
||||
CONFIG_SERIAL_8250=y
|
||||
CONFIG_SERIAL_8250_CONSOLE=y
|
||||
# CONFIG_HW_RANDOM is not set
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2C_CHARDEV=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_SUN5I=y
|
||||
CONFIG_SUN5I_SPI_NDMA=y
|
||||
CONFIG_SPI_SPIDEV=m
|
||||
CONFIG_GPIOLIB=y
|
||||
CONFIG_GPIO_SYSFS=y
|
||||
CONFIG_GPIO_SUNXI=m
|
||||
CONFIG_W1=m
|
||||
CONFIG_W1_SUNXI=m
|
||||
CONFIG_W1_MASTER_GPIO=m
|
||||
CONFIG_POWER_SUPPLY=y
|
||||
CONFIG_AW_AXP=y
|
||||
# CONFIG_SENSORS_MMA7660 is not set
|
||||
CONFIG_REGULATOR=y
|
||||
CONFIG_MEDIA_SUPPORT=y
|
||||
CONFIG_PA_CONTROL=y
|
||||
CONFIG_DRM=m
|
||||
CONFIG_DRM_MALI=m
|
||||
CONFIG_MALI=m
|
||||
# CONFIG_UMP_DEBUG is not set
|
||||
CONFIG_FB=y
|
||||
CONFIG_FB_SUNXI=m
|
||||
CONFIG_FB_SUNXI_LCD=m
|
||||
CONFIG_FB_SUNXI_HDMI=m
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
CONFIG_LOGO=y
|
||||
CONFIG_SOUND=y
|
||||
CONFIG_SND=y
|
||||
CONFIG_SND_SOC=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_EHCI_ROOT_HUB_TT=y
|
||||
CONFIG_USB_OHCI_HCD=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_USB_STORAGE_REALTEK=y
|
||||
CONFIG_USB_STORAGE_DATAFAB=y
|
||||
CONFIG_USB_STORAGE_FREECOM=y
|
||||
CONFIG_USB_STORAGE_ISD200=y
|
||||
CONFIG_USB_STORAGE_USBAT=y
|
||||
CONFIG_USB_STORAGE_SDDR09=y
|
||||
CONFIG_USB_STORAGE_SDDR55=y
|
||||
CONFIG_USB_STORAGE_JUMPSHOT=y
|
||||
CONFIG_USB_STORAGE_ALAUDA=y
|
||||
CONFIG_USB_STORAGE_ONETOUCH=y
|
||||
CONFIG_USB_STORAGE_KARMA=y
|
||||
CONFIG_USB_STORAGE_CYPRESS_ATACB=y
|
||||
CONFIG_USB_STORAGE_ENE_UB6250=y
|
||||
CONFIG_USB_CYPRESS_CY7C63=m
|
||||
CONFIG_USB_GADGET=y
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MMC_UNSAFE_RESUME=y
|
||||
# CONFIG_MMC_BLOCK_BOUNCE is not set
|
||||
CONFIG_MMC_SUNXI_POWER_CONTROL=y
|
||||
CONFIG_NEW_LEDS=y
|
||||
CONFIG_LEDS_CLASS=y
|
||||
CONFIG_LEDS_SUNXI=y
|
||||
CONFIG_LEDS_TRIGGERS=y
|
||||
CONFIG_LEDS_TRIGGER_TIMER=y
|
||||
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
|
||||
CONFIG_SWITCH=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_SUN5I=y
|
||||
CONFIG_STAGING=y
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
CONFIG_QUOTA=y
|
||||
CONFIG_QUOTA_NETLINK_INTERFACE=y
|
||||
# CONFIG_PRINT_QUOTA_WARNING is not set
|
||||
CONFIG_AUTOFS4_FS=y
|
||||
CONFIG_FUSE_FS=y
|
||||
CONFIG_CUSE=y
|
||||
CONFIG_FSCACHE=y
|
||||
CONFIG_FSCACHE_STATS=y
|
||||
CONFIG_CACHEFILES=y
|
||||
CONFIG_MSDOS_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_NTFS_FS=y
|
||||
CONFIG_NTFS_RW=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
CONFIG_CONFIGFS_FS=y
|
||||
# CONFIG_MISC_FILESYSTEMS is not set
|
||||
CONFIG_NFS_FS=y
|
||||
CONFIG_CIFS=y
|
||||
CONFIG_NLS_DEFAULT="utf8"
|
||||
CONFIG_NLS_CODEPAGE_437=y
|
||||
CONFIG_NLS_CODEPAGE_936=y
|
||||
CONFIG_NLS_CODEPAGE_950=y
|
||||
CONFIG_NLS_CODEPAGE_932=y
|
||||
CONFIG_NLS_CODEPAGE_949=y
|
||||
CONFIG_NLS_ASCII=y
|
||||
CONFIG_NLS_ISO8859_1=y
|
||||
CONFIG_NLS_UTF8=y
|
||||
CONFIG_PRINTK_TIME=y
|
||||
# CONFIG_ENABLE_WARN_DEPRECATED is not set
|
||||
CONFIG_FRAME_WARN=2048
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_STRIP_ASM_SYMS=y
|
||||
CONFIG_DEBUG_FS=y
|
||||
CONFIG_DEBUG_KERNEL=y
|
||||
CONFIG_DEBUG_SHIRQ=y
|
||||
CONFIG_DETECT_HUNG_TASK=y
|
||||
CONFIG_SCHEDSTATS=y
|
||||
CONFIG_TIMER_STATS=y
|
||||
CONFIG_DEBUG_LIST=y
|
||||
CONFIG_BOOT_PRINTK_DELAY=y
|
||||
CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
|
||||
# CONFIG_FTRACE is not set
|
||||
CONFIG_DYNAMIC_DEBUG=y
|
||||
CONFIG_STRICT_DEVMEM=y
|
||||
CONFIG_DEBUG_LL=y
|
||||
CONFIG_SECURITYFS=y
|
||||
# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
|
||||
CONFIG_CRYPTO_GF128MUL=y
|
||||
CONFIG_CRYPTO_SEQIV=y
|
||||
CONFIG_CRYPTO_ZLIB=y
|
||||
CONFIG_CRYPTO_LZO=y
|
||||
# CONFIG_CRYPTO_ANSI_CPRNG is not set
|
||||
# CONFIG_CRYPTO_HW is not set
|
||||
CONFIG_CRC_ITU_T=y
|
||||
CONFIG_LIBCRC32C=y
|
330
recipes-kernel/linux/linux-sunxi/olinuxino-a13som/defconfig
Normal file
330
recipes-kernel/linux/linux-sunxi/olinuxino-a13som/defconfig
Normal file
@ -0,0 +1,330 @@
|
||||
CONFIG_EXPERIMENTAL=y
|
||||
# CONFIG_LOCALVERSION_AUTO is not set
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_BSD_PROCESS_ACCT=y
|
||||
CONFIG_BSD_PROCESS_ACCT_V3=y
|
||||
CONFIG_FHANDLE=y
|
||||
CONFIG_TASKSTATS=y
|
||||
CONFIG_TASK_DELAY_ACCT=y
|
||||
CONFIG_TASK_XACCT=y
|
||||
CONFIG_TASK_IO_ACCOUNTING=y
|
||||
CONFIG_AUDIT=y
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_LOG_BUF_SHIFT=19
|
||||
CONFIG_CGROUPS=y
|
||||
CONFIG_CGROUP_FREEZER=y
|
||||
CONFIG_CGROUP_DEVICE=y
|
||||
CONFIG_CPUSETS=y
|
||||
CONFIG_CGROUP_CPUACCT=y
|
||||
CONFIG_RESOURCE_COUNTERS=y
|
||||
CONFIG_BLK_CGROUP=y
|
||||
CONFIG_RELAY=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
CONFIG_KALLSYMS_ALL=y
|
||||
CONFIG_PERF_COUNTERS=y
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_FORCE_LOAD=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_MODVERSIONS=y
|
||||
CONFIG_MODULE_SRCVERSION_ALL=y
|
||||
CONFIG_BLK_DEV_INTEGRITY=y
|
||||
CONFIG_PARTITION_ADVANCED=y
|
||||
CONFIG_OSF_PARTITION=y
|
||||
CONFIG_AMIGA_PARTITION=y
|
||||
CONFIG_MAC_PARTITION=y
|
||||
CONFIG_BSD_DISKLABEL=y
|
||||
CONFIG_MINIX_SUBPARTITION=y
|
||||
CONFIG_SOLARIS_X86_PARTITION=y
|
||||
CONFIG_UNIXWARE_DISKLABEL=y
|
||||
CONFIG_SGI_PARTITION=y
|
||||
CONFIG_SUN_PARTITION=y
|
||||
CONFIG_KARMA_PARTITION=y
|
||||
CONFIG_EFI_PARTITION=y
|
||||
CONFIG_CFQ_GROUP_IOSCHED=y
|
||||
CONFIG_ARCH_SUN5I=y
|
||||
CONFIG_SW_DEBUG_UART=1
|
||||
CONFIG_SWP_EMULATE=y
|
||||
CONFIG_PREEMPT=y
|
||||
CONFIG_AEABI=y
|
||||
CONFIG_HIGHMEM=y
|
||||
CONFIG_COMPACTION=y
|
||||
CONFIG_KSM=y
|
||||
CONFIG_ZBOOT_ROM_TEXT=0x0
|
||||
CONFIG_ZBOOT_ROM_BSS=0x0
|
||||
CONFIG_CMDLINE=" debug"
|
||||
CONFIG_CPU_FREQ=y
|
||||
CONFIG_CPU_FREQ_STAT_DETAILS=y
|
||||
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
|
||||
CONFIG_CPU_FREQ_GOV_USERSPACE=y
|
||||
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
|
||||
CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
|
||||
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
|
||||
CONFIG_CPU_FREQ_USR_EVNT_NOTIFY=y
|
||||
CONFIG_CPU_FREQ_DVFS=y
|
||||
CONFIG_CPU_IDLE=y
|
||||
CONFIG_VFP=y
|
||||
CONFIG_NEON=y
|
||||
CONFIG_BINFMT_MISC=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_XFRM_USER=y
|
||||
CONFIG_NET_KEY=y
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
CONFIG_NET_IPIP=y
|
||||
CONFIG_IP_MROUTE=y
|
||||
CONFIG_IP_PIMSM_V1=y
|
||||
CONFIG_IP_PIMSM_V2=y
|
||||
CONFIG_SYN_COOKIES=y
|
||||
CONFIG_INET_AH=y
|
||||
CONFIG_INET_ESP=y
|
||||
CONFIG_INET_IPCOMP=y
|
||||
# CONFIG_INET_DIAG is not set
|
||||
CONFIG_IPV6=y
|
||||
CONFIG_IPV6_PRIVACY=y
|
||||
CONFIG_IPV6_ROUTER_PREF=y
|
||||
CONFIG_IPV6_ROUTE_INFO=y
|
||||
CONFIG_IPV6_OPTIMISTIC_DAD=y
|
||||
CONFIG_INET6_AH=m
|
||||
CONFIG_INET6_ESP=m
|
||||
CONFIG_INET6_IPCOMP=m
|
||||
CONFIG_IPV6_MIP6=m
|
||||
CONFIG_INET6_XFRM_MODE_TRANSPORT=m
|
||||
CONFIG_INET6_XFRM_MODE_TUNNEL=m
|
||||
CONFIG_INET6_XFRM_MODE_BEET=m
|
||||
CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
|
||||
CONFIG_IPV6_SIT=m
|
||||
CONFIG_IPV6_SIT_6RD=y
|
||||
CONFIG_IPV6_TUNNEL=m
|
||||
CONFIG_IPV6_MULTIPLE_TABLES=y
|
||||
CONFIG_IPV6_SUBTREES=y
|
||||
CONFIG_IPV6_MROUTE=y
|
||||
CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y
|
||||
CONFIG_IPV6_PIMSM_V2=y
|
||||
# CONFIG_ANDROID_PARANOID_NETWORK is not set
|
||||
CONFIG_NETWORK_SECMARK=y
|
||||
CONFIG_BRIDGE=y
|
||||
CONFIG_VLAN_8021Q=y
|
||||
CONFIG_VLAN_8021Q_GVRP=y
|
||||
CONFIG_NET_PKTGEN=m
|
||||
CONFIG_CFG80211=y
|
||||
CONFIG_MAC80211=y
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_DEVTMPFS_MOUNT=y
|
||||
# CONFIG_FIRMWARE_IN_KERNEL is not set
|
||||
CONFIG_CMA=y
|
||||
CONFIG_CMA_SIZE_MBYTES=192
|
||||
CONFIG_CONNECTOR=y
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
CONFIG_BLK_DEV_CRYPTOLOOP=y
|
||||
CONFIG_BLK_DEV_UB=y
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_COUNT=4
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_BLK_DEV_SR=y
|
||||
CONFIG_BLK_DEV_SR_VENDOR=y
|
||||
CONFIG_SCSI_MULTI_LUN=y
|
||||
CONFIG_MD=y
|
||||
CONFIG_BLK_DEV_MD=y
|
||||
CONFIG_MD_LINEAR=y
|
||||
CONFIG_MD_MULTIPATH=y
|
||||
CONFIG_MD_FAULTY=y
|
||||
CONFIG_BLK_DEV_DM=y
|
||||
CONFIG_DM_CRYPT=y
|
||||
CONFIG_DM_SNAPSHOT=y
|
||||
CONFIG_DM_MIRROR=y
|
||||
CONFIG_DM_ZERO=y
|
||||
CONFIG_DM_MULTIPATH=y
|
||||
CONFIG_DM_MULTIPATH_QL=y
|
||||
CONFIG_DM_MULTIPATH_ST=y
|
||||
CONFIG_NETDEVICES=y
|
||||
# CONFIG_NET_VENDOR_BROADCOM is not set
|
||||
# CONFIG_NET_VENDOR_CHELSIO is not set
|
||||
# CONFIG_NET_VENDOR_CIRRUS is not set
|
||||
# CONFIG_NET_VENDOR_FARADAY is not set
|
||||
# CONFIG_NET_VENDOR_INTEL is not set
|
||||
# CONFIG_NET_VENDOR_MARVELL is not set
|
||||
# CONFIG_NET_VENDOR_MICREL is not set
|
||||
# CONFIG_NET_VENDOR_MICROCHIP is not set
|
||||
# CONFIG_NET_VENDOR_NATSEMI is not set
|
||||
# CONFIG_NET_VENDOR_SEEQ is not set
|
||||
# CONFIG_NET_VENDOR_SMSC is not set
|
||||
# CONFIG_NET_VENDOR_STMICRO is not set
|
||||
CONFIG_PHYLIB=y
|
||||
CONFIG_USB_CATC=y
|
||||
CONFIG_USB_KAWETH=y
|
||||
CONFIG_USB_PEGASUS=y
|
||||
CONFIG_USB_RTL8150=y
|
||||
CONFIG_USB_USBNET=y
|
||||
CONFIG_USB_NET_CDC_EEM=y
|
||||
CONFIG_USB_NET_DM9601=y
|
||||
CONFIG_USB_NET_SMSC75XX=y
|
||||
CONFIG_USB_NET_SMSC95XX=y
|
||||
CONFIG_USB_NET_GL620A=y
|
||||
CONFIG_USB_NET_PLUSB=y
|
||||
CONFIG_USB_NET_MCS7830=y
|
||||
CONFIG_USB_NET_RNDIS_HOST=y
|
||||
CONFIG_USB_ALI_M5632=y
|
||||
CONFIG_USB_AN2720=y
|
||||
CONFIG_USB_EPSON2888=y
|
||||
CONFIG_USB_KC2190=y
|
||||
CONFIG_USB_NET_CX82310_ETH=y
|
||||
CONFIG_USB_NET_KALMIA=y
|
||||
CONFIG_USB_NET_QMI_WWAN=y
|
||||
CONFIG_USB_NET_INT51X1=y
|
||||
CONFIG_USB_IPHETH=y
|
||||
CONFIG_USB_SIERRA_NET=y
|
||||
CONFIG_USB_VL600=y
|
||||
CONFIG_RTL8192CU_SW=m
|
||||
CONFIG_INPUT_FF_MEMLESS=y
|
||||
CONFIG_INPUT_POLLDEV=y
|
||||
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
|
||||
CONFIG_INPUT_EVDEV=y
|
||||
CONFIG_KEYBOARD_SUN4IKEYPAD=m
|
||||
CONFIG_KEYBOARD_SUN4I_KEYBOARD=m
|
||||
CONFIG_KEYBOARD_HV2605_KEYBOARD=m
|
||||
# CONFIG_INPUT_MOUSE is not set
|
||||
CONFIG_INPUT_TOUCHSCREEN=y
|
||||
CONFIG_TOUCHSCREEN_GT801=m
|
||||
CONFIG_TOUCHSCREEN_GT811=m
|
||||
CONFIG_TOUCHSCREEN_GT818=m
|
||||
CONFIG_TOUCHSCREEN_SUN4I_TS=m
|
||||
CONFIG_TOUCHSCREEN_FT5X_TS=m
|
||||
CONFIG_TOUCHSCREEN_ZT8031=m
|
||||
CONFIG_VT_HW_CONSOLE_BINDING=y
|
||||
CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
|
||||
CONFIG_SERIAL_NONSTANDARD=y
|
||||
# CONFIG_DEVKMEM is not set
|
||||
CONFIG_SERIAL_8250=y
|
||||
CONFIG_SERIAL_8250_CONSOLE=y
|
||||
# CONFIG_HW_RANDOM is not set
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2C_CHARDEV=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_SUN5I=y
|
||||
CONFIG_SUN5I_SPI_NDMA=y
|
||||
CONFIG_SPI_SPIDEV=m
|
||||
CONFIG_GPIOLIB=y
|
||||
CONFIG_GPIO_SYSFS=y
|
||||
CONFIG_GPIO_SUNXI=m
|
||||
CONFIG_W1=m
|
||||
CONFIG_W1_SUNXI=m
|
||||
CONFIG_W1_MASTER_GPIO=m
|
||||
CONFIG_POWER_SUPPLY=y
|
||||
CONFIG_AW_AXP=y
|
||||
# CONFIG_SENSORS_MMA7660 is not set
|
||||
CONFIG_REGULATOR=y
|
||||
CONFIG_MEDIA_SUPPORT=y
|
||||
CONFIG_PA_CONTROL=y
|
||||
CONFIG_DRM=m
|
||||
CONFIG_DRM_MALI=m
|
||||
CONFIG_MALI=m
|
||||
# CONFIG_UMP_DEBUG is not set
|
||||
CONFIG_FB=y
|
||||
CONFIG_FB_SUNXI=m
|
||||
CONFIG_FB_SUNXI_LCD=m
|
||||
CONFIG_FB_SUNXI_HDMI=m
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
CONFIG_LOGO=y
|
||||
CONFIG_SOUND=y
|
||||
CONFIG_SND=y
|
||||
CONFIG_SND_SOC=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_EHCI_ROOT_HUB_TT=y
|
||||
CONFIG_USB_OHCI_HCD=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_USB_STORAGE_REALTEK=y
|
||||
CONFIG_USB_STORAGE_DATAFAB=y
|
||||
CONFIG_USB_STORAGE_FREECOM=y
|
||||
CONFIG_USB_STORAGE_ISD200=y
|
||||
CONFIG_USB_STORAGE_USBAT=y
|
||||
CONFIG_USB_STORAGE_SDDR09=y
|
||||
CONFIG_USB_STORAGE_SDDR55=y
|
||||
CONFIG_USB_STORAGE_JUMPSHOT=y
|
||||
CONFIG_USB_STORAGE_ALAUDA=y
|
||||
CONFIG_USB_STORAGE_ONETOUCH=y
|
||||
CONFIG_USB_STORAGE_KARMA=y
|
||||
CONFIG_USB_STORAGE_CYPRESS_ATACB=y
|
||||
CONFIG_USB_STORAGE_ENE_UB6250=y
|
||||
CONFIG_USB_CYPRESS_CY7C63=m
|
||||
CONFIG_USB_GADGET=y
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MMC_UNSAFE_RESUME=y
|
||||
# CONFIG_MMC_BLOCK_BOUNCE is not set
|
||||
CONFIG_MMC_SUNXI_POWER_CONTROL=y
|
||||
CONFIG_NEW_LEDS=y
|
||||
CONFIG_LEDS_CLASS=y
|
||||
CONFIG_LEDS_SUNXI=y
|
||||
CONFIG_LEDS_TRIGGERS=y
|
||||
CONFIG_LEDS_TRIGGER_TIMER=y
|
||||
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
|
||||
CONFIG_SWITCH=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_SUN5I=y
|
||||
CONFIG_STAGING=y
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
CONFIG_QUOTA=y
|
||||
CONFIG_QUOTA_NETLINK_INTERFACE=y
|
||||
# CONFIG_PRINT_QUOTA_WARNING is not set
|
||||
CONFIG_AUTOFS4_FS=y
|
||||
CONFIG_FUSE_FS=y
|
||||
CONFIG_CUSE=y
|
||||
CONFIG_FSCACHE=y
|
||||
CONFIG_FSCACHE_STATS=y
|
||||
CONFIG_CACHEFILES=y
|
||||
CONFIG_MSDOS_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_NTFS_FS=y
|
||||
CONFIG_NTFS_RW=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
CONFIG_CONFIGFS_FS=y
|
||||
# CONFIG_MISC_FILESYSTEMS is not set
|
||||
CONFIG_NFS_FS=y
|
||||
CONFIG_CIFS=y
|
||||
CONFIG_NLS_DEFAULT="utf8"
|
||||
CONFIG_NLS_CODEPAGE_437=y
|
||||
CONFIG_NLS_CODEPAGE_936=y
|
||||
CONFIG_NLS_CODEPAGE_950=y
|
||||
CONFIG_NLS_CODEPAGE_932=y
|
||||
CONFIG_NLS_CODEPAGE_949=y
|
||||
CONFIG_NLS_ASCII=y
|
||||
CONFIG_NLS_ISO8859_1=y
|
||||
CONFIG_NLS_UTF8=y
|
||||
CONFIG_PRINTK_TIME=y
|
||||
# CONFIG_ENABLE_WARN_DEPRECATED is not set
|
||||
CONFIG_FRAME_WARN=2048
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_STRIP_ASM_SYMS=y
|
||||
CONFIG_DEBUG_FS=y
|
||||
CONFIG_DEBUG_KERNEL=y
|
||||
CONFIG_DEBUG_SHIRQ=y
|
||||
CONFIG_DETECT_HUNG_TASK=y
|
||||
CONFIG_SCHEDSTATS=y
|
||||
CONFIG_TIMER_STATS=y
|
||||
CONFIG_DEBUG_LIST=y
|
||||
CONFIG_BOOT_PRINTK_DELAY=y
|
||||
CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
|
||||
# CONFIG_FTRACE is not set
|
||||
CONFIG_DYNAMIC_DEBUG=y
|
||||
CONFIG_STRICT_DEVMEM=y
|
||||
CONFIG_DEBUG_LL=y
|
||||
CONFIG_SECURITYFS=y
|
||||
# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
|
||||
CONFIG_CRYPTO_GF128MUL=y
|
||||
CONFIG_CRYPTO_SEQIV=y
|
||||
CONFIG_CRYPTO_ZLIB=y
|
||||
CONFIG_CRYPTO_LZO=y
|
||||
# CONFIG_CRYPTO_ANSI_CPRNG is not set
|
||||
# CONFIG_CRYPTO_HW is not set
|
||||
CONFIG_CRC_ITU_T=y
|
||||
CONFIG_LIBCRC32C=y
|
1223
recipes-kernel/linux/linux-sunxi/olinuxino-a20lime/defconfig
Normal file
1223
recipes-kernel/linux/linux-sunxi/olinuxino-a20lime/defconfig
Normal file
File diff suppressed because it is too large
Load Diff
1263
recipes-kernel/linux/linux-sunxi/olinuxino-a20lime2/defconfig
Normal file
1263
recipes-kernel/linux/linux-sunxi/olinuxino-a20lime2/defconfig
Normal file
File diff suppressed because it is too large
Load Diff
3339
recipes-kernel/linux/linux-sunxi/olinuxino-a20som/defconfig
Normal file
3339
recipes-kernel/linux/linux-sunxi/olinuxino-a20som/defconfig
Normal file
File diff suppressed because it is too large
Load Diff
55
recipes-kernel/linux/linux-sunxi_3.4.bb
Normal file
55
recipes-kernel/linux/linux-sunxi_3.4.bb
Normal file
@ -0,0 +1,55 @@
|
||||
require linux.inc
|
||||
|
||||
DESCRIPTION = "Linux kernel for Allwinner a10/a20 processors"
|
||||
|
||||
COMPATIBLE_MACHINE = "(sun4i|sun5i|sun7i)"
|
||||
RDEPENDS_${PN} += "sunxi-board-fex"
|
||||
|
||||
PV = "3.4.104"
|
||||
PR = "r1"
|
||||
SRCREV_pn-${PN} = "d47d367036be38c5180632ec8a3ad169a4593a88"
|
||||
|
||||
MACHINE_KERNEL_PR_append = "a"
|
||||
|
||||
SRC_URI += "git://github.com/linux-sunxi/linux-sunxi.git;branch=sunxi-3.4;protocol=git \
|
||||
file://0001-compiler-gcc5.patch \
|
||||
file://0002-use-static-inline-in-ARM-ftrace.patch \
|
||||
file://0001-gcc5-fixes.patch \
|
||||
file://defconfig \
|
||||
"
|
||||
|
||||
S = "${WORKDIR}/git"
|
||||
|
||||
#fix QA issue "Files/directories were installed but not shipped: /usr/src/debug"
|
||||
INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
|
||||
|
||||
do_configure_prepend() {
|
||||
#fix arch QA issues ("Architecture did not match")
|
||||
rm -f ${S}/drivers/net/wireless/rtxx7x/tools/bin2h
|
||||
rm -f ${S}/modules/wifi/ar6302/AR6K_SDK_ISC.build_3.1_RC.329/host/lib/wac/wac
|
||||
rm -f ${S}/modules/wifi/ar6302/AR6K_SDK_ISC.build_3.1_RC.329/host/tools/pal_host_intf/pal_app
|
||||
rm -f ${S}/modules/wifi/nano-c047.12/obj/hic-proxy
|
||||
rm -f ${S}/modules/wifi/nano-c047.12/obj/x_mac_4.69.axf
|
||||
rm -f ${S}/modules/wifi/nano-c047.12/obj/x_mac_patch_4_65.axf
|
||||
rm -f ${S}/modules/wifi/nano-c047.12/obj/x_mac_4.66.axf
|
||||
rm -f ${S}/modules/wifi/nano-c047.12/obj/x_mac-v4.68.axf
|
||||
rm -f ${S}/modules/wifi/nano-c047.12/obj/x_mac.axf
|
||||
rm -f ${S}/modules/wifi/bcm40181/open-src/src/wl/exe/wl
|
||||
rm -f ${S}/modules/wifi/bcm40181/open-src/src/wl/exe/socket_noasd/x86/wl_server_socket
|
||||
rm -f ${S}/modules/wifi/bcm40181/open-src/src/wl/exe/wifi_noasd/x86/wl_server_serial
|
||||
rm -f ${S}/modules/wifi/bcm40181/open-src/src/wl/exe/wifi_noasd/x86/wl_server_wifi
|
||||
rm -f ${S}/modules/wifi/bcm40181/open-src/src/wl/exe/make/wl
|
||||
rm -f ${S}/modules/wifi/bcm40181/open-src/src/wl/exe/make/socket_noasd/x86/wl_server_socket
|
||||
rm -f ${S}/modules/wifi/bcm40181/open-src/src/wl/exe/make/wifi_noasd/x86/wl_server_serial
|
||||
rm -f ${S}/modules/wifi/bcm40181/open-src/src/wl/exe/make/wifi_noasd/x86/wl_server_wifi
|
||||
rm -f ${S}/modules/wifi/bcm40181/open-src/src/wl/exe/make/dongle_noasd/x86/wl_server_dongle
|
||||
rm -f ${S}/modules/wifi/bcm40181/open-src/src/wl/exe/dongle_noasd/x86/wl_server_dongle
|
||||
rm -f ${S}/modules/wifi/bcm40181/apps/tc_cli
|
||||
rm -f ${S}/modules/wifi/bcm40181/apps/wfa_ca
|
||||
rm -f ${S}/modules/wifi/bcm40181/apps/dhd
|
||||
rm -f ${S}/modules/wifi/bcm40181/apps/ca_cli
|
||||
|
||||
#fix ldflags QA issues ("No GNU_HASH in the elf binary")
|
||||
rm -f ${S}/modules/wifi/usi-bcm4329/v4.218.248.15/apps/epi_ttcp
|
||||
rm -f ${S}/modules/wifi/bcm40181/apps/epi_ttcp
|
||||
}
|
@ -1,131 +1,131 @@
|
||||
DESCRIPTION = "Linux Kernel"
|
||||
SECTION = "kernel"
|
||||
LICENSE = "GPLv2"
|
||||
|
||||
LIC_FILES_CHKSUM = "file://COPYING;md5=d7810fab7487fb0aad327b76f1be7cd7"
|
||||
|
||||
INC_PR = "r0"
|
||||
|
||||
inherit kernel siteinfo
|
||||
|
||||
# Enable OABI compat for people stuck with obsolete userspace
|
||||
ARM_KEEP_OABI ?= "1"
|
||||
|
||||
# Quirk for udev greater or equal 141
|
||||
UDEV_GE_141 ?= "1"
|
||||
ARM_KEEP_OABI ?= "0"
|
||||
|
||||
# Set the verbosity of kernel messages during runtime
|
||||
# You can define CMDLINE_DEBUG in your local.conf or distro.conf to override this behaviour
|
||||
CMDLINE_DEBUG ?= '${@base_conditional("DISTRO_TYPE", "release", "quiet", "debug", d)}'
|
||||
CMDLINE_append = " ${CMDLINE_DEBUG}"
|
||||
CMDLINE_DEBUG ?= "loglevel=3"
|
||||
|
||||
# Set a variable in .configure
|
||||
# $1 - Configure variable to be set
|
||||
# $2 - value [n/y/value]
|
||||
kernel_configure_variable() {
|
||||
# Remove the config
|
||||
CONF_SED_SCRIPT="$CONF_SED_SCRIPT /CONFIG_$1[ =]/d;"
|
||||
if test "$2" = "n"
|
||||
then
|
||||
echo "# CONFIG_$1 is not set" >> ${S}/.config
|
||||
else
|
||||
echo "CONFIG_$1=$2" >> ${S}/.config
|
||||
fi
|
||||
# Kernel bootlogo is distro-specific (default is OE logo).
|
||||
# Logo resolution (qvga, vga, ...) is machine-specific.
|
||||
LOGO_SIZE ?= '${@base_conditional("MACHINE_GUI_CLASS", "bigscreen", "vga", "qvga", d)}'
|
||||
# To use this, add file://${LOGO_SIZE}/logo_linux_clut224.ppm.bz2 or similar
|
||||
# to your kernel recipe, and then structure your logos for each resolution
|
||||
# accordingly.
|
||||
|
||||
LOCALVERSION ?= ""
|
||||
|
||||
#kernel_conf_variable CMDLINE "\"${CMDLINE} ${CMDLINE_DEBUG}\""
|
||||
kernel_conf_variable() {
|
||||
CONF_SED_SCRIPT="$CONF_SED_SCRIPT /CONFIG_$1[ =]/d;"
|
||||
if test "$2" = "n"
|
||||
then
|
||||
echo "# CONFIG_$1 is not set" >> ${B}/.config
|
||||
else
|
||||
echo "CONFIG_$1=$2" >> ${B}/.config
|
||||
fi
|
||||
}
|
||||
|
||||
do_configure_prepend() {
|
||||
# Clean .config
|
||||
echo "" > ${S}/.config
|
||||
CONF_SED_SCRIPT=""
|
||||
echo "" > ${B}/.config
|
||||
CONF_SED_SCRIPT=""
|
||||
|
||||
# oabi / eabi support
|
||||
if [ "${TARGET_OS}" = "linux-gnueabi" -o "${TARGET_OS}" = "linux-uclibceabi" ]; then
|
||||
kernel_configure_variable AEABI y
|
||||
if [ "${ARM_KEEP_OABI}" = "1" ] ; then
|
||||
kernel_configure_variable OABI_COMPAT y
|
||||
else
|
||||
kernel_configure_variable OABI_COMPAT n
|
||||
fi
|
||||
else
|
||||
kernel_configure_variable AEABI n
|
||||
kernel_configure_variable OABI_COMPAT n
|
||||
fi
|
||||
#
|
||||
# logo support, if you supply logo_linux_clut224.ppm in SRC_URI, then it's going to be used
|
||||
#
|
||||
if [ -e ${WORKDIR}/logo_linux_clut224.ppm ]; then
|
||||
install -m 0644 ${WORKDIR}/logo_linux_clut224.ppm drivers/video/logo/logo_linux_clut224.ppm
|
||||
kernel_conf_variable LOGO y
|
||||
kernel_conf_variable LOGO_LINUX_CLUT224 y
|
||||
fi
|
||||
|
||||
# Set cmdline
|
||||
kernel_configure_variable CMDLINE "\"${CMDLINE}\""
|
||||
#
|
||||
# oabi / eabi support
|
||||
#
|
||||
kernel_conf_variable AEABI y
|
||||
if [ "${ARM_KEEP_OABI}" = "1" ] ; then
|
||||
kernel_conf_variable OABI_COMPAT y
|
||||
else
|
||||
kernel_conf_variable OABI_COMPAT n
|
||||
fi
|
||||
|
||||
# Localversion
|
||||
kernel_configure_variable LOCALVERSION "\"\""
|
||||
kernel_configure_variable LOCALVERSION_AUTO n
|
||||
# When enabling thumb for userspace we also need thumb support in the kernel
|
||||
if [ "${ARM_INSTRUCTION_SET}" = "thumb" ] ; then
|
||||
kernel_conf_variable ARM_THUMB y
|
||||
fi
|
||||
|
||||
# Udev quirks
|
||||
# Newer versions of udev mandate that sysfs doesn't have deprecated entries
|
||||
if [ "${UDEV_GE_141}" = "1" ] ; then
|
||||
kernel_configure_variable SYSFS_DEPRECATED n
|
||||
kernel_configure_variable SYSFS_DEPRECATED_V2 n
|
||||
kernel_configure_variable HOTPLUG y
|
||||
kernel_configure_variable UEVENT_HELPER_PATH "\"\""
|
||||
kernel_configure_variable UNIX y
|
||||
kernel_configure_variable SYSFS y
|
||||
kernel_configure_variable PROC_FS y
|
||||
kernel_configure_variable TMPFS y
|
||||
kernel_configure_variable INOTIFY_USER y
|
||||
kernel_configure_variable SIGNALFD y
|
||||
kernel_configure_variable TMPFS_POSIX_ACL y
|
||||
kernel_configure_variable BLK_DEV_BSG y
|
||||
kernel_configure_variable DEVTMPFS y
|
||||
kernel_configure_variable DEVTMPFS_MOUNT y
|
||||
fi
|
||||
kernel_conf_variable CMDLINE "\"${CMDLINE} ${CMDLINE_DEBUG}\""
|
||||
|
||||
# Newer inits like systemd need cgroup support
|
||||
if [ "${KERNEL_ENABLE_CGROUPS}" = "1" ] ; then
|
||||
kernel_configure_variable CGROUP_SCHED y
|
||||
kernel_configure_variable CGROUPS y
|
||||
kernel_configure_variable CGROUP_NS y
|
||||
kernel_configure_variable CGROUP_FREEZER y
|
||||
kernel_configure_variable CGROUP_DEVICE y
|
||||
kernel_configure_variable CPUSETS y
|
||||
kernel_configure_variable PROC_PID_CPUSET y
|
||||
kernel_configure_variable CGROUP_CPUACCT y
|
||||
kernel_configure_variable RESOURCE_COUNTERS y
|
||||
fi
|
||||
kernel_conf_variable LOCALVERSION "\"${LOCALVERSION}\""
|
||||
kernel_conf_variable LOCALVERSION_AUTO n
|
||||
|
||||
# root-over-nfs-over-usb-eth support. Limited, but should cover some cases
|
||||
# Enable this by setting a proper CMDLINE_NFSROOT_USB.
|
||||
if [ ! -z "${CMDLINE_NFSROOT_USB}" ]; then
|
||||
oenote "Configuring the kernel for root-over-nfs-over-usb-eth with CMDLINE ${CMDLINE_NFSROOT_USB}"
|
||||
kernel_configure_variable INET y
|
||||
kernel_configure_variable IP_PNP y
|
||||
kernel_configure_variable USB_GADGET y
|
||||
kernel_configure_variable USB_GADGET_SELECTED y
|
||||
kernel_configure_variable USB_ETH y
|
||||
kernel_configure_variable NFS_FS y
|
||||
kernel_configure_variable ROOT_NFS y
|
||||
kernel_configure_variable ROOT_NFS y
|
||||
kernel_configure_variable CMDLINE "\"${CMDLINE_NFSROOT_USB}\""
|
||||
fi
|
||||
kernel_conf_variable SYSFS_DEPRECATED n
|
||||
kernel_conf_variable SYSFS_DEPRECATED_V2 n
|
||||
kernel_conf_variable HOTPLUG y
|
||||
kernel_conf_variable UEVENT_HELPER_PATH \"\"
|
||||
kernel_conf_variable UNIX y
|
||||
kernel_conf_variable SYSFS y
|
||||
kernel_conf_variable PROC_FS y
|
||||
kernel_conf_variable TMPFS y
|
||||
kernel_conf_variable INOTIFY_USER y
|
||||
kernel_conf_variable SIGNALFD y
|
||||
kernel_conf_variable TMPFS_POSIX_ACL y
|
||||
kernel_conf_variable BLK_DEV_BSG y
|
||||
kernel_conf_variable DEVTMPFS y
|
||||
kernel_conf_variable DEVTMPFS_MOUNT y
|
||||
|
||||
# Activate CONFIG_LEGACY_PTYS
|
||||
kernel_configure_variable LEGACY_PTYS y
|
||||
# Newer inits like systemd need cgroup support
|
||||
if [ "${KERNEL_ENABLE_CGROUPS}" = "1" ] ; then
|
||||
kernel_conf_variable CGROUP_SCHED y
|
||||
kernel_conf_variable CGROUPS y
|
||||
kernel_conf_variable CGROUP_NS y
|
||||
kernel_conf_variable CGROUP_FREEZER y
|
||||
kernel_conf_variable CGROUP_DEVICE y
|
||||
kernel_conf_variable CPUSETS y
|
||||
kernel_conf_variable PROC_PID_CPUSET y
|
||||
kernel_conf_variable CGROUP_CPUACCT y
|
||||
kernel_conf_variable RESOURCE_COUNTERS y
|
||||
fi
|
||||
|
||||
# Keep this the last line
|
||||
# Remove all modified configs and add the rest to .config
|
||||
sed -e "${CONF_SED_SCRIPT}" < '${WORKDIR}/defconfig' >> '${S}/.config'
|
||||
#
|
||||
# root-over-nfs-over-usb-eth support. Limited, but should cover some cases.
|
||||
# Enable this by setting a proper CMDLINE_NFSROOT_USB.
|
||||
#
|
||||
if [ ! -z "${CMDLINE_NFSROOT_USB}" ]; then
|
||||
bbnote "Configuring the kernel for root-over-nfs-over-usb-eth with CMDLINE ${CMDLINE_NFSROOT_USB}"
|
||||
kernel_conf_variable INET y
|
||||
kernel_conf_variable IP_PNP y
|
||||
kernel_conf_variable USB_GADGET y
|
||||
kernel_conf_variable USB_GADGET_SELECTED y
|
||||
kernel_conf_variable USB_ETH y
|
||||
kernel_conf_variable NFS_FS y
|
||||
kernel_conf_variable ROOT_NFS y
|
||||
kernel_conf_variable CMDLINE \"${CMDLINE_NFSROOT_USB} ${CMDLINE_DEBUG}\"
|
||||
fi
|
||||
|
||||
yes '' | oe_runmake oldconfig
|
||||
sed -e "${CONF_SED_SCRIPT}" \
|
||||
< '${WORKDIR}/defconfig' >>'${B}/.config'
|
||||
|
||||
yes '' | oe_runmake -C ${S} O=${B} oldconfig
|
||||
}
|
||||
|
||||
# Automatically depend on lzop-native if CONFIG_KERNEL_LZO is enabled
|
||||
python () {
|
||||
try:
|
||||
defconfig = bb.fetch2.localpath('file://defconfig', d)
|
||||
except bb.fetch2.FetchError:
|
||||
return
|
||||
|
||||
try:
|
||||
configfile = open(defconfig)
|
||||
except IOError:
|
||||
return
|
||||
|
||||
if 'CONFIG_KERNEL_LZO=y\n' in configfile.readlines():
|
||||
depends = d.getVar('DEPENDS', False)
|
||||
d.setVar('DEPENDS', depends + ' lzop-native')
|
||||
do_configure_append() {
|
||||
if test -e scripts/Makefile.fwinst ; then
|
||||
sed -i -e "s:-m0644:-m 0644:g" scripts/Makefile.fwinst
|
||||
fi
|
||||
}
|
||||
|
||||
do_install_append() {
|
||||
oe_runmake headers_install INSTALL_HDR_PATH=${D}${exec_prefix}/src/linux-${KERNEL_VERSION} ARCH=$ARCH
|
||||
}
|
||||
|
||||
PACKAGES =+ "kernel-headers"
|
||||
FILES_kernel-headers = "${exec_prefix}/src/linux*"
|
||||
|
@ -1,37 +0,0 @@
|
||||
aufs3.0 kbuild patch
|
||||
|
||||
diff --git a/fs/Kconfig b/fs/Kconfig
|
||||
index 19891aa..b660b64 100644
|
||||
--- a/fs/Kconfig
|
||||
+++ b/fs/Kconfig
|
||||
@@ -208,5 +208,6 @@ source "fs/pstore/Kconfig"
|
||||
source "fs/sysv/Kconfig"
|
||||
source "fs/ufs/Kconfig"
|
||||
source "fs/exofs/Kconfig"
|
||||
+source "fs/aufs/Kconfig"
|
||||
|
||||
endif # MISC_FILESYSTEMS
|
||||
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
|
||||
index 01f6362..8b3b9f1 100644
|
||||
--- a/include/linux/Kbuild
|
||||
+++ b/include/linux/Kbuild
|
||||
@@ -65,6 +65,7 @@ header-y += atmppp.h
|
||||
header-y += atmsap.h
|
||||
header-y += atmsvc.h
|
||||
header-y += audit.h
|
||||
+header-y += aufs_type.h
|
||||
header-y += auto_fs.h
|
||||
header-y += auto_fs4.h
|
||||
header-y += auxvec.h
|
||||
diff --git a/fs/Makefile b/fs/Makefile
|
||||
index 2999b4d..60af3ce 100644
|
||||
--- a/fs/Makefile
|
||||
+++ b/fs/Makefile
|
||||
@@ -124,6 +124,7 @@ obj-$(CONFIG_GFS2_FS) += gfs2/
|
||||
obj-$(CONFIG_EXOFS_FS) += exofs/
|
||||
obj-$(CONFIG_CEPH_FS) += ceph/
|
||||
obj-$(CONFIG_PSTORE) += pstore/
|
||||
+obj-$(CONFIG_AUFS_FS) += aufs/
|
||||
|
||||
# Patched by YAFFS
|
||||
obj-$(CONFIG_YAFFS_FS) += yaffs2/
|
@ -1,70 +0,0 @@
|
||||
aufs3.0 base patch
|
||||
|
||||
diff --git a/fs/namei.c b/fs/namei.c
|
||||
index 14ab8d3..eb4aef1 100644
|
||||
--- a/fs/namei.c
|
||||
+++ b/fs/namei.c
|
||||
@@ -1697,7 +1697,7 @@ static struct dentry *__lookup_hash(struct qstr *name,
|
||||
* needs parent already locked. Doesn't follow mounts.
|
||||
* SMP-safe.
|
||||
*/
|
||||
-static struct dentry *lookup_hash(struct nameidata *nd)
|
||||
+struct dentry *lookup_hash(struct nameidata *nd)
|
||||
{
|
||||
return __lookup_hash(&nd->last, nd->path.dentry, nd);
|
||||
}
|
||||
diff --git a/fs/splice.c b/fs/splice.c
|
||||
index aa866d3..19afec6 100644
|
||||
--- a/fs/splice.c
|
||||
+++ b/fs/splice.c
|
||||
@@ -1085,8 +1085,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
|
||||
/*
|
||||
* Attempt to initiate a splice from pipe to file.
|
||||
*/
|
||||
-static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
|
||||
- loff_t *ppos, size_t len, unsigned int flags)
|
||||
+long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
|
||||
+ loff_t *ppos, size_t len, unsigned int flags)
|
||||
{
|
||||
ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
|
||||
loff_t *, size_t, unsigned int);
|
||||
@@ -1113,9 +1113,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
|
||||
/*
|
||||
* Attempt to initiate a splice from a file to a pipe.
|
||||
*/
|
||||
-static long do_splice_to(struct file *in, loff_t *ppos,
|
||||
- struct pipe_inode_info *pipe, size_t len,
|
||||
- unsigned int flags)
|
||||
+long do_splice_to(struct file *in, loff_t *ppos,
|
||||
+ struct pipe_inode_info *pipe, size_t len,
|
||||
+ unsigned int flags)
|
||||
{
|
||||
ssize_t (*splice_read)(struct file *, loff_t *,
|
||||
struct pipe_inode_info *, size_t, unsigned int);
|
||||
diff --git a/include/linux/namei.h b/include/linux/namei.h
|
||||
index eba45ea..21ed6c9 100644
|
||||
--- a/include/linux/namei.h
|
||||
+++ b/include/linux/namei.h
|
||||
@@ -82,6 +82,7 @@ extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
|
||||
extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
|
||||
int (*open)(struct inode *, struct file *));
|
||||
|
||||
+extern struct dentry *lookup_hash(struct nameidata *nd);
|
||||
extern struct dentry *lookup_one_len(const char *, struct dentry *, int);
|
||||
|
||||
extern int follow_down_one(struct path *);
|
||||
diff --git a/include/linux/splice.h b/include/linux/splice.h
|
||||
index 997c3b4..be9a153 100644
|
||||
--- a/include/linux/splice.h
|
||||
+++ b/include/linux/splice.h
|
||||
@@ -89,4 +89,10 @@ extern int splice_grow_spd(struct pipe_inode_info *, struct splice_pipe_desc *);
|
||||
extern void splice_shrink_spd(struct pipe_inode_info *,
|
||||
struct splice_pipe_desc *);
|
||||
|
||||
+extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
|
||||
+ loff_t *ppos, size_t len, unsigned int flags);
|
||||
+extern long do_splice_to(struct file *in, loff_t *ppos,
|
||||
+ struct pipe_inode_info *pipe, size_t len,
|
||||
+ unsigned int flags);
|
||||
+
|
||||
#endif
|
@ -1,205 +0,0 @@
|
||||
aufs3.0 proc_map patch
|
||||
|
||||
diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c
|
||||
index b1822dd..8b29ab7 100644
|
||||
--- a/fs/proc/nommu.c
|
||||
+++ b/fs/proc/nommu.c
|
||||
@@ -46,6 +46,10 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region)
|
||||
|
||||
if (file) {
|
||||
struct inode *inode = region->vm_file->f_path.dentry->d_inode;
|
||||
+ if (region->vm_prfile) {
|
||||
+ file = region->vm_prfile;
|
||||
+ inode = file->f_path.dentry->d_inode;
|
||||
+ }
|
||||
dev = inode->i_sb->s_dev;
|
||||
ino = inode->i_ino;
|
||||
}
|
||||
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
|
||||
index 25b6a88..47ed5d8 100644
|
||||
--- a/fs/proc/task_mmu.c
|
||||
+++ b/fs/proc/task_mmu.c
|
||||
@@ -220,6 +220,10 @@ static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
|
||||
|
||||
if (file) {
|
||||
struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
|
||||
+ if (vma->vm_prfile) {
|
||||
+ file = vma->vm_prfile;
|
||||
+ inode = file->f_path.dentry->d_inode;
|
||||
+ }
|
||||
dev = inode->i_sb->s_dev;
|
||||
ino = inode->i_ino;
|
||||
pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
|
||||
@@ -1001,6 +1005,8 @@ static int show_numa_map(struct seq_file *m, void *v)
|
||||
|
||||
if (file) {
|
||||
seq_printf(m, " file=");
|
||||
+ if (vma->vm_prfile)
|
||||
+ file = vma->vm_prfile;
|
||||
seq_path(m, &file->f_path, "\n\t= ");
|
||||
} else if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
|
||||
seq_printf(m, " heap");
|
||||
diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
|
||||
index 980de54..4ee031f 100644
|
||||
--- a/fs/proc/task_nommu.c
|
||||
+++ b/fs/proc/task_nommu.c
|
||||
@@ -148,6 +148,10 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma)
|
||||
|
||||
if (file) {
|
||||
struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
|
||||
+ if (vma->vm_prfile) {
|
||||
+ file = vma->vm_prfile;
|
||||
+ inode = file->f_path.dentry->d_inode;
|
||||
+ }
|
||||
dev = inode->i_sb->s_dev;
|
||||
ino = inode->i_ino;
|
||||
pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT;
|
||||
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
|
||||
index 027935c..0ade381 100644
|
||||
--- a/include/linux/mm_types.h
|
||||
+++ b/include/linux/mm_types.h
|
||||
@@ -117,6 +117,7 @@ struct vm_region {
|
||||
unsigned long vm_top; /* region allocated to here */
|
||||
unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */
|
||||
struct file *vm_file; /* the backing file or NULL */
|
||||
+ struct file *vm_prfile; /* the virtual backing file or NULL */
|
||||
|
||||
int vm_usage; /* region usage count (access under nommu_region_sem) */
|
||||
bool vm_icache_flushed : 1; /* true if the icache has been flushed for
|
||||
@@ -176,6 +177,7 @@ struct vm_area_struct {
|
||||
unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE
|
||||
units, *not* PAGE_CACHE_SIZE */
|
||||
struct file * vm_file; /* File we map to (can be NULL). */
|
||||
+ struct file *vm_prfile; /* shadow of vm_file */
|
||||
void * vm_private_data; /* was vm_pte (shared mem) */
|
||||
|
||||
#ifndef CONFIG_MMU
|
||||
diff --git a/kernel/fork.c b/kernel/fork.c
|
||||
index 0276c30..39d8176 100644
|
||||
--- a/kernel/fork.c
|
||||
+++ b/kernel/fork.c
|
||||
@@ -380,6 +380,8 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
|
||||
struct address_space *mapping = file->f_mapping;
|
||||
|
||||
get_file(file);
|
||||
+ if (tmp->vm_prfile)
|
||||
+ get_file(tmp->vm_prfile);
|
||||
if (tmp->vm_flags & VM_DENYWRITE)
|
||||
atomic_dec(&inode->i_writecount);
|
||||
mutex_lock(&mapping->i_mmap_mutex);
|
||||
diff --git a/mm/memory.c b/mm/memory.c
|
||||
index 9b8a01d..8902d06 100644
|
||||
--- a/mm/memory.c
|
||||
+++ b/mm/memory.c
|
||||
@@ -2577,6 +2577,8 @@ reuse:
|
||||
/* file_update_time outside page_lock */
|
||||
if (vma->vm_file)
|
||||
file_update_time(vma->vm_file);
|
||||
+ if (vma->vm_prfile)
|
||||
+ file_update_time(vma->vm_prfile);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -3257,6 +3259,8 @@ out:
|
||||
/* file_update_time outside page_lock */
|
||||
if (vma->vm_file)
|
||||
file_update_time(vma->vm_file);
|
||||
+ if (vma->vm_prfile)
|
||||
+ file_update_time(vma->vm_prfile);
|
||||
} else {
|
||||
unlock_page(vmf.page);
|
||||
if (anon)
|
||||
diff --git a/mm/mmap.c b/mm/mmap.c
|
||||
index d49736f..0290c8e 100644
|
||||
--- a/mm/mmap.c
|
||||
+++ b/mm/mmap.c
|
||||
@@ -240,6 +240,8 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
|
||||
vma->vm_ops->close(vma);
|
||||
if (vma->vm_file) {
|
||||
fput(vma->vm_file);
|
||||
+ if (vma->vm_prfile)
|
||||
+ fput(vma->vm_prfile);
|
||||
if (vma->vm_flags & VM_EXECUTABLE)
|
||||
removed_exe_file_vma(vma->vm_mm);
|
||||
}
|
||||
@@ -627,6 +629,8 @@ again: remove_next = 1 + (end > next->vm_end);
|
||||
if (remove_next) {
|
||||
if (file) {
|
||||
fput(file);
|
||||
+ if (vma->vm_prfile)
|
||||
+ fput(vma->vm_prfile);
|
||||
if (next->vm_flags & VM_EXECUTABLE)
|
||||
removed_exe_file_vma(mm);
|
||||
}
|
||||
@@ -1973,6 +1977,8 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
|
||||
|
||||
if (new->vm_file) {
|
||||
get_file(new->vm_file);
|
||||
+ if (new->vm_prfile)
|
||||
+ get_file(new->vm_prfile);
|
||||
if (vma->vm_flags & VM_EXECUTABLE)
|
||||
added_exe_file_vma(mm);
|
||||
}
|
||||
@@ -1997,6 +2003,8 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
|
||||
if (vma->vm_flags & VM_EXECUTABLE)
|
||||
removed_exe_file_vma(mm);
|
||||
fput(new->vm_file);
|
||||
+ if (new->vm_prfile)
|
||||
+ fput(new->vm_prfile);
|
||||
}
|
||||
unlink_anon_vmas(new);
|
||||
out_free_mpol:
|
||||
@@ -2364,6 +2372,8 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
|
||||
new_vma->vm_pgoff = pgoff;
|
||||
if (new_vma->vm_file) {
|
||||
get_file(new_vma->vm_file);
|
||||
+ if (new_vma->vm_prfile)
|
||||
+ get_file(new_vma->vm_prfile);
|
||||
if (vma->vm_flags & VM_EXECUTABLE)
|
||||
added_exe_file_vma(mm);
|
||||
}
|
||||
diff --git a/mm/nommu.c b/mm/nommu.c
|
||||
index 9edc897..72631ebe 100644
|
||||
--- a/mm/nommu.c
|
||||
+++ b/mm/nommu.c
|
||||
@@ -634,6 +634,8 @@ static void __put_nommu_region(struct vm_region *region)
|
||||
|
||||
if (region->vm_file)
|
||||
fput(region->vm_file);
|
||||
+ if (region->vm_prfile)
|
||||
+ fput(region->vm_prfile);
|
||||
|
||||
/* IO memory and memory shared directly out of the pagecache
|
||||
* from ramfs/tmpfs mustn't be released here */
|
||||
@@ -790,6 +792,8 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma)
|
||||
vma->vm_ops->close(vma);
|
||||
if (vma->vm_file) {
|
||||
fput(vma->vm_file);
|
||||
+ if (vma->vm_prfile)
|
||||
+ fput(vma->vm_prfile);
|
||||
if (vma->vm_flags & VM_EXECUTABLE)
|
||||
removed_exe_file_vma(mm);
|
||||
}
|
||||
@@ -1363,6 +1367,8 @@ unsigned long do_mmap_pgoff(struct file *file,
|
||||
}
|
||||
}
|
||||
fput(region->vm_file);
|
||||
+ if (region->vm_prfile)
|
||||
+ fput(region->vm_prfile);
|
||||
kmem_cache_free(vm_region_jar, region);
|
||||
region = pregion;
|
||||
result = start;
|
||||
@@ -1439,9 +1445,13 @@ error_just_free:
|
||||
error:
|
||||
if (region->vm_file)
|
||||
fput(region->vm_file);
|
||||
+ if (region->vm_prfile)
|
||||
+ fput(region->vm_prfile);
|
||||
kmem_cache_free(vm_region_jar, region);
|
||||
if (vma->vm_file)
|
||||
fput(vma->vm_file);
|
||||
+ if (vma->vm_prfile)
|
||||
+ fput(vma->vm_prfile);
|
||||
if (vma->vm_flags & VM_EXECUTABLE)
|
||||
removed_exe_file_vma(vma->vm_mm);
|
||||
kmem_cache_free(vm_area_cachep, vma);
|
@ -1,257 +0,0 @@
|
||||
aufs3.0 standalone patch
|
||||
|
||||
diff --git a/fs/file_table.c b/fs/file_table.c
|
||||
index 01e4c1e..0e800e2 100644
|
||||
--- a/fs/file_table.c
|
||||
+++ b/fs/file_table.c
|
||||
@@ -443,6 +443,8 @@ void file_sb_list_del(struct file *file)
|
||||
}
|
||||
}
|
||||
|
||||
+EXPORT_SYMBOL(file_sb_list_del);
|
||||
+
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
/*
|
||||
diff --git a/fs/inode.c b/fs/inode.c
|
||||
index 43566d1..4291eae 100644
|
||||
--- a/fs/inode.c
|
||||
+++ b/fs/inode.c
|
||||
@@ -69,6 +69,7 @@ static DEFINE_SPINLOCK(inode_lru_lock);
|
||||
|
||||
__cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_sb_list_lock);
|
||||
__cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_wb_list_lock);
|
||||
+EXPORT_SYMBOL(inode_sb_list_lock);
|
||||
|
||||
/*
|
||||
* iprune_sem provides exclusion between the icache shrinking and the
|
||||
diff --git a/fs/namei.c b/fs/namei.c
|
||||
index eb4aef1..66d04c6 100644
|
||||
--- a/fs/namei.c
|
||||
+++ b/fs/namei.c
|
||||
@@ -365,6 +365,7 @@ int deny_write_access(struct file * file)
|
||||
|
||||
return 0;
|
||||
}
|
||||
+EXPORT_SYMBOL(deny_write_access);
|
||||
|
||||
/**
|
||||
* path_get - get a reference to a path
|
||||
@@ -1701,6 +1702,7 @@ struct dentry *lookup_hash(struct nameidata *nd)
|
||||
{
|
||||
return __lookup_hash(&nd->last, nd->path.dentry, nd);
|
||||
}
|
||||
+EXPORT_SYMBOL(lookup_hash);
|
||||
|
||||
/**
|
||||
* lookup_one_len - filesystem helper to lookup single pathname component
|
||||
diff --git a/fs/namespace.c b/fs/namespace.c
|
||||
index fe59bd1..7d3843f 100644
|
||||
--- a/fs/namespace.c
|
||||
+++ b/fs/namespace.c
|
||||
@@ -1508,6 +1508,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
+EXPORT_SYMBOL(iterate_mounts);
|
||||
|
||||
static void cleanup_group_ids(struct vfsmount *mnt, struct vfsmount *end)
|
||||
{
|
||||
diff --git a/fs/notify/group.c b/fs/notify/group.c
|
||||
index d309f38..f0e9568 100644
|
||||
--- a/fs/notify/group.c
|
||||
+++ b/fs/notify/group.c
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <linux/srcu.h>
|
||||
#include <linux/rculist.h>
|
||||
#include <linux/wait.h>
|
||||
+#include <linux/module.h>
|
||||
|
||||
#include <linux/fsnotify_backend.h>
|
||||
#include "fsnotify.h"
|
||||
@@ -70,6 +71,7 @@ void fsnotify_put_group(struct fsnotify_group *group)
|
||||
if (atomic_dec_and_test(&group->refcnt))
|
||||
fsnotify_destroy_group(group);
|
||||
}
|
||||
+EXPORT_SYMBOL(fsnotify_put_group);
|
||||
|
||||
/*
|
||||
* Create a new fsnotify_group and hold a reference for the group returned.
|
||||
@@ -102,3 +104,4 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops)
|
||||
|
||||
return group;
|
||||
}
|
||||
+EXPORT_SYMBOL(fsnotify_alloc_group);
|
||||
diff --git a/fs/notify/mark.c b/fs/notify/mark.c
|
||||
index 252ab1f..2199b9b 100644
|
||||
--- a/fs/notify/mark.c
|
||||
+++ b/fs/notify/mark.c
|
||||
@@ -112,6 +112,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
|
||||
if (atomic_dec_and_test(&mark->refcnt))
|
||||
mark->free_mark(mark);
|
||||
}
|
||||
+EXPORT_SYMBOL(fsnotify_put_mark);
|
||||
|
||||
/*
|
||||
* Any time a mark is getting freed we end up here.
|
||||
@@ -189,6 +190,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark)
|
||||
if (unlikely(atomic_dec_and_test(&group->num_marks)))
|
||||
fsnotify_final_destroy_group(group);
|
||||
}
|
||||
+EXPORT_SYMBOL(fsnotify_destroy_mark);
|
||||
|
||||
void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask)
|
||||
{
|
||||
@@ -276,6 +278,7 @@ err:
|
||||
|
||||
return ret;
|
||||
}
|
||||
+EXPORT_SYMBOL(fsnotify_add_mark);
|
||||
|
||||
/*
|
||||
* clear any marks in a group in which mark->flags & flags is true
|
||||
@@ -331,6 +334,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark,
|
||||
atomic_set(&mark->refcnt, 1);
|
||||
mark->free_mark = free_mark;
|
||||
}
|
||||
+EXPORT_SYMBOL(fsnotify_init_mark);
|
||||
|
||||
static int fsnotify_mark_destroy(void *ignored)
|
||||
{
|
||||
diff --git a/fs/open.c b/fs/open.c
|
||||
index b52cf01..c1b341c 100644
|
||||
--- a/fs/open.c
|
||||
+++ b/fs/open.c
|
||||
@@ -60,6 +60,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
|
||||
mutex_unlock(&dentry->d_inode->i_mutex);
|
||||
return ret;
|
||||
}
|
||||
+EXPORT_SYMBOL(do_truncate);
|
||||
|
||||
static long do_sys_truncate(const char __user *pathname, loff_t length)
|
||||
{
|
||||
diff --git a/fs/splice.c b/fs/splice.c
|
||||
index 19afec6..11f07f86 100644
|
||||
--- a/fs/splice.c
|
||||
+++ b/fs/splice.c
|
||||
@@ -1109,6 +1109,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
|
||||
|
||||
return splice_write(pipe, out, ppos, len, flags);
|
||||
}
|
||||
+EXPORT_SYMBOL(do_splice_from);
|
||||
|
||||
/*
|
||||
* Attempt to initiate a splice from a file to a pipe.
|
||||
@@ -1135,6 +1136,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
|
||||
|
||||
return splice_read(in, ppos, pipe, len, flags);
|
||||
}
|
||||
+EXPORT_SYMBOL(do_splice_to);
|
||||
|
||||
/**
|
||||
* splice_direct_to_actor - splices data directly between two non-pipes
|
||||
diff --git a/security/commoncap.c b/security/commoncap.c
|
||||
index a93b3b7..024282c 100644
|
||||
--- a/security/commoncap.c
|
||||
+++ b/security/commoncap.c
|
||||
@@ -971,3 +971,4 @@ int cap_file_mmap(struct file *file, unsigned long reqprot,
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
+EXPORT_SYMBOL(cap_file_mmap);
|
||||
diff --git a/security/device_cgroup.c b/security/device_cgroup.c
|
||||
index 1be6826..215278c 100644
|
||||
--- a/security/device_cgroup.c
|
||||
+++ b/security/device_cgroup.c
|
||||
@@ -508,6 +508,7 @@ found:
|
||||
|
||||
return -EPERM;
|
||||
}
|
||||
+EXPORT_SYMBOL(__devcgroup_inode_permission);
|
||||
|
||||
int devcgroup_inode_mknod(int mode, dev_t dev)
|
||||
{
|
||||
diff --git a/security/security.c b/security/security.c
|
||||
index 4ba6d4c..9f64bb8 100644
|
||||
--- a/security/security.c
|
||||
+++ b/security/security.c
|
||||
@@ -373,6 +373,7 @@ int security_path_rmdir(struct path *dir, struct dentry *dentry)
|
||||
return 0;
|
||||
return security_ops->path_rmdir(dir, dentry);
|
||||
}
|
||||
+EXPORT_SYMBOL(security_path_rmdir);
|
||||
|
||||
int security_path_unlink(struct path *dir, struct dentry *dentry)
|
||||
{
|
||||
@@ -389,6 +390,7 @@ int security_path_symlink(struct path *dir, struct dentry *dentry,
|
||||
return 0;
|
||||
return security_ops->path_symlink(dir, dentry, old_name);
|
||||
}
|
||||
+EXPORT_SYMBOL(security_path_symlink);
|
||||
|
||||
int security_path_link(struct dentry *old_dentry, struct path *new_dir,
|
||||
struct dentry *new_dentry)
|
||||
@@ -397,6 +399,7 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir,
|
||||
return 0;
|
||||
return security_ops->path_link(old_dentry, new_dir, new_dentry);
|
||||
}
|
||||
+EXPORT_SYMBOL(security_path_link);
|
||||
|
||||
int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
|
||||
struct path *new_dir, struct dentry *new_dentry)
|
||||
@@ -415,6 +418,7 @@ int security_path_truncate(struct path *path)
|
||||
return 0;
|
||||
return security_ops->path_truncate(path);
|
||||
}
|
||||
+EXPORT_SYMBOL(security_path_truncate);
|
||||
|
||||
int security_path_chmod(struct dentry *dentry, struct vfsmount *mnt,
|
||||
mode_t mode)
|
||||
@@ -423,6 +427,7 @@ int security_path_chmod(struct dentry *dentry, struct vfsmount *mnt,
|
||||
return 0;
|
||||
return security_ops->path_chmod(dentry, mnt, mode);
|
||||
}
|
||||
+EXPORT_SYMBOL(security_path_chmod);
|
||||
|
||||
int security_path_chown(struct path *path, uid_t uid, gid_t gid)
|
||||
{
|
||||
@@ -430,6 +435,7 @@ int security_path_chown(struct path *path, uid_t uid, gid_t gid)
|
||||
return 0;
|
||||
return security_ops->path_chown(path, uid, gid);
|
||||
}
|
||||
+EXPORT_SYMBOL(security_path_chown);
|
||||
|
||||
int security_path_chroot(struct path *path)
|
||||
{
|
||||
@@ -506,6 +512,7 @@ int security_inode_readlink(struct dentry *dentry)
|
||||
return 0;
|
||||
return security_ops->inode_readlink(dentry);
|
||||
}
|
||||
+EXPORT_SYMBOL(security_inode_readlink);
|
||||
|
||||
int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd)
|
||||
{
|
||||
@@ -520,6 +527,7 @@ int security_inode_permission(struct inode *inode, int mask)
|
||||
return 0;
|
||||
return security_ops->inode_permission(inode, mask, 0);
|
||||
}
|
||||
+EXPORT_SYMBOL(security_inode_permission);
|
||||
|
||||
int security_inode_exec_permission(struct inode *inode, unsigned int flags)
|
||||
{
|
||||
@@ -626,6 +634,7 @@ int security_file_permission(struct file *file, int mask)
|
||||
|
||||
return fsnotify_perm(file, mask);
|
||||
}
|
||||
+EXPORT_SYMBOL(security_file_permission);
|
||||
|
||||
int security_file_alloc(struct file *file)
|
||||
{
|
||||
@@ -653,6 +662,7 @@ int security_file_mmap(struct file *file, unsigned long reqprot,
|
||||
return ret;
|
||||
return ima_file_mmap(file, prot);
|
||||
}
|
||||
+EXPORT_SYMBOL(security_file_mmap);
|
||||
|
||||
int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
|
||||
unsigned long prot)
|
@ -1,233 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2012 Junjiro R. Okajima
|
||||
*
|
||||
* This program, aufs is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef __AUFS_TYPE_H__
|
||||
#define __AUFS_TYPE_H__
|
||||
|
||||
#define AUFS_NAME "aufs"
|
||||
|
||||
#ifdef __KERNEL__
|
||||
/*
|
||||
* define it before including all other headers.
|
||||
* sched.h may use pr_* macros before defining "current", so define the
|
||||
* no-current version first, and re-define later.
|
||||
*/
|
||||
#define pr_fmt(fmt) AUFS_NAME " %s:%d: " fmt, __func__, __LINE__
|
||||
#include <linux/sched.h>
|
||||
#undef pr_fmt
|
||||
#define pr_fmt(fmt) AUFS_NAME " %s:%d:%s[%d]: " fmt, \
|
||||
__func__, __LINE__, current->comm, current->pid
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#include <linux/limits.h>
|
||||
|
||||
#define AUFS_VERSION "3.0-20120827"
|
||||
|
||||
/* todo? move this to linux-2.6.19/include/magic.h */
|
||||
#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#ifdef CONFIG_AUFS_BRANCH_MAX_127
|
||||
typedef int8_t aufs_bindex_t;
|
||||
#define AUFS_BRANCH_MAX 127
|
||||
#else
|
||||
typedef int16_t aufs_bindex_t;
|
||||
#ifdef CONFIG_AUFS_BRANCH_MAX_511
|
||||
#define AUFS_BRANCH_MAX 511
|
||||
#elif defined(CONFIG_AUFS_BRANCH_MAX_1023)
|
||||
#define AUFS_BRANCH_MAX 1023
|
||||
#elif defined(CONFIG_AUFS_BRANCH_MAX_32767)
|
||||
#define AUFS_BRANCH_MAX 32767
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#ifndef AUFS_BRANCH_MAX
|
||||
#error unknown CONFIG_AUFS_BRANCH_MAX value
|
||||
#endif
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#define AUFS_FSTYPE AUFS_NAME
|
||||
|
||||
#define AUFS_ROOT_INO 2
|
||||
#define AUFS_FIRST_INO 11
|
||||
|
||||
#define AUFS_WH_PFX ".wh."
|
||||
#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1)
|
||||
#define AUFS_WH_TMP_LEN 4
|
||||
/* a limit for rmdir/rename a dir */
|
||||
#define AUFS_MAX_NAMELEN (NAME_MAX \
|
||||
- AUFS_WH_PFX_LEN * 2 /* doubly whiteouted */\
|
||||
- 1 /* dot */\
|
||||
- AUFS_WH_TMP_LEN) /* hex */
|
||||
#define AUFS_XINO_FNAME "." AUFS_NAME ".xino"
|
||||
#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME
|
||||
#define AUFS_XINO_TRUNC_INIT 64 /* blocks */
|
||||
#define AUFS_XINO_TRUNC_STEP 4 /* blocks */
|
||||
#define AUFS_DIRWH_DEF 3
|
||||
#define AUFS_RDCACHE_DEF 10 /* seconds */
|
||||
#define AUFS_RDCACHE_MAX 3600 /* seconds */
|
||||
#define AUFS_RDBLK_DEF 512 /* bytes */
|
||||
#define AUFS_RDHASH_DEF 32
|
||||
#define AUFS_WKQ_NAME AUFS_NAME "d"
|
||||
#define AUFS_MFS_DEF_SEC 30 /* seconds */
|
||||
#define AUFS_MFS_MAX_SEC 3600 /* seconds */
|
||||
#define AUFS_PLINK_WARN 100 /* number of plinks */
|
||||
|
||||
/* pseudo-link maintenace under /proc */
|
||||
#define AUFS_PLINK_MAINT_NAME "plink_maint"
|
||||
#define AUFS_PLINK_MAINT_DIR "fs/" AUFS_NAME
|
||||
#define AUFS_PLINK_MAINT_PATH AUFS_PLINK_MAINT_DIR "/" AUFS_PLINK_MAINT_NAME
|
||||
|
||||
#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */
|
||||
#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME
|
||||
|
||||
#define AUFS_BASE_NAME AUFS_WH_PFX AUFS_NAME
|
||||
#define AUFS_PLINKDIR_NAME AUFS_WH_PFX "plnk"
|
||||
#define AUFS_ORPHDIR_NAME AUFS_WH_PFX "orph"
|
||||
|
||||
/* doubly whiteouted */
|
||||
#define AUFS_WH_BASE AUFS_WH_PFX AUFS_BASE_NAME
|
||||
#define AUFS_WH_PLINKDIR AUFS_WH_PFX AUFS_PLINKDIR_NAME
|
||||
#define AUFS_WH_ORPHDIR AUFS_WH_PFX AUFS_ORPHDIR_NAME
|
||||
|
||||
/* branch permissions and attributes */
|
||||
#define AUFS_BRPERM_RW "rw"
|
||||
#define AUFS_BRPERM_RO "ro"
|
||||
#define AUFS_BRPERM_RR "rr"
|
||||
#define AUFS_BRRATTR_WH "wh"
|
||||
#define AUFS_BRWATTR_NLWH "nolwh"
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/* ioctl */
|
||||
enum {
|
||||
/* readdir in userspace */
|
||||
AuCtl_RDU,
|
||||
AuCtl_RDU_INO,
|
||||
|
||||
/* pathconf wrapper */
|
||||
AuCtl_WBR_FD,
|
||||
|
||||
/* busy inode */
|
||||
AuCtl_IBUSY
|
||||
};
|
||||
|
||||
/* borrowed from linux/include/linux/kernel.h */
|
||||
#ifndef ALIGN
|
||||
#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1)
|
||||
#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask))
|
||||
#endif
|
||||
|
||||
/* borrowed from linux/include/linux/compiler-gcc3.h */
|
||||
#ifndef __aligned
|
||||
#define __aligned(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#ifndef __packed
|
||||
#define __packed __attribute__((packed))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
struct au_rdu_cookie {
|
||||
uint64_t h_pos;
|
||||
int16_t bindex;
|
||||
uint8_t flags;
|
||||
uint8_t pad;
|
||||
uint32_t generation;
|
||||
} __aligned(8);
|
||||
|
||||
struct au_rdu_ent {
|
||||
uint64_t ino;
|
||||
int16_t bindex;
|
||||
uint8_t type;
|
||||
uint8_t nlen;
|
||||
uint8_t wh;
|
||||
char name[0];
|
||||
} __aligned(8);
|
||||
|
||||
static inline int au_rdu_len(int nlen)
|
||||
{
|
||||
/* include the terminating NULL */
|
||||
return ALIGN(sizeof(struct au_rdu_ent) + nlen + 1,
|
||||
sizeof(uint64_t));
|
||||
}
|
||||
|
||||
union au_rdu_ent_ul {
|
||||
struct au_rdu_ent __user *e;
|
||||
uint64_t ul;
|
||||
};
|
||||
|
||||
enum {
|
||||
AufsCtlRduV_SZ,
|
||||
AufsCtlRduV_End
|
||||
};
|
||||
|
||||
struct aufs_rdu {
|
||||
/* input */
|
||||
union {
|
||||
uint64_t sz; /* AuCtl_RDU */
|
||||
uint64_t nent; /* AuCtl_RDU_INO */
|
||||
};
|
||||
union au_rdu_ent_ul ent;
|
||||
uint16_t verify[AufsCtlRduV_End];
|
||||
|
||||
/* input/output */
|
||||
uint32_t blk;
|
||||
|
||||
/* output */
|
||||
union au_rdu_ent_ul tail;
|
||||
/* number of entries which were added in a single call */
|
||||
uint64_t rent;
|
||||
uint8_t full;
|
||||
uint8_t shwh;
|
||||
|
||||
struct au_rdu_cookie cookie;
|
||||
} __aligned(8);
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
struct aufs_wbr_fd {
|
||||
uint32_t oflags;
|
||||
int16_t brid;
|
||||
} __aligned(8);
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
struct aufs_ibusy {
|
||||
uint64_t ino, h_ino;
|
||||
int16_t bindex;
|
||||
} __aligned(8);
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#define AuCtlType 'A'
|
||||
#define AUFS_CTL_RDU _IOWR(AuCtlType, AuCtl_RDU, struct aufs_rdu)
|
||||
#define AUFS_CTL_RDU_INO _IOWR(AuCtlType, AuCtl_RDU_INO, struct aufs_rdu)
|
||||
#define AUFS_CTL_WBR_FD _IOW(AuCtlType, AuCtl_WBR_FD, \
|
||||
struct aufs_wbr_fd)
|
||||
#define AUFS_CTL_IBUSY _IOWR(AuCtlType, AuCtl_IBUSY, struct aufs_ibusy)
|
||||
|
||||
#endif /* __AUFS_TYPE_H__ */
|
747
recipes-kernel/linux/linux/defconfig
Normal file
747
recipes-kernel/linux/linux/defconfig
Normal file
@ -0,0 +1,747 @@
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_POSIX_MQUEUE=y
|
||||
CONFIG_FHANDLE=y
|
||||
CONFIG_NO_HZ=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_CGROUPS=y
|
||||
CONFIG_BSD_PROCESS_ACCT=y
|
||||
CONFIG_BSD_PROCESS_ACCT_V3=y
|
||||
CONFIG_TASKSTATS=y
|
||||
CONFIG_TASK_DELAY_ACCT=y
|
||||
CONFIG_TASK_XACCT=y
|
||||
CONFIG_TASK_IO_ACCOUNTING=y
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_SCHED_AUTOGROUP=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
CONFIG_BPF_SYSCALL=y
|
||||
CONFIG_PERF_EVENTS=y
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_BLK_DEV_BSGLIB=y
|
||||
CONFIG_BLK_DEV_INTEGRITY=y
|
||||
CONFIG_PARTITION_ADVANCED=y
|
||||
CONFIG_MAC_PARTITION=y
|
||||
CONFIG_LDM_PARTITION=y
|
||||
CONFIG_ARCH_SUNXI=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_NR_CPUS=8
|
||||
CONFIG_AEABI=y
|
||||
CONFIG_HIGHMEM=y
|
||||
CONFIG_HIGHPTE=y
|
||||
CONFIG_ZBOOT_ROM_TEXT=0x0
|
||||
CONFIG_ZBOOT_ROM_BSS=0x0
|
||||
CONFIG_ARM_APPENDED_DTB=y
|
||||
CONFIG_ARM_ATAG_DTB_COMPAT=y
|
||||
CONFIG_CPU_FREQ=y
|
||||
CONFIG_CPU_FREQ_STAT_DETAILS=y
|
||||
CONFIG_CPU_FREQ_GOV_POWERSAVE=m
|
||||
CONFIG_CPU_FREQ_GOV_USERSPACE=m
|
||||
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
|
||||
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
|
||||
CONFIG_CPUFREQ_DT=y
|
||||
CONFIG_CPU_IDLE=y
|
||||
CONFIG_ARM_CPUIDLE=y
|
||||
CONFIG_VFP=y
|
||||
CONFIG_NEON=y
|
||||
CONFIG_KERNEL_MODE_NEON=y
|
||||
CONFIG_HIBERNATION=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_PACKET_DIAG=m
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_UNIX_DIAG=m
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
CONFIG_IP_ADVANCED_ROUTER=y
|
||||
CONFIG_IP_FIB_TRIE_STATS=y
|
||||
CONFIG_IP_MULTIPLE_TABLES=y
|
||||
CONFIG_IP_ROUTE_MULTIPATH=y
|
||||
CONFIG_IP_ROUTE_VERBOSE=y
|
||||
CONFIG_IP_PNP=y
|
||||
CONFIG_IP_PNP_DHCP=y
|
||||
CONFIG_IP_PNP_BOOTP=y
|
||||
CONFIG_NET_IPIP=m
|
||||
CONFIG_NET_IPGRE_DEMUX=m
|
||||
CONFIG_NET_IPGRE=m
|
||||
CONFIG_NET_FOU=m
|
||||
CONFIG_INET_AH=m
|
||||
CONFIG_INET_ESP=m
|
||||
CONFIG_INET_IPCOMP=m
|
||||
CONFIG_INET_XFRM_MODE_TRANSPORT=m
|
||||
CONFIG_INET_XFRM_MODE_TUNNEL=m
|
||||
CONFIG_INET_XFRM_MODE_BEET=m
|
||||
CONFIG_INET_LRO=m
|
||||
CONFIG_INET_DIAG=m
|
||||
CONFIG_INET_UDP_DIAG=m
|
||||
CONFIG_TCP_CONG_ADVANCED=y
|
||||
CONFIG_TCP_CONG_HSTCP=m
|
||||
CONFIG_TCP_CONG_HYBLA=m
|
||||
CONFIG_TCP_CONG_SCALABLE=m
|
||||
CONFIG_TCP_CONG_LP=m
|
||||
CONFIG_TCP_CONG_VENO=m
|
||||
CONFIG_TCP_CONG_YEAH=m
|
||||
CONFIG_TCP_CONG_ILLINOIS=m
|
||||
CONFIG_TCP_CONG_DCTCP=m
|
||||
CONFIG_INET6_AH=m
|
||||
CONFIG_INET6_ESP=m
|
||||
CONFIG_INET6_IPCOMP=m
|
||||
CONFIG_IPV6_MIP6=m
|
||||
CONFIG_IPV6_VTI=m
|
||||
CONFIG_IPV6_GRE=m
|
||||
CONFIG_IPV6_MULTIPLE_TABLES=y
|
||||
CONFIG_IPV6_SUBTREES=y
|
||||
CONFIG_IPV6_MROUTE=y
|
||||
CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y
|
||||
CONFIG_IPV6_PIMSM_V2=y
|
||||
CONFIG_NETFILTER=y
|
||||
CONFIG_NF_CONNTRACK=m
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y
|
||||
CONFIG_NF_CONNTRACK_TIMEOUT=y
|
||||
CONFIG_NF_CONNTRACK_TIMESTAMP=y
|
||||
CONFIG_NF_CT_PROTO_DCCP=m
|
||||
CONFIG_NF_CT_PROTO_SCTP=m
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=m
|
||||
CONFIG_NF_CONNTRACK_AMANDA=m
|
||||
CONFIG_NF_CONNTRACK_FTP=m
|
||||
CONFIG_NF_CONNTRACK_H323=m
|
||||
CONFIG_NF_CONNTRACK_IRC=m
|
||||
CONFIG_NF_CONNTRACK_NETBIOS_NS=m
|
||||
CONFIG_NF_CONNTRACK_SNMP=m
|
||||
CONFIG_NF_CONNTRACK_PPTP=m
|
||||
CONFIG_NF_CONNTRACK_SANE=m
|
||||
CONFIG_NF_CONNTRACK_SIP=m
|
||||
CONFIG_NF_CONNTRACK_TFTP=m
|
||||
CONFIG_NF_CT_NETLINK=m
|
||||
CONFIG_NF_CT_NETLINK_TIMEOUT=m
|
||||
CONFIG_NF_CT_NETLINK_HELPER=m
|
||||
CONFIG_NETFILTER_NETLINK_QUEUE_CT=y
|
||||
CONFIG_NF_TABLES=m
|
||||
CONFIG_NF_TABLES_INET=m
|
||||
CONFIG_NFT_EXTHDR=m
|
||||
CONFIG_NFT_META=m
|
||||
CONFIG_NFT_CT=m
|
||||
CONFIG_NFT_RBTREE=m
|
||||
CONFIG_NFT_HASH=m
|
||||
CONFIG_NFT_COUNTER=m
|
||||
CONFIG_NFT_LOG=m
|
||||
CONFIG_NFT_LIMIT=m
|
||||
CONFIG_NFT_MASQ=m
|
||||
CONFIG_NFT_REDIR=m
|
||||
CONFIG_NFT_NAT=m
|
||||
CONFIG_NFT_QUEUE=m
|
||||
CONFIG_NFT_REJECT=m
|
||||
CONFIG_NFT_COMPAT=m
|
||||
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
|
||||
CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_HMARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
|
||||
CONFIG_NETFILTER_XT_TARGET_LED=m
|
||||
CONFIG_NETFILTER_XT_TARGET_LOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TEE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
|
||||
CONFIG_NETFILTER_XT_MATCH_BPF=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CGROUP=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
|
||||
CONFIG_NETFILTER_XT_MATCH_COMMENT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CPU=m
|
||||
CONFIG_NETFILTER_XT_MATCH_DCCP=m
|
||||
CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
|
||||
CONFIG_NETFILTER_XT_MATCH_DSCP=m
|
||||
CONFIG_NETFILTER_XT_MATCH_ESP=m
|
||||
CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_HELPER=m
|
||||
CONFIG_NETFILTER_XT_MATCH_IPCOMP=m
|
||||
CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
|
||||
CONFIG_NETFILTER_XT_MATCH_LENGTH=m
|
||||
CONFIG_NETFILTER_XT_MATCH_LIMIT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_MAC=m
|
||||
CONFIG_NETFILTER_XT_MATCH_MARK=m
|
||||
CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_NFACCT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_OSF=m
|
||||
CONFIG_NETFILTER_XT_MATCH_OWNER=m
|
||||
CONFIG_NETFILTER_XT_MATCH_POLICY=m
|
||||
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
|
||||
CONFIG_NETFILTER_XT_MATCH_QUOTA=m
|
||||
CONFIG_NETFILTER_XT_MATCH_RATEEST=m
|
||||
CONFIG_NETFILTER_XT_MATCH_REALM=m
|
||||
CONFIG_NETFILTER_XT_MATCH_RECENT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_SCTP=m
|
||||
CONFIG_NETFILTER_XT_MATCH_SOCKET=m
|
||||
CONFIG_NETFILTER_XT_MATCH_STATE=m
|
||||
CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
|
||||
CONFIG_NETFILTER_XT_MATCH_STRING=m
|
||||
CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
|
||||
CONFIG_NETFILTER_XT_MATCH_TIME=m
|
||||
CONFIG_NETFILTER_XT_MATCH_U32=m
|
||||
CONFIG_IP_VS=m
|
||||
CONFIG_IP_VS_IPV6=y
|
||||
CONFIG_IP_VS_DEBUG=y
|
||||
CONFIG_IP_VS_PROTO_TCP=y
|
||||
CONFIG_IP_VS_PROTO_UDP=y
|
||||
CONFIG_IP_VS_PROTO_ESP=y
|
||||
CONFIG_IP_VS_PROTO_AH=y
|
||||
CONFIG_IP_VS_PROTO_SCTP=y
|
||||
CONFIG_IP_VS_RR=m
|
||||
CONFIG_IP_VS_WRR=m
|
||||
CONFIG_IP_VS_LC=m
|
||||
CONFIG_IP_VS_WLC=m
|
||||
CONFIG_IP_VS_FO=m
|
||||
CONFIG_IP_VS_LBLC=m
|
||||
CONFIG_IP_VS_LBLCR=m
|
||||
CONFIG_IP_VS_DH=m
|
||||
CONFIG_IP_VS_SH=m
|
||||
CONFIG_IP_VS_SED=m
|
||||
CONFIG_IP_VS_NQ=m
|
||||
CONFIG_IP_VS_FTP=m
|
||||
CONFIG_IP_VS_PE_SIP=m
|
||||
CONFIG_NF_CONNTRACK_IPV4=m
|
||||
CONFIG_NFT_CHAIN_ROUTE_IPV4=m
|
||||
CONFIG_NF_TABLES_ARP=m
|
||||
CONFIG_NF_LOG_ARP=m
|
||||
CONFIG_NFT_CHAIN_NAT_IPV4=m
|
||||
CONFIG_NFT_MASQ_IPV4=m
|
||||
CONFIG_NFT_REDIR_IPV4=m
|
||||
CONFIG_IP_NF_IPTABLES=m
|
||||
CONFIG_IP_NF_MATCH_AH=m
|
||||
CONFIG_IP_NF_MATCH_ECN=m
|
||||
CONFIG_IP_NF_MATCH_TTL=m
|
||||
CONFIG_IP_NF_FILTER=m
|
||||
CONFIG_IP_NF_TARGET_REJECT=m
|
||||
CONFIG_IP_NF_TARGET_SYNPROXY=m
|
||||
CONFIG_IP_NF_NAT=m
|
||||
CONFIG_IP_NF_TARGET_MASQUERADE=m
|
||||
CONFIG_IP_NF_TARGET_NETMAP=m
|
||||
CONFIG_IP_NF_TARGET_REDIRECT=m
|
||||
CONFIG_IP_NF_MANGLE=m
|
||||
CONFIG_IP_NF_TARGET_CLUSTERIP=m
|
||||
CONFIG_IP_NF_TARGET_ECN=m
|
||||
CONFIG_IP_NF_TARGET_TTL=m
|
||||
CONFIG_IP_NF_RAW=m
|
||||
CONFIG_IP_NF_ARPTABLES=m
|
||||
CONFIG_IP_NF_ARPFILTER=m
|
||||
CONFIG_IP_NF_ARP_MANGLE=m
|
||||
CONFIG_NF_CONNTRACK_IPV6=m
|
||||
CONFIG_NFT_CHAIN_ROUTE_IPV6=m
|
||||
CONFIG_NFT_CHAIN_NAT_IPV6=m
|
||||
CONFIG_NFT_MASQ_IPV6=m
|
||||
CONFIG_NFT_REDIR_IPV6=m
|
||||
CONFIG_IP6_NF_MATCH_AH=m
|
||||
CONFIG_IP6_NF_MATCH_EUI64=m
|
||||
CONFIG_IP6_NF_MATCH_FRAG=m
|
||||
CONFIG_IP6_NF_MATCH_OPTS=m
|
||||
CONFIG_IP6_NF_MATCH_HL=m
|
||||
CONFIG_IP6_NF_MATCH_IPV6HEADER=m
|
||||
CONFIG_IP6_NF_MATCH_MH=m
|
||||
CONFIG_IP6_NF_MATCH_RPFILTER=m
|
||||
CONFIG_IP6_NF_MATCH_RT=m
|
||||
CONFIG_IP6_NF_TARGET_HL=m
|
||||
CONFIG_IP6_NF_FILTER=m
|
||||
CONFIG_IP6_NF_TARGET_REJECT=m
|
||||
CONFIG_IP6_NF_TARGET_SYNPROXY=m
|
||||
CONFIG_IP6_NF_MANGLE=m
|
||||
CONFIG_IP6_NF_RAW=m
|
||||
CONFIG_IP6_NF_NAT=m
|
||||
CONFIG_IP6_NF_TARGET_MASQUERADE=m
|
||||
CONFIG_IP6_NF_TARGET_NPT=m
|
||||
CONFIG_L2TP=m
|
||||
CONFIG_BRIDGE=m
|
||||
CONFIG_BRIDGE_VLAN_FILTERING=y
|
||||
CONFIG_VLAN_8021Q=m
|
||||
CONFIG_VLAN_8021Q_GVRP=y
|
||||
CONFIG_VLAN_8021Q_MVRP=y
|
||||
CONFIG_6LOWPAN=m
|
||||
CONFIG_IEEE802154=m
|
||||
CONFIG_IEEE802154_6LOWPAN=m
|
||||
CONFIG_MAC802154=m
|
||||
CONFIG_NET_SCHED=y
|
||||
CONFIG_NET_SCH_CBQ=m
|
||||
CONFIG_NET_SCH_HTB=y
|
||||
CONFIG_NET_SCH_HFSC=m
|
||||
CONFIG_NET_SCH_PRIO=m
|
||||
CONFIG_NET_SCH_MULTIQ=m
|
||||
CONFIG_NET_SCH_RED=m
|
||||
CONFIG_NET_SCH_SFB=m
|
||||
CONFIG_NET_SCH_SFQ=y
|
||||
CONFIG_NET_SCH_TEQL=m
|
||||
CONFIG_NET_SCH_TBF=m
|
||||
CONFIG_NET_SCH_GRED=m
|
||||
CONFIG_NET_SCH_DSMARK=m
|
||||
CONFIG_NET_SCH_NETEM=m
|
||||
CONFIG_NET_SCH_DRR=m
|
||||
CONFIG_NET_SCH_MQPRIO=m
|
||||
CONFIG_NET_SCH_CHOKE=m
|
||||
CONFIG_NET_SCH_QFQ=m
|
||||
CONFIG_NET_SCH_CODEL=m
|
||||
CONFIG_NET_SCH_FQ_CODEL=y
|
||||
CONFIG_NET_SCH_FQ=m
|
||||
CONFIG_NET_SCH_HHF=m
|
||||
CONFIG_NET_SCH_PIE=y
|
||||
CONFIG_NET_SCH_PLUG=m
|
||||
CONFIG_NET_CLS_BASIC=m
|
||||
CONFIG_NET_CLS_TCINDEX=m
|
||||
CONFIG_NET_CLS_ROUTE4=m
|
||||
CONFIG_NET_CLS_FW=m
|
||||
CONFIG_NET_CLS_U32=m
|
||||
CONFIG_NET_CLS_RSVP=m
|
||||
CONFIG_NET_CLS_RSVP6=m
|
||||
CONFIG_NET_CLS_FLOW=m
|
||||
CONFIG_NET_CLS_CGROUP=m
|
||||
CONFIG_NET_CLS_BPF=m
|
||||
CONFIG_NET_EMATCH=y
|
||||
CONFIG_NET_EMATCH_CMP=m
|
||||
CONFIG_NET_EMATCH_NBYTE=m
|
||||
CONFIG_NET_EMATCH_U32=m
|
||||
CONFIG_NET_EMATCH_META=m
|
||||
CONFIG_NET_EMATCH_TEXT=m
|
||||
CONFIG_NET_CLS_ACT=y
|
||||
CONFIG_NET_ACT_POLICE=m
|
||||
CONFIG_NET_ACT_GACT=m
|
||||
CONFIG_NET_ACT_MIRRED=m
|
||||
CONFIG_NET_ACT_IPT=m
|
||||
CONFIG_NET_ACT_NAT=m
|
||||
CONFIG_NET_ACT_SIMP=m
|
||||
CONFIG_NET_ACT_SKBEDIT=m
|
||||
CONFIG_NET_ACT_CSUM=m
|
||||
CONFIG_NET_ACT_VLAN=m
|
||||
CONFIG_NET_ACT_BPF=m
|
||||
CONFIG_NET_ACT_CONNMARK=m
|
||||
CONFIG_VSOCKETS=m
|
||||
CONFIG_NETLINK_MMAP=y
|
||||
CONFIG_NETLINK_DIAG=y
|
||||
CONFIG_BPF_JIT=y
|
||||
CONFIG_BT=m
|
||||
CONFIG_BT_RFCOMM=m
|
||||
CONFIG_BT_RFCOMM_TTY=y
|
||||
CONFIG_BT_BNEP=m
|
||||
CONFIG_BT_BNEP_PROTO_FILTER=y
|
||||
CONFIG_BT_HIDP=m
|
||||
CONFIG_BT_HCIBTUSB=m
|
||||
CONFIG_BT_HCIBTSDIO=m
|
||||
CONFIG_BT_HCIUART=m
|
||||
CONFIG_BT_HCIUART_BCSP=y
|
||||
CONFIG_BT_HCIUART_ATH3K=y
|
||||
CONFIG_BT_HCIUART_LL=y
|
||||
CONFIG_BT_HCIUART_3WIRE=y
|
||||
CONFIG_BT_HCIUART_INTEL=y
|
||||
CONFIG_BT_HCIUART_BCM=y
|
||||
CONFIG_BT_HCIBCM203X=m
|
||||
CONFIG_BT_HCIBPA10X=m
|
||||
CONFIG_BT_HCIBFUSB=m
|
||||
CONFIG_BT_MRVL=m
|
||||
CONFIG_BT_MRVL_SDIO=m
|
||||
CONFIG_BT_ATH3K=m
|
||||
CONFIG_CFG80211=m
|
||||
CONFIG_CFG80211_WEXT=y
|
||||
CONFIG_MAC80211=m
|
||||
CONFIG_MAC80211_MESH=y
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_DEVTMPFS_MOUNT=y
|
||||
CONFIG_BLK_DEV_LOOP=m
|
||||
CONFIG_BLK_DEV_LOOP_MIN_COUNT=0
|
||||
CONFIG_BLK_DEV_NBD=m
|
||||
CONFIG_BLK_DEV_RAM=m
|
||||
CONFIG_CDROM_PKTCDVD=m
|
||||
CONFIG_CDROM_PKTCDVD_WCACHE=y
|
||||
CONFIG_EEPROM_SUNXI_SID=y
|
||||
CONFIG_SCSI_MQ_DEFAULT=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_CHR_DEV_SG=y
|
||||
CONFIG_ATA=y
|
||||
CONFIG_AHCI_SUNXI=y
|
||||
CONFIG_MD=y
|
||||
CONFIG_MD_LINEAR=m
|
||||
CONFIG_MD_RAID0=m
|
||||
CONFIG_MD_MULTIPATH=m
|
||||
CONFIG_MD_FAULTY=m
|
||||
CONFIG_BCACHE=m
|
||||
CONFIG_BLK_DEV_DM=m
|
||||
CONFIG_DM_MQ_DEFAULT=y
|
||||
CONFIG_DM_CRYPT=m
|
||||
CONFIG_DM_SNAPSHOT=m
|
||||
CONFIG_DM_THIN_PROVISIONING=m
|
||||
CONFIG_DM_CACHE=m
|
||||
CONFIG_DM_ERA=m
|
||||
CONFIG_DM_MIRROR=m
|
||||
CONFIG_DM_LOG_USERSPACE=m
|
||||
CONFIG_DM_RAID=m
|
||||
CONFIG_DM_ZERO=m
|
||||
CONFIG_DM_MULTIPATH=m
|
||||
CONFIG_DM_MULTIPATH_QL=m
|
||||
CONFIG_DM_MULTIPATH_ST=m
|
||||
CONFIG_DM_DELAY=m
|
||||
CONFIG_DM_UEVENT=y
|
||||
CONFIG_DM_FLAKEY=m
|
||||
CONFIG_DM_VERITY=m
|
||||
CONFIG_DM_SWITCH=m
|
||||
CONFIG_DM_LOG_WRITES=m
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_BONDING=m
|
||||
CONFIG_DUMMY=m
|
||||
CONFIG_NET_TEAM=m
|
||||
CONFIG_NET_TEAM_MODE_BROADCAST=m
|
||||
CONFIG_NET_TEAM_MODE_ROUNDROBIN=m
|
||||
CONFIG_NET_TEAM_MODE_RANDOM=m
|
||||
CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m
|
||||
CONFIG_NET_TEAM_MODE_LOADBALANCE=m
|
||||
CONFIG_MACVLAN=m
|
||||
CONFIG_MACVTAP=m
|
||||
CONFIG_IPVLAN=m
|
||||
CONFIG_VXLAN=m
|
||||
CONFIG_TUN=m
|
||||
CONFIG_VETH=m
|
||||
CONFIG_NLMON=m
|
||||
CONFIG_SUN4I_EMAC=y
|
||||
# CONFIG_NET_VENDOR_ARC is not set
|
||||
# CONFIG_NET_CADENCE is not set
|
||||
# CONFIG_NET_VENDOR_BROADCOM is not set
|
||||
# CONFIG_NET_VENDOR_CIRRUS is not set
|
||||
# CONFIG_NET_VENDOR_FARADAY is not set
|
||||
# CONFIG_NET_VENDOR_INTEL is not set
|
||||
# CONFIG_NET_VENDOR_MARVELL is not set
|
||||
# CONFIG_NET_VENDOR_MICREL is not set
|
||||
# CONFIG_NET_VENDOR_MICROCHIP is not set
|
||||
# CONFIG_NET_VENDOR_NATSEMI is not set
|
||||
# CONFIG_NET_VENDOR_SAMSUNG is not set
|
||||
# CONFIG_NET_VENDOR_SEEQ is not set
|
||||
# CONFIG_NET_VENDOR_SMSC is not set
|
||||
CONFIG_STMMAC_ETH=y
|
||||
# CONFIG_NET_VENDOR_VIA is not set
|
||||
# CONFIG_NET_VENDOR_WIZNET is not set
|
||||
CONFIG_PPP=m
|
||||
CONFIG_PPP_BSDCOMP=m
|
||||
CONFIG_PPP_DEFLATE=m
|
||||
CONFIG_PPP_FILTER=y
|
||||
CONFIG_PPP_MPPE=m
|
||||
CONFIG_PPP_MULTILINK=y
|
||||
CONFIG_PPPOE=m
|
||||
CONFIG_PPTP=m
|
||||
CONFIG_PPPOL2TP=m
|
||||
CONFIG_PPP_ASYNC=m
|
||||
CONFIG_PPP_SYNC_TTY=m
|
||||
CONFIG_LIBERTAS_THINFIRM=m
|
||||
CONFIG_LIBERTAS_THINFIRM_USB=m
|
||||
CONFIG_AT76C50X_USB=m
|
||||
CONFIG_USB_ZD1201=m
|
||||
CONFIG_USB_NET_RNDIS_WLAN=m
|
||||
CONFIG_RTL8187=m
|
||||
CONFIG_ATH_CARDS=m
|
||||
CONFIG_ATH9K=m
|
||||
CONFIG_ATH9K_AHB=y
|
||||
CONFIG_ATH9K_CHANNEL_CONTEXT=y
|
||||
CONFIG_ATH9K_HTC=m
|
||||
CONFIG_CARL9170=m
|
||||
CONFIG_ATH6KL=m
|
||||
CONFIG_ATH6KL_SDIO=m
|
||||
CONFIG_ATH6KL_USB=m
|
||||
CONFIG_AR5523=m
|
||||
CONFIG_ATH10K=m
|
||||
CONFIG_WCN36XX=m
|
||||
CONFIG_B43=m
|
||||
CONFIG_B43_SDIO=y
|
||||
CONFIG_BRCMFMAC=m
|
||||
CONFIG_BRCMFMAC_USB=y
|
||||
CONFIG_HOSTAP=m
|
||||
CONFIG_HOSTAP_FIRMWARE=y
|
||||
CONFIG_LIBERTAS=m
|
||||
CONFIG_LIBERTAS_USB=m
|
||||
CONFIG_LIBERTAS_SDIO=m
|
||||
CONFIG_LIBERTAS_SPI=m
|
||||
CONFIG_P54_COMMON=m
|
||||
CONFIG_P54_USB=m
|
||||
CONFIG_P54_SPI=m
|
||||
CONFIG_RT2X00=m
|
||||
CONFIG_RT2500USB=m
|
||||
CONFIG_RT73USB=m
|
||||
CONFIG_RT2800USB=m
|
||||
CONFIG_RT2800USB_RT3573=y
|
||||
CONFIG_RT2800USB_RT53XX=y
|
||||
CONFIG_RT2800USB_RT55XX=y
|
||||
CONFIG_RT2800USB_UNKNOWN=y
|
||||
CONFIG_RTL8192CU=m
|
||||
CONFIG_WL_TI=y
|
||||
CONFIG_WL1251=m
|
||||
CONFIG_WL1251_SPI=m
|
||||
CONFIG_WL1251_SDIO=m
|
||||
CONFIG_WL12XX=m
|
||||
CONFIG_WL18XX=m
|
||||
CONFIG_WLCORE_SPI=m
|
||||
CONFIG_WLCORE_SDIO=m
|
||||
CONFIG_ZD1211RW=m
|
||||
CONFIG_MWIFIEX=m
|
||||
CONFIG_MWIFIEX_SDIO=m
|
||||
CONFIG_MWIFIEX_USB=m
|
||||
CONFIG_CW1200=m
|
||||
CONFIG_CW1200_WLAN_SDIO=m
|
||||
CONFIG_CW1200_WLAN_SPI=m
|
||||
CONFIG_RSI_91X=m
|
||||
# CONFIG_INPUT_MOUSEDEV is not set
|
||||
# CONFIG_INPUT_KEYBOARD is not set
|
||||
# CONFIG_INPUT_MOUSE is not set
|
||||
CONFIG_INPUT_TOUCHSCREEN=y
|
||||
CONFIG_TOUCHSCREEN_SUN4I=y
|
||||
CONFIG_INPUT_MISC=y
|
||||
CONFIG_INPUT_AXP20X_PEK=y
|
||||
CONFIG_SERIAL_8250=y
|
||||
CONFIG_SERIAL_8250_CONSOLE=y
|
||||
CONFIG_SERIAL_8250_NR_UARTS=8
|
||||
CONFIG_SERIAL_8250_RUNTIME_UARTS=8
|
||||
CONFIG_SERIAL_8250_DW=y
|
||||
CONFIG_SERIAL_OF_PLATFORM=y
|
||||
# CONFIG_HW_RANDOM is not set
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2C_CHARDEV=y
|
||||
CONFIG_I2C_MV64XXX=y
|
||||
CONFIG_I2C_SUN6I_P2WI=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_SUN4I=y
|
||||
CONFIG_SPI_SUN6I=y
|
||||
CONFIG_GPIO_SYSFS=y
|
||||
CONFIG_POWER_SUPPLY=y
|
||||
CONFIG_POWER_RESET=y
|
||||
CONFIG_THERMAL=y
|
||||
CONFIG_CPU_THERMAL=y
|
||||
CONFIG_WATCHDOG=y
|
||||
CONFIG_SUNXI_WATCHDOG=y
|
||||
CONFIG_MFD_AXP20X=y
|
||||
CONFIG_REGULATOR=y
|
||||
CONFIG_REGULATOR_FIXED_VOLTAGE=y
|
||||
CONFIG_REGULATOR_AXP20X=y
|
||||
CONFIG_REGULATOR_GPIO=y
|
||||
CONFIG_MEDIA_SUPPORT=m
|
||||
CONFIG_MEDIA_CAMERA_SUPPORT=y
|
||||
CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
|
||||
CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
|
||||
CONFIG_MEDIA_RADIO_SUPPORT=y
|
||||
CONFIG_MEDIA_SDR_SUPPORT=y
|
||||
CONFIG_MEDIA_RC_SUPPORT=y
|
||||
CONFIG_MEDIA_CONTROLLER=y
|
||||
CONFIG_VIDEO_ADV_DEBUG=y
|
||||
CONFIG_DVB_DYNAMIC_MINORS=y
|
||||
CONFIG_MEDIA_USB_SUPPORT=y
|
||||
CONFIG_USB_VIDEO_CLASS=m
|
||||
CONFIG_USB_M5602=m
|
||||
CONFIG_USB_STV06XX=m
|
||||
CONFIG_USB_GL860=m
|
||||
CONFIG_USB_GSPCA_BENQ=m
|
||||
CONFIG_USB_GSPCA_CONEX=m
|
||||
CONFIG_USB_GSPCA_CPIA1=m
|
||||
CONFIG_USB_GSPCA_DTCS033=m
|
||||
CONFIG_USB_GSPCA_ETOMS=m
|
||||
CONFIG_USB_GSPCA_FINEPIX=m
|
||||
CONFIG_USB_GSPCA_JEILINJ=m
|
||||
CONFIG_USB_GSPCA_JL2005BCD=m
|
||||
CONFIG_USB_GSPCA_KINECT=m
|
||||
CONFIG_USB_GSPCA_KONICA=m
|
||||
CONFIG_USB_GSPCA_MARS=m
|
||||
CONFIG_USB_GSPCA_MR97310A=m
|
||||
CONFIG_USB_GSPCA_NW80X=m
|
||||
CONFIG_USB_GSPCA_OV519=m
|
||||
CONFIG_USB_GSPCA_OV534=m
|
||||
CONFIG_USB_GSPCA_OV534_9=m
|
||||
CONFIG_USB_GSPCA_PAC207=m
|
||||
CONFIG_USB_GSPCA_PAC7302=m
|
||||
CONFIG_USB_GSPCA_PAC7311=m
|
||||
CONFIG_USB_GSPCA_SE401=m
|
||||
CONFIG_USB_GSPCA_SN9C2028=m
|
||||
CONFIG_USB_GSPCA_SN9C20X=m
|
||||
CONFIG_USB_GSPCA_SONIXB=m
|
||||
CONFIG_USB_GSPCA_SONIXJ=m
|
||||
CONFIG_USB_GSPCA_SPCA500=m
|
||||
CONFIG_USB_GSPCA_SPCA501=m
|
||||
CONFIG_USB_GSPCA_SPCA505=m
|
||||
CONFIG_USB_GSPCA_SPCA506=m
|
||||
CONFIG_USB_GSPCA_SPCA508=m
|
||||
CONFIG_USB_GSPCA_SPCA561=m
|
||||
CONFIG_USB_GSPCA_SPCA1528=m
|
||||
CONFIG_USB_GSPCA_SQ905=m
|
||||
CONFIG_USB_GSPCA_SQ905C=m
|
||||
CONFIG_USB_GSPCA_SQ930X=m
|
||||
CONFIG_USB_GSPCA_STK014=m
|
||||
CONFIG_USB_GSPCA_STK1135=m
|
||||
CONFIG_USB_GSPCA_STV0680=m
|
||||
CONFIG_USB_GSPCA_SUNPLUS=m
|
||||
CONFIG_USB_GSPCA_T613=m
|
||||
CONFIG_USB_GSPCA_TOPRO=m
|
||||
CONFIG_USB_GSPCA_TOUPTEK=m
|
||||
CONFIG_USB_GSPCA_TV8532=m
|
||||
CONFIG_USB_GSPCA_VC032X=m
|
||||
CONFIG_USB_GSPCA_VICAM=m
|
||||
CONFIG_USB_GSPCA_XIRLINK_CIT=m
|
||||
CONFIG_USB_GSPCA_ZC3XX=m
|
||||
CONFIG_USB_PWC=m
|
||||
CONFIG_VIDEO_CPIA2=m
|
||||
CONFIG_USB_ZR364XX=m
|
||||
CONFIG_USB_STKWEBCAM=m
|
||||
CONFIG_USB_S2255=m
|
||||
CONFIG_VIDEO_PVRUSB2=m
|
||||
CONFIG_VIDEO_HDPVR=m
|
||||
CONFIG_VIDEO_USBVISION=m
|
||||
CONFIG_VIDEO_STK1160_COMMON=m
|
||||
CONFIG_VIDEO_AU0828=m
|
||||
CONFIG_VIDEO_AU0828_RC=y
|
||||
CONFIG_VIDEO_CX231XX=m
|
||||
CONFIG_VIDEO_CX231XX_DVB=m
|
||||
CONFIG_VIDEO_TM6000=m
|
||||
CONFIG_VIDEO_TM6000_DVB=m
|
||||
CONFIG_DVB_USB=m
|
||||
CONFIG_DVB_USB_A800=m
|
||||
CONFIG_DVB_USB_DIBUSB_MB=m
|
||||
CONFIG_DVB_USB_DIBUSB_MC=m
|
||||
CONFIG_DVB_USB_DIB0700=m
|
||||
CONFIG_DVB_USB_UMT_010=m
|
||||
CONFIG_DVB_USB_CXUSB=m
|
||||
CONFIG_DVB_USB_M920X=m
|
||||
CONFIG_DVB_USB_DIGITV=m
|
||||
CONFIG_DVB_USB_VP7045=m
|
||||
CONFIG_DVB_USB_VP702X=m
|
||||
CONFIG_DVB_USB_GP8PSK=m
|
||||
CONFIG_DVB_USB_NOVA_T_USB2=m
|
||||
CONFIG_DVB_USB_TTUSB2=m
|
||||
CONFIG_DVB_USB_DTT200U=m
|
||||
CONFIG_DVB_USB_OPERA1=m
|
||||
CONFIG_DVB_USB_AF9005=m
|
||||
CONFIG_DVB_USB_AF9005_REMOTE=m
|
||||
CONFIG_DVB_USB_PCTV452E=m
|
||||
CONFIG_DVB_USB_DW2102=m
|
||||
CONFIG_DVB_USB_CINERGY_T2=m
|
||||
CONFIG_DVB_USB_DTV5100=m
|
||||
CONFIG_DVB_USB_FRIIO=m
|
||||
CONFIG_DVB_USB_AZ6027=m
|
||||
CONFIG_DVB_USB_TECHNISAT_USB2=m
|
||||
CONFIG_DVB_USB_V2=m
|
||||
CONFIG_DVB_USB_AF9015=m
|
||||
CONFIG_DVB_USB_AF9035=m
|
||||
CONFIG_DVB_USB_ANYSEE=m
|
||||
CONFIG_DVB_USB_AU6610=m
|
||||
CONFIG_DVB_USB_AZ6007=m
|
||||
CONFIG_DVB_USB_CE6230=m
|
||||
CONFIG_DVB_USB_EC168=m
|
||||
CONFIG_DVB_USB_GL861=m
|
||||
CONFIG_DVB_USB_LME2510=m
|
||||
CONFIG_DVB_USB_MXL111SF=m
|
||||
CONFIG_DVB_USB_RTL28XXU=m
|
||||
CONFIG_DVB_USB_DVBSKY=m
|
||||
CONFIG_SMS_USB_DRV=m
|
||||
CONFIG_DVB_B2C2_FLEXCOP_USB=m
|
||||
CONFIG_DVB_AS102=m
|
||||
CONFIG_USB_AIRSPY=m
|
||||
CONFIG_USB_HACKRF=m
|
||||
CONFIG_USB_MSI2500=m
|
||||
CONFIG_V4L_PLATFORM_DRIVERS=y
|
||||
CONFIG_SOC_CAMERA=m
|
||||
CONFIG_SOC_CAMERA_PLATFORM=m
|
||||
CONFIG_V4L_MEM2MEM_DRIVERS=y
|
||||
CONFIG_V4L_TEST_DRIVERS=y
|
||||
CONFIG_VIDEO_VIVID=m
|
||||
CONFIG_VIDEO_VIM2M=m
|
||||
CONFIG_SMS_SDIO_DRV=m
|
||||
CONFIG_RADIO_SI470X=y
|
||||
CONFIG_USB_SI470X=m
|
||||
CONFIG_I2C_SI470X=m
|
||||
CONFIG_RADIO_SI4713=m
|
||||
CONFIG_USB_SI4713=m
|
||||
CONFIG_PLATFORM_SI4713=m
|
||||
CONFIG_USB_MR800=m
|
||||
CONFIG_USB_DSBR=m
|
||||
CONFIG_RADIO_SHARK=m
|
||||
CONFIG_RADIO_SHARK2=m
|
||||
CONFIG_USB_KEENE=m
|
||||
CONFIG_USB_RAREMONO=m
|
||||
CONFIG_USB_MA901=m
|
||||
CONFIG_RADIO_TEA5764=m
|
||||
CONFIG_RADIO_SAA7706H=m
|
||||
CONFIG_RADIO_TEF6862=m
|
||||
CONFIG_RADIO_WL1273=m
|
||||
CONFIG_SOC_CAMERA_IMX074=m
|
||||
CONFIG_SOC_CAMERA_MT9M001=m
|
||||
CONFIG_SOC_CAMERA_MT9M111=m
|
||||
CONFIG_SOC_CAMERA_MT9T031=m
|
||||
CONFIG_SOC_CAMERA_MT9T112=m
|
||||
CONFIG_SOC_CAMERA_MT9V022=m
|
||||
CONFIG_SOC_CAMERA_OV2640=m
|
||||
CONFIG_SOC_CAMERA_OV5642=m
|
||||
CONFIG_SOC_CAMERA_OV6650=m
|
||||
CONFIG_SOC_CAMERA_OV772X=m
|
||||
CONFIG_SOC_CAMERA_OV9640=m
|
||||
CONFIG_SOC_CAMERA_OV9740=m
|
||||
CONFIG_SOC_CAMERA_RJ54N1=m
|
||||
CONFIG_SOC_CAMERA_TW9910=m
|
||||
CONFIG_FB=y
|
||||
CONFIG_FB_SIMPLE=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_EHCI_HCD_PLATFORM=y
|
||||
CONFIG_USB_OHCI_HCD=y
|
||||
CONFIG_USB_OHCI_HCD_PLATFORM=y
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MMC_SUNXI=y
|
||||
CONFIG_LEDS_CLASS=y
|
||||
CONFIG_LEDS_CLASS_FLASH=y
|
||||
CONFIG_LEDS_LM3530=m
|
||||
CONFIG_LEDS_GPIO=y
|
||||
CONFIG_LEDS_LP3944=m
|
||||
CONFIG_LEDS_LP5521=m
|
||||
CONFIG_LEDS_LP5523=m
|
||||
CONFIG_LEDS_LP5562=m
|
||||
CONFIG_LEDS_LP8501=m
|
||||
CONFIG_LEDS_PCA955X=m
|
||||
CONFIG_LEDS_PCA963X=m
|
||||
CONFIG_LEDS_DAC124S085=m
|
||||
CONFIG_LEDS_REGULATOR=y
|
||||
CONFIG_LEDS_BD2802=m
|
||||
CONFIG_LEDS_LT3593=m
|
||||
CONFIG_LEDS_TCA6507=m
|
||||
CONFIG_LEDS_LM355x=m
|
||||
CONFIG_LEDS_BLINKM=m
|
||||
CONFIG_LEDS_TRIGGER_TIMER=y
|
||||
CONFIG_LEDS_TRIGGER_ONESHOT=y
|
||||
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
|
||||
CONFIG_LEDS_TRIGGER_BACKLIGHT=y
|
||||
CONFIG_LEDS_TRIGGER_CPU=y
|
||||
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
|
||||
CONFIG_LEDS_TRIGGER_TRANSIENT=y
|
||||
CONFIG_LEDS_TRIGGER_CAMERA=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
# CONFIG_RTC_INTF_SYSFS is not set
|
||||
# CONFIG_RTC_INTF_PROC is not set
|
||||
CONFIG_RTC_DRV_SUN6I=y
|
||||
CONFIG_RTC_DRV_SUNXI=y
|
||||
CONFIG_DMADEVICES=y
|
||||
CONFIG_DMA_SUN6I=y
|
||||
# CONFIG_IOMMU_SUPPORT is not set
|
||||
CONFIG_EXTCON=y
|
||||
CONFIG_PWM=y
|
||||
CONFIG_PWM_SUN4I=y
|
||||
CONFIG_PHY_SUN4I_USB=y
|
||||
CONFIG_PHY_SUN9I_USB=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_FANOTIFY=y
|
||||
CONFIG_AUTOFS4_FS=m
|
||||
CONFIG_FUSE_FS=m
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_NFS_FS=y
|
||||
CONFIG_NFS_V3_ACL=y
|
||||
CONFIG_NFS_V4=y
|
||||
CONFIG_ROOT_NFS=y
|
||||
CONFIG_NLS_CODEPAGE_437=y
|
||||
CONFIG_NLS_ISO8859_1=y
|
||||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_CRYPTO_DEV_SUN4I_SS=y
|
||||
CONFIG_ARM_CRYPTO=y
|
||||
CONFIG_CRYPTO_SHA1_ARM_NEON=y
|
||||
CONFIG_CRYPTO_SHA256_ARM=y
|
||||
CONFIG_CRYPTO_SHA512_ARM_NEON=y
|
||||
CONFIG_CRYPTO_AES_ARM_BS=y
|
@ -1,203 +0,0 @@
|
||||
config AUFS_FS
|
||||
tristate "Aufs (Advanced multi layered unification filesystem) support"
|
||||
depends on EXPERIMENTAL
|
||||
help
|
||||
Aufs is a stackable unification filesystem such as Unionfs,
|
||||
which unifies several directories and provides a merged single
|
||||
directory.
|
||||
In the early days, aufs was entirely re-designed and
|
||||
re-implemented Unionfs Version 1.x series. Introducing many
|
||||
original ideas, approaches and improvements, it becomes totally
|
||||
different from Unionfs while keeping the basic features.
|
||||
|
||||
if AUFS_FS
|
||||
choice
|
||||
prompt "Maximum number of branches"
|
||||
default AUFS_BRANCH_MAX_127
|
||||
help
|
||||
Specifies the maximum number of branches (or member directories)
|
||||
in a single aufs. The larger value consumes more system
|
||||
resources and has a minor impact to performance.
|
||||
config AUFS_BRANCH_MAX_127
|
||||
bool "127"
|
||||
help
|
||||
Specifies the maximum number of branches (or member directories)
|
||||
in a single aufs. The larger value consumes more system
|
||||
resources and has a minor impact to performance.
|
||||
config AUFS_BRANCH_MAX_511
|
||||
bool "511"
|
||||
help
|
||||
Specifies the maximum number of branches (or member directories)
|
||||
in a single aufs. The larger value consumes more system
|
||||
resources and has a minor impact to performance.
|
||||
config AUFS_BRANCH_MAX_1023
|
||||
bool "1023"
|
||||
help
|
||||
Specifies the maximum number of branches (or member directories)
|
||||
in a single aufs. The larger value consumes more system
|
||||
resources and has a minor impact to performance.
|
||||
config AUFS_BRANCH_MAX_32767
|
||||
bool "32767"
|
||||
help
|
||||
Specifies the maximum number of branches (or member directories)
|
||||
in a single aufs. The larger value consumes more system
|
||||
resources and has a minor impact to performance.
|
||||
endchoice
|
||||
|
||||
config AUFS_SBILIST
|
||||
bool
|
||||
depends on AUFS_MAGIC_SYSRQ || PROC_FS
|
||||
default y
|
||||
help
|
||||
Automatic configuration for internal use.
|
||||
When aufs supports Magic SysRq or /proc, enabled automatically.
|
||||
|
||||
config AUFS_HNOTIFY
|
||||
bool "Detect direct branch access (bypassing aufs)"
|
||||
help
|
||||
If you want to modify files on branches directly, eg. bypassing aufs,
|
||||
and want aufs to detect the changes of them fully, then enable this
|
||||
option and use 'udba=notify' mount option.
|
||||
Currently there is only one available configuration, "fsnotify".
|
||||
It will have a negative impact to the performance.
|
||||
See detail in aufs.5.
|
||||
|
||||
choice
|
||||
prompt "method" if AUFS_HNOTIFY
|
||||
default AUFS_HFSNOTIFY
|
||||
config AUFS_HFSNOTIFY
|
||||
bool "fsnotify"
|
||||
select FSNOTIFY
|
||||
endchoice
|
||||
|
||||
config AUFS_EXPORT
|
||||
bool "NFS-exportable aufs"
|
||||
depends on EXPORTFS
|
||||
help
|
||||
If you want to export your mounted aufs via NFS, then enable this
|
||||
option. There are several requirements for this configuration.
|
||||
See detail in aufs.5.
|
||||
|
||||
config AUFS_INO_T_64
|
||||
bool
|
||||
depends on AUFS_EXPORT
|
||||
depends on 64BIT && !(ALPHA || S390)
|
||||
default y
|
||||
help
|
||||
Automatic configuration for internal use.
|
||||
/* typedef unsigned long/int __kernel_ino_t */
|
||||
/* alpha and s390x are int */
|
||||
|
||||
config AUFS_RDU
|
||||
bool "Readdir in userspace"
|
||||
help
|
||||
Aufs has two methods to provide a merged view for a directory,
|
||||
by a user-space library and by kernel-space natively. The latter
|
||||
is always enabled but sometimes large and slow.
|
||||
If you enable this option, install the library in aufs2-util
|
||||
package, and set some environment variables for your readdir(3),
|
||||
then the work will be handled in user-space which generally
|
||||
shows better performance in most cases.
|
||||
See detail in aufs.5.
|
||||
|
||||
config AUFS_PROC_MAP
|
||||
bool "support for /proc/maps and lsof(1)"
|
||||
depends on PROC_FS
|
||||
help
|
||||
When you issue mmap(2) in aufs, it is actually a direct mmap(2)
|
||||
call to the file on the branch fs since the file in aufs is
|
||||
purely virtual. And the file path printed in /proc/maps (and
|
||||
others) will be the path on the branch fs. In most cases, it
|
||||
does no harm. But some utilities like lsof(1) may confuse since
|
||||
the utility or user may expect the file path in aufs to be
|
||||
printed.
|
||||
To address this issue, aufs provides a patch which introduces a
|
||||
new member called vm_prfile into struct vm_are_struct. The patch
|
||||
is meaningless without enabling this configuration since nobody
|
||||
sets the new vm_prfile member.
|
||||
If you don't apply the patch, then enabling this configuration
|
||||
will cause a compile error.
|
||||
This approach is fragile since if someone else make some changes
|
||||
around vm_file, then vm_prfile may not work anymore. As a
|
||||
workaround such case, aufs provides this configuration. If you
|
||||
disable it, then lsof(1) may produce incorrect result but the
|
||||
problem will be gone even if the aufs patch is applied (I hope).
|
||||
|
||||
config AUFS_SP_IATTR
|
||||
bool "Respect the attributes (mtime/ctime mainly) of special files"
|
||||
help
|
||||
When you write something to a special file, some attributes of it
|
||||
(mtime/ctime mainly) may be updated. Generally such updates are
|
||||
less important (actually some device drivers and NFS ignore
|
||||
it). But some applications (such like test program) requires
|
||||
such updates. If you need these updates, then enable this
|
||||
configuration which introduces some overhead.
|
||||
Currently this configuration handles FIFO only.
|
||||
|
||||
config AUFS_SHWH
|
||||
bool "Show whiteouts"
|
||||
help
|
||||
If you want to make the whiteouts in aufs visible, then enable
|
||||
this option and specify 'shwh' mount option. Although it may
|
||||
sounds like philosophy or something, but in technically it
|
||||
simply shows the name of whiteout with keeping its behaviour.
|
||||
|
||||
config AUFS_BR_RAMFS
|
||||
bool "Ramfs (initramfs/rootfs) as an aufs branch"
|
||||
help
|
||||
If you want to use ramfs as an aufs branch fs, then enable this
|
||||
option. Generally tmpfs is recommended.
|
||||
Aufs prohibited them to be a branch fs by default, because
|
||||
initramfs becomes unusable after switch_root or something
|
||||
generally. If you sets initramfs as an aufs branch and boot your
|
||||
system by switch_root, you will meet a problem easily since the
|
||||
files in initramfs may be inaccessible.
|
||||
Unless you are going to use ramfs as an aufs branch fs without
|
||||
switch_root or something, leave it N.
|
||||
|
||||
config AUFS_BR_FUSE
|
||||
bool "Fuse fs as an aufs branch"
|
||||
depends on FUSE_FS
|
||||
select AUFS_POLL
|
||||
help
|
||||
If you want to use fuse-based userspace filesystem as an aufs
|
||||
branch fs, then enable this option.
|
||||
It implements the internal poll(2) operation which is
|
||||
implemented by fuse only (curretnly).
|
||||
|
||||
config AUFS_POLL
|
||||
bool
|
||||
help
|
||||
Automatic configuration for internal use.
|
||||
|
||||
config AUFS_BR_HFSPLUS
|
||||
bool "Hfsplus as an aufs branch"
|
||||
depends on HFSPLUS_FS
|
||||
default y
|
||||
help
|
||||
If you want to use hfsplus fs as an aufs branch fs, then enable
|
||||
this option. This option introduces a small overhead at
|
||||
copying-up a file on hfsplus.
|
||||
|
||||
config AUFS_BDEV_LOOP
|
||||
bool
|
||||
depends on BLK_DEV_LOOP
|
||||
default y
|
||||
help
|
||||
Automatic configuration for internal use.
|
||||
Convert =[ym] into =y.
|
||||
|
||||
config AUFS_DEBUG
|
||||
bool "Debug aufs"
|
||||
help
|
||||
Enable this to compile aufs internal debug code.
|
||||
It will have a negative impact to the performance.
|
||||
|
||||
config AUFS_MAGIC_SYSRQ
|
||||
bool
|
||||
depends on AUFS_DEBUG && MAGIC_SYSRQ
|
||||
default y
|
||||
help
|
||||
Automatic configuration for internal use.
|
||||
When aufs supports Magic SysRq, enabled automatically.
|
||||
endif
|
@ -1,42 +0,0 @@
|
||||
|
||||
include ${src}/magic.mk
|
||||
ifeq (${CONFIG_AUFS_FS},m)
|
||||
include ${src}/conf.mk
|
||||
endif
|
||||
-include ${src}/priv_def.mk
|
||||
|
||||
# cf. include/linux/kernel.h
|
||||
# enable pr_debug
|
||||
ccflags-y += -DDEBUG
|
||||
# sparse requires the full pathname
|
||||
ifdef M
|
||||
ccflags-y += -include ${M}/../../include/linux/aufs_type.h
|
||||
else
|
||||
ccflags-y += -include ${srctree}/include/linux/aufs_type.h
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_AUFS_FS) += aufs.o
|
||||
aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \
|
||||
wkq.o vfsub.o dcsub.o \
|
||||
cpup.o whout.o wbr_policy.o \
|
||||
dinfo.o dentry.o \
|
||||
dynop.o \
|
||||
finfo.o file.o f_op.o \
|
||||
dir.o vdir.o \
|
||||
iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \
|
||||
ioctl.o
|
||||
|
||||
# all are boolean
|
||||
aufs-$(CONFIG_PROC_FS) += procfs.o plink.o
|
||||
aufs-$(CONFIG_SYSFS) += sysfs.o
|
||||
aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o
|
||||
aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o
|
||||
aufs-$(CONFIG_AUFS_HNOTIFY) += hnotify.o
|
||||
aufs-$(CONFIG_AUFS_HFSNOTIFY) += hfsnotify.o
|
||||
aufs-$(CONFIG_AUFS_EXPORT) += export.o
|
||||
aufs-$(CONFIG_AUFS_POLL) += poll.o
|
||||
aufs-$(CONFIG_AUFS_RDU) += rdu.o
|
||||
aufs-$(CONFIG_AUFS_SP_IATTR) += f_op_sp.o
|
||||
aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o
|
||||
aufs-$(CONFIG_AUFS_DEBUG) += debug.o
|
||||
aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o
|
@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2012 Junjiro R. Okajima
|
||||
*
|
||||
* This program, aufs is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* all header files
|
||||
*/
|
||||
|
||||
#ifndef __AUFS_H__
|
||||
#define __AUFS_H__
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#define AuStub(type, name, body, ...) \
|
||||
static inline type name(__VA_ARGS__) { body; }
|
||||
|
||||
#define AuStubVoid(name, ...) \
|
||||
AuStub(void, name, , __VA_ARGS__)
|
||||
#define AuStubInt0(name, ...) \
|
||||
AuStub(int, name, return 0, __VA_ARGS__)
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
#include "branch.h"
|
||||
#include "cpup.h"
|
||||
#include "dcsub.h"
|
||||
#include "dbgaufs.h"
|
||||
#include "dentry.h"
|
||||
#include "dir.h"
|
||||
#include "dynop.h"
|
||||
#include "file.h"
|
||||
#include "fstype.h"
|
||||
#include "inode.h"
|
||||
#include "loop.h"
|
||||
#include "module.h"
|
||||
#include "opts.h"
|
||||
#include "rwsem.h"
|
||||
#include "spl.h"
|
||||
#include "super.h"
|
||||
#include "sysaufs.h"
|
||||
#include "vfsub.h"
|
||||
#include "whout.h"
|
||||
#include "wkq.h"
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* __AUFS_H__ */
|
File diff suppressed because it is too large
Load Diff
@ -1,230 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2012 Junjiro R. Okajima
|
||||
*
|
||||
* This program, aufs is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* branch filesystems and xino for them
|
||||
*/
|
||||
|
||||
#ifndef __AUFS_BRANCH_H__
|
||||
#define __AUFS_BRANCH_H__
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/mount.h>
|
||||
#include "dynop.h"
|
||||
#include "rwsem.h"
|
||||
#include "super.h"
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/* a xino file */
|
||||
struct au_xino_file {
|
||||
struct file *xi_file;
|
||||
struct mutex xi_nondir_mtx;
|
||||
|
||||
/* todo: make xino files an array to support huge inode number */
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
struct dentry *xi_dbgaufs;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* members for writable branch only */
|
||||
enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last};
|
||||
struct au_wbr {
|
||||
struct au_rwsem wbr_wh_rwsem;
|
||||
struct dentry *wbr_wh[AuBrWh_Last];
|
||||
atomic_t wbr_wh_running;
|
||||
#define wbr_whbase wbr_wh[AuBrWh_BASE] /* whiteout base */
|
||||
#define wbr_plink wbr_wh[AuBrWh_PLINK] /* pseudo-link dir */
|
||||
#define wbr_orph wbr_wh[AuBrWh_ORPH] /* dir for orphans */
|
||||
|
||||
/* mfs mode */
|
||||
unsigned long long wbr_bytes;
|
||||
};
|
||||
|
||||
/* ext2 has 3 types of operations at least, ext3 has 4 */
|
||||
#define AuBrDynOp (AuDyLast * 4)
|
||||
|
||||
/* protected by superblock rwsem */
|
||||
struct au_branch {
|
||||
struct au_xino_file br_xino;
|
||||
|
||||
aufs_bindex_t br_id;
|
||||
|
||||
int br_perm;
|
||||
struct vfsmount *br_mnt;
|
||||
spinlock_t br_dykey_lock;
|
||||
struct au_dykey *br_dykey[AuBrDynOp];
|
||||
atomic_t br_count;
|
||||
|
||||
struct au_wbr *br_wbr;
|
||||
|
||||
/* xino truncation */
|
||||
blkcnt_t br_xino_upper; /* watermark in blocks */
|
||||
atomic_t br_xino_running;
|
||||
|
||||
#ifdef CONFIG_AUFS_HFSNOTIFY
|
||||
struct fsnotify_group *br_hfsn_group;
|
||||
struct fsnotify_ops br_hfsn_ops;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYSFS
|
||||
/* an entry under sysfs per mount-point */
|
||||
char br_name[8];
|
||||
struct attribute br_attr;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/* branch permissions and attributes */
|
||||
#define AuBrPerm_RW 1 /* writable, hardlinkable wh */
|
||||
#define AuBrPerm_RO (1 << 1) /* readonly */
|
||||
#define AuBrPerm_RR (1 << 2) /* natively readonly */
|
||||
#define AuBrPerm_Mask (AuBrPerm_RW | AuBrPerm_RO | AuBrPerm_RR)
|
||||
|
||||
#define AuBrRAttr_WH (1 << 3) /* whiteout-able */
|
||||
|
||||
#define AuBrWAttr_NoLinkWH (1 << 4) /* un-hardlinkable whiteouts */
|
||||
|
||||
static inline int au_br_writable(int brperm)
|
||||
{
|
||||
return brperm & AuBrPerm_RW;
|
||||
}
|
||||
|
||||
static inline int au_br_whable(int brperm)
|
||||
{
|
||||
return brperm & (AuBrPerm_RW | AuBrRAttr_WH);
|
||||
}
|
||||
|
||||
static inline int au_br_wh_linkable(int brperm)
|
||||
{
|
||||
return !(brperm & AuBrWAttr_NoLinkWH);
|
||||
}
|
||||
|
||||
static inline int au_br_rdonly(struct au_branch *br)
|
||||
{
|
||||
return ((br->br_mnt->mnt_sb->s_flags & MS_RDONLY)
|
||||
|| !au_br_writable(br->br_perm))
|
||||
? -EROFS : 0;
|
||||
}
|
||||
|
||||
static inline int au_br_hnotifyable(int brperm __maybe_unused)
|
||||
{
|
||||
#ifdef CONFIG_AUFS_HNOTIFY
|
||||
return !(brperm & AuBrPerm_RR);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/* branch.c */
|
||||
struct au_sbinfo;
|
||||
void au_br_free(struct au_sbinfo *sinfo);
|
||||
int au_br_index(struct super_block *sb, aufs_bindex_t br_id);
|
||||
struct au_opt_add;
|
||||
int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount);
|
||||
struct au_opt_del;
|
||||
int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount);
|
||||
long au_ibusy_ioctl(struct file *file, unsigned long arg);
|
||||
#ifdef CONFIG_COMPAT
|
||||
long au_ibusy_compat_ioctl(struct file *file, unsigned long arg);
|
||||
#endif
|
||||
struct au_opt_mod;
|
||||
int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
|
||||
int *do_refresh);
|
||||
|
||||
/* xino.c */
|
||||
static const loff_t au_loff_max = LLONG_MAX;
|
||||
|
||||
int au_xib_trunc(struct super_block *sb);
|
||||
ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size,
|
||||
loff_t *pos);
|
||||
ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
|
||||
loff_t *pos);
|
||||
struct file *au_xino_create2(struct file *base_file, struct file *copy_src);
|
||||
struct file *au_xino_create(struct super_block *sb, char *fname, int silent);
|
||||
ino_t au_xino_new_ino(struct super_block *sb);
|
||||
void au_xino_delete_inode(struct inode *inode, const int unlinked);
|
||||
int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
|
||||
ino_t ino);
|
||||
int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
|
||||
ino_t *ino);
|
||||
int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t hino,
|
||||
struct file *base_file, int do_test);
|
||||
int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex);
|
||||
|
||||
struct au_opt_xino;
|
||||
int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount);
|
||||
void au_xino_clr(struct super_block *sb);
|
||||
struct file *au_xino_def(struct super_block *sb);
|
||||
int au_xino_path(struct seq_file *seq, struct file *file);
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/* Superblock to branch */
|
||||
static inline
|
||||
aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex)
|
||||
{
|
||||
return au_sbr(sb, bindex)->br_id;
|
||||
}
|
||||
|
||||
static inline
|
||||
struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex)
|
||||
{
|
||||
return au_sbr(sb, bindex)->br_mnt;
|
||||
}
|
||||
|
||||
static inline
|
||||
struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex)
|
||||
{
|
||||
return au_sbr_mnt(sb, bindex)->mnt_sb;
|
||||
}
|
||||
|
||||
static inline void au_sbr_put(struct super_block *sb, aufs_bindex_t bindex)
|
||||
{
|
||||
atomic_dec(&au_sbr(sb, bindex)->br_count);
|
||||
}
|
||||
|
||||
static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex)
|
||||
{
|
||||
return au_sbr(sb, bindex)->br_perm;
|
||||
}
|
||||
|
||||
static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex)
|
||||
{
|
||||
return au_br_whable(au_sbr_perm(sb, bindex));
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* wbr_wh_read_lock, wbr_wh_write_lock
|
||||
* wbr_wh_read_unlock, wbr_wh_write_unlock, wbr_wh_downgrade_lock
|
||||
*/
|
||||
AuSimpleRwsemFuncs(wbr_wh, struct au_wbr *wbr, &wbr->wbr_wh_rwsem);
|
||||
|
||||
#define WbrWhMustNoWaiters(wbr) AuRwMustNoWaiters(&wbr->wbr_wh_rwsem)
|
||||
#define WbrWhMustAnyLock(wbr) AuRwMustAnyLock(&wbr->wbr_wh_rwsem)
|
||||
#define WbrWhMustWriteLock(wbr) AuRwMustWriteLock(&wbr->wbr_wh_rwsem)
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* __AUFS_BRANCH_H__ */
|
@ -1,38 +0,0 @@
|
||||
|
||||
AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS}
|
||||
|
||||
define AuConf
|
||||
ifdef ${1}
|
||||
AuConfStr += ${1}=${${1}}
|
||||
endif
|
||||
endef
|
||||
|
||||
AuConfAll = BRANCH_MAX_127 BRANCH_MAX_511 BRANCH_MAX_1023 BRANCH_MAX_32767 \
|
||||
SBILIST \
|
||||
HNOTIFY HFSNOTIFY \
|
||||
EXPORT INO_T_64 \
|
||||
RDU \
|
||||
PROC_MAP \
|
||||
SP_IATTR \
|
||||
SHWH \
|
||||
BR_RAMFS \
|
||||
BR_FUSE POLL \
|
||||
BR_HFSPLUS \
|
||||
BDEV_LOOP \
|
||||
DEBUG MAGIC_SYSRQ
|
||||
$(foreach i, ${AuConfAll}, \
|
||||
$(eval $(call AuConf,CONFIG_AUFS_${i})))
|
||||
|
||||
AuConfName = ${obj}/conf.str
|
||||
${AuConfName}.tmp: FORCE
|
||||
@echo ${AuConfStr} | tr ' ' '\n' | sed -e 's/^/"/' -e 's/$$/\\n"/' > $@
|
||||
${AuConfName}: ${AuConfName}.tmp
|
||||
@diff -q $< $@ > /dev/null 2>&1 || { \
|
||||
echo ' GEN ' $@; \
|
||||
cp -p $< $@; \
|
||||
}
|
||||
FORCE:
|
||||
clean-files += ${AuConfName} ${AuConfName}.tmp
|
||||
${obj}/sysfs.o: ${AuConfName}
|
||||
|
||||
-include ${srctree}/${src}/conf_priv.mk
|
File diff suppressed because it is too large
Load Diff
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2012 Junjiro R. Okajima
|
||||
*
|
||||
* This program, aufs is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* copy-up/down functions
|
||||
*/
|
||||
|
||||
#ifndef __AUFS_CPUP_H__
|
||||
#define __AUFS_CPUP_H__
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/path.h>
|
||||
|
||||
struct inode;
|
||||
struct file;
|
||||
|
||||
void au_cpup_attr_flags(struct inode *dst, struct inode *src);
|
||||
void au_cpup_attr_timesizes(struct inode *inode);
|
||||
void au_cpup_attr_nlink(struct inode *inode, int force);
|
||||
void au_cpup_attr_changeable(struct inode *inode);
|
||||
void au_cpup_igen(struct inode *inode, struct inode *h_inode);
|
||||
void au_cpup_attr_all(struct inode *inode, int force);
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/* cpup flags */
|
||||
#define AuCpup_DTIME 1 /* do dtime_store/revert */
|
||||
#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino,
|
||||
for link(2) */
|
||||
#define au_ftest_cpup(flags, name) ((flags) & AuCpup_##name)
|
||||
#define au_fset_cpup(flags, name) \
|
||||
do { (flags) |= AuCpup_##name; } while (0)
|
||||
#define au_fclr_cpup(flags, name) \
|
||||
do { (flags) &= ~AuCpup_##name; } while (0)
|
||||
|
||||
int au_copy_file(struct file *dst, struct file *src, loff_t len);
|
||||
int au_sio_cpup_single(struct dentry *dentry, aufs_bindex_t bdst,
|
||||
aufs_bindex_t bsrc, loff_t len, unsigned int flags,
|
||||
struct dentry *dst_parent);
|
||||
int au_sio_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
|
||||
unsigned int flags);
|
||||
int au_sio_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
|
||||
struct file *file);
|
||||
|
||||
int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
|
||||
int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
|
||||
struct dentry *h_parent, void *arg),
|
||||
void *arg);
|
||||
int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
|
||||
int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/* keep timestamps when copyup */
|
||||
struct au_dtime {
|
||||
struct dentry *dt_dentry;
|
||||
struct path dt_h_path;
|
||||
struct timespec dt_atime, dt_mtime;
|
||||
};
|
||||
void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
|
||||
struct path *h_path);
|
||||
void au_dtime_revert(struct au_dtime *dt);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* __AUFS_CPUP_H__ */
|
@ -1,334 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2012 Junjiro R. Okajima
|
||||
*
|
||||
* This program, aufs is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* debugfs interface
|
||||
*/
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
#include "aufs.h"
|
||||
|
||||
#ifndef CONFIG_SYSFS
|
||||
#error DEBUG_FS depends upon SYSFS
|
||||
#endif
|
||||
|
||||
static struct dentry *dbgaufs;
|
||||
static const mode_t dbgaufs_mode = S_IRUSR | S_IRGRP | S_IROTH;
|
||||
|
||||
/* 20 is max digits length of ulong 64 */
|
||||
struct dbgaufs_arg {
|
||||
int n;
|
||||
char a[20 * 4];
|
||||
};
|
||||
|
||||
/*
|
||||
* common function for all XINO files
|
||||
*/
|
||||
static int dbgaufs_xi_release(struct inode *inode __maybe_unused,
|
||||
struct file *file)
|
||||
{
|
||||
kfree(file->private_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt)
|
||||
{
|
||||
int err;
|
||||
struct kstat st;
|
||||
struct dbgaufs_arg *p;
|
||||
|
||||
err = -ENOMEM;
|
||||
p = kmalloc(sizeof(*p), GFP_NOFS);
|
||||
if (unlikely(!p))
|
||||
goto out;
|
||||
|
||||
err = 0;
|
||||
p->n = 0;
|
||||
file->private_data = p;
|
||||
if (!xf)
|
||||
goto out;
|
||||
|
||||
err = vfs_getattr(xf->f_vfsmnt, xf->f_dentry, &st);
|
||||
if (!err) {
|
||||
if (do_fcnt)
|
||||
p->n = snprintf
|
||||
(p->a, sizeof(p->a), "%ld, %llux%lu %lld\n",
|
||||
(long)file_count(xf), st.blocks, st.blksize,
|
||||
(long long)st.size);
|
||||
else
|
||||
p->n = snprintf(p->a, sizeof(p->a), "%llux%lu %lld\n",
|
||||
st.blocks, st.blksize,
|
||||
(long long)st.size);
|
||||
AuDebugOn(p->n >= sizeof(p->a));
|
||||
} else {
|
||||
p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err);
|
||||
err = 0;
|
||||
}
|
||||
|
||||
out:
|
||||
return err;
|
||||
|
||||
}
|
||||
|
||||
static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct dbgaufs_arg *p;
|
||||
|
||||
p = file->private_data;
|
||||
return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static int dbgaufs_xib_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
int err;
|
||||
struct au_sbinfo *sbinfo;
|
||||
struct super_block *sb;
|
||||
|
||||
sbinfo = inode->i_private;
|
||||
sb = sbinfo->si_sb;
|
||||
si_noflush_read_lock(sb);
|
||||
err = dbgaufs_xi_open(sbinfo->si_xib, file, /*do_fcnt*/0);
|
||||
si_read_unlock(sb);
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct file_operations dbgaufs_xib_fop = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = dbgaufs_xib_open,
|
||||
.release = dbgaufs_xi_release,
|
||||
.read = dbgaufs_xi_read
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#define DbgaufsXi_PREFIX "xi"
|
||||
|
||||
static int dbgaufs_xino_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
int err;
|
||||
long l;
|
||||
struct au_sbinfo *sbinfo;
|
||||
struct super_block *sb;
|
||||
struct file *xf;
|
||||
struct qstr *name;
|
||||
|
||||
err = -ENOENT;
|
||||
xf = NULL;
|
||||
name = &file->f_dentry->d_name;
|
||||
if (unlikely(name->len < sizeof(DbgaufsXi_PREFIX)
|
||||
|| memcmp(name->name, DbgaufsXi_PREFIX,
|
||||
sizeof(DbgaufsXi_PREFIX) - 1)))
|
||||
goto out;
|
||||
err = strict_strtol(name->name + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l);
|
||||
if (unlikely(err))
|
||||
goto out;
|
||||
|
||||
sbinfo = inode->i_private;
|
||||
sb = sbinfo->si_sb;
|
||||
si_noflush_read_lock(sb);
|
||||
if (l <= au_sbend(sb)) {
|
||||
xf = au_sbr(sb, (aufs_bindex_t)l)->br_xino.xi_file;
|
||||
err = dbgaufs_xi_open(xf, file, /*do_fcnt*/1);
|
||||
} else
|
||||
err = -ENOENT;
|
||||
si_read_unlock(sb);
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct file_operations dbgaufs_xino_fop = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = dbgaufs_xino_open,
|
||||
.release = dbgaufs_xi_release,
|
||||
.read = dbgaufs_xi_read
|
||||
};
|
||||
|
||||
void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
|
||||
{
|
||||
aufs_bindex_t bend;
|
||||
struct au_branch *br;
|
||||
struct au_xino_file *xi;
|
||||
|
||||
if (!au_sbi(sb)->si_dbgaufs)
|
||||
return;
|
||||
|
||||
bend = au_sbend(sb);
|
||||
for (; bindex <= bend; bindex++) {
|
||||
br = au_sbr(sb, bindex);
|
||||
xi = &br->br_xino;
|
||||
if (xi->xi_dbgaufs) {
|
||||
debugfs_remove(xi->xi_dbgaufs);
|
||||
xi->xi_dbgaufs = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
|
||||
{
|
||||
struct au_sbinfo *sbinfo;
|
||||
struct dentry *parent;
|
||||
struct au_branch *br;
|
||||
struct au_xino_file *xi;
|
||||
aufs_bindex_t bend;
|
||||
char name[sizeof(DbgaufsXi_PREFIX) + 5]; /* "xi" bindex NULL */
|
||||
|
||||
sbinfo = au_sbi(sb);
|
||||
parent = sbinfo->si_dbgaufs;
|
||||
if (!parent)
|
||||
return;
|
||||
|
||||
bend = au_sbend(sb);
|
||||
for (; bindex <= bend; bindex++) {
|
||||
snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d", bindex);
|
||||
br = au_sbr(sb, bindex);
|
||||
xi = &br->br_xino;
|
||||
AuDebugOn(xi->xi_dbgaufs);
|
||||
xi->xi_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent,
|
||||
sbinfo, &dbgaufs_xino_fop);
|
||||
/* ignore an error */
|
||||
if (unlikely(!xi->xi_dbgaufs))
|
||||
AuWarn1("failed %s under debugfs\n", name);
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#ifdef CONFIG_AUFS_EXPORT
|
||||
static int dbgaufs_xigen_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
int err;
|
||||
struct au_sbinfo *sbinfo;
|
||||
struct super_block *sb;
|
||||
|
||||
sbinfo = inode->i_private;
|
||||
sb = sbinfo->si_sb;
|
||||
si_noflush_read_lock(sb);
|
||||
err = dbgaufs_xi_open(sbinfo->si_xigen, file, /*do_fcnt*/0);
|
||||
si_read_unlock(sb);
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct file_operations dbgaufs_xigen_fop = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = dbgaufs_xigen_open,
|
||||
.release = dbgaufs_xi_release,
|
||||
.read = dbgaufs_xi_read
|
||||
};
|
||||
|
||||
static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
|
||||
{
|
||||
int err;
|
||||
|
||||
/*
|
||||
* This function is a dynamic '__init' fucntion actually,
|
||||
* so the tiny check for si_rwsem is unnecessary.
|
||||
*/
|
||||
/* AuRwMustWriteLock(&sbinfo->si_rwsem); */
|
||||
|
||||
err = -EIO;
|
||||
sbinfo->si_dbgaufs_xigen = debugfs_create_file
|
||||
("xigen", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
|
||||
&dbgaufs_xigen_fop);
|
||||
if (sbinfo->si_dbgaufs_xigen)
|
||||
err = 0;
|
||||
|
||||
return err;
|
||||
}
|
||||
#else
|
||||
static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_AUFS_EXPORT */
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void dbgaufs_si_fin(struct au_sbinfo *sbinfo)
|
||||
{
|
||||
/*
|
||||
* This function is a dynamic '__init' fucntion actually,
|
||||
* so the tiny check for si_rwsem is unnecessary.
|
||||
*/
|
||||
/* AuRwMustWriteLock(&sbinfo->si_rwsem); */
|
||||
|
||||
debugfs_remove_recursive(sbinfo->si_dbgaufs);
|
||||
sbinfo->si_dbgaufs = NULL;
|
||||
kobject_put(&sbinfo->si_kobj);
|
||||
}
|
||||
|
||||
int dbgaufs_si_init(struct au_sbinfo *sbinfo)
|
||||
{
|
||||
int err;
|
||||
char name[SysaufsSiNameLen];
|
||||
|
||||
/*
|
||||
* This function is a dynamic '__init' fucntion actually,
|
||||
* so the tiny check for si_rwsem is unnecessary.
|
||||
*/
|
||||
/* AuRwMustWriteLock(&sbinfo->si_rwsem); */
|
||||
|
||||
err = -ENOENT;
|
||||
if (!dbgaufs) {
|
||||
AuErr1("/debug/aufs is uninitialized\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = -EIO;
|
||||
sysaufs_name(sbinfo, name);
|
||||
sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs);
|
||||
if (unlikely(!sbinfo->si_dbgaufs))
|
||||
goto out;
|
||||
kobject_get(&sbinfo->si_kobj);
|
||||
|
||||
sbinfo->si_dbgaufs_xib = debugfs_create_file
|
||||
("xib", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
|
||||
&dbgaufs_xib_fop);
|
||||
if (unlikely(!sbinfo->si_dbgaufs_xib))
|
||||
goto out_dir;
|
||||
|
||||
err = dbgaufs_xigen_init(sbinfo);
|
||||
if (!err)
|
||||
goto out; /* success */
|
||||
|
||||
out_dir:
|
||||
dbgaufs_si_fin(sbinfo);
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void dbgaufs_fin(void)
|
||||
{
|
||||
debugfs_remove(dbgaufs);
|
||||
}
|
||||
|
||||
int __init dbgaufs_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = -EIO;
|
||||
dbgaufs = debugfs_create_dir(AUFS_NAME, NULL);
|
||||
if (dbgaufs)
|
||||
err = 0;
|
||||
return err;
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2012 Junjiro R. Okajima
|
||||
*
|
||||
* This program, aufs is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* debugfs interface
|
||||
*/
|
||||
|
||||
#ifndef __DBGAUFS_H__
|
||||
#define __DBGAUFS_H__
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
struct super_block;
|
||||
struct au_sbinfo;
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
/* dbgaufs.c */
|
||||
void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
|
||||
void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
|
||||
void dbgaufs_si_fin(struct au_sbinfo *sbinfo);
|
||||
int dbgaufs_si_init(struct au_sbinfo *sbinfo);
|
||||
void dbgaufs_fin(void);
|
||||
int __init dbgaufs_init(void);
|
||||
#else
|
||||
AuStubVoid(dbgaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
|
||||
AuStubVoid(dbgaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
|
||||
AuStubVoid(dbgaufs_si_fin, struct au_sbinfo *sbinfo)
|
||||
AuStubInt0(dbgaufs_si_init, struct au_sbinfo *sbinfo)
|
||||
AuStubVoid(dbgaufs_fin, void)
|
||||
AuStubInt0(__init dbgaufs_init, void)
|
||||
#endif /* CONFIG_DEBUG_FS */
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* __DBGAUFS_H__ */
|
@ -1,243 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2012 Junjiro R. Okajima
|
||||
*
|
||||
* This program, aufs is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* sub-routines for dentry cache
|
||||
*/
|
||||
|
||||
#include "aufs.h"
|
||||
|
||||
static void au_dpage_free(struct au_dpage *dpage)
|
||||
{
|
||||
int i;
|
||||
struct dentry **p;
|
||||
|
||||
p = dpage->dentries;
|
||||
for (i = 0; i < dpage->ndentry; i++)
|
||||
dput(*p++);
|
||||
free_page((unsigned long)dpage->dentries);
|
||||
}
|
||||
|
||||
int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp)
|
||||
{
|
||||
int err;
|
||||
void *p;
|
||||
|
||||
err = -ENOMEM;
|
||||
dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp);
|
||||
if (unlikely(!dpages->dpages))
|
||||
goto out;
|
||||
|
||||
p = (void *)__get_free_page(gfp);
|
||||
if (unlikely(!p))
|
||||
goto out_dpages;
|
||||
|
||||
dpages->dpages[0].ndentry = 0;
|
||||
dpages->dpages[0].dentries = p;
|
||||
dpages->ndpage = 1;
|
||||
return 0; /* success */
|
||||
|
||||
out_dpages:
|
||||
kfree(dpages->dpages);
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
void au_dpages_free(struct au_dcsub_pages *dpages)
|
||||
{
|
||||
int i;
|
||||
struct au_dpage *p;
|
||||
|
||||
p = dpages->dpages;
|
||||
for (i = 0; i < dpages->ndpage; i++)
|
||||
au_dpage_free(p++);
|
||||
kfree(dpages->dpages);
|
||||
}
|
||||
|
||||
static int au_dpages_append(struct au_dcsub_pages *dpages,
|
||||
struct dentry *dentry, gfp_t gfp)
|
||||
{
|
||||
int err, sz;
|
||||
struct au_dpage *dpage;
|
||||
void *p;
|
||||
|
||||
dpage = dpages->dpages + dpages->ndpage - 1;
|
||||
sz = PAGE_SIZE / sizeof(dentry);
|
||||
if (unlikely(dpage->ndentry >= sz)) {
|
||||
AuLabel(new dpage);
|
||||
err = -ENOMEM;
|
||||
sz = dpages->ndpage * sizeof(*dpages->dpages);
|
||||
p = au_kzrealloc(dpages->dpages, sz,
|
||||
sz + sizeof(*dpages->dpages), gfp);
|
||||
if (unlikely(!p))
|
||||
goto out;
|
||||
|
||||
dpages->dpages = p;
|
||||
dpage = dpages->dpages + dpages->ndpage;
|
||||
p = (void *)__get_free_page(gfp);
|
||||
if (unlikely(!p))
|
||||
goto out;
|
||||
|
||||
dpage->ndentry = 0;
|
||||
dpage->dentries = p;
|
||||
dpages->ndpage++;
|
||||
}
|
||||
|
||||
AuDebugOn(!dentry->d_count);
|
||||
dpage->dentries[dpage->ndentry++] = dget_dlock(dentry);
|
||||
return 0; /* success */
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
|
||||
au_dpages_test test, void *arg)
|
||||
{
|
||||
int err;
|
||||
struct dentry *this_parent;
|
||||
struct list_head *next;
|
||||
struct super_block *sb = root->d_sb;
|
||||
|
||||
err = 0;
|
||||
write_seqlock(&rename_lock);
|
||||
this_parent = root;
|
||||
spin_lock(&this_parent->d_lock);
|
||||
repeat:
|
||||
next = this_parent->d_subdirs.next;
|
||||
resume:
|
||||
if (this_parent->d_sb == sb
|
||||
&& !IS_ROOT(this_parent)
|
||||
&& au_di(this_parent)
|
||||
&& this_parent->d_count
|
||||
&& (!test || test(this_parent, arg))) {
|
||||
err = au_dpages_append(dpages, this_parent, GFP_ATOMIC);
|
||||
if (unlikely(err))
|
||||
goto out;
|
||||
}
|
||||
|
||||
while (next != &this_parent->d_subdirs) {
|
||||
struct list_head *tmp = next;
|
||||
struct dentry *dentry = list_entry(tmp, struct dentry,
|
||||
d_u.d_child);
|
||||
|
||||
next = tmp->next;
|
||||
spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
|
||||
if (dentry->d_count) {
|
||||
if (!list_empty(&dentry->d_subdirs)) {
|
||||
spin_unlock(&this_parent->d_lock);
|
||||
spin_release(&dentry->d_lock.dep_map, 1,
|
||||
_RET_IP_);
|
||||
this_parent = dentry;
|
||||
spin_acquire(&this_parent->d_lock.dep_map, 0, 1,
|
||||
_RET_IP_);
|
||||
goto repeat;
|
||||
}
|
||||
if (dentry->d_sb == sb
|
||||
&& au_di(dentry)
|
||||
&& (!test || test(dentry, arg)))
|
||||
err = au_dpages_append(dpages, dentry,
|
||||
GFP_ATOMIC);
|
||||
}
|
||||
spin_unlock(&dentry->d_lock);
|
||||
if (unlikely(err))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (this_parent != root) {
|
||||
struct dentry *tmp;
|
||||
struct dentry *child;
|
||||
|
||||
tmp = this_parent->d_parent;
|
||||
rcu_read_lock();
|
||||
spin_unlock(&this_parent->d_lock);
|
||||
child = this_parent;
|
||||
this_parent = tmp;
|
||||
spin_lock(&this_parent->d_lock);
|
||||
rcu_read_unlock();
|
||||
next = child->d_u.d_child.next;
|
||||
goto resume;
|
||||
}
|
||||
|
||||
out:
|
||||
spin_unlock(&this_parent->d_lock);
|
||||
write_sequnlock(&rename_lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
|
||||
int do_include, au_dpages_test test, void *arg)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = 0;
|
||||
write_seqlock(&rename_lock);
|
||||
spin_lock(&dentry->d_lock);
|
||||
if (do_include
|
||||
&& dentry->d_count
|
||||
&& (!test || test(dentry, arg)))
|
||||
err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
|
||||
spin_unlock(&dentry->d_lock);
|
||||
if (unlikely(err))
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* vfsmount_lock is unnecessary since this is a traverse in a single
|
||||
* mount
|
||||
*/
|
||||
while (!IS_ROOT(dentry)) {
|
||||
dentry = dentry->d_parent; /* rename_lock is locked */
|
||||
spin_lock(&dentry->d_lock);
|
||||
if (dentry->d_count
|
||||
&& (!test || test(dentry, arg)))
|
||||
err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
|
||||
spin_unlock(&dentry->d_lock);
|
||||
if (unlikely(err))
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
write_sequnlock(&rename_lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
static inline int au_dcsub_dpages_aufs(struct dentry *dentry, void *arg)
|
||||
{
|
||||
return au_di(dentry) && dentry->d_sb == arg;
|
||||
}
|
||||
|
||||
int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
|
||||
struct dentry *dentry, int do_include)
|
||||
{
|
||||
return au_dcsub_pages_rev(dpages, dentry, do_include,
|
||||
au_dcsub_dpages_aufs, dentry->d_sb);
|
||||
}
|
||||
|
||||
int au_test_subdir(struct dentry *d1, struct dentry *d2)
|
||||
{
|
||||
struct path path[2] = {
|
||||
{
|
||||
.dentry = d1
|
||||
},
|
||||
{
|
||||
.dentry = d2
|
||||
}
|
||||
};
|
||||
|
||||
return path_is_under(path + 0, path + 1);
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2012 Junjiro R. Okajima
|
||||
*
|
||||
* This program, aufs is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* sub-routines for dentry cache
|
||||
*/
|
||||
|
||||
#ifndef __AUFS_DCSUB_H__
|
||||
#define __AUFS_DCSUB_H__
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/dcache.h>
|
||||
#include <linux/fs.h>
|
||||
|
||||
struct dentry;
|
||||
|
||||
struct au_dpage {
|
||||
int ndentry;
|
||||
struct dentry **dentries;
|
||||
};
|
||||
|
||||
struct au_dcsub_pages {
|
||||
int ndpage;
|
||||
struct au_dpage *dpages;
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/* dcsub.c */
|
||||
int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp);
|
||||
void au_dpages_free(struct au_dcsub_pages *dpages);
|
||||
typedef int (*au_dpages_test)(struct dentry *dentry, void *arg);
|
||||
int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
|
||||
au_dpages_test test, void *arg);
|
||||
int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
|
||||
int do_include, au_dpages_test test, void *arg);
|
||||
int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
|
||||
struct dentry *dentry, int do_include);
|
||||
int au_test_subdir(struct dentry *d1, struct dentry *d2);
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static inline int au_d_hashed_positive(struct dentry *d)
|
||||
{
|
||||
int err;
|
||||
struct inode *inode = d->d_inode;
|
||||
err = 0;
|
||||
if (unlikely(d_unhashed(d) || !inode || !inode->i_nlink))
|
||||
err = -ENOENT;
|
||||
return err;
|
||||
}
|
||||
|
||||
static inline int au_d_alive(struct dentry *d)
|
||||
{
|
||||
int err;
|
||||
struct inode *inode;
|
||||
err = 0;
|
||||
if (!IS_ROOT(d))
|
||||
err = au_d_hashed_positive(d);
|
||||
else {
|
||||
inode = d->d_inode;
|
||||
if (unlikely(d_unlinked(d) || !inode || !inode->i_nlink))
|
||||
err = -ENOENT;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static inline int au_alive_dir(struct dentry *d)
|
||||
{
|
||||
int err;
|
||||
err = au_d_alive(d);
|
||||
if (unlikely(err || IS_DEADDIR(d->d_inode)))
|
||||
err = -ENOENT;
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* __AUFS_DCSUB_H__ */
|
@ -1,489 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2012 Junjiro R. Okajima
|
||||
*
|
||||
* This program, aufs is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* debug print functions
|
||||
*/
|
||||
|
||||
#include <linux/vt_kern.h>
|
||||
#include "aufs.h"
|
||||
|
||||
int aufs_debug;
|
||||
MODULE_PARM_DESC(debug, "debug print");
|
||||
module_param_named(debug, aufs_debug, int, S_IRUGO | S_IWUSR | S_IWGRP);
|
||||
|
||||
char *au_plevel = KERN_DEBUG;
|
||||
#define dpri(fmt, ...) do { \
|
||||
if ((au_plevel \
|
||||
&& strcmp(au_plevel, KERN_DEBUG)) \
|
||||
|| au_debug_test()) \
|
||||
printk("%s" fmt, au_plevel, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void au_dpri_whlist(struct au_nhash *whlist)
|
||||
{
|
||||
unsigned long ul, n;
|
||||
struct hlist_head *head;
|
||||
struct au_vdir_wh *tpos;
|
||||
struct hlist_node *pos;
|
||||
|
||||
n = whlist->nh_num;
|
||||
head = whlist->nh_head;
|
||||
for (ul = 0; ul < n; ul++) {
|
||||
hlist_for_each_entry(tpos, pos, head, wh_hash)
|
||||
dpri("b%d, %.*s, %d\n",
|
||||
tpos->wh_bindex,
|
||||
tpos->wh_str.len, tpos->wh_str.name,
|
||||
tpos->wh_str.len);
|
||||
head++;
|
||||
}
|
||||
}
|
||||
|
||||
void au_dpri_vdir(struct au_vdir *vdir)
|
||||
{
|
||||
unsigned long ul;
|
||||
union au_vdir_deblk_p p;
|
||||
unsigned char *o;
|
||||
|
||||
if (!vdir || IS_ERR(vdir)) {
|
||||
dpri("err %ld\n", PTR_ERR(vdir));
|
||||
return;
|
||||
}
|
||||
|
||||
dpri("deblk %u, nblk %lu, deblk %p, last{%lu, %p}, ver %lu\n",
|
||||
vdir->vd_deblk_sz, vdir->vd_nblk, vdir->vd_deblk,
|
||||
vdir->vd_last.ul, vdir->vd_last.p.deblk, vdir->vd_version);
|
||||
for (ul = 0; ul < vdir->vd_nblk; ul++) {
|
||||
p.deblk = vdir->vd_deblk[ul];
|
||||
o = p.deblk;
|
||||
dpri("[%lu]: %p\n", ul, o);
|
||||
}
|
||||
}
|
||||
|
||||
static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode, int hn,
|
||||
struct dentry *wh)
|
||||
{
|
||||
char *n = NULL;
|
||||
int l = 0;
|
||||
|
||||
if (!inode || IS_ERR(inode)) {
|
||||
dpri("i%d: err %ld\n", bindex, PTR_ERR(inode));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* the type of i_blocks depends upon CONFIG_LSF */
|
||||
BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long)
|
||||
&& sizeof(inode->i_blocks) != sizeof(u64));
|
||||
if (wh) {
|
||||
n = (void *)wh->d_name.name;
|
||||
l = wh->d_name.len;
|
||||
}
|
||||
|
||||
dpri("i%d: %p, i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu,"
|
||||
" hn %d, ct %lld, np %lu, st 0x%lx, f 0x%x, v %llu, g %x%s%.*s\n",
|
||||
bindex, inode,
|
||||
inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??",
|
||||
atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode,
|
||||
i_size_read(inode), (unsigned long long)inode->i_blocks,
|
||||
hn, (long long)timespec_to_ns(&inode->i_ctime) & 0x0ffff,
|
||||
inode->i_mapping ? inode->i_mapping->nrpages : 0,
|
||||
inode->i_state, inode->i_flags, inode->i_version,
|
||||
inode->i_generation,
|
||||
l ? ", wh " : "", l, n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void au_dpri_inode(struct inode *inode)
|
||||
{
|
||||
struct au_iinfo *iinfo;
|
||||
aufs_bindex_t bindex;
|
||||
int err, hn;
|
||||
|
||||
err = do_pri_inode(-1, inode, -1, NULL);
|
||||
if (err || !au_test_aufs(inode->i_sb))
|
||||
return;
|
||||
|
||||
iinfo = au_ii(inode);
|
||||
if (!iinfo)
|
||||
return;
|
||||
dpri("i-1: bstart %d, bend %d, gen %d\n",
|
||||
iinfo->ii_bstart, iinfo->ii_bend, au_iigen(inode));
|
||||
if (iinfo->ii_bstart < 0)
|
||||
return;
|
||||
hn = 0;
|
||||
for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; bindex++) {
|
||||
hn = !!au_hn(iinfo->ii_hinode + bindex);
|
||||
do_pri_inode(bindex, iinfo->ii_hinode[0 + bindex].hi_inode, hn,
|
||||
iinfo->ii_hinode[0 + bindex].hi_whdentry);
|
||||
}
|
||||
}
|
||||
|
||||
void au_dpri_dalias(struct inode *inode)
|
||||
{
|
||||
struct dentry *d;
|
||||
|
||||
spin_lock(&inode->i_lock);
|
||||
list_for_each_entry(d, &inode->i_dentry, d_alias)
|
||||
au_dpri_dentry(d);
|
||||
spin_unlock(&inode->i_lock);
|
||||
}
|
||||
|
||||
static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry)
|
||||
{
|
||||
struct dentry *wh = NULL;
|
||||
int hn;
|
||||
|
||||
if (!dentry || IS_ERR(dentry)) {
|
||||
dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry));
|
||||
return -1;
|
||||
}
|
||||
/* do not call dget_parent() here */
|
||||
/* note: access d_xxx without d_lock */
|
||||
dpri("d%d: %.*s?/%.*s, %s, cnt %d, flags 0x%x\n",
|
||||
bindex,
|
||||
AuDLNPair(dentry->d_parent), AuDLNPair(dentry),
|
||||
dentry->d_sb ? au_sbtype(dentry->d_sb) : "??",
|
||||
dentry->d_count, dentry->d_flags);
|
||||
hn = -1;
|
||||
if (bindex >= 0 && dentry->d_inode && au_test_aufs(dentry->d_sb)) {
|
||||
struct au_iinfo *iinfo = au_ii(dentry->d_inode);
|
||||
if (iinfo) {
|
||||
hn = !!au_hn(iinfo->ii_hinode + bindex);
|
||||
wh = iinfo->ii_hinode[0 + bindex].hi_whdentry;
|
||||
}
|
||||
}
|
||||
do_pri_inode(bindex, dentry->d_inode, hn, wh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void au_dpri_dentry(struct dentry *dentry)
|
||||
{
|
||||
struct au_dinfo *dinfo;
|
||||
aufs_bindex_t bindex;
|
||||
int err;
|
||||
struct au_hdentry *hdp;
|
||||
|
||||
err = do_pri_dentry(-1, dentry);
|
||||
if (err || !au_test_aufs(dentry->d_sb))
|
||||
return;
|
||||
|
||||
dinfo = au_di(dentry);
|
||||
if (!dinfo)
|
||||
return;
|
||||
dpri("d-1: bstart %d, bend %d, bwh %d, bdiropq %d, gen %d\n",
|
||||
dinfo->di_bstart, dinfo->di_bend,
|
||||
dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry));
|
||||
if (dinfo->di_bstart < 0)
|
||||
return;
|
||||
hdp = dinfo->di_hdentry;
|
||||
for (bindex = dinfo->di_bstart; bindex <= dinfo->di_bend; bindex++)
|
||||
do_pri_dentry(bindex, hdp[0 + bindex].hd_dentry);
|
||||
}
|
||||
|
||||
static int do_pri_file(aufs_bindex_t bindex, struct file *file)
|
||||
{
|
||||
char a[32];
|
||||
|
||||
if (!file || IS_ERR(file)) {
|
||||
dpri("f%d: err %ld\n", bindex, PTR_ERR(file));
|
||||
return -1;
|
||||
}
|
||||
a[0] = 0;
|
||||
if (bindex < 0
|
||||
&& file->f_dentry
|
||||
&& au_test_aufs(file->f_dentry->d_sb)
|
||||
&& au_fi(file))
|
||||
snprintf(a, sizeof(a), ", gen %d, mmapped %d",
|
||||
au_figen(file), atomic_read(&au_fi(file)->fi_mmapped));
|
||||
dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, v %llu, pos %llu%s\n",
|
||||
bindex, file->f_mode, file->f_flags, (long)file_count(file),
|
||||
file->f_version, file->f_pos, a);
|
||||
if (file->f_dentry)
|
||||
do_pri_dentry(bindex, file->f_dentry);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void au_dpri_file(struct file *file)
|
||||
{
|
||||
struct au_finfo *finfo;
|
||||
struct au_fidir *fidir;
|
||||
struct au_hfile *hfile;
|
||||
aufs_bindex_t bindex;
|
||||
int err;
|
||||
|
||||
err = do_pri_file(-1, file);
|
||||
if (err || !file->f_dentry || !au_test_aufs(file->f_dentry->d_sb))
|
||||
return;
|
||||
|
||||
finfo = au_fi(file);
|
||||
if (!finfo)
|
||||
return;
|
||||
if (finfo->fi_btop < 0)
|
||||
return;
|
||||
fidir = finfo->fi_hdir;
|
||||
if (!fidir)
|
||||
do_pri_file(finfo->fi_btop, finfo->fi_htop.hf_file);
|
||||
else
|
||||
for (bindex = finfo->fi_btop;
|
||||
bindex >= 0 && bindex <= fidir->fd_bbot;
|
||||
bindex++) {
|
||||
hfile = fidir->fd_hfile + bindex;
|
||||
do_pri_file(bindex, hfile ? hfile->hf_file : NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br)
|
||||
{
|
||||
struct vfsmount *mnt;
|
||||
struct super_block *sb;
|
||||
|
||||
if (!br || IS_ERR(br))
|
||||
goto out;
|
||||
mnt = br->br_mnt;
|
||||
if (!mnt || IS_ERR(mnt))
|
||||
goto out;
|
||||
sb = mnt->mnt_sb;
|
||||
if (!sb || IS_ERR(sb))
|
||||
goto out;
|
||||
|
||||
dpri("s%d: {perm 0x%x, id %d, cnt %d, wbr %p}, "
|
||||
"%s, dev 0x%02x%02x, flags 0x%lx, cnt %d, active %d, "
|
||||
"xino %d\n",
|
||||
bindex, br->br_perm, br->br_id, atomic_read(&br->br_count),
|
||||
br->br_wbr, au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev),
|
||||
sb->s_flags, sb->s_count,
|
||||
atomic_read(&sb->s_active), !!br->br_xino.xi_file);
|
||||
return 0;
|
||||
|
||||
out:
|
||||
dpri("s%d: err %ld\n", bindex, PTR_ERR(br));
|
||||
return -1;
|
||||
}
|
||||
|
||||
void au_dpri_sb(struct super_block *sb)
|
||||
{
|
||||
struct au_sbinfo *sbinfo;
|
||||
aufs_bindex_t bindex;
|
||||
int err;
|
||||
/* to reuduce stack size */
|
||||
struct {
|
||||
struct vfsmount mnt;
|
||||
struct au_branch fake;
|
||||
} *a;
|
||||
|
||||
/* this function can be called from magic sysrq */
|
||||
a = kzalloc(sizeof(*a), GFP_ATOMIC);
|
||||
if (unlikely(!a)) {
|
||||
dpri("no memory\n");
|
||||
return;
|
||||
}
|
||||
|
||||
a->mnt.mnt_sb = sb;
|
||||
a->fake.br_perm = 0;
|
||||
a->fake.br_mnt = &a->mnt;
|
||||
a->fake.br_xino.xi_file = NULL;
|
||||
atomic_set(&a->fake.br_count, 0);
|
||||
smp_mb(); /* atomic_set */
|
||||
err = do_pri_br(-1, &a->fake);
|
||||
kfree(a);
|
||||
dpri("dev 0x%x\n", sb->s_dev);
|
||||
if (err || !au_test_aufs(sb))
|
||||
return;
|
||||
|
||||
sbinfo = au_sbi(sb);
|
||||
if (!sbinfo)
|
||||
return;
|
||||
dpri("nw %d, gen %u, kobj %d\n",
|
||||
atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation,
|
||||
atomic_read(&sbinfo->si_kobj.kref.refcount));
|
||||
for (bindex = 0; bindex <= sbinfo->si_bend; bindex++)
|
||||
do_pri_br(bindex, sbinfo->si_branch[0 + bindex]);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void au_dbg_sleep_jiffy(int jiffy)
|
||||
{
|
||||
while (jiffy)
|
||||
jiffy = schedule_timeout_uninterruptible(jiffy);
|
||||
}
|
||||
|
||||
void au_dbg_iattr(struct iattr *ia)
|
||||
{
|
||||
#define AuBit(name) if (ia->ia_valid & ATTR_ ## name) \
|
||||
dpri(#name "\n")
|
||||
AuBit(MODE);
|
||||
AuBit(UID);
|
||||
AuBit(GID);
|
||||
AuBit(SIZE);
|
||||
AuBit(ATIME);
|
||||
AuBit(MTIME);
|
||||
AuBit(CTIME);
|
||||
AuBit(ATIME_SET);
|
||||
AuBit(MTIME_SET);
|
||||
AuBit(FORCE);
|
||||
AuBit(ATTR_FLAG);
|
||||
AuBit(KILL_SUID);
|
||||
AuBit(KILL_SGID);
|
||||
AuBit(FILE);
|
||||
AuBit(KILL_PRIV);
|
||||
AuBit(OPEN);
|
||||
AuBit(TIMES_SET);
|
||||
#undef AuBit
|
||||
dpri("ia_file %p\n", ia->ia_file);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line)
|
||||
{
|
||||
struct inode *h_inode, *inode = dentry->d_inode;
|
||||
struct dentry *h_dentry;
|
||||
aufs_bindex_t bindex, bend, bi;
|
||||
|
||||
if (!inode /* || au_di(dentry)->di_lsc == AuLsc_DI_TMP */)
|
||||
return;
|
||||
|
||||
bend = au_dbend(dentry);
|
||||
bi = au_ibend(inode);
|
||||
if (bi < bend)
|
||||
bend = bi;
|
||||
bindex = au_dbstart(dentry);
|
||||
bi = au_ibstart(inode);
|
||||
if (bi > bindex)
|
||||
bindex = bi;
|
||||
|
||||
for (; bindex <= bend; bindex++) {
|
||||
h_dentry = au_h_dptr(dentry, bindex);
|
||||
if (!h_dentry)
|
||||
continue;
|
||||
h_inode = au_h_iptr(inode, bindex);
|
||||
if (unlikely(h_inode != h_dentry->d_inode)) {
|
||||
int old = au_debug_test();
|
||||
if (!old)
|
||||
au_debug(1);
|
||||
AuDbg("b%d, %s:%d\n", bindex, func, line);
|
||||
AuDbgDentry(dentry);
|
||||
AuDbgInode(inode);
|
||||
if (!old)
|
||||
au_debug(0);
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen)
|
||||
{
|
||||
struct dentry *parent;
|
||||
|
||||
parent = dget_parent(dentry);
|
||||
AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode));
|
||||
AuDebugOn(IS_ROOT(dentry));
|
||||
AuDebugOn(au_digen_test(parent, sigen));
|
||||
dput(parent);
|
||||
}
|
||||
|
||||
void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen)
|
||||
{
|
||||
struct dentry *parent;
|
||||
struct inode *inode;
|
||||
|
||||
parent = dget_parent(dentry);
|
||||
inode = dentry->d_inode;
|
||||
AuDebugOn(inode && S_ISDIR(dentry->d_inode->i_mode));
|
||||
AuDebugOn(au_digen_test(parent, sigen));
|
||||
dput(parent);
|
||||
}
|
||||
|
||||
void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen)
|
||||
{
|
||||
int err, i, j;
|
||||
struct au_dcsub_pages dpages;
|
||||
struct au_dpage *dpage;
|
||||
struct dentry **dentries;
|
||||
|
||||
err = au_dpages_init(&dpages, GFP_NOFS);
|
||||
AuDebugOn(err);
|
||||
err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/1);
|
||||
AuDebugOn(err);
|
||||
for (i = dpages.ndpage - 1; !err && i >= 0; i--) {
|
||||
dpage = dpages.dpages + i;
|
||||
dentries = dpage->dentries;
|
||||
for (j = dpage->ndentry - 1; !err && j >= 0; j--)
|
||||
AuDebugOn(au_digen_test(dentries[j], sigen));
|
||||
}
|
||||
au_dpages_free(&dpages);
|
||||
}
|
||||
|
||||
void au_dbg_verify_kthread(void)
|
||||
{
|
||||
if (au_wkq_test()) {
|
||||
au_dbg_blocked();
|
||||
/*
|
||||
* It may be recursive, but udba=notify between two aufs mounts,
|
||||
* where a single ro branch is shared, is not a problem.
|
||||
*/
|
||||
/* WARN_ON(1); */
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void au_debug_sbinfo_init(struct au_sbinfo *sbinfo __maybe_unused)
|
||||
{
|
||||
#ifdef AuForceNoPlink
|
||||
au_opt_clr(sbinfo->si_mntflags, PLINK);
|
||||
#endif
|
||||
#ifdef AuForceNoXino
|
||||
au_opt_clr(sbinfo->si_mntflags, XINO);
|
||||
#endif
|
||||
#ifdef AuForceNoRefrof
|
||||
au_opt_clr(sbinfo->si_mntflags, REFROF);
|
||||
#endif
|
||||
#ifdef AuForceHnotify
|
||||
au_opt_set_udba(sbinfo->si_mntflags, UDBA_HNOTIFY);
|
||||
#endif
|
||||
#ifdef AuForceRd0
|
||||
sbinfo->si_rdblk = 0;
|
||||
sbinfo->si_rdhash = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int __init au_debug_init(void)
|
||||
{
|
||||
aufs_bindex_t bindex;
|
||||
struct au_vdir_destr destr;
|
||||
|
||||
bindex = -1;
|
||||
AuDebugOn(bindex >= 0);
|
||||
|
||||
destr.len = -1;
|
||||
AuDebugOn(destr.len < NAME_MAX);
|
||||
|
||||
#ifdef CONFIG_4KSTACKS
|
||||
pr_warn("CONFIG_4KSTACKS is defined.\n");
|
||||
#endif
|
||||
|
||||
#ifdef AuForceNoBrs
|
||||
sysaufs_brs = 0;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,243 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2012 Junjiro R. Okajima
|
||||
*
|
||||
* This program, aufs is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* debug print functions
|
||||
*/
|
||||
|
||||
#ifndef __AUFS_DEBUG_H__
|
||||
#define __AUFS_DEBUG_H__
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kallsyms.h>
|
||||
#include <linux/sysrq.h>
|
||||
|
||||
#ifdef CONFIG_AUFS_DEBUG
|
||||
#define AuDebugOn(a) BUG_ON(a)
|
||||
|
||||
/* module parameter */
|
||||
extern int aufs_debug;
|
||||
static inline void au_debug(int n)
|
||||
{
|
||||
aufs_debug = n;
|
||||
smp_mb();
|
||||
}
|
||||
|
||||
static inline int au_debug_test(void)
|
||||
{
|
||||
return aufs_debug;
|
||||
}
|
||||
#else
|
||||
#define AuDebugOn(a) do {} while (0)
|
||||
AuStubVoid(au_debug, int n)
|
||||
AuStubInt0(au_debug_test, void)
|
||||
#endif /* CONFIG_AUFS_DEBUG */
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/* debug print */
|
||||
|
||||
#define AuDbg(fmt, ...) do { \
|
||||
if (au_debug_test()) \
|
||||
pr_debug("DEBUG: " fmt, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
#define AuLabel(l) AuDbg(#l "\n")
|
||||
#define AuIOErr(fmt, ...) pr_err("I/O Error, " fmt, ##__VA_ARGS__)
|
||||
#define AuWarn1(fmt, ...) do { \
|
||||
static unsigned char _c; \
|
||||
if (!_c++) \
|
||||
pr_warn(fmt, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define AuErr1(fmt, ...) do { \
|
||||
static unsigned char _c; \
|
||||
if (!_c++) \
|
||||
pr_err(fmt, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define AuIOErr1(fmt, ...) do { \
|
||||
static unsigned char _c; \
|
||||
if (!_c++) \
|
||||
AuIOErr(fmt, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define AuUnsupportMsg "This operation is not supported." \
|
||||
" Please report this application to aufs-users ML."
|
||||
#define AuUnsupport(fmt, ...) do { \
|
||||
pr_err(AuUnsupportMsg "\n" fmt, ##__VA_ARGS__); \
|
||||
dump_stack(); \
|
||||
} while (0)
|
||||
|
||||
#define AuTraceErr(e) do { \
|
||||
if (unlikely((e) < 0)) \
|
||||
AuDbg("err %d\n", (int)(e)); \
|
||||
} while (0)
|
||||
|
||||
#define AuTraceErrPtr(p) do { \
|
||||
if (IS_ERR(p)) \
|
||||
AuDbg("err %ld\n", PTR_ERR(p)); \
|
||||
} while (0)
|
||||
|
||||
/* dirty macros for debug print, use with "%.*s" and caution */
|
||||
#define AuLNPair(qstr) (qstr)->len, (qstr)->name
|
||||
#define AuDLNPair(d) AuLNPair(&(d)->d_name)
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
struct au_sbinfo;
|
||||
struct au_finfo;
|
||||
struct dentry;
|
||||
#ifdef CONFIG_AUFS_DEBUG
|
||||
extern char *au_plevel;
|
||||
struct au_nhash;
|
||||
void au_dpri_whlist(struct au_nhash *whlist);
|
||||
struct au_vdir;
|
||||
void au_dpri_vdir(struct au_vdir *vdir);
|
||||
struct inode;
|
||||
void au_dpri_inode(struct inode *inode);
|
||||
void au_dpri_dalias(struct inode *inode);
|
||||
void au_dpri_dentry(struct dentry *dentry);
|
||||
struct file;
|
||||
void au_dpri_file(struct file *filp);
|
||||
struct super_block;
|
||||
void au_dpri_sb(struct super_block *sb);
|
||||
|
||||
void au_dbg_sleep_jiffy(int jiffy);
|
||||
struct iattr;
|
||||
void au_dbg_iattr(struct iattr *ia);
|
||||
|
||||
#define au_dbg_verify_dinode(d) __au_dbg_verify_dinode(d, __func__, __LINE__)
|
||||
void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line);
|
||||
void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen);
|
||||
void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen);
|
||||
void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen);
|
||||
void au_dbg_verify_kthread(void);
|
||||
|
||||
int __init au_debug_init(void);
|
||||
void au_debug_sbinfo_init(struct au_sbinfo *sbinfo);
|
||||
#define AuDbgWhlist(w) do { \
|
||||
AuDbg(#w "\n"); \
|
||||
au_dpri_whlist(w); \
|
||||
} while (0)
|
||||
|
||||
#define AuDbgVdir(v) do { \
|
||||
AuDbg(#v "\n"); \
|
||||
au_dpri_vdir(v); \
|
||||
} while (0)
|
||||
|
||||
#define AuDbgInode(i) do { \
|
||||
AuDbg(#i "\n"); \
|
||||
au_dpri_inode(i); \
|
||||
} while (0)
|
||||
|
||||
#define AuDbgDAlias(i) do { \
|
||||
AuDbg(#i "\n"); \
|
||||
au_dpri_dalias(i); \
|
||||
} while (0)
|
||||
|
||||
#define AuDbgDentry(d) do { \
|
||||
AuDbg(#d "\n"); \
|
||||
au_dpri_dentry(d); \
|
||||
} while (0)
|
||||
|
||||
#define AuDbgFile(f) do { \
|
||||
AuDbg(#f "\n"); \
|
||||
au_dpri_file(f); \
|
||||
} while (0)
|
||||
|
||||
#define AuDbgSb(sb) do { \
|
||||
AuDbg(#sb "\n"); \
|
||||
au_dpri_sb(sb); \
|
||||
} while (0)
|
||||
|
||||
#define AuDbgSleep(sec) do { \
|
||||
AuDbg("sleep %d sec\n", sec); \
|
||||
ssleep(sec); \
|
||||
} while (0)
|
||||
|
||||
#define AuDbgSleepJiffy(jiffy) do { \
|
||||
AuDbg("sleep %d jiffies\n", jiffy); \
|
||||
au_dbg_sleep_jiffy(jiffy); \
|
||||
} while (0)
|
||||
|
||||
#define AuDbgIAttr(ia) do { \
|
||||
AuDbg("ia_valid 0x%x\n", (ia)->ia_valid); \
|
||||
au_dbg_iattr(ia); \
|
||||
} while (0)
|
||||
|
||||
#define AuDbgSym(addr) do { \
|
||||
char sym[KSYM_SYMBOL_LEN]; \
|
||||
sprint_symbol(sym, (unsigned long)addr); \
|
||||
AuDbg("%s\n", sym); \
|
||||
} while (0)
|
||||
|
||||
#define AuInfoSym(addr) do { \
|
||||
char sym[KSYM_SYMBOL_LEN]; \
|
||||
sprint_symbol(sym, (unsigned long)addr); \
|
||||
AuInfo("%s\n", sym); \
|
||||
} while (0)
|
||||
#else
|
||||
AuStubVoid(au_dbg_verify_dinode, struct dentry *dentry)
|
||||
AuStubVoid(au_dbg_verify_dir_parent, struct dentry *dentry, unsigned int sigen)
|
||||
AuStubVoid(au_dbg_verify_nondir_parent, struct dentry *dentry,
|
||||
unsigned int sigen)
|
||||
AuStubVoid(au_dbg_verify_gen, struct dentry *parent, unsigned int sigen)
|
||||
AuStubVoid(au_dbg_verify_kthread, void)
|
||||
AuStubInt0(__init au_debug_init, void)
|
||||
AuStubVoid(au_debug_sbinfo_init, struct au_sbinfo *sbinfo)
|
||||
|
||||
#define AuDbgWhlist(w) do {} while (0)
|
||||
#define AuDbgVdir(v) do {} while (0)
|
||||
#define AuDbgInode(i) do {} while (0)
|
||||
#define AuDbgDAlias(i) do {} while (0)
|
||||
#define AuDbgDentry(d) do {} while (0)
|
||||
#define AuDbgFile(f) do {} while (0)
|
||||
#define AuDbgSb(sb) do {} while (0)
|
||||
#define AuDbgSleep(sec) do {} while (0)
|
||||
#define AuDbgSleepJiffy(jiffy) do {} while (0)
|
||||
#define AuDbgIAttr(ia) do {} while (0)
|
||||
#define AuDbgSym(addr) do {} while (0)
|
||||
#define AuInfoSym(addr) do {} while (0)
|
||||
#endif /* CONFIG_AUFS_DEBUG */
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#ifdef CONFIG_AUFS_MAGIC_SYSRQ
|
||||
int __init au_sysrq_init(void);
|
||||
void au_sysrq_fin(void);
|
||||
|
||||
#ifdef CONFIG_HW_CONSOLE
|
||||
#define au_dbg_blocked() do { \
|
||||
WARN_ON(1); \
|
||||
handle_sysrq('w'); \
|
||||
} while (0)
|
||||
#else
|
||||
AuStubVoid(au_dbg_blocked, void)
|
||||
#endif
|
||||
|
||||
#else
|
||||
AuStubInt0(__init au_sysrq_init, void)
|
||||
AuStubVoid(au_sysrq_fin, void)
|
||||
AuStubVoid(au_dbg_blocked, void)
|
||||
#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* __AUFS_DEBUG_H__ */
|
File diff suppressed because it is too large
Load Diff
@ -1,237 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2012 Junjiro R. Okajima
|
||||
*
|
||||
* This program, aufs is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* lookup and dentry operations
|
||||
*/
|
||||
|
||||
#ifndef __AUFS_DENTRY_H__
|
||||
#define __AUFS_DENTRY_H__
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/dcache.h>
|
||||
#include "rwsem.h"
|
||||
|
||||
struct au_hdentry {
|
||||
struct dentry *hd_dentry;
|
||||
aufs_bindex_t hd_id;
|
||||
};
|
||||
|
||||
struct au_dinfo {
|
||||
atomic_t di_generation;
|
||||
|
||||
struct au_rwsem di_rwsem;
|
||||
aufs_bindex_t di_bstart, di_bend, di_bwh, di_bdiropq;
|
||||
struct au_hdentry *di_hdentry;
|
||||
} ____cacheline_aligned_in_smp;
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/* dentry.c */
|
||||
extern const struct dentry_operations aufs_dop;
|
||||
struct au_branch;
|
||||
struct dentry *au_lkup_one(struct qstr *name, struct dentry *h_parent,
|
||||
struct au_branch *br, struct nameidata *nd);
|
||||
struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent,
|
||||
struct au_branch *br);
|
||||
int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
|
||||
struct dentry *h_parent, struct au_branch *br);
|
||||
|
||||
int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type,
|
||||
struct nameidata *nd);
|
||||
int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex);
|
||||
int au_refresh_dentry(struct dentry *dentry, struct dentry *parent);
|
||||
int au_reval_dpath(struct dentry *dentry, unsigned int sigen);
|
||||
|
||||
/* dinfo.c */
|
||||
void au_di_init_once(void *_di);
|
||||
struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc);
|
||||
void au_di_free(struct au_dinfo *dinfo);
|
||||
void au_di_swap(struct au_dinfo *a, struct au_dinfo *b);
|
||||
void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src);
|
||||
int au_di_init(struct dentry *dentry);
|
||||
void au_di_fin(struct dentry *dentry);
|
||||
int au_di_realloc(struct au_dinfo *dinfo, int nbr);
|
||||
|
||||
void di_read_lock(struct dentry *d, int flags, unsigned int lsc);
|
||||
void di_read_unlock(struct dentry *d, int flags);
|
||||
void di_downgrade_lock(struct dentry *d, int flags);
|
||||
void di_write_lock(struct dentry *d, unsigned int lsc);
|
||||
void di_write_unlock(struct dentry *d);
|
||||
void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir);
|
||||
void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir);
|
||||
void di_write_unlock2(struct dentry *d1, struct dentry *d2);
|
||||
|
||||
struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex);
|
||||
struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex);
|
||||
aufs_bindex_t au_dbtail(struct dentry *dentry);
|
||||
aufs_bindex_t au_dbtaildir(struct dentry *dentry);
|
||||
|
||||
void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
|
||||
struct dentry *h_dentry);
|
||||
int au_digen_test(struct dentry *dentry, unsigned int sigen);
|
||||
int au_dbrange_test(struct dentry *dentry);
|
||||
void au_update_digen(struct dentry *dentry);
|
||||
void au_update_dbrange(struct dentry *dentry, int do_put_zero);
|
||||
void au_update_dbstart(struct dentry *dentry);
|
||||
void au_update_dbend(struct dentry *dentry);
|
||||
int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry);
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static inline struct au_dinfo *au_di(struct dentry *dentry)
|
||||
{
|
||||
return dentry->d_fsdata;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/* lock subclass for dinfo */
|
||||
enum {
|
||||
AuLsc_DI_CHILD, /* child first */
|
||||
AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hnotify */
|
||||
AuLsc_DI_CHILD3, /* copyup dirs */
|
||||
AuLsc_DI_PARENT,
|
||||
AuLsc_DI_PARENT2,
|
||||
AuLsc_DI_PARENT3,
|
||||
AuLsc_DI_TMP /* temp for replacing dinfo */
|
||||
};
|
||||
|
||||
/*
|
||||
* di_read_lock_child, di_write_lock_child,
|
||||
* di_read_lock_child2, di_write_lock_child2,
|
||||
* di_read_lock_child3, di_write_lock_child3,
|
||||
* di_read_lock_parent, di_write_lock_parent,
|
||||
* di_read_lock_parent2, di_write_lock_parent2,
|
||||
* di_read_lock_parent3, di_write_lock_parent3,
|
||||
*/
|
||||
#define AuReadLockFunc(name, lsc) \
|
||||
static inline void di_read_lock_##name(struct dentry *d, int flags) \
|
||||
{ di_read_lock(d, flags, AuLsc_DI_##lsc); }
|
||||
|
||||
#define AuWriteLockFunc(name, lsc) \
|
||||
static inline void di_write_lock_##name(struct dentry *d) \
|
||||
{ di_write_lock(d, AuLsc_DI_##lsc); }
|
||||
|
||||
#define AuRWLockFuncs(name, lsc) \
|
||||
AuReadLockFunc(name, lsc) \
|
||||
AuWriteLockFunc(name, lsc)
|
||||
|
||||
AuRWLockFuncs(child, CHILD);
|
||||
AuRWLockFuncs(child2, CHILD2);
|
||||
AuRWLockFuncs(child3, CHILD3);
|
||||
AuRWLockFuncs(parent, PARENT);
|
||||
AuRWLockFuncs(parent2, PARENT2);
|
||||
AuRWLockFuncs(parent3, PARENT3);
|
||||
|
||||
#undef AuReadLockFunc
|
||||
#undef AuWriteLockFunc
|
||||
#undef AuRWLockFuncs
|
||||
|
||||
#define DiMustNoWaiters(d) AuRwMustNoWaiters(&au_di(d)->di_rwsem)
|
||||
#define DiMustAnyLock(d) AuRwMustAnyLock(&au_di(d)->di_rwsem)
|
||||
#define DiMustWriteLock(d) AuRwMustWriteLock(&au_di(d)->di_rwsem)
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/* todo: memory barrier? */
|
||||
static inline unsigned int au_digen(struct dentry *d)
|
||||
{
|
||||
return atomic_read(&au_di(d)->di_generation);
|
||||
}
|
||||
|
||||
static inline void au_h_dentry_init(struct au_hdentry *hdentry)
|
||||
{
|
||||
hdentry->hd_dentry = NULL;
|
||||
}
|
||||
|
||||
static inline void au_hdput(struct au_hdentry *hd)
|
||||
{
|
||||
if (hd)
|
||||
dput(hd->hd_dentry);
|
||||
}
|
||||
|
||||
static inline aufs_bindex_t au_dbstart(struct dentry *dentry)
|
||||
{
|
||||
DiMustAnyLock(dentry);
|
||||
return au_di(dentry)->di_bstart;
|
||||
}
|
||||
|
||||
static inline aufs_bindex_t au_dbend(struct dentry *dentry)
|
||||
{
|
||||
DiMustAnyLock(dentry);
|
||||
return au_di(dentry)->di_bend;
|
||||
}
|
||||
|
||||
static inline aufs_bindex_t au_dbwh(struct dentry *dentry)
|
||||
{
|
||||
DiMustAnyLock(dentry);
|
||||
return au_di(dentry)->di_bwh;
|
||||
}
|
||||
|
||||
static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry)
|
||||
{
|
||||
DiMustAnyLock(dentry);
|
||||
return au_di(dentry)->di_bdiropq;
|
||||
}
|
||||
|
||||
/* todo: hard/soft set? */
|
||||
static inline void au_set_dbstart(struct dentry *dentry, aufs_bindex_t bindex)
|
||||
{
|
||||
DiMustWriteLock(dentry);
|
||||
au_di(dentry)->di_bstart = bindex;
|
||||
}
|
||||
|
||||
static inline void au_set_dbend(struct dentry *dentry, aufs_bindex_t bindex)
|
||||
{
|
||||
DiMustWriteLock(dentry);
|
||||
au_di(dentry)->di_bend = bindex;
|
||||
}
|
||||
|
||||
static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex)
|
||||
{
|
||||
DiMustWriteLock(dentry);
|
||||
/* dbwh can be outside of bstart - bend range */
|
||||
au_di(dentry)->di_bwh = bindex;
|
||||
}
|
||||
|
||||
static inline void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex)
|
||||
{
|
||||
DiMustWriteLock(dentry);
|
||||
au_di(dentry)->di_bdiropq = bindex;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#ifdef CONFIG_AUFS_HNOTIFY
|
||||
static inline void au_digen_dec(struct dentry *d)
|
||||
{
|
||||
atomic_dec(&au_di(d)->di_generation);
|
||||
}
|
||||
|
||||
static inline void au_hn_di_reinit(struct dentry *dentry)
|
||||
{
|
||||
dentry->d_fsdata = NULL;
|
||||
}
|
||||
#else
|
||||
AuStubVoid(au_hn_di_reinit, struct dentry *dentry __maybe_unused)
|
||||
#endif /* CONFIG_AUFS_HNOTIFY */
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* __AUFS_DENTRY_H__ */
|
@ -1,543 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2012 Junjiro R. Okajima
|
||||
*
|
||||
* This program, aufs is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* dentry private data
|
||||
*/
|
||||
|
||||
#include "aufs.h"
|
||||
|
||||
void au_di_init_once(void *_dinfo)
|
||||
{
|
||||
struct au_dinfo *dinfo = _dinfo;
|
||||
static struct lock_class_key aufs_di;
|
||||
|
||||
au_rw_init(&dinfo->di_rwsem);
|
||||
au_rw_class(&dinfo->di_rwsem, &aufs_di);
|
||||
}
|
||||
|
||||
struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc)
|
||||
{
|
||||
struct au_dinfo *dinfo;
|
||||
int nbr, i;
|
||||
|
||||
dinfo = au_cache_alloc_dinfo();
|
||||
if (unlikely(!dinfo))
|
||||
goto out;
|
||||
|
||||
nbr = au_sbend(sb) + 1;
|
||||
if (nbr <= 0)
|
||||
nbr = 1;
|
||||
dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS);
|
||||
if (dinfo->di_hdentry) {
|
||||
au_rw_write_lock_nested(&dinfo->di_rwsem, lsc);
|
||||
dinfo->di_bstart = -1;
|
||||
dinfo->di_bend = -1;
|
||||
dinfo->di_bwh = -1;
|
||||
dinfo->di_bdiropq = -1;
|
||||
for (i = 0; i < nbr; i++)
|
||||
dinfo->di_hdentry[i].hd_id = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
au_cache_free_dinfo(dinfo);
|
||||
dinfo = NULL;
|
||||
|
||||
out:
|
||||
return dinfo;
|
||||
}
|
||||
|
||||
void au_di_free(struct au_dinfo *dinfo)
|
||||
{
|
||||
struct au_hdentry *p;
|
||||
aufs_bindex_t bend, bindex;
|
||||
|
||||
/* dentry may not be revalidated */
|
||||
bindex = dinfo->di_bstart;
|
||||
if (bindex >= 0) {
|
||||
bend = dinfo->di_bend;
|
||||
p = dinfo->di_hdentry + bindex;
|
||||
while (bindex++ <= bend)
|
||||
au_hdput(p++);
|
||||
}
|
||||
kfree(dinfo->di_hdentry);
|
||||
au_cache_free_dinfo(dinfo);
|
||||
}
|
||||
|
||||
void au_di_swap(struct au_dinfo *a, struct au_dinfo *b)
|
||||
{
|
||||
struct au_hdentry *p;
|
||||
aufs_bindex_t bi;
|
||||
|
||||
AuRwMustWriteLock(&a->di_rwsem);
|
||||
AuRwMustWriteLock(&b->di_rwsem);
|
||||
|
||||
#define DiSwap(v, name) \
|
||||
do { \
|
||||
v = a->di_##name; \
|
||||
a->di_##name = b->di_##name; \
|
||||
b->di_##name = v; \
|
||||
} while (0)
|
||||
|
||||
DiSwap(p, hdentry);
|
||||
DiSwap(bi, bstart);
|
||||
DiSwap(bi, bend);
|
||||
DiSwap(bi, bwh);
|
||||
DiSwap(bi, bdiropq);
|
||||
/* smp_mb(); */
|
||||
|
||||
#undef DiSwap
|
||||
}
|
||||
|
||||
void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src)
|
||||
{
|
||||
AuRwMustWriteLock(&dst->di_rwsem);
|
||||
AuRwMustWriteLock(&src->di_rwsem);
|
||||
|
||||
dst->di_bstart = src->di_bstart;
|
||||
dst->di_bend = src->di_bend;
|
||||
dst->di_bwh = src->di_bwh;
|
||||
dst->di_bdiropq = src->di_bdiropq;
|
||||
/* smp_mb(); */
|
||||
}
|
||||
|
||||
int au_di_init(struct dentry *dentry)
|
||||
{
|
||||
int err;
|
||||
struct super_block *sb;
|
||||
struct au_dinfo *dinfo;
|
||||
|
||||
err = 0;
|
||||
sb = dentry->d_sb;
|
||||
dinfo = au_di_alloc(sb, AuLsc_DI_CHILD);
|
||||
if (dinfo) {
|
||||
atomic_set(&dinfo->di_generation, au_sigen(sb));
|
||||
/* smp_mb(); */ /* atomic_set */
|
||||
dentry->d_fsdata = dinfo;
|
||||
} else
|
||||
err = -ENOMEM;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void au_di_fin(struct dentry *dentry)
|
||||
{
|
||||
struct au_dinfo *dinfo;
|
||||
|
||||
dinfo = au_di(dentry);
|
||||
AuRwDestroy(&dinfo->di_rwsem);
|
||||
au_di_free(dinfo);
|
||||
}
|
||||
|
||||
int au_di_realloc(struct au_dinfo *dinfo, int nbr)
|
||||
{
|
||||
int err, sz;
|
||||
struct au_hdentry *hdp;
|
||||
|
||||
AuRwMustWriteLock(&dinfo->di_rwsem);
|
||||
|
||||
err = -ENOMEM;
|
||||
sz = sizeof(*hdp) * (dinfo->di_bend + 1);
|
||||
if (!sz)
|
||||
sz = sizeof(*hdp);
|
||||
hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS);
|
||||
if (hdp) {
|
||||
dinfo->di_hdentry = hdp;
|
||||
err = 0;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static void do_ii_write_lock(struct inode *inode, unsigned int lsc)
|
||||
{
|
||||
switch (lsc) {
|
||||
case AuLsc_DI_CHILD:
|
||||
ii_write_lock_child(inode);
|
||||
break;
|
||||
case AuLsc_DI_CHILD2:
|
||||
ii_write_lock_child2(inode);
|
||||
break;
|
||||
case AuLsc_DI_CHILD3:
|
||||
ii_write_lock_child3(inode);
|
||||
break;
|
||||
case AuLsc_DI_PARENT:
|
||||
ii_write_lock_parent(inode);
|
||||
break;
|
||||
case AuLsc_DI_PARENT2:
|
||||
ii_write_lock_parent2(inode);
|
||||
break;
|
||||
case AuLsc_DI_PARENT3:
|
||||
ii_write_lock_parent3(inode);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static void do_ii_read_lock(struct inode *inode, unsigned int lsc)
|
||||
{
|
||||
switch (lsc) {
|
||||
case AuLsc_DI_CHILD:
|
||||
ii_read_lock_child(inode);
|
||||
break;
|
||||
case AuLsc_DI_CHILD2:
|
||||
ii_read_lock_child2(inode);
|
||||
break;
|
||||
case AuLsc_DI_CHILD3:
|
||||
ii_read_lock_child3(inode);
|
||||
break;
|
||||
case AuLsc_DI_PARENT:
|
||||
ii_read_lock_parent(inode);
|
||||
break;
|
||||
case AuLsc_DI_PARENT2:
|
||||
ii_read_lock_parent2(inode);
|
||||
break;
|
||||
case AuLsc_DI_PARENT3:
|
||||
ii_read_lock_parent3(inode);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
void di_read_lock(struct dentry *d, int flags, unsigned int lsc)
|
||||
{
|
||||
au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc);
|
||||
if (d->d_inode) {
|
||||
if (au_ftest_lock(flags, IW))
|
||||
do_ii_write_lock(d->d_inode, lsc);
|
||||
else if (au_ftest_lock(flags, IR))
|
||||
do_ii_read_lock(d->d_inode, lsc);
|
||||
}
|
||||
}
|
||||
|
||||
void di_read_unlock(struct dentry *d, int flags)
|
||||
{
|
||||
if (d->d_inode) {
|
||||
if (au_ftest_lock(flags, IW)) {
|
||||
au_dbg_verify_dinode(d);
|
||||
ii_write_unlock(d->d_inode);
|
||||
} else if (au_ftest_lock(flags, IR)) {
|
||||
au_dbg_verify_dinode(d);
|
||||
ii_read_unlock(d->d_inode);
|
||||
}
|
||||
}
|
||||
au_rw_read_unlock(&au_di(d)->di_rwsem);
|
||||
}
|
||||
|
||||
void di_downgrade_lock(struct dentry *d, int flags)
|
||||
{
|
||||
if (d->d_inode && au_ftest_lock(flags, IR))
|
||||
ii_downgrade_lock(d->d_inode);
|
||||
au_rw_dgrade_lock(&au_di(d)->di_rwsem);
|
||||
}
|
||||
|
||||
void di_write_lock(struct dentry *d, unsigned int lsc)
|
||||
{
|
||||
au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc);
|
||||
if (d->d_inode)
|
||||
do_ii_write_lock(d->d_inode, lsc);
|
||||
}
|
||||
|
||||
void di_write_unlock(struct dentry *d)
|
||||
{
|
||||
au_dbg_verify_dinode(d);
|
||||
if (d->d_inode)
|
||||
ii_write_unlock(d->d_inode);
|
||||
au_rw_write_unlock(&au_di(d)->di_rwsem);
|
||||
}
|
||||
|
||||
void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir)
|
||||
{
|
||||
AuDebugOn(d1 == d2
|
||||
|| d1->d_inode == d2->d_inode
|
||||
|| d1->d_sb != d2->d_sb);
|
||||
|
||||
if (isdir && au_test_subdir(d1, d2)) {
|
||||
di_write_lock_child(d1);
|
||||
di_write_lock_child2(d2);
|
||||
} else {
|
||||
/* there should be no races */
|
||||
di_write_lock_child(d2);
|
||||
di_write_lock_child2(d1);
|
||||
}
|
||||
}
|
||||
|
||||
void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir)
|
||||
{
|
||||
AuDebugOn(d1 == d2
|
||||
|| d1->d_inode == d2->d_inode
|
||||
|| d1->d_sb != d2->d_sb);
|
||||
|
||||
if (isdir && au_test_subdir(d1, d2)) {
|
||||
di_write_lock_parent(d1);
|
||||
di_write_lock_parent2(d2);
|
||||
} else {
|
||||
/* there should be no races */
|
||||
di_write_lock_parent(d2);
|
||||
di_write_lock_parent2(d1);
|
||||
}
|
||||
}
|
||||
|
||||
void di_write_unlock2(struct dentry *d1, struct dentry *d2)
|
||||
{
|
||||
di_write_unlock(d1);
|
||||
if (d1->d_inode == d2->d_inode)
|
||||
au_rw_write_unlock(&au_di(d2)->di_rwsem);
|
||||
else
|
||||
di_write_unlock(d2);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex)
|
||||
{
|
||||
struct dentry *d;
|
||||
|
||||
DiMustAnyLock(dentry);
|
||||
|
||||
if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
|
||||
return NULL;
|
||||
AuDebugOn(bindex < 0);
|
||||
d = au_di(dentry)->di_hdentry[0 + bindex].hd_dentry;
|
||||
AuDebugOn(d && d->d_count <= 0);
|
||||
return d;
|
||||
}
|
||||
|
||||
/*
|
||||
* extended version of au_h_dptr().
|
||||
* returns a hashed and positive h_dentry in bindex, NULL, or error.
|
||||
*/
|
||||
struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex)
|
||||
{
|
||||
struct dentry *h_dentry;
|
||||
struct inode *inode, *h_inode;
|
||||
|
||||
inode = dentry->d_inode;
|
||||
AuDebugOn(!inode);
|
||||
|
||||
h_dentry = NULL;
|
||||
if (au_dbstart(dentry) <= bindex
|
||||
&& bindex <= au_dbend(dentry))
|
||||
h_dentry = au_h_dptr(dentry, bindex);
|
||||
if (h_dentry && !au_d_hashed_positive(h_dentry)) {
|
||||
dget(h_dentry);
|
||||
goto out; /* success */
|
||||
}
|
||||
|
||||
AuDebugOn(bindex < au_ibstart(inode));
|
||||
AuDebugOn(au_ibend(inode) < bindex);
|
||||
h_inode = au_h_iptr(inode, bindex);
|
||||
h_dentry = d_find_alias(h_inode);
|
||||
if (h_dentry) {
|
||||
if (!IS_ERR(h_dentry)) {
|
||||
if (!au_d_hashed_positive(h_dentry))
|
||||
goto out; /* success */
|
||||
dput(h_dentry);
|
||||
} else
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (au_opt_test(au_mntflags(dentry->d_sb), PLINK)) {
|
||||
h_dentry = au_plink_lkup(inode, bindex);
|
||||
AuDebugOn(!h_dentry);
|
||||
if (!IS_ERR(h_dentry)) {
|
||||
if (!au_d_hashed_positive(h_dentry))
|
||||
goto out; /* success */
|
||||
dput(h_dentry);
|
||||
h_dentry = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
AuDbgDentry(h_dentry);
|
||||
return h_dentry;
|
||||
}
|
||||
|
||||
aufs_bindex_t au_dbtail(struct dentry *dentry)
|
||||
{
|
||||
aufs_bindex_t bend, bwh;
|
||||
|
||||
bend = au_dbend(dentry);
|
||||
if (0 <= bend) {
|
||||
bwh = au_dbwh(dentry);
|
||||
if (!bwh)
|
||||
return bwh;
|
||||
if (0 < bwh && bwh < bend)
|
||||
return bwh - 1;
|
||||
}
|
||||
return bend;
|
||||
}
|
||||
|
||||
aufs_bindex_t au_dbtaildir(struct dentry *dentry)
|
||||
{
|
||||
aufs_bindex_t bend, bopq;
|
||||
|
||||
bend = au_dbtail(dentry);
|
||||
if (0 <= bend) {
|
||||
bopq = au_dbdiropq(dentry);
|
||||
if (0 <= bopq && bopq < bend)
|
||||
bend = bopq;
|
||||
}
|
||||
return bend;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
|
||||
struct dentry *h_dentry)
|
||||
{
|
||||
struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex;
|
||||
struct au_branch *br;
|
||||
|
||||
DiMustWriteLock(dentry);
|
||||
|
||||
au_hdput(hd);
|
||||
hd->hd_dentry = h_dentry;
|
||||
if (h_dentry) {
|
||||
br = au_sbr(dentry->d_sb, bindex);
|
||||
hd->hd_id = br->br_id;
|
||||
}
|
||||
}
|
||||
|
||||
int au_dbrange_test(struct dentry *dentry)
|
||||
{
|
||||
int err;
|
||||
aufs_bindex_t bstart, bend;
|
||||
|
||||
err = 0;
|
||||
bstart = au_dbstart(dentry);
|
||||
bend = au_dbend(dentry);
|
||||
if (bstart >= 0)
|
||||
AuDebugOn(bend < 0 && bstart > bend);
|
||||
else {
|
||||
err = -EIO;
|
||||
AuDebugOn(bend >= 0);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int au_digen_test(struct dentry *dentry, unsigned int sigen)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = 0;
|
||||
if (unlikely(au_digen(dentry) != sigen
|
||||
|| au_iigen_test(dentry->d_inode, sigen)))
|
||||
err = -EIO;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void au_update_digen(struct dentry *dentry)
|
||||
{
|
||||
atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb));
|
||||
/* smp_mb(); */ /* atomic_set */
|
||||
}
|
||||
|
||||
void au_update_dbrange(struct dentry *dentry, int do_put_zero)
|
||||
{
|
||||
struct au_dinfo *dinfo;
|
||||
struct dentry *h_d;
|
||||
struct au_hdentry *hdp;
|
||||
|
||||
DiMustWriteLock(dentry);
|
||||
|
||||
dinfo = au_di(dentry);
|
||||
if (!dinfo || dinfo->di_bstart < 0)
|
||||
return;
|
||||
|
||||
hdp = dinfo->di_hdentry;
|
||||
if (do_put_zero) {
|
||||
aufs_bindex_t bindex, bend;
|
||||
|
||||
bend = dinfo->di_bend;
|
||||
for (bindex = dinfo->di_bstart; bindex <= bend; bindex++) {
|
||||
h_d = hdp[0 + bindex].hd_dentry;
|
||||
if (h_d && !h_d->d_inode)
|
||||
au_set_h_dptr(dentry, bindex, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
dinfo->di_bstart = -1;
|
||||
while (++dinfo->di_bstart <= dinfo->di_bend)
|
||||
if (hdp[0 + dinfo->di_bstart].hd_dentry)
|
||||
break;
|
||||
if (dinfo->di_bstart > dinfo->di_bend) {
|
||||
dinfo->di_bstart = -1;
|
||||
dinfo->di_bend = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
dinfo->di_bend++;
|
||||
while (0 <= --dinfo->di_bend)
|
||||
if (hdp[0 + dinfo->di_bend].hd_dentry)
|
||||
break;
|
||||
AuDebugOn(dinfo->di_bstart > dinfo->di_bend || dinfo->di_bend < 0);
|
||||
}
|
||||
|
||||
void au_update_dbstart(struct dentry *dentry)
|
||||
{
|
||||
aufs_bindex_t bindex, bend;
|
||||
struct dentry *h_dentry;
|
||||
|
||||
bend = au_dbend(dentry);
|
||||
for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
|
||||
h_dentry = au_h_dptr(dentry, bindex);
|
||||
if (!h_dentry)
|
||||
continue;
|
||||
if (h_dentry->d_inode) {
|
||||
au_set_dbstart(dentry, bindex);
|
||||
return;
|
||||
}
|
||||
au_set_h_dptr(dentry, bindex, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void au_update_dbend(struct dentry *dentry)
|
||||
{
|
||||
aufs_bindex_t bindex, bstart;
|
||||
struct dentry *h_dentry;
|
||||
|
||||
bstart = au_dbstart(dentry);
|
||||
for (bindex = au_dbend(dentry); bindex >= bstart; bindex--) {
|
||||
h_dentry = au_h_dptr(dentry, bindex);
|
||||
if (!h_dentry)
|
||||
continue;
|
||||
if (h_dentry->d_inode) {
|
||||
au_set_dbend(dentry, bindex);
|
||||
return;
|
||||
}
|
||||
au_set_h_dptr(dentry, bindex, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry)
|
||||
{
|
||||
aufs_bindex_t bindex, bend;
|
||||
|
||||
bend = au_dbend(dentry);
|
||||
for (bindex = au_dbstart(dentry); bindex <= bend; bindex++)
|
||||
if (au_h_dptr(dentry, bindex) == h_dentry)
|
||||
return bindex;
|
||||
return -1;
|
||||
}
|
@ -1,623 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2012 Junjiro R. Okajima
|
||||
*
|
||||
* This program, aufs is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* directory operations
|
||||
*/
|
||||
|
||||
#include <linux/fs_stack.h>
|
||||
#include "aufs.h"
|
||||
|
||||
void au_add_nlink(struct inode *dir, struct inode *h_dir)
|
||||
{
|
||||
AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
|
||||
|
||||
dir->i_nlink += h_dir->i_nlink - 2;
|
||||
if (h_dir->i_nlink < 2)
|
||||
dir->i_nlink += 2;
|
||||
}
|
||||
|
||||
void au_sub_nlink(struct inode *dir, struct inode *h_dir)
|
||||
{
|
||||
AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
|
||||
|
||||
dir->i_nlink -= h_dir->i_nlink - 2;
|
||||
if (h_dir->i_nlink < 2)
|
||||
dir->i_nlink -= 2;
|
||||
}
|
||||
|
||||
loff_t au_dir_size(struct file *file, struct dentry *dentry)
|
||||
{
|
||||
loff_t sz;
|
||||
aufs_bindex_t bindex, bend;
|
||||
struct file *h_file;
|
||||
struct dentry *h_dentry;
|
||||
|
||||
sz = 0;
|
||||
if (file) {
|
||||
AuDebugOn(!file->f_dentry);
|
||||
AuDebugOn(!file->f_dentry->d_inode);
|
||||
AuDebugOn(!S_ISDIR(file->f_dentry->d_inode->i_mode));
|
||||
|
||||
bend = au_fbend_dir(file);
|
||||
for (bindex = au_fbstart(file);
|
||||
bindex <= bend && sz < KMALLOC_MAX_SIZE;
|
||||
bindex++) {
|
||||
h_file = au_hf_dir(file, bindex);
|
||||
if (h_file
|
||||
&& h_file->f_dentry
|
||||
&& h_file->f_dentry->d_inode)
|
||||
sz += i_size_read(h_file->f_dentry->d_inode);
|
||||
}
|
||||
} else {
|
||||
AuDebugOn(!dentry);
|
||||
AuDebugOn(!dentry->d_inode);
|
||||
AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode));
|
||||
|
||||
bend = au_dbtaildir(dentry);
|
||||
for (bindex = au_dbstart(dentry);
|
||||
bindex <= bend && sz < KMALLOC_MAX_SIZE;
|
||||
bindex++) {
|
||||
h_dentry = au_h_dptr(dentry, bindex);
|
||||
if (h_dentry && h_dentry->d_inode)
|
||||
sz += i_size_read(h_dentry->d_inode);
|
||||
}
|
||||
}
|
||||
if (sz < KMALLOC_MAX_SIZE)
|
||||
sz = roundup_pow_of_two(sz);
|
||||
if (sz > KMALLOC_MAX_SIZE)
|
||||
sz = KMALLOC_MAX_SIZE;
|
||||
else if (sz < NAME_MAX) {
|
||||
BUILD_BUG_ON(AUFS_RDBLK_DEF < NAME_MAX);
|
||||
sz = AUFS_RDBLK_DEF;
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static int reopen_dir(struct file *file)
|
||||
{
|
||||
int err;
|
||||
unsigned int flags;
|
||||
aufs_bindex_t bindex, btail, bstart;
|
||||
struct dentry *dentry, *h_dentry;
|
||||
struct file *h_file;
|
||||
|
||||
/* open all lower dirs */
|
||||
dentry = file->f_dentry;
|
||||
bstart = au_dbstart(dentry);
|
||||
for (bindex = au_fbstart(file); bindex < bstart; bindex++)
|
||||
au_set_h_fptr(file, bindex, NULL);
|
||||
au_set_fbstart(file, bstart);
|
||||
|
||||
btail = au_dbtaildir(dentry);
|
||||
for (bindex = au_fbend_dir(file); btail < bindex; bindex--)
|
||||
au_set_h_fptr(file, bindex, NULL);
|
||||
au_set_fbend_dir(file, btail);
|
||||
|
||||
flags = vfsub_file_flags(file);
|
||||
for (bindex = bstart; bindex <= btail; bindex++) {
|
||||
h_dentry = au_h_dptr(dentry, bindex);
|
||||
if (!h_dentry)
|
||||
continue;
|
||||
h_file = au_hf_dir(file, bindex);
|
||||
if (h_file)
|
||||
continue;
|
||||
|
||||
h_file = au_h_open(dentry, bindex, flags, file);
|
||||
err = PTR_ERR(h_file);
|
||||
if (IS_ERR(h_file))
|
||||
goto out; /* close all? */
|
||||
au_set_h_fptr(file, bindex, h_file);
|
||||
}
|
||||
au_update_figen(file);
|
||||
/* todo: necessary? */
|
||||
/* file->f_ra = h_file->f_ra; */
|
||||
err = 0;
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int do_open_dir(struct file *file, int flags)
|
||||
{
|
||||
int err;
|
||||
aufs_bindex_t bindex, btail;
|
||||
struct dentry *dentry, *h_dentry;
|
||||
struct file *h_file;
|
||||
|
||||
FiMustWriteLock(file);
|
||||
|
||||
dentry = file->f_dentry;
|
||||
err = au_alive_dir(dentry);
|
||||
if (unlikely(err))
|
||||
goto out;
|
||||
|
||||
file->f_version = dentry->d_inode->i_version;
|
||||
bindex = au_dbstart(dentry);
|
||||
au_set_fbstart(file, bindex);
|
||||
btail = au_dbtaildir(dentry);
|
||||
au_set_fbend_dir(file, btail);
|
||||
for (; !err && bindex <= btail; bindex++) {
|
||||
h_dentry = au_h_dptr(dentry, bindex);
|
||||
if (!h_dentry)
|
||||
continue;
|
||||
|
||||
h_file = au_h_open(dentry, bindex, flags, file);
|
||||
if (IS_ERR(h_file)) {
|
||||
err = PTR_ERR(h_file);
|
||||
break;
|
||||
}
|
||||
au_set_h_fptr(file, bindex, h_file);
|
||||
}
|
||||
au_update_figen(file);
|
||||
/* todo: necessary? */
|
||||
/* file->f_ra = h_file->f_ra; */
|
||||
if (!err)
|
||||
return 0; /* success */
|
||||
|
||||
/* close all */
|
||||
for (bindex = au_fbstart(file); bindex <= btail; bindex++)
|
||||
au_set_h_fptr(file, bindex, NULL);
|
||||
au_set_fbstart(file, -1);
|
||||
au_set_fbend_dir(file, -1);
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int aufs_open_dir(struct inode *inode __maybe_unused,
|
||||
struct file *file)
|
||||
{
|
||||
int err;
|
||||
struct super_block *sb;
|
||||
struct au_fidir *fidir;
|
||||
|
||||
err = -ENOMEM;
|
||||
sb = file->f_dentry->d_sb;
|
||||
si_read_lock(sb, AuLock_FLUSH);
|
||||
fidir = au_fidir_alloc(sb);
|
||||
if (fidir) {
|
||||
err = au_do_open(file, do_open_dir, fidir);
|
||||
if (unlikely(err))
|
||||
kfree(fidir);
|
||||
}
|
||||
si_read_unlock(sb);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int aufs_release_dir(struct inode *inode __maybe_unused,
|
||||
struct file *file)
|
||||
{
|
||||
struct au_vdir *vdir_cache;
|
||||
struct au_finfo *finfo;
|
||||
struct au_fidir *fidir;
|
||||
aufs_bindex_t bindex, bend;
|
||||
|
||||
finfo = au_fi(file);
|
||||
fidir = finfo->fi_hdir;
|
||||
if (fidir) {
|
||||
/* remove me from sb->s_files */
|
||||
file_sb_list_del(file);
|
||||
|
||||
vdir_cache = fidir->fd_vdir_cache; /* lock-free */
|
||||
if (vdir_cache)
|
||||
au_vdir_free(vdir_cache);
|
||||
|
||||
bindex = finfo->fi_btop;
|
||||
if (bindex >= 0) {
|
||||
/*
|
||||
* calls fput() instead of filp_close(),
|
||||
* since no dnotify or lock for the lower file.
|
||||
*/
|
||||
bend = fidir->fd_bbot;
|
||||
for (; bindex <= bend; bindex++)
|
||||
au_set_h_fptr(file, bindex, NULL);
|
||||
}
|
||||
kfree(fidir);
|
||||
finfo->fi_hdir = NULL;
|
||||
}
|
||||
au_finfo_fin(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static int au_do_flush_dir(struct file *file, fl_owner_t id)
|
||||
{
|
||||
int err;
|
||||
aufs_bindex_t bindex, bend;
|
||||
struct file *h_file;
|
||||
|
||||
err = 0;
|
||||
bend = au_fbend_dir(file);
|
||||
for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
|
||||
h_file = au_hf_dir(file, bindex);
|
||||
if (h_file)
|
||||
err = vfsub_flush(h_file, id);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int aufs_flush_dir(struct file *file, fl_owner_t id)
|
||||
{
|
||||
return au_do_flush(file, id, au_do_flush_dir);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static int au_do_fsync_dir_no_file(struct dentry *dentry, int datasync)
|
||||
{
|
||||
int err;
|
||||
aufs_bindex_t bend, bindex;
|
||||
struct inode *inode;
|
||||
struct super_block *sb;
|
||||
|
||||
err = 0;
|
||||
sb = dentry->d_sb;
|
||||
inode = dentry->d_inode;
|
||||
IMustLock(inode);
|
||||
bend = au_dbend(dentry);
|
||||
for (bindex = au_dbstart(dentry); !err && bindex <= bend; bindex++) {
|
||||
struct path h_path;
|
||||
|
||||
if (au_test_ro(sb, bindex, inode))
|
||||
continue;
|
||||
h_path.dentry = au_h_dptr(dentry, bindex);
|
||||
if (!h_path.dentry)
|
||||
continue;
|
||||
|
||||
h_path.mnt = au_sbr_mnt(sb, bindex);
|
||||
err = vfsub_fsync(NULL, &h_path, datasync);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int au_do_fsync_dir(struct file *file, int datasync)
|
||||
{
|
||||
int err;
|
||||
aufs_bindex_t bend, bindex;
|
||||
struct file *h_file;
|
||||
struct super_block *sb;
|
||||
struct inode *inode;
|
||||
|
||||
err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
|
||||
if (unlikely(err))
|
||||
goto out;
|
||||
|
||||
sb = file->f_dentry->d_sb;
|
||||
inode = file->f_dentry->d_inode;
|
||||
bend = au_fbend_dir(file);
|
||||
for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
|
||||
h_file = au_hf_dir(file, bindex);
|
||||
if (!h_file || au_test_ro(sb, bindex, inode))
|
||||
continue;
|
||||
|
||||
err = vfsub_fsync(h_file, &h_file->f_path, datasync);
|
||||
}
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* @file may be NULL
|
||||
*/
|
||||
static int aufs_fsync_dir(struct file *file, int datasync)
|
||||
{
|
||||
int err;
|
||||
struct dentry *dentry;
|
||||
struct super_block *sb;
|
||||
|
||||
dentry = file->f_dentry;
|
||||
IMustLock(dentry->d_inode);
|
||||
|
||||
err = 0;
|
||||
sb = dentry->d_sb;
|
||||
si_noflush_read_lock(sb);
|
||||
if (file)
|
||||
err = au_do_fsync_dir(file, datasync);
|
||||
else {
|
||||
di_write_lock_child(dentry);
|
||||
err = au_do_fsync_dir_no_file(dentry, datasync);
|
||||
}
|
||||
au_cpup_attr_timesizes(dentry->d_inode);
|
||||
di_write_unlock(dentry);
|
||||
if (file)
|
||||
fi_write_unlock(file);
|
||||
|
||||
si_read_unlock(sb);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static int aufs_readdir(struct file *file, void *dirent, filldir_t filldir)
|
||||
{
|
||||
int err;
|
||||
struct dentry *dentry;
|
||||
struct inode *inode, *h_inode;
|
||||
struct super_block *sb;
|
||||
|
||||
dentry = file->f_dentry;
|
||||
inode = dentry->d_inode;
|
||||
IMustLock(inode);
|
||||
|
||||
sb = dentry->d_sb;
|
||||
si_read_lock(sb, AuLock_FLUSH);
|
||||
err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
|
||||
if (unlikely(err))
|
||||
goto out;
|
||||
err = au_alive_dir(dentry);
|
||||
if (!err)
|
||||
err = au_vdir_init(file);
|
||||
di_downgrade_lock(dentry, AuLock_IR);
|
||||
if (unlikely(err))
|
||||
goto out_unlock;
|
||||
|
||||
h_inode = au_h_iptr(inode, au_ibstart(inode));
|
||||
if (!au_test_nfsd()) {
|
||||
err = au_vdir_fill_de(file, dirent, filldir);
|
||||
fsstack_copy_attr_atime(inode, h_inode);
|
||||
} else {
|
||||
/*
|
||||
* nfsd filldir may call lookup_one_len(), vfs_getattr(),
|
||||
* encode_fh() and others.
|
||||
*/
|
||||
atomic_inc(&h_inode->i_count);
|
||||
di_read_unlock(dentry, AuLock_IR);
|
||||
si_read_unlock(sb);
|
||||
err = au_vdir_fill_de(file, dirent, filldir);
|
||||
fsstack_copy_attr_atime(inode, h_inode);
|
||||
fi_write_unlock(file);
|
||||
iput(h_inode);
|
||||
|
||||
AuTraceErr(err);
|
||||
return err;
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
di_read_unlock(dentry, AuLock_IR);
|
||||
fi_write_unlock(file);
|
||||
out:
|
||||
si_read_unlock(sb);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#define AuTestEmpty_WHONLY 1
|
||||
#define AuTestEmpty_CALLED (1 << 1)
|
||||
#define AuTestEmpty_SHWH (1 << 2)
|
||||
#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name)
|
||||
#define au_fset_testempty(flags, name) \
|
||||
do { (flags) |= AuTestEmpty_##name; } while (0)
|
||||
#define au_fclr_testempty(flags, name) \
|
||||
do { (flags) &= ~AuTestEmpty_##name; } while (0)
|
||||
|
||||
#ifndef CONFIG_AUFS_SHWH
|
||||
#undef AuTestEmpty_SHWH
|
||||
#define AuTestEmpty_SHWH 0
|
||||
#endif
|
||||
|
||||
struct test_empty_arg {
|
||||
struct au_nhash *whlist;
|
||||
unsigned int flags;
|
||||
int err;
|
||||
aufs_bindex_t bindex;
|
||||
};
|
||||
|
||||
static int test_empty_cb(void *__arg, const char *__name, int namelen,
|
||||
loff_t offset __maybe_unused, u64 ino,
|
||||
unsigned int d_type)
|
||||
{
|
||||
struct test_empty_arg *arg = __arg;
|
||||
char *name = (void *)__name;
|
||||
|
||||
arg->err = 0;
|
||||
au_fset_testempty(arg->flags, CALLED);
|
||||
/* smp_mb(); */
|
||||
if (name[0] == '.'
|
||||
&& (namelen == 1 || (name[1] == '.' && namelen == 2)))
|
||||
goto out; /* success */
|
||||
|
||||
if (namelen <= AUFS_WH_PFX_LEN
|
||||
|| memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
|
||||
if (au_ftest_testempty(arg->flags, WHONLY)
|
||||
&& !au_nhash_test_known_wh(arg->whlist, name, namelen))
|
||||
arg->err = -ENOTEMPTY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
name += AUFS_WH_PFX_LEN;
|
||||
namelen -= AUFS_WH_PFX_LEN;
|
||||
if (!au_nhash_test_known_wh(arg->whlist, name, namelen))
|
||||
arg->err = au_nhash_append_wh
|
||||
(arg->whlist, name, namelen, ino, d_type, arg->bindex,
|
||||
au_ftest_testempty(arg->flags, SHWH));
|
||||
|
||||
out:
|
||||
/* smp_mb(); */
|
||||
AuTraceErr(arg->err);
|
||||
return arg->err;
|
||||
}
|
||||
|
||||
static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
|
||||
{
|
||||
int err;
|
||||
struct file *h_file;
|
||||
|
||||
h_file = au_h_open(dentry, arg->bindex,
|
||||
O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE,
|
||||
/*file*/NULL);
|
||||
err = PTR_ERR(h_file);
|
||||
if (IS_ERR(h_file))
|
||||
goto out;
|
||||
|
||||
err = 0;
|
||||
if (!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
|
||||
&& !h_file->f_dentry->d_inode->i_nlink)
|
||||
goto out_put;
|
||||
|
||||
do {
|
||||
arg->err = 0;
|
||||
au_fclr_testempty(arg->flags, CALLED);
|
||||
/* smp_mb(); */
|
||||
err = vfsub_readdir(h_file, test_empty_cb, arg);
|
||||
if (err >= 0)
|
||||
err = arg->err;
|
||||
} while (!err && au_ftest_testempty(arg->flags, CALLED));
|
||||
|
||||
out_put:
|
||||
fput(h_file);
|
||||
au_sbr_put(dentry->d_sb, arg->bindex);
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
struct do_test_empty_args {
|
||||
int *errp;
|
||||
struct dentry *dentry;
|
||||
struct test_empty_arg *arg;
|
||||
};
|
||||
|
||||
static void call_do_test_empty(void *args)
|
||||
{
|
||||
struct do_test_empty_args *a = args;
|
||||
*a->errp = do_test_empty(a->dentry, a->arg);
|
||||
}
|
||||
|
||||
static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
|
||||
{
|
||||
int err, wkq_err;
|
||||
struct dentry *h_dentry;
|
||||
struct inode *h_inode;
|
||||
|
||||
h_dentry = au_h_dptr(dentry, arg->bindex);
|
||||
h_inode = h_dentry->d_inode;
|
||||
/* todo: i_mode changes anytime? */
|
||||
mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
|
||||
err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ);
|
||||
mutex_unlock(&h_inode->i_mutex);
|
||||
if (!err)
|
||||
err = do_test_empty(dentry, arg);
|
||||
else {
|
||||
struct do_test_empty_args args = {
|
||||
.errp = &err,
|
||||
.dentry = dentry,
|
||||
.arg = arg
|
||||
};
|
||||
unsigned int flags = arg->flags;
|
||||
|
||||
wkq_err = au_wkq_wait(call_do_test_empty, &args);
|
||||
if (unlikely(wkq_err))
|
||||
err = wkq_err;
|
||||
arg->flags = flags;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int au_test_empty_lower(struct dentry *dentry)
|
||||
{
|
||||
int err;
|
||||
unsigned int rdhash;
|
||||
aufs_bindex_t bindex, bstart, btail;
|
||||
struct au_nhash whlist;
|
||||
struct test_empty_arg arg;
|
||||
|
||||
SiMustAnyLock(dentry->d_sb);
|
||||
|
||||
rdhash = au_sbi(dentry->d_sb)->si_rdhash;
|
||||
if (!rdhash)
|
||||
rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, dentry));
|
||||
err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
|
||||
if (unlikely(err))
|
||||
goto out;
|
||||
|
||||
arg.flags = 0;
|
||||
arg.whlist = &whlist;
|
||||
bstart = au_dbstart(dentry);
|
||||
if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
|
||||
au_fset_testempty(arg.flags, SHWH);
|
||||
arg.bindex = bstart;
|
||||
err = do_test_empty(dentry, &arg);
|
||||
if (unlikely(err))
|
||||
goto out_whlist;
|
||||
|
||||
au_fset_testempty(arg.flags, WHONLY);
|
||||
btail = au_dbtaildir(dentry);
|
||||
for (bindex = bstart + 1; !err && bindex <= btail; bindex++) {
|
||||
struct dentry *h_dentry;
|
||||
|
||||
h_dentry = au_h_dptr(dentry, bindex);
|
||||
if (h_dentry && h_dentry->d_inode) {
|
||||
arg.bindex = bindex;
|
||||
err = do_test_empty(dentry, &arg);
|
||||
}
|
||||
}
|
||||
|
||||
out_whlist:
|
||||
au_nhash_wh_free(&whlist);
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
int au_test_empty(struct dentry *dentry, struct au_nhash *whlist)
|
||||
{
|
||||
int err;
|
||||
struct test_empty_arg arg;
|
||||
aufs_bindex_t bindex, btail;
|
||||
|
||||
err = 0;
|
||||
arg.whlist = whlist;
|
||||
arg.flags = AuTestEmpty_WHONLY;
|
||||
if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
|
||||
au_fset_testempty(arg.flags, SHWH);
|
||||
btail = au_dbtaildir(dentry);
|
||||
for (bindex = au_dbstart(dentry); !err && bindex <= btail; bindex++) {
|
||||
struct dentry *h_dentry;
|
||||
|
||||
h_dentry = au_h_dptr(dentry, bindex);
|
||||
if (h_dentry && h_dentry->d_inode) {
|
||||
arg.bindex = bindex;
|
||||
err = sio_test_empty(dentry, &arg);
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
const struct file_operations aufs_dir_fop = {
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = default_llseek,
|
||||
.read = generic_read_dir,
|
||||
.readdir = aufs_readdir,
|
||||
.unlocked_ioctl = aufs_ioctl_dir,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = aufs_compat_ioctl_dir,
|
||||
#endif
|
||||
.open = aufs_open_dir,
|
||||
.release = aufs_release_dir,
|
||||
.flush = aufs_flush_dir,
|
||||
.fsync = aufs_fsync_dir
|
||||
};
|
@ -1,137 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2012 Junjiro R. Okajima
|
||||
*
|
||||
* This program, aufs is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* directory operations
|
||||
*/
|
||||
|
||||
#ifndef __AUFS_DIR_H__
|
||||
#define __AUFS_DIR_H__
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/fs.h>
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/* need to be faster and smaller */
|
||||
|
||||
struct au_nhash {
|
||||
unsigned int nh_num;
|
||||
struct hlist_head *nh_head;
|
||||
};
|
||||
|
||||
struct au_vdir_destr {
|
||||
unsigned char len;
|
||||
unsigned char name[0];
|
||||
} __packed;
|
||||
|
||||
struct au_vdir_dehstr {
|
||||
struct hlist_node hash;
|
||||
struct au_vdir_destr *str;
|
||||
} ____cacheline_aligned_in_smp;
|
||||
|
||||
struct au_vdir_de {
|
||||
ino_t de_ino;
|
||||
unsigned char de_type;
|
||||
/* caution: packed */
|
||||
struct au_vdir_destr de_str;
|
||||
} __packed;
|
||||
|
||||
struct au_vdir_wh {
|
||||
struct hlist_node wh_hash;
|
||||
#ifdef CONFIG_AUFS_SHWH
|
||||
ino_t wh_ino;
|
||||
aufs_bindex_t wh_bindex;
|
||||
unsigned char wh_type;
|
||||
#else
|
||||
aufs_bindex_t wh_bindex;
|
||||
#endif
|
||||
/* caution: packed */
|
||||
struct au_vdir_destr wh_str;
|
||||
} __packed;
|
||||
|
||||
union au_vdir_deblk_p {
|
||||
unsigned char *deblk;
|
||||
struct au_vdir_de *de;
|
||||
};
|
||||
|
||||
struct au_vdir {
|
||||
unsigned char **vd_deblk;
|
||||
unsigned long vd_nblk;
|
||||
struct {
|
||||
unsigned long ul;
|
||||
union au_vdir_deblk_p p;
|
||||
} vd_last;
|
||||
|
||||
unsigned long vd_version;
|
||||
unsigned int vd_deblk_sz;
|
||||
unsigned long vd_jiffy;
|
||||
} ____cacheline_aligned_in_smp;
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/* dir.c */
|
||||
extern const struct file_operations aufs_dir_fop;
|
||||
void au_add_nlink(struct inode *dir, struct inode *h_dir);
|
||||
void au_sub_nlink(struct inode *dir, struct inode *h_dir);
|
||||
loff_t au_dir_size(struct file *file, struct dentry *dentry);
|
||||
int au_test_empty_lower(struct dentry *dentry);
|
||||
int au_test_empty(struct dentry *dentry, struct au_nhash *whlist);
|
||||
|
||||
/* vdir.c */
|
||||
unsigned int au_rdhash_est(loff_t sz);
|
||||
int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp);
|
||||
void au_nhash_wh_free(struct au_nhash *whlist);
|
||||
int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
|
||||
int limit);
|
||||
int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen);
|
||||
int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
|
||||
unsigned int d_type, aufs_bindex_t bindex,
|
||||
unsigned char shwh);
|
||||
void au_vdir_free(struct au_vdir *vdir);
|
||||
int au_vdir_init(struct file *file);
|
||||
int au_vdir_fill_de(struct file *file, void *dirent, filldir_t filldir);
|
||||
|
||||
/* ioctl.c */
|
||||
long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg);
|
||||
|
||||
#ifdef CONFIG_AUFS_RDU
|
||||
/* rdu.c */
|
||||
long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
|
||||
#ifdef CONFIG_COMPAT
|
||||
long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
#endif
|
||||
#else
|
||||
static inline long au_rdu_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
#ifdef CONFIG_COMPAT
|
||||
static inline long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* __AUFS_DIR_H__ */
|
@ -1,377 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2012 Junjiro R. Okajima
|
||||
*
|
||||
* This program, aufs is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* dynamically customizable operations for regular files
|
||||
*/
|
||||
|
||||
#include "aufs.h"
|
||||
|
||||
#define DyPrSym(key) AuDbgSym(key->dk_op.dy_hop)
|
||||
|
||||
/*
|
||||
* How large will these lists be?
|
||||
* Usually just a few elements, 20-30 at most for each, I guess.
|
||||
*/
|
||||
static struct au_splhead dynop[AuDyLast];
|
||||
|
||||
static struct au_dykey *dy_gfind_get(struct au_splhead *spl, const void *h_op)
|
||||
{
|
||||
struct au_dykey *key, *tmp;
|
||||
struct list_head *head;
|
||||
|
||||
key = NULL;
|
||||
head = &spl->head;
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(tmp, head, dk_list)
|
||||
if (tmp->dk_op.dy_hop == h_op) {
|
||||
key = tmp;
|
||||
kref_get(&key->dk_kref);
|
||||
break;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
static struct au_dykey *dy_bradd(struct au_branch *br, struct au_dykey *key)
|
||||
{
|
||||
struct au_dykey **k, *found;
|
||||
const void *h_op = key->dk_op.dy_hop;
|
||||
int i;
|
||||
|
||||
found = NULL;
|
||||
k = br->br_dykey;
|
||||
for (i = 0; i < AuBrDynOp; i++)
|
||||
if (k[i]) {
|
||||
if (k[i]->dk_op.dy_hop == h_op) {
|
||||
found = k[i];
|
||||
break;
|
||||
}
|
||||
} else
|
||||
break;
|
||||
if (!found) {
|
||||
spin_lock(&br->br_dykey_lock);
|
||||
for (; i < AuBrDynOp; i++)
|
||||
if (k[i]) {
|
||||
if (k[i]->dk_op.dy_hop == h_op) {
|
||||
found = k[i];
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
k[i] = key;
|
||||
break;
|
||||
}
|
||||
spin_unlock(&br->br_dykey_lock);
|
||||
BUG_ON(i == AuBrDynOp); /* expand the array */
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/* kref_get() if @key is already added */
|
||||
static struct au_dykey *dy_gadd(struct au_splhead *spl, struct au_dykey *key)
|
||||
{
|
||||
struct au_dykey *tmp, *found;
|
||||
struct list_head *head;
|
||||
const void *h_op = key->dk_op.dy_hop;
|
||||
|
||||
found = NULL;
|
||||
head = &spl->head;
|
||||
spin_lock(&spl->spin);
|
||||
list_for_each_entry(tmp, head, dk_list)
|
||||
if (tmp->dk_op.dy_hop == h_op) {
|
||||
kref_get(&tmp->dk_kref);
|
||||
found = tmp;
|
||||
break;
|
||||
}
|
||||
if (!found)
|
||||
list_add_rcu(&key->dk_list, head);
|
||||
spin_unlock(&spl->spin);
|
||||
|
||||
if (!found)
|
||||
DyPrSym(key);
|
||||
return found;
|
||||
}
|
||||
|
||||
static void dy_free_rcu(struct rcu_head *rcu)
|
||||
{
|
||||
struct au_dykey *key;
|
||||
|
||||
key = container_of(rcu, struct au_dykey, dk_rcu);
|
||||
DyPrSym(key);
|
||||
kfree(key);
|
||||
}
|
||||
|
||||
static void dy_free(struct kref *kref)
|
||||
{
|
||||
struct au_dykey *key;
|
||||
struct au_splhead *spl;
|
||||
|
||||
key = container_of(kref, struct au_dykey, dk_kref);
|
||||
spl = dynop + key->dk_op.dy_type;
|
||||
au_spl_del_rcu(&key->dk_list, spl);
|
||||
call_rcu(&key->dk_rcu, dy_free_rcu);
|
||||
}
|
||||
|
||||
void au_dy_put(struct au_dykey *key)
|
||||
{
|
||||
kref_put(&key->dk_kref, dy_free);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#define DyDbgSize(cnt, op) AuDebugOn(cnt != sizeof(op)/sizeof(void *))
|
||||
|
||||
#ifdef CONFIG_AUFS_DEBUG
|
||||
#define DyDbgDeclare(cnt) unsigned int cnt = 0
|
||||
#define DyDbgInc(cnt) do { cnt++; } while (0)
|
||||
#else
|
||||
#define DyDbgDeclare(cnt) do {} while (0)
|
||||
#define DyDbgInc(cnt) do {} while (0)
|
||||
#endif
|
||||
|
||||
#define DySet(func, dst, src, h_op, h_sb) do { \
|
||||
DyDbgInc(cnt); \
|
||||
if (h_op->func) { \
|
||||
if (src.func) \
|
||||
dst.func = src.func; \
|
||||
else \
|
||||
AuDbg("%s %s\n", au_sbtype(h_sb), #func); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DySetForce(func, dst, src) do { \
|
||||
AuDebugOn(!src.func); \
|
||||
DyDbgInc(cnt); \
|
||||
dst.func = src.func; \
|
||||
} while (0)
|
||||
|
||||
#define DySetAop(func) \
|
||||
DySet(func, dyaop->da_op, aufs_aop, h_aop, h_sb)
|
||||
#define DySetAopForce(func) \
|
||||
DySetForce(func, dyaop->da_op, aufs_aop)
|
||||
|
||||
static void dy_aop(struct au_dykey *key, const void *h_op,
|
||||
struct super_block *h_sb __maybe_unused)
|
||||
{
|
||||
struct au_dyaop *dyaop = (void *)key;
|
||||
const struct address_space_operations *h_aop = h_op;
|
||||
DyDbgDeclare(cnt);
|
||||
|
||||
AuDbg("%s\n", au_sbtype(h_sb));
|
||||
|
||||
DySetAop(writepage);
|
||||
DySetAopForce(readpage); /* force */
|
||||
DySetAop(writepages);
|
||||
DySetAop(set_page_dirty);
|
||||
DySetAop(readpages);
|
||||
DySetAop(write_begin);
|
||||
DySetAop(write_end);
|
||||
DySetAop(bmap);
|
||||
DySetAop(invalidatepage);
|
||||
DySetAop(releasepage);
|
||||
DySetAop(freepage);
|
||||
/* these two will be changed according to an aufs mount option */
|
||||
DySetAop(direct_IO);
|
||||
DySetAop(get_xip_mem);
|
||||
DySetAop(migratepage);
|
||||
DySetAop(launder_page);
|
||||
DySetAop(is_partially_uptodate);
|
||||
DySetAop(error_remove_page);
|
||||
|
||||
DyDbgSize(cnt, *h_aop);
|
||||
dyaop->da_get_xip_mem = h_aop->get_xip_mem;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static void dy_bug(struct kref *kref)
|
||||
{
|
||||
BUG();
|
||||
}
|
||||
|
||||
static struct au_dykey *dy_get(struct au_dynop *op, struct au_branch *br)
|
||||
{
|
||||
struct au_dykey *key, *old;
|
||||
struct au_splhead *spl;
|
||||
struct op {
|
||||
unsigned int sz;
|
||||
void (*set)(struct au_dykey *key, const void *h_op,
|
||||
struct super_block *h_sb __maybe_unused);
|
||||
};
|
||||
static const struct op a[] = {
|
||||
[AuDy_AOP] = {
|
||||
.sz = sizeof(struct au_dyaop),
|
||||
.set = dy_aop
|
||||
}
|
||||
};
|
||||
const struct op *p;
|
||||
|
||||
spl = dynop + op->dy_type;
|
||||
key = dy_gfind_get(spl, op->dy_hop);
|
||||
if (key)
|
||||
goto out_add; /* success */
|
||||
|
||||
p = a + op->dy_type;
|
||||
key = kzalloc(p->sz, GFP_NOFS);
|
||||
if (unlikely(!key)) {
|
||||
key = ERR_PTR(-ENOMEM);
|
||||
goto out;
|
||||
}
|
||||
|
||||
key->dk_op.dy_hop = op->dy_hop;
|
||||
kref_init(&key->dk_kref);
|
||||
p->set(key, op->dy_hop, br->br_mnt->mnt_sb);
|
||||
old = dy_gadd(spl, key);
|
||||
if (old) {
|
||||
kfree(key);
|
||||
key = old;
|
||||
}
|
||||
|
||||
out_add:
|
||||
old = dy_bradd(br, key);
|
||||
if (old)
|
||||
/* its ref-count should never be zero here */
|
||||
kref_put(&key->dk_kref, dy_bug);
|
||||
out:
|
||||
return key;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/*
|
||||
* Aufs prohibits O_DIRECT by defaut even if the branch supports it.
|
||||
* This behaviour is neccessary to return an error from open(O_DIRECT) instead
|
||||
* of the succeeding I/O. The dio mount option enables O_DIRECT and makes
|
||||
* open(O_DIRECT) always succeed, but the succeeding I/O may return an error.
|
||||
* See the aufs manual in detail.
|
||||
*
|
||||
* To keep this behaviour, aufs has to set NULL to ->get_xip_mem too, and the
|
||||
* performance of fadvise() and madvise() may be affected.
|
||||
*/
|
||||
static void dy_adx(struct au_dyaop *dyaop, int do_dx)
|
||||
{
|
||||
if (!do_dx) {
|
||||
dyaop->da_op.direct_IO = NULL;
|
||||
dyaop->da_op.get_xip_mem = NULL;
|
||||
} else {
|
||||
dyaop->da_op.direct_IO = aufs_aop.direct_IO;
|
||||
dyaop->da_op.get_xip_mem = aufs_aop.get_xip_mem;
|
||||
if (!dyaop->da_get_xip_mem)
|
||||
dyaop->da_op.get_xip_mem = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static struct au_dyaop *dy_aget(struct au_branch *br,
|
||||
const struct address_space_operations *h_aop,
|
||||
int do_dx)
|
||||
{
|
||||
struct au_dyaop *dyaop;
|
||||
struct au_dynop op;
|
||||
|
||||
op.dy_type = AuDy_AOP;
|
||||
op.dy_haop = h_aop;
|
||||
dyaop = (void *)dy_get(&op, br);
|
||||
if (IS_ERR(dyaop))
|
||||
goto out;
|
||||
dy_adx(dyaop, do_dx);
|
||||
|
||||
out:
|
||||
return dyaop;
|
||||
}
|
||||
|
||||
int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
|
||||
struct inode *h_inode)
|
||||
{
|
||||
int err, do_dx;
|
||||
struct super_block *sb;
|
||||
struct au_branch *br;
|
||||
struct au_dyaop *dyaop;
|
||||
|
||||
AuDebugOn(!S_ISREG(h_inode->i_mode));
|
||||
IiMustWriteLock(inode);
|
||||
|
||||
sb = inode->i_sb;
|
||||
br = au_sbr(sb, bindex);
|
||||
do_dx = !!au_opt_test(au_mntflags(sb), DIO);
|
||||
dyaop = dy_aget(br, h_inode->i_mapping->a_ops, do_dx);
|
||||
err = PTR_ERR(dyaop);
|
||||
if (IS_ERR(dyaop))
|
||||
/* unnecessary to call dy_fput() */
|
||||
goto out;
|
||||
|
||||
err = 0;
|
||||
inode->i_mapping->a_ops = &dyaop->da_op;
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Is it safe to replace a_ops during the inode/file is in operation?
|
||||
* Yes, I hope so.
|
||||
*/
|
||||
int au_dy_irefresh(struct inode *inode)
|
||||
{
|
||||
int err;
|
||||
aufs_bindex_t bstart;
|
||||
struct inode *h_inode;
|
||||
|
||||
err = 0;
|
||||
if (S_ISREG(inode->i_mode)) {
|
||||
bstart = au_ibstart(inode);
|
||||
h_inode = au_h_iptr(inode, bstart);
|
||||
err = au_dy_iaop(inode, bstart, h_inode);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
void au_dy_arefresh(int do_dx)
|
||||
{
|
||||
struct au_splhead *spl;
|
||||
struct list_head *head;
|
||||
struct au_dykey *key;
|
||||
|
||||
spl = dynop + AuDy_AOP;
|
||||
head = &spl->head;
|
||||
spin_lock(&spl->spin);
|
||||
list_for_each_entry(key, head, dk_list)
|
||||
dy_adx((void *)key, do_dx);
|
||||
spin_unlock(&spl->spin);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void __init au_dy_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* make sure that 'struct au_dykey *' can be any type */
|
||||
BUILD_BUG_ON(offsetof(struct au_dyaop, da_key));
|
||||
|
||||
for (i = 0; i < AuDyLast; i++)
|
||||
au_spl_init(dynop + i);
|
||||
}
|
||||
|
||||
void au_dy_fin(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < AuDyLast; i++)
|
||||
WARN_ON(!list_empty(&dynop[i].head));
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2012 Junjiro R. Okajima
|
||||
*
|
||||
* This program, aufs is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* dynamically customizable operations (for regular files only)
|
||||
*/
|
||||
|
||||
#ifndef __AUFS_DYNOP_H__
|
||||
#define __AUFS_DYNOP_H__
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include "inode.h"
|
||||
|
||||
enum {AuDy_AOP, AuDyLast};
|
||||
|
||||
struct au_dynop {
|
||||
int dy_type;
|
||||
union {
|
||||
const void *dy_hop;
|
||||
const struct address_space_operations *dy_haop;
|
||||
};
|
||||
};
|
||||
|
||||
struct au_dykey {
|
||||
union {
|
||||
struct list_head dk_list;
|
||||
struct rcu_head dk_rcu;
|
||||
};
|
||||
struct au_dynop dk_op;
|
||||
|
||||
/*
|
||||
* during I am in the branch local array, kref is gotten. when the
|
||||
* branch is removed, kref is put.
|
||||
*/
|
||||
struct kref dk_kref;
|
||||
};
|
||||
|
||||
/* stop unioning since their sizes are very different from each other */
|
||||
struct au_dyaop {
|
||||
struct au_dykey da_key;
|
||||
struct address_space_operations da_op; /* not const */
|
||||
int (*da_get_xip_mem)(struct address_space *, pgoff_t, int,
|
||||
void **, unsigned long *);
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/* dynop.c */
|
||||
struct au_branch;
|
||||
void au_dy_put(struct au_dykey *key);
|
||||
int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
|
||||
struct inode *h_inode);
|
||||
int au_dy_irefresh(struct inode *inode);
|
||||
void au_dy_arefresh(int do_dio);
|
||||
|
||||
void __init au_dy_init(void);
|
||||
void au_dy_fin(void);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* __AUFS_DYNOP_H__ */
|
@ -1,804 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2012 Junjiro R. Okajima
|
||||
*
|
||||
* This program, aufs is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* export via nfs
|
||||
*/
|
||||
|
||||
#include <linux/exportfs.h>
|
||||
#include <linux/mnt_namespace.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/nsproxy.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/writeback.h>
|
||||
#include "aufs.h"
|
||||
|
||||
union conv {
|
||||
#ifdef CONFIG_AUFS_INO_T_64
|
||||
__u32 a[2];
|
||||
#else
|
||||
__u32 a[1];
|
||||
#endif
|
||||
ino_t ino;
|
||||
};
|
||||
|
||||
static ino_t decode_ino(__u32 *a)
|
||||
{
|
||||
union conv u;
|
||||
|
||||
BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a));
|
||||
u.a[0] = a[0];
|
||||
#ifdef CONFIG_AUFS_INO_T_64
|
||||
u.a[1] = a[1];
|
||||
#endif
|
||||
return u.ino;
|
||||
}
|
||||
|
||||
static void encode_ino(__u32 *a, ino_t ino)
|
||||
{
|
||||
union conv u;
|
||||
|
||||
u.ino = ino;
|
||||
a[0] = u.a[0];
|
||||
#ifdef CONFIG_AUFS_INO_T_64
|
||||
a[1] = u.a[1];
|
||||
#endif
|
||||
}
|
||||
|
||||
/* NFS file handle */
|
||||
enum {
|
||||
Fh_br_id,
|
||||
Fh_sigen,
|
||||
#ifdef CONFIG_AUFS_INO_T_64
|
||||
/* support 64bit inode number */
|
||||
Fh_ino1,
|
||||
Fh_ino2,
|
||||
Fh_dir_ino1,
|
||||
Fh_dir_ino2,
|
||||
#else
|
||||
Fh_ino1,
|
||||
Fh_dir_ino1,
|
||||
#endif
|
||||
Fh_igen,
|
||||
Fh_h_type,
|
||||
Fh_tail,
|
||||
|
||||
Fh_ino = Fh_ino1,
|
||||
Fh_dir_ino = Fh_dir_ino1
|
||||
};
|
||||
|
||||
static int au_test_anon(struct dentry *dentry)
|
||||
{
|
||||
/* note: read d_flags without d_lock */
|
||||
return !!(dentry->d_flags & DCACHE_DISCONNECTED);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* inode generation external table */
|
||||
|
||||
void au_xigen_inc(struct inode *inode)
|
||||
{
|
||||
loff_t pos;
|
||||
ssize_t sz;
|
||||
__u32 igen;
|
||||
struct super_block *sb;
|
||||
struct au_sbinfo *sbinfo;
|
||||
|
||||
sb = inode->i_sb;
|
||||
AuDebugOn(!au_opt_test(au_mntflags(sb), XINO));
|
||||
|
||||
sbinfo = au_sbi(sb);
|
||||
pos = inode->i_ino;
|
||||
pos *= sizeof(igen);
|
||||
igen = inode->i_generation + 1;
|
||||
sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen,
|
||||
sizeof(igen), &pos);
|
||||
if (sz == sizeof(igen))
|
||||
return; /* success */
|
||||
|
||||
if (unlikely(sz >= 0))
|
||||
AuIOErr("xigen error (%zd)\n", sz);
|
||||
}
|
||||
|
||||
int au_xigen_new(struct inode *inode)
|
||||
{
|
||||
int err;
|
||||
loff_t pos;
|
||||
ssize_t sz;
|
||||
struct super_block *sb;
|
||||
struct au_sbinfo *sbinfo;
|
||||
struct file *file;
|
||||
|
||||
err = 0;
|
||||
/* todo: dirty, at mount time */
|
||||
if (inode->i_ino == AUFS_ROOT_INO)
|
||||
goto out;
|
||||
sb = inode->i_sb;
|
||||
SiMustAnyLock(sb);
|
||||
if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
|
||||
goto out;
|
||||
|
||||
err = -EFBIG;
|
||||
pos = inode->i_ino;
|
||||
if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) {
|
||||
AuIOErr1("too large i%lld\n", pos);
|
||||
goto out;
|
||||
}
|
||||
pos *= sizeof(inode->i_generation);
|
||||
|
||||
err = 0;
|
||||
sbinfo = au_sbi(sb);
|
||||
file = sbinfo->si_xigen;
|
||||
BUG_ON(!file);
|
||||
|
||||
if (i_size_read(file->f_dentry->d_inode)
|
||||
< pos + sizeof(inode->i_generation)) {
|
||||
inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next);
|
||||
sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation,
|
||||
sizeof(inode->i_generation), &pos);
|
||||
} else
|
||||
sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation,
|
||||
sizeof(inode->i_generation), &pos);
|
||||
if (sz == sizeof(inode->i_generation))
|
||||
goto out; /* success */
|
||||
|
||||
err = sz;
|
||||
if (unlikely(sz >= 0)) {
|
||||
err = -EIO;
|
||||
AuIOErr("xigen error (%zd)\n", sz);
|
||||
}
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
int au_xigen_set(struct super_block *sb, struct file *base)
|
||||
{
|
||||
int err;
|
||||
struct au_sbinfo *sbinfo;
|
||||
struct file *file;
|
||||
|
||||
SiMustWriteLock(sb);
|
||||
|
||||
sbinfo = au_sbi(sb);
|
||||
file = au_xino_create2(base, sbinfo->si_xigen);
|
||||
err = PTR_ERR(file);
|
||||
if (IS_ERR(file))
|
||||
goto out;
|
||||
err = 0;
|
||||
if (sbinfo->si_xigen)
|
||||
fput(sbinfo->si_xigen);
|
||||
sbinfo->si_xigen = file;
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
void au_xigen_clr(struct super_block *sb)
|
||||
{
|
||||
struct au_sbinfo *sbinfo;
|
||||
|
||||
SiMustWriteLock(sb);
|
||||
|
||||
sbinfo = au_sbi(sb);
|
||||
if (sbinfo->si_xigen) {
|
||||
fput(sbinfo->si_xigen);
|
||||
sbinfo->si_xigen = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino,
|
||||
ino_t dir_ino)
|
||||
{
|
||||
struct dentry *dentry, *d;
|
||||
struct inode *inode;
|
||||
unsigned int sigen;
|
||||
|
||||
dentry = NULL;
|
||||
inode = ilookup(sb, ino);
|
||||
if (!inode)
|
||||
goto out;
|
||||
|
||||
dentry = ERR_PTR(-ESTALE);
|
||||
sigen = au_sigen(sb);
|
||||
if (unlikely(is_bad_inode(inode)
|
||||
|| IS_DEADDIR(inode)
|
||||
|| sigen != au_iigen(inode)))
|
||||
goto out_iput;
|
||||
|
||||
dentry = NULL;
|
||||
if (!dir_ino || S_ISDIR(inode->i_mode))
|
||||
dentry = d_find_alias(inode);
|
||||
else {
|
||||
spin_lock(&inode->i_lock);
|
||||
list_for_each_entry(d, &inode->i_dentry, d_alias) {
|
||||
spin_lock(&d->d_lock);
|
||||
if (!au_test_anon(d)
|
||||
&& d->d_parent->d_inode->i_ino == dir_ino) {
|
||||
dentry = dget_dlock(d);
|
||||
spin_unlock(&d->d_lock);
|
||||
break;
|
||||
}
|
||||
spin_unlock(&d->d_lock);
|
||||
}
|
||||
spin_unlock(&inode->i_lock);
|
||||
}
|
||||
if (unlikely(dentry && au_digen_test(dentry, sigen))) {
|
||||
/* need to refresh */
|
||||
dput(dentry);
|
||||
dentry = NULL;
|
||||
}
|
||||
|
||||
out_iput:
|
||||
iput(inode);
|
||||
out:
|
||||
AuTraceErrPtr(dentry);
|
||||
return dentry;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/* todo: dirty? */
|
||||
/* if exportfs_decode_fh() passed vfsmount*, we could be happy */
|
||||
|
||||
struct au_compare_mnt_args {
|
||||
/* input */
|
||||
struct super_block *sb;
|
||||
|
||||
/* output */
|
||||
struct vfsmount *mnt;
|
||||
};
|
||||
|
||||
static int au_compare_mnt(struct vfsmount *mnt, void *arg)
|
||||
{
|
||||
struct au_compare_mnt_args *a = arg;
|
||||
|
||||
if (mnt->mnt_sb != a->sb)
|
||||
return 0;
|
||||
a->mnt = mntget(mnt);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct vfsmount *au_mnt_get(struct super_block *sb)
|
||||
{
|
||||
int err;
|
||||
struct au_compare_mnt_args args = {
|
||||
.sb = sb
|
||||
};
|
||||
struct mnt_namespace *ns;
|
||||
|
||||
br_read_lock(vfsmount_lock);
|
||||
/* no get/put ?? */
|
||||
AuDebugOn(!current->nsproxy);
|
||||
ns = current->nsproxy->mnt_ns;
|
||||
AuDebugOn(!ns);
|
||||
err = iterate_mounts(au_compare_mnt, &args, ns->root);
|
||||
br_read_unlock(vfsmount_lock);
|
||||
AuDebugOn(!err);
|
||||
AuDebugOn(!args.mnt);
|
||||
return args.mnt;
|
||||
}
|
||||
|
||||
struct au_nfsd_si_lock {
|
||||
unsigned int sigen;
|
||||
aufs_bindex_t bindex, br_id;
|
||||
unsigned char force_lock;
|
||||
};
|
||||
|
||||
static int si_nfsd_read_lock(struct super_block *sb,
|
||||
struct au_nfsd_si_lock *nsi_lock)
|
||||
{
|
||||
int err;
|
||||
aufs_bindex_t bindex;
|
||||
|
||||
si_read_lock(sb, AuLock_FLUSH);
|
||||
|
||||
/* branch id may be wrapped around */
|
||||
err = 0;
|
||||
bindex = au_br_index(sb, nsi_lock->br_id);
|
||||
if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb))
|
||||
goto out; /* success */
|
||||
|
||||
err = -ESTALE;
|
||||
bindex = -1;
|
||||
if (!nsi_lock->force_lock)
|
||||
si_read_unlock(sb);
|
||||
|
||||
out:
|
||||
nsi_lock->bindex = bindex;
|
||||
return err;
|
||||
}
|
||||
|
||||
struct find_name_by_ino {
|
||||
int called, found;
|
||||
ino_t ino;
|
||||
char *name;
|
||||
int namelen;
|
||||
};
|
||||
|
||||
static int
|
||||
find_name_by_ino(void *arg, const char *name, int namelen, loff_t offset,
|
||||
u64 ino, unsigned int d_type)
|
||||
{
|
||||
struct find_name_by_ino *a = arg;
|
||||
|
||||
a->called++;
|
||||
if (a->ino != ino)
|
||||
return 0;
|
||||
|
||||
memcpy(a->name, name, namelen);
|
||||
a->namelen = namelen;
|
||||
a->found = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino,
|
||||
struct au_nfsd_si_lock *nsi_lock)
|
||||
{
|
||||
struct dentry *dentry, *parent;
|
||||
struct file *file;
|
||||
struct inode *dir;
|
||||
struct find_name_by_ino arg;
|
||||
int err;
|
||||
|
||||
parent = path->dentry;
|
||||
if (nsi_lock)
|
||||
si_read_unlock(parent->d_sb);
|
||||
file = vfsub_dentry_open(path, au_dir_roflags);
|
||||
dentry = (void *)file;
|
||||
if (IS_ERR(file))
|
||||
goto out;
|
||||
|
||||
dentry = ERR_PTR(-ENOMEM);
|
||||
arg.name = __getname_gfp(GFP_NOFS);
|
||||
if (unlikely(!arg.name))
|
||||
goto out_file;
|
||||
arg.ino = ino;
|
||||
arg.found = 0;
|
||||
do {
|
||||
arg.called = 0;
|
||||
/* smp_mb(); */
|
||||
err = vfsub_readdir(file, find_name_by_ino, &arg);
|
||||
} while (!err && !arg.found && arg.called);
|
||||
dentry = ERR_PTR(err);
|
||||
if (unlikely(err))
|
||||
goto out_name;
|
||||
dentry = ERR_PTR(-ENOENT);
|
||||
if (!arg.found)
|
||||
goto out_name;
|
||||
|
||||
/* do not call au_lkup_one() */
|
||||
dir = parent->d_inode;
|
||||
mutex_lock(&dir->i_mutex);
|
||||
dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen);
|
||||
mutex_unlock(&dir->i_mutex);
|
||||
AuTraceErrPtr(dentry);
|
||||
if (IS_ERR(dentry))
|
||||
goto out_name;
|
||||
AuDebugOn(au_test_anon(dentry));
|
||||
if (unlikely(!dentry->d_inode)) {
|
||||
dput(dentry);
|
||||
dentry = ERR_PTR(-ENOENT);
|
||||
}
|
||||
|
||||
out_name:
|
||||
__putname(arg.name);
|
||||
out_file:
|
||||
fput(file);
|
||||
out:
|
||||
if (unlikely(nsi_lock
|
||||
&& si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0))
|
||||
if (!IS_ERR(dentry)) {
|
||||
dput(dentry);
|
||||
dentry = ERR_PTR(-ESTALE);
|
||||
}
|
||||
AuTraceErrPtr(dentry);
|
||||
return dentry;
|
||||
}
|
||||
|
||||
static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino,
|
||||
ino_t dir_ino,
|
||||
struct au_nfsd_si_lock *nsi_lock)
|
||||
{
|
||||
struct dentry *dentry;
|
||||
struct path path;
|
||||
|
||||
if (dir_ino != AUFS_ROOT_INO) {
|
||||
path.dentry = decode_by_ino(sb, dir_ino, 0);
|
||||
dentry = path.dentry;
|
||||
if (!path.dentry || IS_ERR(path.dentry))
|
||||
goto out;
|
||||
AuDebugOn(au_test_anon(path.dentry));
|
||||
} else
|
||||
path.dentry = dget(sb->s_root);
|
||||
|
||||
path.mnt = au_mnt_get(sb);
|
||||
dentry = au_lkup_by_ino(&path, ino, nsi_lock);
|
||||
path_put(&path);
|
||||
|
||||
out:
|
||||
AuTraceErrPtr(dentry);
|
||||
return dentry;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static int h_acceptable(void *expv, struct dentry *dentry)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath,
|
||||
char *buf, int len, struct super_block *sb)
|
||||
{
|
||||
char *p;
|
||||
int n;
|
||||
struct path path;
|
||||
|
||||
p = d_path(h_rootpath, buf, len);
|
||||
if (IS_ERR(p))
|
||||
goto out;
|
||||
n = strlen(p);
|
||||
|
||||
path.mnt = h_rootpath->mnt;
|
||||
path.dentry = h_parent;
|
||||
p = d_path(&path, buf, len);
|
||||
if (IS_ERR(p))
|
||||
goto out;
|
||||
if (n != 1)
|
||||
p += n;
|
||||
|
||||
path.mnt = au_mnt_get(sb);
|
||||
path.dentry = sb->s_root;
|
||||
p = d_path(&path, buf, len - strlen(p));
|
||||
mntput(path.mnt);
|
||||
if (IS_ERR(p))
|
||||
goto out;
|
||||
if (n != 1)
|
||||
p[strlen(p)] = '/';
|
||||
|
||||
out:
|
||||
AuTraceErrPtr(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
static
|
||||
struct dentry *decode_by_path(struct super_block *sb, ino_t ino, __u32 *fh,
|
||||
int fh_len, struct au_nfsd_si_lock *nsi_lock)
|
||||
{
|
||||
struct dentry *dentry, *h_parent, *root;
|
||||
struct super_block *h_sb;
|
||||
char *pathname, *p;
|
||||
struct vfsmount *h_mnt;
|
||||
struct au_branch *br;
|
||||
int err;
|
||||
struct path path;
|
||||
|
||||
br = au_sbr(sb, nsi_lock->bindex);
|
||||
h_mnt = br->br_mnt;
|
||||
h_sb = h_mnt->mnt_sb;
|
||||
/* todo: call lower fh_to_dentry()? fh_to_parent()? */
|
||||
h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail),
|
||||
fh_len - Fh_tail, fh[Fh_h_type],
|
||||
h_acceptable, /*context*/NULL);
|
||||
dentry = h_parent;
|
||||
if (unlikely(!h_parent || IS_ERR(h_parent))) {
|
||||
AuWarn1("%s decode_fh failed, %ld\n",
|
||||
au_sbtype(h_sb), PTR_ERR(h_parent));
|
||||
goto out;
|
||||
}
|
||||
dentry = NULL;
|
||||
if (unlikely(au_test_anon(h_parent))) {
|
||||
AuWarn1("%s decode_fh returned a disconnected dentry\n",
|
||||
au_sbtype(h_sb));
|
||||
goto out_h_parent;
|
||||
}
|
||||
|
||||
dentry = ERR_PTR(-ENOMEM);
|
||||
pathname = (void *)__get_free_page(GFP_NOFS);
|
||||
if (unlikely(!pathname))
|
||||
goto out_h_parent;
|
||||
|
||||
root = sb->s_root;
|
||||
path.mnt = h_mnt;
|
||||
di_read_lock_parent(root, !AuLock_IR);
|
||||
path.dentry = au_h_dptr(root, nsi_lock->bindex);
|
||||
di_read_unlock(root, !AuLock_IR);
|
||||
p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb);
|
||||
dentry = (void *)p;
|
||||
if (IS_ERR(p))
|
||||
goto out_pathname;
|
||||
|
||||
si_read_unlock(sb);
|
||||
err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
|
||||
dentry = ERR_PTR(err);
|
||||
if (unlikely(err))
|
||||
goto out_relock;
|
||||
|
||||
dentry = ERR_PTR(-ENOENT);
|
||||
AuDebugOn(au_test_anon(path.dentry));
|
||||
if (unlikely(!path.dentry->d_inode))
|
||||
goto out_path;
|
||||
|
||||
if (ino != path.dentry->d_inode->i_ino)
|
||||
dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL);
|
||||
else
|
||||
dentry = dget(path.dentry);
|
||||
|
||||
out_path:
|
||||
path_put(&path);
|
||||
out_relock:
|
||||
if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0))
|
||||
if (!IS_ERR(dentry)) {
|
||||
dput(dentry);
|
||||
dentry = ERR_PTR(-ESTALE);
|
||||
}
|
||||
out_pathname:
|
||||
free_page((unsigned long)pathname);
|
||||
out_h_parent:
|
||||
dput(h_parent);
|
||||
out:
|
||||
AuTraceErrPtr(dentry);
|
||||
return dentry;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static struct dentry *
|
||||
aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len,
|
||||
int fh_type)
|
||||
{
|
||||
struct dentry *dentry;
|
||||
__u32 *fh = fid->raw;
|
||||
struct au_branch *br;
|
||||
ino_t ino, dir_ino;
|
||||
struct au_nfsd_si_lock nsi_lock = {
|
||||
.force_lock = 0
|
||||
};
|
||||
|
||||
dentry = ERR_PTR(-ESTALE);
|
||||
/* it should never happen, but the file handle is unreliable */
|
||||
if (unlikely(fh_len < Fh_tail))
|
||||
goto out;
|
||||
nsi_lock.sigen = fh[Fh_sigen];
|
||||
nsi_lock.br_id = fh[Fh_br_id];
|
||||
|
||||
/* branch id may be wrapped around */
|
||||
br = NULL;
|
||||
if (unlikely(si_nfsd_read_lock(sb, &nsi_lock)))
|
||||
goto out;
|
||||
nsi_lock.force_lock = 1;
|
||||
|
||||
/* is this inode still cached? */
|
||||
ino = decode_ino(fh + Fh_ino);
|
||||
/* it should never happen */
|
||||
if (unlikely(ino == AUFS_ROOT_INO))
|
||||
goto out;
|
||||
|
||||
dir_ino = decode_ino(fh + Fh_dir_ino);
|
||||
dentry = decode_by_ino(sb, ino, dir_ino);
|
||||
if (IS_ERR(dentry))
|
||||
goto out_unlock;
|
||||
if (dentry)
|
||||
goto accept;
|
||||
|
||||
/* is the parent dir cached? */
|
||||
br = au_sbr(sb, nsi_lock.bindex);
|
||||
atomic_inc(&br->br_count);
|
||||
dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock);
|
||||
if (IS_ERR(dentry))
|
||||
goto out_unlock;
|
||||
if (dentry)
|
||||
goto accept;
|
||||
|
||||
/* lookup path */
|
||||
dentry = decode_by_path(sb, ino, fh, fh_len, &nsi_lock);
|
||||
if (IS_ERR(dentry))
|
||||
goto out_unlock;
|
||||
if (unlikely(!dentry))
|
||||
/* todo?: make it ESTALE */
|
||||
goto out_unlock;
|
||||
|
||||
accept:
|
||||
if (!au_digen_test(dentry, au_sigen(sb))
|
||||
&& dentry->d_inode->i_generation == fh[Fh_igen])
|
||||
goto out_unlock; /* success */
|
||||
|
||||
dput(dentry);
|
||||
dentry = ERR_PTR(-ESTALE);
|
||||
out_unlock:
|
||||
if (br)
|
||||
atomic_dec(&br->br_count);
|
||||
si_read_unlock(sb);
|
||||
out:
|
||||
AuTraceErrPtr(dentry);
|
||||
return dentry;
|
||||
}
|
||||
|
||||
#if 0 /* reserved for future use */
|
||||
/* support subtreecheck option */
|
||||
static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid,
|
||||
int fh_len, int fh_type)
|
||||
{
|
||||
struct dentry *parent;
|
||||
__u32 *fh = fid->raw;
|
||||
ino_t dir_ino;
|
||||
|
||||
dir_ino = decode_ino(fh + Fh_dir_ino);
|
||||
parent = decode_by_ino(sb, dir_ino, 0);
|
||||
if (IS_ERR(parent))
|
||||
goto out;
|
||||
if (!parent)
|
||||
parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]),
|
||||
dir_ino, fh, fh_len);
|
||||
|
||||
out:
|
||||
AuTraceErrPtr(parent);
|
||||
return parent;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static int aufs_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len,
|
||||
int connectable)
|
||||
{
|
||||
int err;
|
||||
aufs_bindex_t bindex, bend;
|
||||
struct super_block *sb, *h_sb;
|
||||
struct inode *inode;
|
||||
struct dentry *parent, *h_parent;
|
||||
struct au_branch *br;
|
||||
|
||||
AuDebugOn(au_test_anon(dentry));
|
||||
|
||||
parent = NULL;
|
||||
err = -ENOSPC;
|
||||
if (unlikely(*max_len <= Fh_tail)) {
|
||||
AuWarn1("NFSv2 client (max_len %d)?\n", *max_len);
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = FILEID_ROOT;
|
||||
if (IS_ROOT(dentry)) {
|
||||
AuDebugOn(dentry->d_inode->i_ino != AUFS_ROOT_INO);
|
||||
goto out;
|
||||
}
|
||||
|
||||
h_parent = NULL;
|
||||
err = aufs_read_lock(dentry, AuLock_FLUSH | AuLock_IR | AuLock_GEN);
|
||||
if (unlikely(err))
|
||||
goto out;
|
||||
|
||||
inode = dentry->d_inode;
|
||||
AuDebugOn(!inode);
|
||||
sb = dentry->d_sb;
|
||||
#ifdef CONFIG_AUFS_DEBUG
|
||||
if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
|
||||
AuWarn1("NFS-exporting requires xino\n");
|
||||
#endif
|
||||
err = -EIO;
|
||||
parent = dget_parent(dentry);
|
||||
di_read_lock_parent(parent, !AuLock_IR);
|
||||
bend = au_dbtaildir(parent);
|
||||
for (bindex = au_dbstart(parent); bindex <= bend; bindex++) {
|
||||
h_parent = au_h_dptr(parent, bindex);
|
||||
if (h_parent) {
|
||||
dget(h_parent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (unlikely(!h_parent))
|
||||
goto out_unlock;
|
||||
|
||||
err = -EPERM;
|
||||
br = au_sbr(sb, bindex);
|
||||
h_sb = br->br_mnt->mnt_sb;
|
||||
if (unlikely(!h_sb->s_export_op)) {
|
||||
AuErr1("%s branch is not exportable\n", au_sbtype(h_sb));
|
||||
goto out_dput;
|
||||
}
|
||||
|
||||
fh[Fh_br_id] = br->br_id;
|
||||
fh[Fh_sigen] = au_sigen(sb);
|
||||
encode_ino(fh + Fh_ino, inode->i_ino);
|
||||
encode_ino(fh + Fh_dir_ino, parent->d_inode->i_ino);
|
||||
fh[Fh_igen] = inode->i_generation;
|
||||
|
||||
*max_len -= Fh_tail;
|
||||
fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail),
|
||||
max_len,
|
||||
/*connectable or subtreecheck*/0);
|
||||
err = fh[Fh_h_type];
|
||||
*max_len += Fh_tail;
|
||||
/* todo: macros? */
|
||||
if (err != 255)
|
||||
err = 99;
|
||||
else
|
||||
AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb));
|
||||
|
||||
out_dput:
|
||||
dput(h_parent);
|
||||
out_unlock:
|
||||
di_read_unlock(parent, !AuLock_IR);
|
||||
dput(parent);
|
||||
aufs_read_unlock(dentry, AuLock_IR);
|
||||
out:
|
||||
if (unlikely(err < 0))
|
||||
err = 255;
|
||||
return err;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static int aufs_commit_metadata(struct inode *inode)
|
||||
{
|
||||
int err;
|
||||
aufs_bindex_t bindex;
|
||||
struct super_block *sb;
|
||||
struct inode *h_inode;
|
||||
int (*f)(struct inode *inode);
|
||||
|
||||
sb = inode->i_sb;
|
||||
si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
|
||||
ii_write_lock_child(inode);
|
||||
bindex = au_ibstart(inode);
|
||||
AuDebugOn(bindex < 0);
|
||||
h_inode = au_h_iptr(inode, bindex);
|
||||
|
||||
f = h_inode->i_sb->s_export_op->commit_metadata;
|
||||
if (f)
|
||||
err = f(h_inode);
|
||||
else {
|
||||
struct writeback_control wbc = {
|
||||
.sync_mode = WB_SYNC_ALL,
|
||||
.nr_to_write = 0 /* metadata only */
|
||||
};
|
||||
|
||||
err = sync_inode(h_inode, &wbc);
|
||||
}
|
||||
|
||||
au_cpup_attr_timesizes(inode);
|
||||
ii_write_unlock(inode);
|
||||
si_read_unlock(sb);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static struct export_operations aufs_export_op = {
|
||||
.fh_to_dentry = aufs_fh_to_dentry,
|
||||
/* .fh_to_parent = aufs_fh_to_parent, */
|
||||
.encode_fh = aufs_encode_fh,
|
||||
.commit_metadata = aufs_commit_metadata
|
||||
};
|
||||
|
||||
void au_export_init(struct super_block *sb)
|
||||
{
|
||||
struct au_sbinfo *sbinfo;
|
||||
__u32 u;
|
||||
|
||||
sb->s_export_op = &aufs_export_op;
|
||||
sbinfo = au_sbi(sb);
|
||||
sbinfo->si_xigen = NULL;
|
||||
get_random_bytes(&u, sizeof(u));
|
||||
BUILD_BUG_ON(sizeof(u) != sizeof(int));
|
||||
atomic_set(&sbinfo->si_xigen_next, u);
|
||||
}
|
@ -1,737 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2012 Junjiro R. Okajima
|
||||
*
|
||||
* This program, aufs is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* file and vm operations
|
||||
*/
|
||||
|
||||
#include <linux/fs_stack.h>
|
||||
#include <linux/mman.h>
|
||||
#include <linux/security.h>
|
||||
#include "aufs.h"
|
||||
|
||||
int au_do_open_nondir(struct file *file, int flags)
|
||||
{
|
||||
int err;
|
||||
aufs_bindex_t bindex;
|
||||
struct file *h_file;
|
||||
struct dentry *dentry;
|
||||
struct au_finfo *finfo;
|
||||
|
||||
FiMustWriteLock(file);
|
||||
|
||||
dentry = file->f_dentry;
|
||||
err = au_d_alive(dentry);
|
||||
if (unlikely(err))
|
||||
goto out;
|
||||
|
||||
finfo = au_fi(file);
|
||||
memset(&finfo->fi_htop, 0, sizeof(finfo->fi_htop));
|
||||
atomic_set(&finfo->fi_mmapped, 0);
|
||||
bindex = au_dbstart(dentry);
|
||||
h_file = au_h_open(dentry, bindex, flags, file);
|
||||
if (IS_ERR(h_file))
|
||||
err = PTR_ERR(h_file);
|
||||
else {
|
||||
au_set_fbstart(file, bindex);
|
||||
au_set_h_fptr(file, bindex, h_file);
|
||||
au_update_figen(file);
|
||||
/* todo: necessary? */
|
||||
/* file->f_ra = h_file->f_ra; */
|
||||
}
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int aufs_open_nondir(struct inode *inode __maybe_unused,
|
||||
struct file *file)
|
||||
{
|
||||
int err;
|
||||
struct super_block *sb;
|
||||
|
||||
AuDbg("%.*s, f_flags 0x%x, f_mode 0x%x\n",
|
||||
AuDLNPair(file->f_dentry), vfsub_file_flags(file),
|
||||
file->f_mode);
|
||||
|
||||
sb = file->f_dentry->d_sb;
|
||||
si_read_lock(sb, AuLock_FLUSH);
|
||||
err = au_do_open(file, au_do_open_nondir, /*fidir*/NULL);
|
||||
si_read_unlock(sb);
|
||||
return err;
|
||||
}
|
||||
|
||||
int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file)
|
||||
{
|
||||
struct au_finfo *finfo;
|
||||
aufs_bindex_t bindex;
|
||||
|
||||
finfo = au_fi(file);
|
||||
bindex = finfo->fi_btop;
|
||||
if (bindex >= 0) {
|
||||
/* remove me from sb->s_files */
|
||||
file_sb_list_del(file);
|
||||
au_set_h_fptr(file, bindex, NULL);
|
||||
}
|
||||
|
||||
au_finfo_fin(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static int au_do_flush_nondir(struct file *file, fl_owner_t id)
|
||||
{
|
||||
int err;
|
||||
struct file *h_file;
|
||||
|
||||
err = 0;
|
||||
h_file = au_hf_top(file);
|
||||
if (h_file)
|
||||
err = vfsub_flush(h_file, id);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int aufs_flush_nondir(struct file *file, fl_owner_t id)
|
||||
{
|
||||
return au_do_flush(file, id, au_do_flush_nondir);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/*
|
||||
* read and write functions acquire [fdi]_rwsem once, but release before
|
||||
* mmap_sem. This is because to stop a race condition between mmap(2).
|
||||
* Releasing these aufs-rwsem should be safe, no branch-mamagement (by keeping
|
||||
* si_rwsem), no harmful copy-up should happen. Actually copy-up may happen in
|
||||
* read functions after [fdi]_rwsem are released, but it should be harmless.
|
||||
*/
|
||||
|
||||
static ssize_t aufs_read(struct file *file, char __user *buf, size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
ssize_t err;
|
||||
struct dentry *dentry;
|
||||
struct file *h_file;
|
||||
struct super_block *sb;
|
||||
|
||||
dentry = file->f_dentry;
|
||||
sb = dentry->d_sb;
|
||||
si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
|
||||
err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
|
||||
if (unlikely(err))
|
||||
goto out;
|
||||
|
||||
h_file = au_hf_top(file);
|
||||
get_file(h_file);
|
||||
di_read_unlock(dentry, AuLock_IR);
|
||||
fi_read_unlock(file);
|
||||
|
||||
/* filedata may be obsoleted by concurrent copyup, but no problem */
|
||||
err = vfsub_read_u(h_file, buf, count, ppos);
|
||||
/* todo: necessary? */
|
||||
/* file->f_ra = h_file->f_ra; */
|
||||
/* update without lock, I don't think it a problem */
|
||||
fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode);
|
||||
fput(h_file);
|
||||
|
||||
out:
|
||||
si_read_unlock(sb);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* todo: very ugly
|
||||
* it locks both of i_mutex and si_rwsem for read in safe.
|
||||
* if the plink maintenance mode continues forever (that is the problem),
|
||||
* may loop forever.
|
||||
*/
|
||||
static void au_mtx_and_read_lock(struct inode *inode)
|
||||
{
|
||||
int err;
|
||||
struct super_block *sb = inode->i_sb;
|
||||
|
||||
while (1) {
|
||||
mutex_lock(&inode->i_mutex);
|
||||
err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
|
||||
if (!err)
|
||||
break;
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
si_read_lock(sb, AuLock_NOPLMW);
|
||||
si_read_unlock(sb);
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t aufs_write(struct file *file, const char __user *ubuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
ssize_t err;
|
||||
struct au_pin pin;
|
||||
struct dentry *dentry;
|
||||
struct super_block *sb;
|
||||
struct inode *inode;
|
||||
struct file *h_file;
|
||||
char __user *buf = (char __user *)ubuf;
|
||||
|
||||
dentry = file->f_dentry;
|
||||
sb = dentry->d_sb;
|
||||
inode = dentry->d_inode;
|
||||
au_mtx_and_read_lock(inode);
|
||||
|
||||
err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
|
||||
if (unlikely(err))
|
||||
goto out;
|
||||
|
||||
err = au_ready_to_write(file, -1, &pin);
|
||||
di_downgrade_lock(dentry, AuLock_IR);
|
||||
if (unlikely(err)) {
|
||||
di_read_unlock(dentry, AuLock_IR);
|
||||
fi_write_unlock(file);
|
||||
goto out;
|
||||
}
|
||||
|
||||
h_file = au_hf_top(file);
|
||||
get_file(h_file);
|
||||
au_unpin(&pin);
|
||||
di_read_unlock(dentry, AuLock_IR);
|
||||
fi_write_unlock(file);
|
||||
|
||||
err = vfsub_write_u(h_file, buf, count, ppos);
|
||||
ii_write_lock_child(inode);
|
||||
au_cpup_attr_timesizes(inode);
|
||||
inode->i_mode = h_file->f_dentry->d_inode->i_mode;
|
||||
ii_write_unlock(inode);
|
||||
fput(h_file);
|
||||
|
||||
out:
|
||||
si_read_unlock(sb);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
static ssize_t au_do_aio(struct file *h_file, int rw, struct kiocb *kio,
|
||||
const struct iovec *iov, unsigned long nv, loff_t pos)
|
||||
{
|
||||
ssize_t err;
|
||||
struct file *file;
|
||||
ssize_t (*func)(struct kiocb *, const struct iovec *, unsigned long,
|
||||
loff_t);
|
||||
|
||||
err = security_file_permission(h_file, rw);
|
||||
if (unlikely(err))
|
||||
goto out;
|
||||
|
||||
err = -ENOSYS;
|
||||
func = NULL;
|
||||
if (rw == MAY_READ)
|
||||
func = h_file->f_op->aio_read;
|
||||
else if (rw == MAY_WRITE)
|
||||
func = h_file->f_op->aio_write;
|
||||
if (func) {
|
||||
file = kio->ki_filp;
|
||||
kio->ki_filp = h_file;
|
||||
lockdep_off();
|
||||
err = func(kio, iov, nv, pos);
|
||||
lockdep_on();
|
||||
kio->ki_filp = file;
|
||||
} else
|
||||
/* currently there is no such fs */
|
||||
WARN_ON_ONCE(1);
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static ssize_t aufs_aio_read(struct kiocb *kio, const struct iovec *iov,
|
||||
unsigned long nv, loff_t pos)
|
||||
{
|
||||
ssize_t err;
|
||||
struct file *file, *h_file;
|
||||
struct dentry *dentry;
|
||||
struct super_block *sb;
|
||||
|
||||
file = kio->ki_filp;
|
||||
dentry = file->f_dentry;
|
||||
sb = dentry->d_sb;
|
||||
si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
|
||||
err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
|
||||
if (unlikely(err))
|
||||
goto out;
|
||||
|
||||
h_file = au_hf_top(file);
|
||||
get_file(h_file);
|
||||
di_read_unlock(dentry, AuLock_IR);
|
||||
fi_read_unlock(file);
|
||||
|
||||
err = au_do_aio(h_file, MAY_READ, kio, iov, nv, pos);
|
||||
/* todo: necessary? */
|
||||
/* file->f_ra = h_file->f_ra; */
|
||||
/* update without lock, I don't think it a problem */
|
||||
fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode);
|
||||
fput(h_file);
|
||||
|
||||
out:
|
||||
si_read_unlock(sb);
|
||||
return err;
|
||||
}
|
||||
|
||||
static ssize_t aufs_aio_write(struct kiocb *kio, const struct iovec *iov,
|
||||
unsigned long nv, loff_t pos)
|
||||
{
|
||||
ssize_t err;
|
||||
struct au_pin pin;
|
||||
struct dentry *dentry;
|
||||
struct inode *inode;
|
||||
struct file *file, *h_file;
|
||||
struct super_block *sb;
|
||||
|
||||
file = kio->ki_filp;
|
||||
dentry = file->f_dentry;
|
||||
sb = dentry->d_sb;
|
||||
inode = dentry->d_inode;
|
||||
au_mtx_and_read_lock(inode);
|
||||
|
||||
err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
|
||||
if (unlikely(err))
|
||||
goto out;
|
||||
|
||||
err = au_ready_to_write(file, -1, &pin);
|
||||
di_downgrade_lock(dentry, AuLock_IR);
|
||||
if (unlikely(err)) {
|
||||
di_read_unlock(dentry, AuLock_IR);
|
||||
fi_write_unlock(file);
|
||||
goto out;
|
||||
}
|
||||
|
||||
h_file = au_hf_top(file);
|
||||
get_file(h_file);
|
||||
au_unpin(&pin);
|
||||
di_read_unlock(dentry, AuLock_IR);
|
||||
fi_write_unlock(file);
|
||||
|
||||
err = au_do_aio(h_file, MAY_WRITE, kio, iov, nv, pos);
|
||||
ii_write_lock_child(inode);
|
||||
au_cpup_attr_timesizes(inode);
|
||||
inode->i_mode = h_file->f_dentry->d_inode->i_mode;
|
||||
ii_write_unlock(inode);
|
||||
fput(h_file);
|
||||
|
||||
out:
|
||||
si_read_unlock(sb);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
|
||||
struct pipe_inode_info *pipe, size_t len,
|
||||
unsigned int flags)
|
||||
{
|
||||
ssize_t err;
|
||||
struct file *h_file;
|
||||
struct dentry *dentry;
|
||||
struct super_block *sb;
|
||||
|
||||
dentry = file->f_dentry;
|
||||
sb = dentry->d_sb;
|
||||
si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
|
||||
err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
|
||||
if (unlikely(err))
|
||||
goto out;
|
||||
|
||||
err = -EINVAL;
|
||||
h_file = au_hf_top(file);
|
||||
get_file(h_file);
|
||||
if (au_test_loopback_kthread()) {
|
||||
au_warn_loopback(h_file->f_dentry->d_sb);
|
||||
if (file->f_mapping != h_file->f_mapping) {
|
||||
file->f_mapping = h_file->f_mapping;
|
||||
smp_mb(); /* unnecessary? */
|
||||
}
|
||||
}
|
||||
di_read_unlock(dentry, AuLock_IR);
|
||||
fi_read_unlock(file);
|
||||
|
||||
err = vfsub_splice_to(h_file, ppos, pipe, len, flags);
|
||||
/* todo: necessasry? */
|
||||
/* file->f_ra = h_file->f_ra; */
|
||||
/* update without lock, I don't think it a problem */
|
||||
fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode);
|
||||
fput(h_file);
|
||||
|
||||
out:
|
||||
si_read_unlock(sb);
|
||||
return err;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos,
|
||||
size_t len, unsigned int flags)
|
||||
{
|
||||
ssize_t err;
|
||||
struct au_pin pin;
|
||||
struct dentry *dentry;
|
||||
struct inode *inode;
|
||||
struct file *h_file;
|
||||
struct super_block *sb;
|
||||
|
||||
dentry = file->f_dentry;
|
||||
sb = dentry->d_sb;
|
||||
inode = dentry->d_inode;
|
||||
au_mtx_and_read_lock(inode);
|
||||
|
||||
err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
|
||||
if (unlikely(err))
|
||||
goto out;
|
||||
|
||||
err = au_ready_to_write(file, -1, &pin);
|
||||
di_downgrade_lock(dentry, AuLock_IR);
|
||||
if (unlikely(err)) {
|
||||
di_read_unlock(dentry, AuLock_IR);
|
||||
fi_write_unlock(file);
|
||||
goto out;
|
||||
}
|
||||
|
||||
h_file = au_hf_top(file);
|
||||
get_file(h_file);
|
||||
au_unpin(&pin);
|
||||
di_read_unlock(dentry, AuLock_IR);
|
||||
fi_write_unlock(file);
|
||||
|
||||
err = vfsub_splice_from(pipe, h_file, ppos, len, flags);
|
||||
ii_write_lock_child(inode);
|
||||
au_cpup_attr_timesizes(inode);
|
||||
inode->i_mode = h_file->f_dentry->d_inode->i_mode;
|
||||
ii_write_unlock(inode);
|
||||
fput(h_file);
|
||||
|
||||
out:
|
||||
si_read_unlock(sb);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* The locking order around current->mmap_sem.
|
||||
* - in most and regular cases
|
||||
* file I/O syscall -- aufs_read() or something
|
||||
* -- si_rwsem for read -- mmap_sem
|
||||
* (Note that [fdi]i_rwsem are released before mmap_sem).
|
||||
* - in mmap case
|
||||
* mmap(2) -- mmap_sem -- aufs_mmap() -- si_rwsem for read -- [fdi]i_rwsem
|
||||
* This AB-BA order is definitly bad, but is not a problem since "si_rwsem for
|
||||
* read" allows muliple processes to acquire it and [fdi]i_rwsem are not held in
|
||||
* file I/O. Aufs needs to stop lockdep in aufs_mmap() though.
|
||||
* It means that when aufs acquires si_rwsem for write, the process should never
|
||||
* acquire mmap_sem.
|
||||
*
|
||||
* Actually aufs_readdir() holds [fdi]i_rwsem before mmap_sem, but this is not a
|
||||
* problem either since any directory is not able to be mmap-ed.
|
||||
* The similar scenario is applied to aufs_readlink() too.
|
||||
*/
|
||||
|
||||
/* cf. linux/include/linux/mman.h: calc_vm_prot_bits() */
|
||||
#define AuConv_VM_PROT(f, b) _calc_vm_trans(f, VM_##b, PROT_##b)
|
||||
|
||||
static unsigned long au_arch_prot_conv(unsigned long flags)
|
||||
{
|
||||
/* currently ppc64 only */
|
||||
#ifdef CONFIG_PPC64
|
||||
/* cf. linux/arch/powerpc/include/asm/mman.h */
|
||||
AuDebugOn(arch_calc_vm_prot_bits(-1) != VM_SAO);
|
||||
return AuConv_VM_PROT(flags, SAO);
|
||||
#else
|
||||
AuDebugOn(arch_calc_vm_prot_bits(-1));
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static unsigned long au_prot_conv(unsigned long flags)
|
||||
{
|
||||
return AuConv_VM_PROT(flags, READ)
|
||||
| AuConv_VM_PROT(flags, WRITE)
|
||||
| AuConv_VM_PROT(flags, EXEC)
|
||||
| au_arch_prot_conv(flags);
|
||||
}
|
||||
|
||||
/* cf. linux/include/linux/mman.h: calc_vm_flag_bits() */
|
||||
#define AuConv_VM_MAP(f, b) _calc_vm_trans(f, VM_##b, MAP_##b)
|
||||
|
||||
static unsigned long au_flag_conv(unsigned long flags)
|
||||
{
|
||||
return AuConv_VM_MAP(flags, GROWSDOWN)
|
||||
| AuConv_VM_MAP(flags, DENYWRITE)
|
||||
| AuConv_VM_MAP(flags, EXECUTABLE)
|
||||
| AuConv_VM_MAP(flags, LOCKED);
|
||||
}
|
||||
|
||||
static int aufs_mmap(struct file *file, struct vm_area_struct *vma)
|
||||
{
|
||||
int err;
|
||||
unsigned long prot;
|
||||
aufs_bindex_t bstart;
|
||||
const unsigned char wlock
|
||||
= (file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED);
|
||||
struct dentry *dentry;
|
||||
struct super_block *sb;
|
||||
struct file *h_file;
|
||||
struct au_branch *br;
|
||||
struct au_pin pin;
|
||||
|
||||
AuDbgVmRegion(file, vma);
|
||||
|
||||
dentry = file->f_dentry;
|
||||
sb = dentry->d_sb;
|
||||
lockdep_off();
|
||||
si_read_lock(sb, AuLock_NOPLMW);
|
||||
err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
|
||||
if (unlikely(err))
|
||||
goto out;
|
||||
|
||||
if (wlock) {
|
||||
err = au_ready_to_write(file, -1, &pin);
|
||||
di_write_unlock(dentry);
|
||||
if (unlikely(err)) {
|
||||
fi_write_unlock(file);
|
||||
goto out;
|
||||
}
|
||||
au_unpin(&pin);
|
||||
} else
|
||||
di_write_unlock(dentry);
|
||||
|
||||
bstart = au_fbstart(file);
|
||||
br = au_sbr(sb, bstart);
|
||||
h_file = au_hf_top(file);
|
||||
get_file(h_file);
|
||||
au_set_mmapped(file);
|
||||
fi_write_unlock(file);
|
||||
lockdep_on();
|
||||
|
||||
au_vm_file_reset(vma, h_file);
|
||||
prot = au_prot_conv(vma->vm_flags);
|
||||
err = security_file_mmap(h_file, /*reqprot*/prot, prot,
|
||||
au_flag_conv(vma->vm_flags), vma->vm_start, 0);
|
||||
if (!err)
|
||||
err = h_file->f_op->mmap(h_file, vma);
|
||||
if (unlikely(err))
|
||||
goto out_reset;
|
||||
|
||||
au_vm_prfile_set(vma, file);
|
||||
/* update without lock, I don't think it a problem */
|
||||
fsstack_copy_attr_atime(file->f_dentry->d_inode,
|
||||
h_file->f_dentry->d_inode);
|
||||
goto out_fput; /* success */
|
||||
|
||||
out_reset:
|
||||
au_unset_mmapped(file);
|
||||
au_vm_file_reset(vma, file);
|
||||
out_fput:
|
||||
fput(h_file);
|
||||
lockdep_off();
|
||||
out:
|
||||
si_read_unlock(sb);
|
||||
lockdep_on();
|
||||
AuTraceErr(err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static int aufs_fsync_nondir(struct file *file, int datasync)
|
||||
{
|
||||
int err;
|
||||
struct au_pin pin;
|
||||
struct dentry *dentry;
|
||||
struct inode *inode;
|
||||
struct file *h_file;
|
||||
struct super_block *sb;
|
||||
|
||||
dentry = file->f_dentry;
|
||||
inode = dentry->d_inode;
|
||||
IMustLock(file->f_mapping->host);
|
||||
if (inode != file->f_mapping->host) {
|
||||
mutex_unlock(&file->f_mapping->host->i_mutex);
|
||||
mutex_lock(&inode->i_mutex);
|
||||
}
|
||||
IMustLock(inode);
|
||||
|
||||
sb = dentry->d_sb;
|
||||
err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
|
||||
if (unlikely(err))
|
||||
goto out;
|
||||
|
||||
err = 0; /* -EBADF; */ /* posix? */
|
||||
if (unlikely(!(file->f_mode & FMODE_WRITE)))
|
||||
goto out_si;
|
||||
err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
|
||||
if (unlikely(err))
|
||||
goto out_si;
|
||||
|
||||
err = au_ready_to_write(file, -1, &pin);
|
||||
di_downgrade_lock(dentry, AuLock_IR);
|
||||
if (unlikely(err))
|
||||
goto out_unlock;
|
||||
au_unpin(&pin);
|
||||
|
||||
err = -EINVAL;
|
||||
h_file = au_hf_top(file);
|
||||
err = vfsub_fsync(h_file, &h_file->f_path, datasync);
|
||||
au_cpup_attr_timesizes(inode);
|
||||
|
||||
out_unlock:
|
||||
di_read_unlock(dentry, AuLock_IR);
|
||||
fi_write_unlock(file);
|
||||
out_si:
|
||||
si_read_unlock(sb);
|
||||
out:
|
||||
if (inode != file->f_mapping->host) {
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
mutex_lock(&file->f_mapping->host->i_mutex);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
/* no one supports this operation, currently */
|
||||
#if 0
|
||||
static int aufs_aio_fsync_nondir(struct kiocb *kio, int datasync)
|
||||
{
|
||||
int err;
|
||||
struct au_pin pin;
|
||||
struct dentry *dentry;
|
||||
struct inode *inode;
|
||||
struct file *file, *h_file;
|
||||
|
||||
file = kio->ki_filp;
|
||||
dentry = file->f_dentry;
|
||||
inode = dentry->d_inode;
|
||||
au_mtx_and_read_lock(inode);
|
||||
|
||||
err = 0; /* -EBADF; */ /* posix? */
|
||||
if (unlikely(!(file->f_mode & FMODE_WRITE)))
|
||||
goto out;
|
||||
err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
|
||||
if (unlikely(err))
|
||||
goto out;
|
||||
|
||||
err = au_ready_to_write(file, -1, &pin);
|
||||
di_downgrade_lock(dentry, AuLock_IR);
|
||||
if (unlikely(err))
|
||||
goto out_unlock;
|
||||
au_unpin(&pin);
|
||||
|
||||
err = -ENOSYS;
|
||||
h_file = au_hf_top(file);
|
||||
if (h_file->f_op && h_file->f_op->aio_fsync) {
|
||||
struct dentry *h_d;
|
||||
struct mutex *h_mtx;
|
||||
|
||||
h_d = h_file->f_dentry;
|
||||
h_mtx = &h_d->d_inode->i_mutex;
|
||||
if (!is_sync_kiocb(kio)) {
|
||||
get_file(h_file);
|
||||
fput(file);
|
||||
}
|
||||
kio->ki_filp = h_file;
|
||||
err = h_file->f_op->aio_fsync(kio, datasync);
|
||||
mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
|
||||
if (!err)
|
||||
vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL);
|
||||
/*ignore*/
|
||||
au_cpup_attr_timesizes(inode);
|
||||
mutex_unlock(h_mtx);
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
di_read_unlock(dentry, AuLock_IR);
|
||||
fi_write_unlock(file);
|
||||
out:
|
||||
si_read_unlock(inode->sb);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int aufs_fasync(int fd, struct file *file, int flag)
|
||||
{
|
||||
int err;
|
||||
struct file *h_file;
|
||||
struct dentry *dentry;
|
||||
struct super_block *sb;
|
||||
|
||||
dentry = file->f_dentry;
|
||||
sb = dentry->d_sb;
|
||||
si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
|
||||
err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
|
||||
if (unlikely(err))
|
||||
goto out;
|
||||
|
||||
h_file = au_hf_top(file);
|
||||
if (h_file->f_op && h_file->f_op->fasync)
|
||||
err = h_file->f_op->fasync(fd, h_file, flag);
|
||||
|
||||
di_read_unlock(dentry, AuLock_IR);
|
||||
fi_read_unlock(file);
|
||||
|
||||
out:
|
||||
si_read_unlock(sb);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/* no one supports this operation, currently */
|
||||
#if 0
|
||||
static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset,
|
||||
size_t len, loff_t *pos , int more)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
const struct file_operations aufs_file_fop = {
|
||||
.owner = THIS_MODULE,
|
||||
|
||||
.llseek = default_llseek,
|
||||
|
||||
.read = aufs_read,
|
||||
.write = aufs_write,
|
||||
.aio_read = aufs_aio_read,
|
||||
.aio_write = aufs_aio_write,
|
||||
#ifdef CONFIG_AUFS_POLL
|
||||
.poll = aufs_poll,
|
||||
#endif
|
||||
.unlocked_ioctl = aufs_ioctl_nondir,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = aufs_ioctl_nondir, /* same */
|
||||
#endif
|
||||
.mmap = aufs_mmap,
|
||||
.open = aufs_open_nondir,
|
||||
.flush = aufs_flush_nondir,
|
||||
.release = aufs_release_nondir,
|
||||
.fsync = aufs_fsync_nondir,
|
||||
/* .aio_fsync = aufs_aio_fsync_nondir, */
|
||||
.fasync = aufs_fasync,
|
||||
/* .sendpage = aufs_sendpage, */
|
||||
.splice_write = aufs_splice_write,
|
||||
.splice_read = aufs_splice_read,
|
||||
#if 0
|
||||
.aio_splice_write = aufs_aio_splice_write,
|
||||
.aio_splice_read = aufs_aio_splice_read
|
||||
#endif
|
||||
};
|
@ -1,298 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2012 Junjiro R. Okajima
|
||||
*
|
||||
* This program, aufs is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* file operations for special files.
|
||||
* while they exist in aufs virtually,
|
||||
* their file I/O is handled out of aufs.
|
||||
*/
|
||||
|
||||
#include "aufs.h"
|
||||
|
||||
static ssize_t aufs_aio_read_sp(struct kiocb *kio, const struct iovec *iov,
|
||||
unsigned long nv, loff_t pos)
|
||||
{
|
||||
ssize_t err;
|
||||
aufs_bindex_t bstart;
|
||||
unsigned char wbr;
|
||||
struct file *file, *h_file;
|
||||
struct super_block *sb;
|
||||
|
||||
file = kio->ki_filp;
|
||||
sb = file->f_dentry->d_sb;
|
||||
si_read_lock(sb, AuLock_FLUSH);
|
||||
fi_read_lock(file);
|
||||
bstart = au_fbstart(file);
|
||||
h_file = au_hf_top(file);
|
||||
fi_read_unlock(file);
|
||||
wbr = !!au_br_writable(au_sbr(sb, bstart)->br_perm);
|
||||
si_read_unlock(sb);
|
||||
|
||||
/* do not change the file in kio */
|
||||
AuDebugOn(!h_file->f_op || !h_file->f_op->aio_read);
|
||||
err = h_file->f_op->aio_read(kio, iov, nv, pos);
|
||||
if (err > 0 && wbr)
|
||||
file_accessed(h_file);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static ssize_t aufs_aio_write_sp(struct kiocb *kio, const struct iovec *iov,
|
||||
unsigned long nv, loff_t pos)
|
||||
{
|
||||
ssize_t err;
|
||||
aufs_bindex_t bstart;
|
||||
unsigned char wbr;
|
||||
struct super_block *sb;
|
||||
struct file *file, *h_file;
|
||||
|
||||
file = kio->ki_filp;
|
||||
sb = file->f_dentry->d_sb;
|
||||
si_read_lock(sb, AuLock_FLUSH);
|
||||
fi_read_lock(file);
|
||||
bstart = au_fbstart(file);
|
||||
h_file = au_hf_top(file);
|
||||
fi_read_unlock(file);
|
||||
wbr = !!au_br_writable(au_sbr(sb, bstart)->br_perm);
|
||||
si_read_unlock(sb);
|
||||
|
||||
/* do not change the file in kio */
|
||||
AuDebugOn(!h_file->f_op || !h_file->f_op->aio_write);
|
||||
err = h_file->f_op->aio_write(kio, iov, nv, pos);
|
||||
if (err > 0 && wbr)
|
||||
file_update_time(h_file);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static int aufs_release_sp(struct inode *inode, struct file *file)
|
||||
{
|
||||
int err;
|
||||
struct file *h_file;
|
||||
|
||||
fi_read_lock(file);
|
||||
h_file = au_hf_top(file);
|
||||
fi_read_unlock(file);
|
||||
/* close this fifo in aufs */
|
||||
err = h_file->f_op->release(inode, file); /* ignore */
|
||||
aufs_release_nondir(inode, file); /* ignore */
|
||||
return err;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/* currently, support only FIFO */
|
||||
enum {
|
||||
AuSp_FIFO, AuSp_FIFO_R, AuSp_FIFO_W, AuSp_FIFO_RW,
|
||||
/* AuSp_SOCK, AuSp_CHR, AuSp_BLK, */
|
||||
AuSp_Last
|
||||
};
|
||||
static int aufs_open_sp(struct inode *inode, struct file *file);
|
||||
static struct au_sp_fop {
|
||||
int done;
|
||||
struct file_operations fop; /* not 'const' */
|
||||
spinlock_t spin;
|
||||
} au_sp_fop[AuSp_Last] = {
|
||||
[AuSp_FIFO] = {
|
||||
.fop = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = aufs_open_sp
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static void au_init_fop_sp(struct file *file)
|
||||
{
|
||||
struct au_sp_fop *p;
|
||||
int i;
|
||||
struct file *h_file;
|
||||
|
||||
p = au_sp_fop;
|
||||
if (unlikely(!p->done)) {
|
||||
/* initialize first time only */
|
||||
static DEFINE_SPINLOCK(spin);
|
||||
|
||||
spin_lock(&spin);
|
||||
if (!p->done) {
|
||||
BUILD_BUG_ON(sizeof(au_sp_fop)/sizeof(*au_sp_fop)
|
||||
!= AuSp_Last);
|
||||
for (i = 0; i < AuSp_Last; i++)
|
||||
spin_lock_init(&p[i].spin);
|
||||
p->done = 1;
|
||||
}
|
||||
spin_unlock(&spin);
|
||||
}
|
||||
|
||||
switch (file->f_mode & (FMODE_READ | FMODE_WRITE)) {
|
||||
case FMODE_READ:
|
||||
i = AuSp_FIFO_R;
|
||||
break;
|
||||
case FMODE_WRITE:
|
||||
i = AuSp_FIFO_W;
|
||||
break;
|
||||
case FMODE_READ | FMODE_WRITE:
|
||||
i = AuSp_FIFO_RW;
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
||||
p += i;
|
||||
if (unlikely(!p->done)) {
|
||||
/* initialize first time only */
|
||||
h_file = au_hf_top(file);
|
||||
spin_lock(&p->spin);
|
||||
if (!p->done) {
|
||||
p->fop = *h_file->f_op;
|
||||
p->fop.owner = THIS_MODULE;
|
||||
if (p->fop.aio_read)
|
||||
p->fop.aio_read = aufs_aio_read_sp;
|
||||
if (p->fop.aio_write)
|
||||
p->fop.aio_write = aufs_aio_write_sp;
|
||||
p->fop.release = aufs_release_sp;
|
||||
p->done = 1;
|
||||
}
|
||||
spin_unlock(&p->spin);
|
||||
}
|
||||
file->f_op = &p->fop;
|
||||
}
|
||||
|
||||
static int au_cpup_sp(struct dentry *dentry)
|
||||
{
|
||||
int err;
|
||||
aufs_bindex_t bcpup;
|
||||
struct au_pin pin;
|
||||
struct au_wr_dir_args wr_dir_args = {
|
||||
.force_btgt = -1,
|
||||
.flags = 0
|
||||
};
|
||||
|
||||
AuDbg("%.*s\n", AuDLNPair(dentry));
|
||||
|
||||
di_read_unlock(dentry, AuLock_IR);
|
||||
di_write_lock_child(dentry);
|
||||
err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
|
||||
if (unlikely(err < 0))
|
||||
goto out;
|
||||
bcpup = err;
|
||||
err = 0;
|
||||
if (bcpup == au_dbstart(dentry))
|
||||
goto out; /* success */
|
||||
|
||||
err = au_pin(&pin, dentry, bcpup, au_opt_udba(dentry->d_sb),
|
||||
AuPin_MNT_WRITE);
|
||||
if (!err) {
|
||||
err = au_sio_cpup_simple(dentry, bcpup, -1, AuCpup_DTIME);
|
||||
au_unpin(&pin);
|
||||
}
|
||||
|
||||
out:
|
||||
di_downgrade_lock(dentry, AuLock_IR);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int au_do_open_sp(struct file *file, int flags)
|
||||
{
|
||||
int err;
|
||||
struct dentry *dentry;
|
||||
struct super_block *sb;
|
||||
struct file *h_file;
|
||||
struct inode *h_inode;
|
||||
|
||||
dentry = file->f_dentry;
|
||||
AuDbg("%.*s\n", AuDLNPair(dentry));
|
||||
|
||||
/*
|
||||
* try copying-up.
|
||||
* operate on the ro branch is not an error.
|
||||
*/
|
||||
au_cpup_sp(dentry); /* ignore */
|
||||
|
||||
/* prepare h_file */
|
||||
err = au_do_open_nondir(file, vfsub_file_flags(file));
|
||||
if (unlikely(err))
|
||||
goto out;
|
||||
|
||||
sb = dentry->d_sb;
|
||||
h_file = au_hf_top(file);
|
||||
h_inode = h_file->f_dentry->d_inode;
|
||||
di_read_unlock(dentry, AuLock_IR);
|
||||
fi_write_unlock(file);
|
||||
si_read_unlock(sb);
|
||||
/* open this fifo in aufs */
|
||||
err = h_inode->i_fop->open(file->f_dentry->d_inode, file);
|
||||
si_noflush_read_lock(sb);
|
||||
fi_write_lock(file);
|
||||
di_read_lock_child(dentry, AuLock_IR);
|
||||
if (!err)
|
||||
au_init_fop_sp(file);
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int aufs_open_sp(struct inode *inode, struct file *file)
|
||||
{
|
||||
int err;
|
||||
struct super_block *sb;
|
||||
|
||||
sb = file->f_dentry->d_sb;
|
||||
si_read_lock(sb, AuLock_FLUSH);
|
||||
err = au_do_open(file, au_do_open_sp, /*fidir*/NULL);
|
||||
si_read_unlock(sb);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void au_init_special_fop(struct inode *inode, umode_t mode, dev_t rdev)
|
||||
{
|
||||
init_special_inode(inode, mode, rdev);
|
||||
|
||||
switch (mode & S_IFMT) {
|
||||
case S_IFIFO:
|
||||
inode->i_fop = &au_sp_fop[AuSp_FIFO].fop;
|
||||
/*FALLTHROUGH*/
|
||||
case S_IFCHR:
|
||||
case S_IFBLK:
|
||||
case S_IFSOCK:
|
||||
break;
|
||||
default:
|
||||
AuDebugOn(1);
|
||||
}
|
||||
}
|
||||
|
||||
int au_special_file(umode_t mode)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = 0;
|
||||
switch (mode & S_IFMT) {
|
||||
case S_IFIFO:
|
||||
#if 0
|
||||
case S_IFCHR:
|
||||
case S_IFBLK:
|
||||
case S_IFSOCK:
|
||||
#endif
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
@ -1,673 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2012 Junjiro R. Okajima
|
||||
*
|
||||
* This program, aufs is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* handling file/dir, and address_space operation
|
||||
*/
|
||||
|
||||
#include <linux/pagemap.h>
|
||||
#include "aufs.h"
|
||||
|
||||
/* drop flags for writing */
|
||||
unsigned int au_file_roflags(unsigned int flags)
|
||||
{
|
||||
flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC);
|
||||
flags |= O_RDONLY | O_NOATIME;
|
||||
return flags;
|
||||
}
|
||||
|
||||
/* common functions to regular file and dir */
|
||||
struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
|
||||
struct file *file)
|
||||
{
|
||||
struct file *h_file;
|
||||
struct dentry *h_dentry;
|
||||
struct inode *h_inode;
|
||||
struct super_block *sb;
|
||||
struct au_branch *br;
|
||||
struct path h_path;
|
||||
int err, exec_flag;
|
||||
|
||||
/* a race condition can happen between open and unlink/rmdir */
|
||||
h_file = ERR_PTR(-ENOENT);
|
||||
h_dentry = au_h_dptr(dentry, bindex);
|
||||
if (au_test_nfsd() && !h_dentry)
|
||||
goto out;
|
||||
h_inode = h_dentry->d_inode;
|
||||
if (au_test_nfsd() && !h_inode)
|
||||
goto out;
|
||||
spin_lock(&h_dentry->d_lock);
|
||||
err = (!d_unhashed(dentry) && d_unlinked(h_dentry))
|
||||
|| !h_inode
|
||||
/* || !dentry->d_inode->i_nlink */
|
||||
;
|
||||
spin_unlock(&h_dentry->d_lock);
|
||||
if (unlikely(err))
|
||||
goto out;
|
||||
|
||||
sb = dentry->d_sb;
|
||||
br = au_sbr(sb, bindex);
|
||||
h_file = ERR_PTR(-EACCES);
|
||||
exec_flag = flags & __FMODE_EXEC;
|
||||
if (exec_flag && (br->br_mnt->mnt_flags & MNT_NOEXEC))
|
||||
goto out;
|
||||
|
||||
/* drop flags for writing */
|
||||
if (au_test_ro(sb, bindex, dentry->d_inode))
|
||||
flags = au_file_roflags(flags);
|
||||
flags &= ~O_CREAT;
|
||||
atomic_inc(&br->br_count);
|
||||
h_path.dentry = h_dentry;
|
||||
h_path.mnt = br->br_mnt;
|
||||
if (!au_special_file(h_inode->i_mode))
|
||||
h_file = vfsub_dentry_open(&h_path, flags);
|
||||
else {
|
||||
/* this block depends upon the configuration */
|
||||
di_read_unlock(dentry, AuLock_IR);
|
||||
fi_write_unlock(file);
|
||||
si_read_unlock(sb);
|
||||
h_file = vfsub_dentry_open(&h_path, flags);
|
||||
si_noflush_read_lock(sb);
|
||||
fi_write_lock(file);
|
||||
di_read_lock_child(dentry, AuLock_IR);
|
||||
}
|
||||
if (IS_ERR(h_file))
|
||||
goto out_br;
|
||||
|
||||
if (exec_flag) {
|
||||
err = deny_write_access(h_file);
|
||||
if (unlikely(err)) {
|
||||
fput(h_file);
|
||||
h_file = ERR_PTR(err);
|
||||
goto out_br;
|
||||
}
|
||||
}
|
||||
fsnotify_open(h_file);
|
||||
goto out; /* success */
|
||||
|
||||
out_br:
|
||||
atomic_dec(&br->br_count);
|
||||
out:
|
||||
return h_file;
|
||||
}
|
||||
|
||||
int au_do_open(struct file *file, int (*open)(struct file *file, int flags),
|
||||
struct au_fidir *fidir)
|
||||
{
|
||||
int err;
|
||||
struct dentry *dentry;
|
||||
|
||||
err = au_finfo_init(file, fidir);
|
||||
if (unlikely(err))
|
||||
goto out;
|
||||
|
||||
dentry = file->f_dentry;
|
||||
di_read_lock_child(dentry, AuLock_IR);
|
||||
err = open(file, vfsub_file_flags(file));
|
||||
di_read_unlock(dentry, AuLock_IR);
|
||||
|
||||
fi_write_unlock(file);
|
||||
if (unlikely(err)) {
|
||||
au_fi(file)->fi_hdir = NULL;
|
||||
au_finfo_fin(file);
|
||||
}
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
int au_reopen_nondir(struct file *file)
|
||||
{
|
||||
int err;
|
||||
aufs_bindex_t bstart;
|
||||
struct dentry *dentry;
|
||||
struct file *h_file, *h_file_tmp;
|
||||
|
||||
dentry = file->f_dentry;
|
||||
AuDebugOn(au_special_file(dentry->d_inode->i_mode));
|
||||
bstart = au_dbstart(dentry);
|
||||
h_file_tmp = NULL;
|
||||
if (au_fbstart(file) == bstart) {
|
||||
h_file = au_hf_top(file);
|
||||
if (file->f_mode == h_file->f_mode)
|
||||
return 0; /* success */
|
||||
h_file_tmp = h_file;
|
||||
get_file(h_file_tmp);
|
||||
au_set_h_fptr(file, bstart, NULL);
|
||||
}
|
||||
AuDebugOn(au_fi(file)->fi_hdir);
|
||||
AuDebugOn(au_fbstart(file) < bstart);
|
||||
|
||||
h_file = au_h_open(dentry, bstart, vfsub_file_flags(file) & ~O_TRUNC,
|
||||
file);
|
||||
err = PTR_ERR(h_file);
|
||||
if (IS_ERR(h_file))
|
||||
goto out; /* todo: close all? */
|
||||
|
||||
err = 0;
|
||||
au_set_fbstart(file, bstart);
|
||||
au_set_h_fptr(file, bstart, h_file);
|
||||
au_update_figen(file);
|
||||
/* todo: necessary? */
|
||||
/* file->f_ra = h_file->f_ra; */
|
||||
|
||||
out:
|
||||
if (h_file_tmp)
|
||||
fput(h_file_tmp);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static int au_reopen_wh(struct file *file, aufs_bindex_t btgt,
|
||||
struct dentry *hi_wh)
|
||||
{
|
||||
int err;
|
||||
aufs_bindex_t bstart;
|
||||
struct au_dinfo *dinfo;
|
||||
struct dentry *h_dentry;
|
||||
struct au_hdentry *hdp;
|
||||
|
||||
dinfo = au_di(file->f_dentry);
|
||||
AuRwMustWriteLock(&dinfo->di_rwsem);
|
||||
|
||||
bstart = dinfo->di_bstart;
|
||||
dinfo->di_bstart = btgt;
|
||||
hdp = dinfo->di_hdentry;
|
||||
h_dentry = hdp[0 + btgt].hd_dentry;
|
||||
hdp[0 + btgt].hd_dentry = hi_wh;
|
||||
err = au_reopen_nondir(file);
|
||||
hdp[0 + btgt].hd_dentry = h_dentry;
|
||||
dinfo->di_bstart = bstart;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int au_ready_to_write_wh(struct file *file, loff_t len,
|
||||
aufs_bindex_t bcpup)
|
||||
{
|
||||
int err;
|
||||
struct inode *inode, *h_inode;
|
||||
struct dentry *dentry, *h_dentry, *hi_wh;
|
||||
|
||||
dentry = file->f_dentry;
|
||||
au_update_dbstart(dentry);
|
||||
inode = dentry->d_inode;
|
||||
h_inode = NULL;
|
||||
if (au_dbstart(dentry) <= bcpup && au_dbend(dentry) >= bcpup) {
|
||||
h_dentry = au_h_dptr(dentry, bcpup);
|
||||
if (h_dentry)
|
||||
h_inode = h_dentry->d_inode;
|
||||
}
|
||||
hi_wh = au_hi_wh(inode, bcpup);
|
||||
if (!hi_wh && !h_inode)
|
||||
err = au_sio_cpup_wh(dentry, bcpup, len, file);
|
||||
else
|
||||
/* already copied-up after unlink */
|
||||
err = au_reopen_wh(file, bcpup, hi_wh);
|
||||
|
||||
if (!err
|
||||
&& inode->i_nlink > 1
|
||||
&& au_opt_test(au_mntflags(dentry->d_sb), PLINK))
|
||||
au_plink_append(inode, bcpup, au_h_dptr(dentry, bcpup));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* prepare the @file for writing.
|
||||
*/
|
||||
int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin)
|
||||
{
|
||||
int err;
|
||||
aufs_bindex_t bstart, bcpup, dbstart;
|
||||
struct dentry *dentry, *parent, *h_dentry;
|
||||
struct inode *h_inode, *inode;
|
||||
struct super_block *sb;
|
||||
struct file *h_file;
|
||||
|
||||
dentry = file->f_dentry;
|
||||
sb = dentry->d_sb;
|
||||
inode = dentry->d_inode;
|
||||
AuDebugOn(au_special_file(inode->i_mode));
|
||||
bstart = au_fbstart(file);
|
||||
err = au_test_ro(sb, bstart, inode);
|
||||
if (!err && (au_hf_top(file)->f_mode & FMODE_WRITE)) {
|
||||
err = au_pin(pin, dentry, bstart, AuOpt_UDBA_NONE, /*flags*/0);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* need to cpup or reopen */
|
||||
parent = dget_parent(dentry);
|
||||
di_write_lock_parent(parent);
|
||||
err = AuWbrCopyup(au_sbi(sb), dentry);
|
||||
bcpup = err;
|
||||
if (unlikely(err < 0))
|
||||
goto out_dgrade;
|
||||
err = 0;
|
||||
|
||||
if (!d_unhashed(dentry) && !au_h_dptr(parent, bcpup)) {
|
||||
err = au_cpup_dirs(dentry, bcpup);
|
||||
if (unlikely(err))
|
||||
goto out_dgrade;
|
||||
}
|
||||
|
||||
err = au_pin(pin, dentry, bcpup, AuOpt_UDBA_NONE,
|
||||
AuPin_DI_LOCKED | AuPin_MNT_WRITE);
|
||||
if (unlikely(err))
|
||||
goto out_dgrade;
|
||||
|
||||
h_dentry = au_hf_top(file)->f_dentry;
|
||||
h_inode = h_dentry->d_inode;
|
||||
dbstart = au_dbstart(dentry);
|
||||
if (dbstart <= bcpup) {
|
||||
h_dentry = au_h_dptr(dentry, bcpup);
|
||||
AuDebugOn(!h_dentry);
|
||||
h_inode = h_dentry->d_inode;
|
||||
AuDebugOn(!h_inode);
|
||||
bstart = bcpup;
|
||||
}
|
||||
|
||||
if (dbstart <= bcpup /* just reopen */
|
||||
|| !d_unhashed(dentry) /* copyup and reopen */
|
||||
) {
|
||||
mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
|
||||
h_file = au_h_open_pre(dentry, bstart);
|
||||
if (IS_ERR(h_file)) {
|
||||
err = PTR_ERR(h_file);
|
||||
h_file = NULL;
|
||||
} else {
|
||||
di_downgrade_lock(parent, AuLock_IR);
|
||||
if (dbstart > bcpup)
|
||||
err = au_sio_cpup_simple(dentry, bcpup, len,
|
||||
AuCpup_DTIME);
|
||||
if (!err)
|
||||
err = au_reopen_nondir(file);
|
||||
}
|
||||
mutex_unlock(&h_inode->i_mutex);
|
||||
au_h_open_post(dentry, bstart, h_file);
|
||||
} else { /* copyup as wh and reopen */
|
||||
/*
|
||||
* since writable hfsplus branch is not supported,
|
||||
* h_open_pre/post() are unnecessary.
|
||||
*/
|
||||
mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
|
||||
err = au_ready_to_write_wh(file, len, bcpup);
|
||||
di_downgrade_lock(parent, AuLock_IR);
|
||||
mutex_unlock(&h_inode->i_mutex);
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
au_pin_set_parent_lflag(pin, /*lflag*/0);
|
||||
goto out_dput; /* success */
|
||||
}
|
||||
au_unpin(pin);
|
||||
goto out_unlock;
|
||||
|
||||
out_dgrade:
|
||||
di_downgrade_lock(parent, AuLock_IR);
|
||||
out_unlock:
|
||||
di_read_unlock(parent, AuLock_IR);
|
||||
out_dput:
|
||||
dput(parent);
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
int au_do_flush(struct file *file, fl_owner_t id,
|
||||
int (*flush)(struct file *file, fl_owner_t id))
|
||||
{
|
||||
int err;
|
||||
struct dentry *dentry;
|
||||
struct super_block *sb;
|
||||
struct inode *inode;
|
||||
|
||||
dentry = file->f_dentry;
|
||||
sb = dentry->d_sb;
|
||||
inode = dentry->d_inode;
|
||||
si_noflush_read_lock(sb);
|
||||
fi_read_lock(file);
|
||||
ii_read_lock_child(inode);
|
||||
|
||||
err = flush(file, id);
|
||||
au_cpup_attr_timesizes(inode);
|
||||
|
||||
ii_read_unlock(inode);
|
||||
fi_read_unlock(file);
|
||||
si_read_unlock(sb);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static int au_file_refresh_by_inode(struct file *file, int *need_reopen)
|
||||
{
|
||||
int err;
|
||||
aufs_bindex_t bstart;
|
||||
struct au_pin pin;
|
||||
struct au_finfo *finfo;
|
||||
struct dentry *dentry, *parent, *hi_wh;
|
||||
struct inode *inode;
|
||||
struct super_block *sb;
|
||||
|
||||
FiMustWriteLock(file);
|
||||
|
||||
err = 0;
|
||||
finfo = au_fi(file);
|
||||
dentry = file->f_dentry;
|
||||
sb = dentry->d_sb;
|
||||
inode = dentry->d_inode;
|
||||
bstart = au_ibstart(inode);
|
||||
if (bstart == finfo->fi_btop || IS_ROOT(dentry))
|
||||
goto out;
|
||||
|
||||
parent = dget_parent(dentry);
|
||||
if (au_test_ro(sb, bstart, inode)) {
|
||||
di_read_lock_parent(parent, !AuLock_IR);
|
||||
err = AuWbrCopyup(au_sbi(sb), dentry);
|
||||
bstart = err;
|
||||
di_read_unlock(parent, !AuLock_IR);
|
||||
if (unlikely(err < 0))
|
||||
goto out_parent;
|
||||
err = 0;
|
||||
}
|
||||
|
||||
di_read_lock_parent(parent, AuLock_IR);
|
||||
hi_wh = au_hi_wh(inode, bstart);
|
||||
if (!S_ISDIR(inode->i_mode)
|
||||
&& au_opt_test(au_mntflags(sb), PLINK)
|
||||
&& au_plink_test(inode)
|
||||
&& !d_unhashed(dentry)) {
|
||||
err = au_test_and_cpup_dirs(dentry, bstart);
|
||||
if (unlikely(err))
|
||||
goto out_unlock;
|
||||
|
||||
/* always superio. */
|
||||
err = au_pin(&pin, dentry, bstart, AuOpt_UDBA_NONE,
|
||||
AuPin_DI_LOCKED | AuPin_MNT_WRITE);
|
||||
if (!err)
|
||||
err = au_sio_cpup_simple(dentry, bstart, -1,
|
||||
AuCpup_DTIME);
|
||||
au_unpin(&pin);
|
||||
} else if (hi_wh) {
|
||||
/* already copied-up after unlink */
|
||||
err = au_reopen_wh(file, bstart, hi_wh);
|
||||
*need_reopen = 0;
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
di_read_unlock(parent, AuLock_IR);
|
||||
out_parent:
|
||||
dput(parent);
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static void au_do_refresh_dir(struct file *file)
|
||||
{
|
||||
aufs_bindex_t bindex, bend, new_bindex, brid;
|
||||
struct au_hfile *p, tmp, *q;
|
||||
struct au_finfo *finfo;
|
||||
struct super_block *sb;
|
||||
struct au_fidir *fidir;
|
||||
|
||||
FiMustWriteLock(file);
|
||||
|
||||
sb = file->f_dentry->d_sb;
|
||||
finfo = au_fi(file);
|
||||
fidir = finfo->fi_hdir;
|
||||
AuDebugOn(!fidir);
|
||||
p = fidir->fd_hfile + finfo->fi_btop;
|
||||
brid = p->hf_br->br_id;
|
||||
bend = fidir->fd_bbot;
|
||||
for (bindex = finfo->fi_btop; bindex <= bend; bindex++, p++) {
|
||||
if (!p->hf_file)
|
||||
continue;
|
||||
|
||||
new_bindex = au_br_index(sb, p->hf_br->br_id);
|
||||
if (new_bindex == bindex)
|
||||
continue;
|
||||
if (new_bindex < 0) {
|
||||
au_set_h_fptr(file, bindex, NULL);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* swap two lower inode, and loop again */
|
||||
q = fidir->fd_hfile + new_bindex;
|
||||
tmp = *q;
|
||||
*q = *p;
|
||||
*p = tmp;
|
||||
if (tmp.hf_file) {
|
||||
bindex--;
|
||||
p--;
|
||||
}
|
||||
}
|
||||
|
||||
p = fidir->fd_hfile;
|
||||
if (!au_test_mmapped(file) && !d_unlinked(file->f_dentry)) {
|
||||
bend = au_sbend(sb);
|
||||
for (finfo->fi_btop = 0; finfo->fi_btop <= bend;
|
||||
finfo->fi_btop++, p++)
|
||||
if (p->hf_file) {
|
||||
if (p->hf_file->f_dentry
|
||||
&& p->hf_file->f_dentry->d_inode)
|
||||
break;
|
||||
else
|
||||
au_hfput(p, file);
|
||||
}
|
||||
} else {
|
||||
bend = au_br_index(sb, brid);
|
||||
for (finfo->fi_btop = 0; finfo->fi_btop < bend;
|
||||
finfo->fi_btop++, p++)
|
||||
if (p->hf_file)
|
||||
au_hfput(p, file);
|
||||
bend = au_sbend(sb);
|
||||
}
|
||||
|
||||
p = fidir->fd_hfile + bend;
|
||||
for (fidir->fd_bbot = bend; fidir->fd_bbot >= finfo->fi_btop;
|
||||
fidir->fd_bbot--, p--)
|
||||
if (p->hf_file) {
|
||||
if (p->hf_file->f_dentry
|
||||
&& p->hf_file->f_dentry->d_inode)
|
||||
break;
|
||||
else
|
||||
au_hfput(p, file);
|
||||
}
|
||||
AuDebugOn(fidir->fd_bbot < finfo->fi_btop);
|
||||
}
|
||||
|
||||
/*
|
||||
* after branch manipulating, refresh the file.
|
||||
*/
|
||||
static int refresh_file(struct file *file, int (*reopen)(struct file *file))
|
||||
{
|
||||
int err, need_reopen;
|
||||
aufs_bindex_t bend, bindex;
|
||||
struct dentry *dentry;
|
||||
struct au_finfo *finfo;
|
||||
struct au_hfile *hfile;
|
||||
|
||||
dentry = file->f_dentry;
|
||||
finfo = au_fi(file);
|
||||
if (!finfo->fi_hdir) {
|
||||
hfile = &finfo->fi_htop;
|
||||
AuDebugOn(!hfile->hf_file);
|
||||
bindex = au_br_index(dentry->d_sb, hfile->hf_br->br_id);
|
||||
AuDebugOn(bindex < 0);
|
||||
if (bindex != finfo->fi_btop)
|
||||
au_set_fbstart(file, bindex);
|
||||
} else {
|
||||
err = au_fidir_realloc(finfo, au_sbend(dentry->d_sb) + 1);
|
||||
if (unlikely(err))
|
||||
goto out;
|
||||
au_do_refresh_dir(file);
|
||||
}
|
||||
|
||||
err = 0;
|
||||
need_reopen = 1;
|
||||
if (!au_test_mmapped(file))
|
||||
err = au_file_refresh_by_inode(file, &need_reopen);
|
||||
if (!err && need_reopen && !d_unlinked(dentry))
|
||||
err = reopen(file);
|
||||
if (!err) {
|
||||
au_update_figen(file);
|
||||
goto out; /* success */
|
||||
}
|
||||
|
||||
/* error, close all lower files */
|
||||
if (finfo->fi_hdir) {
|
||||
bend = au_fbend_dir(file);
|
||||
for (bindex = au_fbstart(file); bindex <= bend; bindex++)
|
||||
au_set_h_fptr(file, bindex, NULL);
|
||||
}
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
/* common function to regular file and dir */
|
||||
int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
|
||||
int wlock)
|
||||
{
|
||||
int err;
|
||||
unsigned int sigen, figen;
|
||||
aufs_bindex_t bstart;
|
||||
unsigned char pseudo_link;
|
||||
struct dentry *dentry;
|
||||
struct inode *inode;
|
||||
|
||||
err = 0;
|
||||
dentry = file->f_dentry;
|
||||
inode = dentry->d_inode;
|
||||
AuDebugOn(au_special_file(inode->i_mode));
|
||||
sigen = au_sigen(dentry->d_sb);
|
||||
fi_write_lock(file);
|
||||
figen = au_figen(file);
|
||||
di_write_lock_child(dentry);
|
||||
bstart = au_dbstart(dentry);
|
||||
pseudo_link = (bstart != au_ibstart(inode));
|
||||
if (sigen == figen && !pseudo_link && au_fbstart(file) == bstart) {
|
||||
if (!wlock) {
|
||||
di_downgrade_lock(dentry, AuLock_IR);
|
||||
fi_downgrade_lock(file);
|
||||
}
|
||||
goto out; /* success */
|
||||
}
|
||||
|
||||
AuDbg("sigen %d, figen %d\n", sigen, figen);
|
||||
if (au_digen_test(dentry, sigen)) {
|
||||
err = au_reval_dpath(dentry, sigen);
|
||||
AuDebugOn(!err && au_digen_test(dentry, sigen));
|
||||
}
|
||||
|
||||
if (!err)
|
||||
err = refresh_file(file, reopen);
|
||||
if (!err) {
|
||||
if (!wlock) {
|
||||
di_downgrade_lock(dentry, AuLock_IR);
|
||||
fi_downgrade_lock(file);
|
||||
}
|
||||
} else {
|
||||
di_write_unlock(dentry);
|
||||
fi_write_unlock(file);
|
||||
}
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/* cf. aufs_nopage() */
|
||||
/* for madvise(2) */
|
||||
static int aufs_readpage(struct file *file __maybe_unused, struct page *page)
|
||||
{
|
||||
unlock_page(page);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* it will never be called, but necessary to support O_DIRECT */
|
||||
static ssize_t aufs_direct_IO(int rw, struct kiocb *iocb,
|
||||
const struct iovec *iov, loff_t offset,
|
||||
unsigned long nr_segs)
|
||||
{ BUG(); return 0; }
|
||||
|
||||
/*
|
||||
* it will never be called, but madvise and fadvise behaves differently
|
||||
* when get_xip_mem is defined
|
||||
*/
|
||||
static int aufs_get_xip_mem(struct address_space *mapping, pgoff_t pgoff,
|
||||
int create, void **kmem, unsigned long *pfn)
|
||||
{ BUG(); return 0; }
|
||||
|
||||
/* they will never be called. */
|
||||
#ifdef CONFIG_AUFS_DEBUG
|
||||
static int aufs_write_begin(struct file *file, struct address_space *mapping,
|
||||
loff_t pos, unsigned len, unsigned flags,
|
||||
struct page **pagep, void **fsdata)
|
||||
{ AuUnsupport(); return 0; }
|
||||
static int aufs_write_end(struct file *file, struct address_space *mapping,
|
||||
loff_t pos, unsigned len, unsigned copied,
|
||||
struct page *page, void *fsdata)
|
||||
{ AuUnsupport(); return 0; }
|
||||
static int aufs_writepage(struct page *page, struct writeback_control *wbc)
|
||||
{ AuUnsupport(); return 0; }
|
||||
|
||||
static int aufs_set_page_dirty(struct page *page)
|
||||
{ AuUnsupport(); return 0; }
|
||||
static void aufs_invalidatepage(struct page *page, unsigned long offset)
|
||||
{ AuUnsupport(); }
|
||||
static int aufs_releasepage(struct page *page, gfp_t gfp)
|
||||
{ AuUnsupport(); return 0; }
|
||||
static int aufs_migratepage(struct address_space *mapping, struct page *newpage,
|
||||
struct page *page)
|
||||
{ AuUnsupport(); return 0; }
|
||||
static int aufs_launder_page(struct page *page)
|
||||
{ AuUnsupport(); return 0; }
|
||||
static int aufs_is_partially_uptodate(struct page *page,
|
||||
read_descriptor_t *desc,
|
||||
unsigned long from)
|
||||
{ AuUnsupport(); return 0; }
|
||||
static int aufs_error_remove_page(struct address_space *mapping,
|
||||
struct page *page)
|
||||
{ AuUnsupport(); return 0; }
|
||||
#endif /* CONFIG_AUFS_DEBUG */
|
||||
|
||||
const struct address_space_operations aufs_aop = {
|
||||
.readpage = aufs_readpage,
|
||||
.direct_IO = aufs_direct_IO,
|
||||
.get_xip_mem = aufs_get_xip_mem,
|
||||
#ifdef CONFIG_AUFS_DEBUG
|
||||
.writepage = aufs_writepage,
|
||||
/* no writepages, because of writepage */
|
||||
.set_page_dirty = aufs_set_page_dirty,
|
||||
/* no readpages, because of readpage */
|
||||
.write_begin = aufs_write_begin,
|
||||
.write_end = aufs_write_end,
|
||||
/* no bmap, no block device */
|
||||
.invalidatepage = aufs_invalidatepage,
|
||||
.releasepage = aufs_releasepage,
|
||||
.migratepage = aufs_migratepage,
|
||||
.launder_page = aufs_launder_page,
|
||||
.is_partially_uptodate = aufs_is_partially_uptodate,
|
||||
.error_remove_page = aufs_error_remove_page
|
||||
#endif /* CONFIG_AUFS_DEBUG */
|
||||
};
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user