diff --git a/kernel/drivers/module-bbswitch/pspec.xml b/kernel/drivers/module-bbswitch/pspec.xml
index 7f6d2ca7..ae49aad7 100644
--- a/kernel/drivers/module-bbswitch/pspec.xml
+++ b/kernel/drivers/module-bbswitch/pspec.xml
@@ -11,7 +11,7 @@
Kernel module allowing to switch dedicated graphics card on Optimus laptops
kernel module allowing to switch dedicated graphics card on Optimus laptops
- kernel-module-headers
+ kernel-module-headers
https://github.com/Bumblebee-Project/bbswitch/archive/v0.8.tar.gz
@@ -20,7 +20,7 @@
module-bbswitch
- kernel
+ kernel
/lib/modules
@@ -34,6 +34,13 @@
+
+ 2015-07-20
+ 0.8
+ Rebuild for kernel-4.1.2.
+ Ertuğrul Erata
+ ertugrulerata@gmail.com
+
2015-07-13
0.8
diff --git a/kernel/drivers/module-broadcom-wl/pspec.xml b/kernel/drivers/module-broadcom-wl/pspec.xml
index 178e5b4c..a60fccae 100644
--- a/kernel/drivers/module-broadcom-wl/pspec.xml
+++ b/kernel/drivers/module-broadcom-wl/pspec.xml
@@ -15,7 +15,7 @@
http://www.broadcom.com/docs/linux_sta/hybrid-v35-nodebug-pcoem-6_30_223_248.tar.gz
http://www.broadcom.com/docs/linux_sta/hybrid-v35_64-nodebug-pcoem-6_30_223_248.tar.gz
- kernel-module-headers
+ kernel-module-headers
patch/linux-40.patch
@@ -30,7 +30,7 @@
module-broadcom-wl
- kernel
+ kernel
module-broadcom-wl-userspace
@@ -62,6 +62,13 @@
+
+ 2015-07-20
+ 6.30.223.248
+ Rebuild for kernel 4.1.2.
+ Ertuğrul Erata
+ ertugrulerata@gmail.com
+
2015-07-13
6.30.223.248
diff --git a/kernel/drivers/module-virtualbox-guest/pspec.xml b/kernel/drivers/module-virtualbox-guest/pspec.xml
index 4dccc694..f9daeab6 100644
--- a/kernel/drivers/module-virtualbox-guest/pspec.xml
+++ b/kernel/drivers/module-virtualbox-guest/pspec.xml
@@ -14,14 +14,14 @@
This package provides the kernel modules needed for mouse integration and shared folder support between VirtualBox host and guest systems.
http://source.pisilinux.org/1.0/module-virtualbox-guest-4.3.28.tar.xz
- kernel-module-headers
+ kernel-module-headers
module-virtualbox-guest
- kernel
+ kernel
baselayout
module-virtualbox-guest-userspace
@@ -51,7 +51,14 @@
-
+
+
+ 2015-07-20
+ 4.3.28
+ Rebuild for kernel-4.1.2.
+ Ertuğrul Erata
+ ertugrulerata@gmail.com
+
2015-07-13
4.3.28
diff --git a/kernel/drivers/module-virtualbox/pspec.xml b/kernel/drivers/module-virtualbox/pspec.xml
index 238e15bb..5d2f875d 100644
--- a/kernel/drivers/module-virtualbox/pspec.xml
+++ b/kernel/drivers/module-virtualbox/pspec.xml
@@ -14,14 +14,14 @@
This package provides the kernel support for VirtualBox.
http://source.pisilinux.org/1.0/module-virtualbox-4.3.28.tar.xz
- kernel-module-headers
+ kernel-module-headers
module-virtualbox
- kernel
+ kernel
module-virtualbox-userspace
@@ -47,6 +47,13 @@
+
+ 2015-07-20
+ 4.3.28
+ Rebuild for kernel-4.1.2.
+ Ertuğrul Erata
+ ertugrulerata@gmail.com
+
2015-07-13
4.3.28
diff --git a/kernel/kernel/files/configs/kernel-x86_64-config b/kernel/kernel/files/configs/kernel-x86_64-config
index e6b02d58..c10f4266 100644
--- a/kernel/kernel/files/configs/kernel-x86_64-config
+++ b/kernel/kernel/files/configs/kernel-x86_64-config
@@ -1,6 +1,6 @@
#
# Automatically generated file; DO NOT EDIT.
-# Linux/x86_64 4.0.4 Kernel Configuration
+# Linux/x86_64 4.1.2 Kernel Configuration
#
CONFIG_64BIT=y
CONFIG_X86_64=y
@@ -41,6 +41,7 @@ CONFIG_X86_HT=y
CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11"
CONFIG_ARCH_SUPPORTS_UPROBES=y
CONFIG_FIX_EARLYCON_MEM=y
+CONFIG_PGTABLE_LEVELS=4
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_IRQ_WORK=y
CONFIG_BUILDTIME_EXTABLE_SORT=y
@@ -98,7 +99,6 @@ CONFIG_ARCH_CLOCKSOURCE_DATA=y
CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y
CONFIG_GENERIC_CMOS_UPDATE=y
@@ -147,6 +147,7 @@ CONFIG_RCU_NOCB_CPU=y
# CONFIG_RCU_NOCB_CPU_NONE is not set
# CONFIG_RCU_NOCB_CPU_ZERO is not set
CONFIG_RCU_NOCB_CPU_ALL=y
+# CONFIG_RCU_EXPEDITE_BOOT is not set
CONFIG_BUILD_BIN2C=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
@@ -203,6 +204,7 @@ CONFIG_HAVE_PCSPKR_PLATFORM=y
CONFIG_BPF=y
# CONFIG_EXPERT is not set
CONFIG_UID16=y
+CONFIG_MULTIUSER=y
CONFIG_SGETMASK_SYSCALL=y
CONFIG_SYSFS_SYSCALL=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -285,9 +287,11 @@ CONFIG_HAVE_CONTEXT_TRACKING=y
CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y
+CONFIG_HAVE_ARCH_HUGE_VMAP=y
CONFIG_HAVE_ARCH_SOFT_DIRTY=y
CONFIG_MODULES_USE_ELF_RELA=y
CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
CONFIG_OLD_SIGSUSPEND3=y
CONFIG_COMPAT_OLD_SIGACTION=y
@@ -402,7 +406,6 @@ CONFIG_KVM_GUEST=y
CONFIG_PARAVIRT_TIME_ACCOUNTING=y
CONFIG_PARAVIRT_CLOCK=y
CONFIG_NO_BOOTMEM=y
-# CONFIG_MEMTEST is not set
# CONFIG_MK8 is not set
# CONFIG_MPSC is not set
# CONFIG_MCORE2 is not set
@@ -431,7 +434,6 @@ CONFIG_SCHED_MC=y
# CONFIG_PREEMPT_NONE is not set
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
-CONFIG_X86_UP_APIC_MSI=y
CONFIG_X86_LOCAL_APIC=y
CONFIG_X86_IO_APIC=y
CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y
@@ -449,13 +451,11 @@ CONFIG_MICROCODE=m
CONFIG_MICROCODE_INTEL=y
CONFIG_MICROCODE_AMD=y
CONFIG_MICROCODE_OLD_INTERFACE=y
-# CONFIG_MICROCODE_INTEL_EARLY is not set
-# CONFIG_MICROCODE_AMD_EARLY is not set
CONFIG_X86_MSR=y
CONFIG_X86_CPUID=y
CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
-CONFIG_DIRECT_GBPAGES=y
+CONFIG_X86_DIRECT_GBPAGES=y
CONFIG_NUMA=y
CONFIG_AMD_NUMA=y
CONFIG_X86_64_ACPI_NUMA=y
@@ -515,6 +515,7 @@ CONFIG_ZPOOL=y
# CONFIG_ZBUD is not set
# CONFIG_ZSMALLOC is not set
CONFIG_GENERIC_EARLY_IOREMAP=y
+# CONFIG_X86_PMEM_LEGACY is not set
CONFIG_X86_CHECK_BIOS_CORRUPTION=y
CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y
CONFIG_X86_RESERVE_LOW=64
@@ -583,6 +584,7 @@ CONFIG_PM_CLK=y
CONFIG_ACPI=y
CONFIG_ACPI_LEGACY_TABLES_LOOKUP=y
CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC=y
+CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT=y
CONFIG_ACPI_SLEEP=y
# CONFIG_ACPI_PROCFS_POWER is not set
CONFIG_ACPI_EC_DEBUGFS=m
@@ -738,7 +740,6 @@ CONFIG_HOTPLUG_PCI_SHPC=m
#
CONFIG_BINFMT_ELF=y
CONFIG_COMPAT_BINFMT_ELF=y
-CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
CONFIG_BINFMT_SCRIPT=y
# CONFIG_HAVE_AOUT is not set
@@ -1077,13 +1078,13 @@ CONFIG_IP_VS_PE_SIP=m
CONFIG_NF_DEFRAG_IPV4=m
CONFIG_NF_CONNTRACK_IPV4=m
# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
-CONFIG_NF_LOG_ARP=m
-CONFIG_NF_LOG_IPV4=m
CONFIG_NF_TABLES_IPV4=m
CONFIG_NFT_CHAIN_ROUTE_IPV4=m
-CONFIG_NF_REJECT_IPV4=y
CONFIG_NFT_REJECT_IPV4=m
CONFIG_NF_TABLES_ARP=m
+CONFIG_NF_LOG_ARP=m
+CONFIG_NF_LOG_IPV4=m
+CONFIG_NF_REJECT_IPV4=y
CONFIG_NF_NAT_IPV4=m
CONFIG_NFT_CHAIN_NAT_IPV4=m
CONFIG_NF_NAT_MASQUERADE_IPV4=m
@@ -1094,6 +1095,7 @@ CONFIG_NF_NAT_H323=m
CONFIG_IP_NF_IPTABLES=y
CONFIG_IP_NF_MATCH_AH=m
CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_PSD=m
CONFIG_IP_NF_MATCH_RPFILTER=m
CONFIG_IP_NF_MATCH_TTL=m
CONFIG_IP_NF_FILTER=y
@@ -1107,6 +1109,7 @@ 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_TARGET_IFWLOG=m
CONFIG_IP_NF_RAW=m
CONFIG_IP_NF_SECURITY=m
CONFIG_IP_NF_ARPTABLES=m
@@ -1120,8 +1123,8 @@ CONFIG_NF_DEFRAG_IPV6=m
CONFIG_NF_CONNTRACK_IPV6=m
CONFIG_NF_TABLES_IPV6=m
CONFIG_NFT_CHAIN_ROUTE_IPV6=m
-CONFIG_NF_REJECT_IPV6=m
CONFIG_NFT_REJECT_IPV6=m
+CONFIG_NF_REJECT_IPV6=m
CONFIG_NF_LOG_IPV6=m
CONFIG_NF_NAT_IPV6=m
CONFIG_NFT_CHAIN_NAT_IPV6=m
@@ -1213,11 +1216,6 @@ CONFIG_BRIDGE=m
CONFIG_BRIDGE_IGMP_SNOOPING=y
CONFIG_BRIDGE_VLAN_FILTERING=y
CONFIG_HAVE_NET_DSA=y
-CONFIG_NET_DSA=m
-CONFIG_NET_DSA_HWMON=y
-CONFIG_NET_DSA_TAG_DSA=y
-CONFIG_NET_DSA_TAG_EDSA=y
-CONFIG_NET_DSA_TAG_TRAILER=y
CONFIG_VLAN_8021Q=m
CONFIG_VLAN_8021Q_GVRP=y
CONFIG_VLAN_8021Q_MVRP=y
@@ -1234,6 +1232,14 @@ CONFIG_IPDDP_ENCAP=y
# CONFIG_LAPB is not set
# CONFIG_PHONET is not set
CONFIG_6LOWPAN=m
+CONFIG_6LOWPAN_NHC=m
+CONFIG_6LOWPAN_NHC_DEST=m
+CONFIG_6LOWPAN_NHC_FRAGMENT=m
+CONFIG_6LOWPAN_NHC_HOP=m
+CONFIG_6LOWPAN_NHC_IPV6=m
+CONFIG_6LOWPAN_NHC_MOBILITY=m
+CONFIG_6LOWPAN_NHC_ROUTING=m
+CONFIG_6LOWPAN_NHC_UDP=m
CONFIG_IEEE802154=m
CONFIG_IEEE802154_SOCKET=m
CONFIG_IEEE802154_6LOWPAN=m
@@ -1324,7 +1330,9 @@ CONFIG_VSOCKETS=m
CONFIG_VMWARE_VMCI_VSOCKETS=m
CONFIG_NETLINK_MMAP=y
CONFIG_NETLINK_DIAG=m
+CONFIG_MPLS=y
CONFIG_NET_MPLS_GSO=m
+CONFIG_MPLS_ROUTING=m
CONFIG_HSR=m
# CONFIG_NET_SWITCHDEV is not set
CONFIG_RPS=y
@@ -1431,11 +1439,15 @@ CONFIG_BT_CMTP=m
CONFIG_BT_HIDP=m
CONFIG_BT_LE=y
CONFIG_BT_6LOWPAN=m
+CONFIG_BT_DEBUGFS=y
#
# Bluetooth device drivers
#
+CONFIG_BT_INTEL=m
+CONFIG_BT_BCM=m
CONFIG_BT_HCIBTUSB=m
+CONFIG_BT_HCIBTUSB_BCM=y
CONFIG_BT_HCIBTSDIO=m
CONFIG_BT_HCIUART=m
CONFIG_BT_HCIUART_H4=y
@@ -1443,6 +1455,8 @@ 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
@@ -1471,6 +1485,7 @@ CONFIG_CFG80211=m
CONFIG_CFG80211_DEBUGFS=y
# CONFIG_CFG80211_INTERNAL_REGDB is not set
CONFIG_CFG80211_WEXT=y
+CONFIG_CFG80211_WEXT_EXPORT=y
CONFIG_LIB80211=m
CONFIG_LIB80211_CRYPT_WEP=m
CONFIG_LIB80211_CRYPT_CCMP=m
@@ -1527,6 +1542,7 @@ CONFIG_NFC_MRVL_USB=m
CONFIG_NFC_ST21NFCA=m
CONFIG_NFC_ST21NFCA_I2C=m
# CONFIG_NFC_ST21NFCB is not set
+# CONFIG_NFC_NXP_NCI is not set
CONFIG_HAVE_BPF_JIT=y
#
@@ -1583,6 +1599,7 @@ CONFIG_MTD=m
# CONFIG_SM_FTL is not set
# CONFIG_MTD_OOPS is not set
# CONFIG_MTD_SWAP is not set
+CONFIG_MTD_PARTITIONED_MASTER=y
#
# RAM/ROM/Flash chip drivers
@@ -1680,6 +1697,7 @@ CONFIG_BLK_DEV_RAM=m
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=16384
CONFIG_BLK_DEV_RAM_DAX=y
+CONFIG_BLK_DEV_PMEM=m
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
# CONFIG_CDROM_PKTCDVD_WCACHE is not set
@@ -2009,11 +2027,13 @@ CONFIG_MD_RAID10=m
CONFIG_MD_RAID456=m
CONFIG_MD_MULTIPATH=m
CONFIG_MD_FAULTY=m
+CONFIG_MD_CLUSTER=m
CONFIG_BCACHE=m
# CONFIG_BCACHE_DEBUG is not set
# CONFIG_BCACHE_CLOSURES_DEBUG is not set
CONFIG_BLK_DEV_DM_BUILTIN=y
CONFIG_BLK_DEV_DM=y
+CONFIG_DM_MQ_DEFAULT=y
CONFIG_DM_DEBUG=y
CONFIG_DM_BUFIO=y
CONFIG_DM_BIO_PRISON=m
@@ -2038,11 +2058,12 @@ CONFIG_DM_UEVENT=y
CONFIG_DM_FLAKEY=m
CONFIG_DM_VERITY=m
# CONFIG_DM_SWITCH is not set
+CONFIG_DM_LOG_WRITES=m
CONFIG_TARGET_CORE=m
CONFIG_TCM_IBLOCK=m
CONFIG_TCM_FILEIO=m
CONFIG_TCM_PSCSI=m
-# CONFIG_TCM_USER is not set
+CONFIG_TCM_USER2=m
CONFIG_LOOPBACK_TARGET=m
CONFIG_TCM_FC=m
CONFIG_ISCSI_TARGET=m
@@ -2127,14 +2148,8 @@ CONFIG_VHOST=m
#
# Distributed Switch Architecture drivers
#
-CONFIG_NET_DSA_MV88E6XXX=m
-CONFIG_NET_DSA_MV88E6060=m
-CONFIG_NET_DSA_MV88E6XXX_NEED_PPU=y
-CONFIG_NET_DSA_MV88E6131=m
-CONFIG_NET_DSA_MV88E6123_61_65=m
-# CONFIG_NET_DSA_MV88E6171 is not set
-# CONFIG_NET_DSA_MV88E6352 is not set
-# CONFIG_NET_DSA_BCM_SF2 is not set
+# CONFIG_NET_DSA_MV88E6XXX is not set
+# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
CONFIG_ETHERNET=y
CONFIG_MDIO=m
CONFIG_NET_VENDOR_3COM=y
@@ -2154,9 +2169,6 @@ CONFIG_NET_VENDOR_AMD=y
CONFIG_AMD8111_ETH=m
CONFIG_PCNET32=m
CONFIG_PCMCIA_NMCLAN=m
-CONFIG_AMD_XGBE=m
-CONFIG_AMD_XGBE_DCB=y
-CONFIG_NET_XGENE=m
CONFIG_NET_VENDOR_ARC=y
CONFIG_NET_VENDOR_ATHEROS=y
CONFIG_ATL2=m
@@ -2164,6 +2176,8 @@ CONFIG_ATL1=m
CONFIG_ATL1E=m
CONFIG_ATL1C=m
CONFIG_ALX=m
+CONFIG_NET_CADENCE=y
+CONFIG_MACB=m
CONFIG_NET_VENDOR_BROADCOM=y
CONFIG_B44=m
CONFIG_B44_PCI_AUTOSELECT=y
@@ -2183,6 +2197,7 @@ CONFIG_CHELSIO_T1_1G=y
CONFIG_CHELSIO_T3=m
CONFIG_CHELSIO_T4=m
CONFIG_CHELSIO_T4_DCB=y
+CONFIG_CHELSIO_T4_FCOE=y
CONFIG_CHELSIO_T4VF=m
CONFIG_NET_VENDOR_CISCO=y
CONFIG_ENIC=m
@@ -2350,7 +2365,6 @@ CONFIG_PHYLIB=y
#
CONFIG_AT803X_PHY=m
CONFIG_AMD_PHY=m
-CONFIG_AMD_XGBE_PHY=m
CONFIG_MARVELL_PHY=m
CONFIG_DAVICOM_PHY=m
CONFIG_QSEMI_PHY=m
@@ -2839,6 +2853,7 @@ CONFIG_MOUSE_PS2_ELANTECH=y
CONFIG_MOUSE_PS2_SENTELIC=y
# CONFIG_MOUSE_PS2_TOUCHKIT is not set
CONFIG_MOUSE_PS2_FOCALTECH=y
+CONFIG_MOUSE_PS2_VMMOUSE=y
CONFIG_MOUSE_SERIAL=m
CONFIG_MOUSE_APPLETOUCH=m
CONFIG_MOUSE_BCM5974=m
@@ -2949,6 +2964,7 @@ CONFIG_TOUCHSCREEN_TSC_SERIO=m
CONFIG_TOUCHSCREEN_TSC2007=m
CONFIG_TOUCHSCREEN_ST1232=m
CONFIG_TOUCHSCREEN_SUR40=m
+CONFIG_TOUCHSCREEN_SX8654=m
CONFIG_TOUCHSCREEN_TPS6507X=m
CONFIG_TOUCHSCREEN_ZFORCE=m
CONFIG_INPUT_MISC=y
@@ -3062,7 +3078,6 @@ CONFIG_SERIAL_8250_DW=m
#
# Non-8250 serial port support
#
-CONFIG_SERIAL_MFD_HSU=m
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SERIAL_JSM=m
@@ -3125,9 +3140,10 @@ CONFIG_TCG_TIS_I2C_NUVOTON=m
CONFIG_TCG_NSC=m
CONFIG_TCG_ATMEL=m
CONFIG_TCG_INFINEON=m
-CONFIG_TCG_TIS_I2C_ST33=m
CONFIG_TCG_XEN=m
CONFIG_TCG_CRB=m
+CONFIG_TCG_TIS_ST33ZP24=m
+CONFIG_TCG_TIS_ST33ZP24_I2C=m
CONFIG_TELCLOCK=m
CONFIG_DEVPORT=y
CONFIG_XILLYBUS=m
@@ -3253,8 +3269,11 @@ CONFIG_PINCTRL=y
CONFIG_PINMUX=y
CONFIG_PINCONF=y
CONFIG_GENERIC_PINCONF=y
+CONFIG_PINCTRL_AMD=y
CONFIG_PINCTRL_BAYTRAIL=y
CONFIG_PINCTRL_CHERRYVIEW=m
+CONFIG_PINCTRL_INTEL=m
+CONFIG_PINCTRL_SUNRISEPOINT=m
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_DEVRES=y
@@ -3265,29 +3284,35 @@ CONFIG_GPIO_GENERIC=y
CONFIG_GPIO_MAX730X=m
#
-# Memory mapped GPIO drivers:
+# Memory mapped GPIO drivers
#
-CONFIG_GPIO_GENERIC_PLATFORM=y
-CONFIG_GPIO_IT8761E=m
+CONFIG_GPIO_DWAPB=m
CONFIG_GPIO_F7188X=m
-CONFIG_GPIO_SCH311X=m
-CONFIG_GPIO_SCH=m
+CONFIG_GPIO_GENERIC_PLATFORM=y
CONFIG_GPIO_ICH=m
-CONFIG_GPIO_VX855=m
+CONFIG_GPIO_IT8761E=m
CONFIG_GPIO_LYNXPOINT=m
+CONFIG_GPIO_SCH=m
+CONFIG_GPIO_SCH311X=m
+CONFIG_GPIO_VX855=m
#
-# I2C GPIO expanders:
+# I2C GPIO expanders
#
-CONFIG_GPIO_LP3943=m
+CONFIG_GPIO_ADP5588=m
CONFIG_GPIO_MAX7300=m
CONFIG_GPIO_MAX732X=m
CONFIG_GPIO_PCA953X=m
CONFIG_GPIO_PCF857X=m
-CONFIG_GPIO_ADP5588=m
#
-# PCI GPIO expanders:
+# MFD GPIO expanders
+#
+CONFIG_GPIO_LP3943=m
+CONFIG_GPIO_UCB1400=m
+
+#
+# PCI GPIO expanders
#
CONFIG_GPIO_AMD8111=m
CONFIG_GPIO_INTEL_MID=y
@@ -3295,25 +3320,7 @@ CONFIG_GPIO_ML_IOH=m
CONFIG_GPIO_RDC321X=m
#
-# SPI GPIO expanders:
-#
-CONFIG_GPIO_MCP23S08=m
-
-#
-# AC97 GPIO expanders:
-#
-CONFIG_GPIO_UCB1400=m
-
-#
-# LPC GPIO expanders:
-#
-
-#
-# MODULbus GPIO expanders:
-#
-
-#
-# USB GPIO expanders:
+# USB GPIO expanders
#
CONFIG_GPIO_VIPERBOARD=m
CONFIG_W1=m
@@ -3458,6 +3465,7 @@ CONFIG_SENSORS_NTC_THERMISTOR=m
CONFIG_SENSORS_NCT6683=m
CONFIG_SENSORS_NCT6775=m
# CONFIG_SENSORS_NCT7802 is not set
+CONFIG_SENSORS_NCT7904=m
CONFIG_SENSORS_PCF8591=m
CONFIG_PMBUS=m
CONFIG_SENSORS_PMBUS=m
@@ -3544,6 +3552,7 @@ CONFIG_WATCHDOG_CORE=y
#
CONFIG_SOFT_WATCHDOG=m
# CONFIG_XILINX_WATCHDOG is not set
+CONFIG_CADENCE_WATCHDOG=m
CONFIG_DW_WATCHDOG=m
CONFIG_RETU_WATCHDOG=m
# CONFIG_ACQUIRE_WDT is not set
@@ -3620,6 +3629,7 @@ CONFIG_BCMA_BLOCKIO=y
CONFIG_BCMA_HOST_PCI_POSSIBLE=y
CONFIG_BCMA_HOST_PCI=y
# CONFIG_BCMA_HOST_SOC is not set
+CONFIG_BCMA_DRIVER_PCI=y
CONFIG_BCMA_DRIVER_GMAC_CMN=y
CONFIG_BCMA_DRIVER_GPIO=y
# CONFIG_BCMA_DEBUG is not set
@@ -3634,10 +3644,12 @@ CONFIG_MFD_CROS_EC_I2C=m
# CONFIG_MFD_DLN2 is not set
# CONFIG_MFD_MC13XXX_I2C is not set
# CONFIG_HTC_PASIC3 is not set
+CONFIG_MFD_INTEL_QUARK_I2C_GPIO=m
CONFIG_LPC_ICH=m
CONFIG_LPC_SCH=m
# CONFIG_MFD_JANZ_CMODIO is not set
# CONFIG_MFD_KEMPLD is not set
+CONFIG_MFD_MT6397=m
# CONFIG_MFD_MENF21BMC is not set
CONFIG_MFD_VIPERBOARD=m
CONFIG_MFD_RETU=m
@@ -3650,6 +3662,7 @@ CONFIG_MFD_RTSX_USB=m
CONFIG_MFD_SI476X_CORE=m
CONFIG_MFD_SM501=m
CONFIG_MFD_SM501_GPIO=y
+CONFIG_MFD_SKY81452=m
# CONFIG_ABX500_CORE is not set
CONFIG_MFD_SYSCON=y
CONFIG_MFD_TI_AM335X_TSCADC=m
@@ -4135,7 +4148,6 @@ CONFIG_MEDIA_TUNER_FC0013=m
CONFIG_MEDIA_TUNER_TDA18212=m
CONFIG_MEDIA_TUNER_E4000=m
CONFIG_MEDIA_TUNER_FC2580=m
-CONFIG_MEDIA_TUNER_M88TS2022=m
CONFIG_MEDIA_TUNER_M88RS6000T=m
CONFIG_MEDIA_TUNER_TUA9001=m
CONFIG_MEDIA_TUNER_SI2157=m
@@ -4233,6 +4245,7 @@ CONFIG_DVB_OR51132=m
CONFIG_DVB_BCM3510=m
CONFIG_DVB_LGDT330X=m
CONFIG_DVB_LGDT3305=m
+CONFIG_DVB_LGDT3306A=m
CONFIG_DVB_LG2160=m
CONFIG_DVB_S5H1409=m
CONFIG_DVB_AU8522=m
@@ -4313,6 +4326,7 @@ CONFIG_DRM_I2C_NXP_TDA998X=m
CONFIG_DRM_TDFX=m
CONFIG_DRM_R128=m
CONFIG_DRM_RADEON=m
+CONFIG_DRM_RADEON_USERPTR=y
# CONFIG_DRM_RADEON_UMS is not set
CONFIG_DRM_NOUVEAU=m
CONFIG_NOUVEAU_DEBUG=5
@@ -4323,10 +4337,12 @@ CONFIG_DRM_I915=m
CONFIG_DRM_I915_KMS=y
CONFIG_DRM_I915_FBDEV=y
CONFIG_DRM_I915_PRELIMINARY_HW_SUPPORT=y
+CONFIG_DRM_MACH64=m
CONFIG_DRM_MGA=m
CONFIG_DRM_SIS=m
CONFIG_DRM_VIA=m
CONFIG_DRM_SAVAGE=m
+CONFIG_DRM_VGEM=m
CONFIG_DRM_VMWGFX=m
CONFIG_DRM_VMWGFX_FBCON=y
CONFIG_DRM_GMA500=m
@@ -4360,13 +4376,16 @@ CONFIG_FB_CFB_IMAGEBLIT=y
CONFIG_FB_SYS_FILLRECT=y
CONFIG_FB_SYS_COPYAREA=y
CONFIG_FB_SYS_IMAGEBLIT=y
-# CONFIG_FB_FOREIGN_ENDIAN is not set
+CONFIG_FB_FOREIGN_ENDIAN=y
+CONFIG_FB_BOTH_ENDIAN=y
+# CONFIG_FB_BIG_ENDIAN is not set
+# CONFIG_FB_LITTLE_ENDIAN is not set
CONFIG_FB_SYS_FOPS=y
CONFIG_FB_DEFERRED_IO=y
# CONFIG_FB_SVGALIB is not set
# CONFIG_FB_MACMODES is not set
CONFIG_FB_BACKLIGHT=y
-# CONFIG_FB_MODE_HELPERS is not set
+CONFIG_FB_MODE_HELPERS=y
CONFIG_FB_TILEBLITTING=y
#
@@ -4379,7 +4398,7 @@ CONFIG_FB_TILEBLITTING=y
# CONFIG_FB_ASILIANT is not set
# CONFIG_FB_IMSTT is not set
CONFIG_FB_VGA16=m
-# CONFIG_FB_UVESA is not set
+CONFIG_FB_UVESA=m
CONFIG_FB_VESA=y
CONFIG_FB_EFI=y
# CONFIG_FB_N411 is not set
@@ -4431,6 +4450,7 @@ CONFIG_BACKLIGHT_APPLE=m
CONFIG_BACKLIGHT_LM3630A=m
CONFIG_BACKLIGHT_LM3639=m
CONFIG_BACKLIGHT_LP855X=m
+CONFIG_BACKLIGHT_SKY81452=m
CONFIG_BACKLIGHT_GPIO=m
CONFIG_BACKLIGHT_LV5207LP=m
CONFIG_BACKLIGHT_BD6107=m
@@ -4600,6 +4620,7 @@ CONFIG_SND_HDA_CODEC_CMEDIA=m
CONFIG_SND_HDA_CODEC_SI3054=m
CONFIG_SND_HDA_GENERIC=m
CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0
+CONFIG_SND_HDA_CORE=m
CONFIG_SND_USB=y
CONFIG_SND_USB_AUDIO=m
CONFIG_SND_USB_UA101=m
@@ -4662,7 +4683,6 @@ CONFIG_HID_EZKEY=y
CONFIG_HID_HOLTEK=m
CONFIG_HOLTEK_FF=y
CONFIG_HID_GT683R=m
-CONFIG_HID_HUION=m
CONFIG_HID_KEYTOUCH=m
CONFIG_HID_KYE=m
CONFIG_HID_UCLOGIC=m
@@ -4724,6 +4744,7 @@ CONFIG_HID_ZEROPLUS=m
CONFIG_ZEROPLUS_FF=y
CONFIG_HID_ZYDACRON=m
CONFIG_HID_SENSOR_HUB=m
+CONFIG_HID_SENSOR_CUSTOM_SENSOR=m
#
# USB HID support
@@ -4847,7 +4868,6 @@ CONFIG_USB_DWC3_PCI=m
# Debugging features
#
# CONFIG_USB_DWC3_DEBUG is not set
-CONFIG_DWC3_HOST_USB3_LPM_ENABLE=y
CONFIG_USB_DWC2=y
CONFIG_USB_DWC2_HOST=y
@@ -4951,6 +4971,7 @@ CONFIG_USB_YUREX=m
CONFIG_USB_EZUSB_FX2=m
CONFIG_USB_HSIC_USB3503=m
# CONFIG_USB_LINK_LAYER_TEST is not set
+CONFIG_USB_CHAOSKEY=m
CONFIG_USB_ATM=m
CONFIG_USB_SPEEDTOUCH=m
CONFIG_USB_CXACRU=m
@@ -4961,7 +4982,7 @@ CONFIG_USB_XUSBATM=m
# USB Physical Layer drivers
#
CONFIG_USB_PHY=y
-CONFIG_NOP_USB_XCEIV=m
+CONFIG_NOP_USB_XCEIV=y
CONFIG_USB_GPIO_VBUS=m
CONFIG_USB_ISP1301=m
# CONFIG_USB_GADGET is not set
@@ -5054,6 +5075,7 @@ CONFIG_LEDS_LM355x=m
# LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM)
#
CONFIG_LEDS_BLINKM=m
+CONFIG_LEDS_PM8941_WLED=m
#
# LED Triggers
@@ -5144,6 +5166,7 @@ CONFIG_RTC_INTF_DEV=y
# I2C RTC drivers
#
CONFIG_RTC_DRV_ABB5ZES3=m
+CONFIG_RTC_DRV_ABX80X=m
CONFIG_RTC_DRV_DS1307=m
CONFIG_RTC_DRV_DS1374=m
# CONFIG_RTC_DRV_DS1374_WDT is not set
@@ -5216,12 +5239,13 @@ CONFIG_DMADEVICES=y
# DMA Devices
#
CONFIG_INTEL_MIC_X100_DMA=m
-# CONFIG_INTEL_MID_DMAC is not set
CONFIG_INTEL_IOATDMA=m
-# CONFIG_DW_DMAC_CORE is not set
# CONFIG_DW_DMAC is not set
# CONFIG_DW_DMAC_PCI is not set
+CONFIG_HSU_DMA=m
+CONFIG_HSU_DMA_PCI=m
CONFIG_DMA_ENGINE=y
+CONFIG_DMA_VIRTUAL_CHANNELS=m
CONFIG_DMA_ACPI=y
#
@@ -5247,6 +5271,7 @@ CONFIG_UIO_PCI_GENERIC=m
# CONFIG_UIO_NETX is not set
# CONFIG_UIO_MF624 is not set
CONFIG_VFIO_IOMMU_TYPE1=y
+CONFIG_VFIO_VIRQFD=y
CONFIG_VFIO=y
CONFIG_VFIO_PCI=y
CONFIG_VFIO_PCI_VGA=y
@@ -5261,6 +5286,7 @@ CONFIG_VIRTIO=y
CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO_PCI_LEGACY=y
CONFIG_VIRTIO_BALLOON=m
+CONFIG_VIRTIO_INPUT=m
CONFIG_VIRTIO_MMIO=m
# CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set
@@ -5295,6 +5321,8 @@ CONFIG_XEN_ACPI_PROCESSOR=m
CONFIG_XEN_MCE_LOG=y
CONFIG_XEN_HAVE_PVMMU=y
CONFIG_XEN_EFI=y
+CONFIG_XEN_AUTO_XLATE=y
+CONFIG_XEN_ACPI=y
CONFIG_STAGING=y
# CONFIG_SLICOSS is not set
# CONFIG_PRISM2_USB is not set
@@ -5312,6 +5340,7 @@ CONFIG_RTS5208=m
# CONFIG_VT6655 is not set
# CONFIG_VT6656 is not set
CONFIG_FB_SM7XX=m
+CONFIG_FB_SM750=m
# CONFIG_FB_XGI is not set
# CONFIG_FT1000 is not set
@@ -5423,10 +5452,13 @@ CONFIG_SAMSUNG_Q10=m
CONFIG_APPLE_GMUX=m
CONFIG_INTEL_RST=m
# CONFIG_INTEL_SMARTCONNECT is not set
+CONFIG_SHUTTLE_WMI=m
CONFIG_PVPANIC=m
CONFIG_CHROME_PLATFORMS=y
CONFIG_CHROMEOS_LAPTOP=m
CONFIG_CHROMEOS_PSTORE=m
+CONFIG_CROS_EC_CHARDEV=m
+CONFIG_CROS_EC_LPC=m
CONFIG_CLKDEV_LOOKUP=y
CONFIG_HAVE_CLK_PREPARE=y
CONFIG_COMMON_CLK=y
@@ -5435,6 +5467,7 @@ CONFIG_COMMON_CLK=y
# Common Clock Framework
#
CONFIG_COMMON_CLK_SI5351=m
+CONFIG_COMMON_CLK_PWM=m
# CONFIG_COMMON_CLK_PXA is not set
CONFIG_COMMON_CLK_CDCE706=m
@@ -5583,6 +5616,8 @@ CONFIG_EXT3_FS_SECURITY=y
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
+CONFIG_EXT4_ENCRYPTION=m
+CONFIG_EXT4_FS_ENCRYPTION=y
# CONFIG_EXT4_DEBUG is not set
CONFIG_JBD=m
# CONFIG_JBD_DEBUG is not set
@@ -5621,6 +5656,13 @@ CONFIG_BTRFS_FS_POSIX_ACL=y
# CONFIG_BTRFS_DEBUG is not set
# CONFIG_BTRFS_ASSERT is not set
CONFIG_NILFS2_FS=m
+CONFIG_F2FS_FS=m
+CONFIG_F2FS_STAT_FS=y
+CONFIG_F2FS_FS_XATTR=y
+CONFIG_F2FS_FS_POSIX_ACL=y
+# CONFIG_F2FS_FS_SECURITY is not set
+# CONFIG_F2FS_CHECK_FS is not set
+CONFIG_F2FS_IO_TRACE=y
CONFIG_FS_DAX=y
CONFIG_FS_POSIX_ACL=y
CONFIG_EXPORTFS=y
@@ -5746,14 +5788,7 @@ CONFIG_UFS_FS=m
# CONFIG_UFS_FS_WRITE is not set
# CONFIG_UFS_DEBUG is not set
# CONFIG_EXOFS_FS is not set
-CONFIG_F2FS_FS=m
-CONFIG_F2FS_STAT_FS=y
-CONFIG_F2FS_FS_XATTR=y
-CONFIG_F2FS_FS_POSIX_ACL=y
-# CONFIG_F2FS_FS_SECURITY is not set
-# CONFIG_F2FS_CHECK_FS is not set
-CONFIG_F2FS_IO_TRACE=y
-CONFIG_AUFS_FS=m
+CONFIG_AUFS_FS=y
# CONFIG_AUFS_BRANCH_MAX_127 is not set
# CONFIG_AUFS_BRANCH_MAX_511 is not set
# CONFIG_AUFS_BRANCH_MAX_1023 is not set
@@ -5944,6 +5979,7 @@ CONFIG_KASAN_SHADOW_OFFSET=0xdffffc0000000000
# CONFIG_PANIC_ON_OOPS is not set
CONFIG_PANIC_ON_OOPS_VALUE=0
CONFIG_PANIC_TIMEOUT=0
+CONFIG_DEBUG_TIMEKEEPING=y
#
# Lock Debugging (spinlocks, mutexes, etc...)
@@ -5954,6 +5990,7 @@ CONFIG_DEBUG_BUGVERBOSE=y
#
# RCU Debugging
#
+# CONFIG_PROVE_RCU is not set
# CONFIG_SPARSE_RCU_POINTER is not set
# CONFIG_TORTURE_TEST is not set
CONFIG_RCU_CPU_STALL_TIMEOUT=60
@@ -6003,6 +6040,7 @@ CONFIG_FTRACE_MCOUNT_RECORD=y
# CONFIG_TRACEPOINT_BENCHMARK is not set
CONFIG_RING_BUFFER_BENCHMARK=m
# CONFIG_RING_BUFFER_STARTUP_TEST is not set
+CONFIG_TRACE_ENUM_MAP_FILE=y
#
# Runtime Testing
@@ -6022,6 +6060,7 @@ CONFIG_TEST_KSTRTOX=y
# CONFIG_TEST_BPF is not set
# CONFIG_TEST_FIRMWARE is not set
# CONFIG_TEST_UDELAY is not set
+# CONFIG_MEMTEST is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_STRICT_DEVMEM=y
@@ -6356,3 +6395,12 @@ CONFIG_FONT_SUPPORT=y
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
CONFIG_ARCH_HAS_SG_CHAIN=y
+
+#
+# Unofficial 3rd party kernel additions
+#
+CONFIG_NDISWRAPPER=m
+CONFIG_RTL8723AS=m
+CONFIG_RTL8723BS=m
+CONFIG_WLAN_SDIO=y
+CONFIG_VIAHSS=m
diff --git a/kernel/kernel/files/patches/mageia/3rd-3rdparty-merge.patch b/kernel/kernel/files/patches/mageia/3rd-3rdparty-merge.patch
index 4d9cc095..8c1f8421 100644
--- a/kernel/kernel/files/patches/mageia/3rd-3rdparty-merge.patch
+++ b/kernel/kernel/files/patches/mageia/3rd-3rdparty-merge.patch
@@ -18,62 +18,62 @@ Signed-off-by: Thomas Backlund
scripts/kconfig/Makefile | 31 +++++++++++++++++--------------
8 files changed, 29 insertions(+), 15 deletions(-)
-diff -Nurp linux-3.18-rc6/arch/alpha/Kconfig linux-3.18-rc6-3rdparty/arch/alpha/Kconfig
---- linux-3.18-rc6/arch/alpha/Kconfig 2014-10-05 22:23:04.000000000 +0300
-+++ linux-3.18-rc6-3rdparty/arch/alpha/Kconfig 2014-11-29 21:42:38.015594440 +0200
-@@ -746,3 +746,4 @@ source "crypto/Kconfig"
+diff -Nurp linux-4.1/arch/alpha/Kconfig linux-4.1-3rd/arch/alpha/Kconfig
+--- linux-4.1/arch/alpha/Kconfig 2015-06-22 07:05:43.000000000 +0200
++++ linux-4.1-3rd/arch/alpha/Kconfig 2015-06-25 20:44:03.221647317 +0200
+@@ -750,3 +750,4 @@ source "crypto/Kconfig"
source "lib/Kconfig"
+source "3rdparty/Kconfig"
-diff -Nurp linux-3.18-rc6/arch/ia64/Kconfig linux-3.18-rc6-3rdparty/arch/ia64/Kconfig
---- linux-3.18-rc6/arch/ia64/Kconfig 2014-10-05 22:23:04.000000000 +0300
-+++ linux-3.18-rc6-3rdparty/arch/ia64/Kconfig 2014-11-29 21:42:38.015594440 +0200
-@@ -646,3 +646,5 @@ source "lib/Kconfig"
+diff -Nurp linux-4.1/arch/ia64/Kconfig linux-4.1-3rd/arch/ia64/Kconfig
+--- linux-4.1/arch/ia64/Kconfig 2015-06-22 07:05:43.000000000 +0200
++++ linux-4.1-3rd/arch/ia64/Kconfig 2015-06-25 20:44:03.231647227 +0200
+@@ -636,3 +636,5 @@ source "lib/Kconfig"
config IOMMU_HELPER
def_bool (IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB || IA64_GENERIC || SWIOTLB)
+
+source "3rdparty/Kconfig"
-diff -Nurp linux-3.18-rc6/arch/mips/Kconfig linux-3.18-rc6-3rdparty/arch/mips/Kconfig
---- linux-3.18-rc6/arch/mips/Kconfig 2014-11-29 21:37:34.434802374 +0200
-+++ linux-3.18-rc6-3rdparty/arch/mips/Kconfig 2014-11-29 21:42:38.015594440 +0200
-@@ -2709,3 +2709,5 @@ source "crypto/Kconfig"
+diff -Nurp linux-4.1/arch/mips/Kconfig linux-4.1-3rd/arch/mips/Kconfig
+--- linux-4.1/arch/mips/Kconfig 2015-06-22 07:05:43.000000000 +0200
++++ linux-4.1-3rd/arch/mips/Kconfig 2015-06-25 20:44:03.231647227 +0200
+@@ -2893,3 +2893,5 @@ source "crypto/Kconfig"
source "lib/Kconfig"
source "arch/mips/kvm/Kconfig"
+
+source "3rdparty/Kconfig"
-diff -Nurp linux-3.18-rc6/arch/powerpc/Kconfig linux-3.18-rc6-3rdparty/arch/powerpc/Kconfig
---- linux-3.18-rc6/arch/powerpc/Kconfig 2014-11-29 21:37:34.446802445 +0200
-+++ linux-3.18-rc6-3rdparty/arch/powerpc/Kconfig 2014-11-29 21:42:38.016594446 +0200
-@@ -1081,3 +1081,5 @@ config PPC_LIB_RHEAP
+diff -Nurp linux-4.1/arch/powerpc/Kconfig linux-4.1-3rd/arch/powerpc/Kconfig
+--- linux-4.1/arch/powerpc/Kconfig 2015-06-22 07:05:43.000000000 +0200
++++ linux-4.1-3rd/arch/powerpc/Kconfig 2015-06-25 20:44:03.231647227 +0200
+@@ -1090,3 +1090,5 @@ config PPC_LIB_RHEAP
bool
source "arch/powerpc/kvm/Kconfig"
+
+source "3rdparty/Kconfig"
-diff -Nurp linux-3.18-rc6/arch/sparc/Kconfig linux-3.18-rc6-3rdparty/arch/sparc/Kconfig
---- linux-3.18-rc6/arch/sparc/Kconfig 2014-11-29 21:37:34.478802634 +0200
-+++ linux-3.18-rc6-3rdparty/arch/sparc/Kconfig 2014-11-29 21:42:38.016594446 +0200
-@@ -562,3 +562,5 @@ source "security/Kconfig"
+diff -Nurp linux-4.1/arch/sparc/Kconfig linux-4.1-3rd/arch/sparc/Kconfig
+--- linux-4.1/arch/sparc/Kconfig 2015-06-22 07:05:43.000000000 +0200
++++ linux-4.1-3rd/arch/sparc/Kconfig 2015-06-25 20:44:03.231647227 +0200
+@@ -569,3 +569,5 @@ source "security/Kconfig"
source "crypto/Kconfig"
source "lib/Kconfig"
+
+source "3rdparty/Kconfig"
-diff -Nurp linux-3.18-rc6/arch/x86/Kconfig linux-3.18-rc6-3rdparty/arch/x86/Kconfig
---- linux-3.18-rc6/arch/x86/Kconfig 2014-11-29 21:37:34.488802693 +0200
-+++ linux-3.18-rc6-3rdparty/arch/x86/Kconfig 2014-11-29 21:42:38.016594446 +0200
-@@ -2509,3 +2509,5 @@ source "crypto/Kconfig"
+diff -Nurp linux-4.1/arch/x86/Kconfig linux-4.1-3rd/arch/x86/Kconfig
+--- linux-4.1/arch/x86/Kconfig 2015-06-22 07:05:43.000000000 +0200
++++ linux-4.1-3rd/arch/x86/Kconfig 2015-06-25 20:44:03.231647227 +0200
+@@ -2594,3 +2594,5 @@ source "crypto/Kconfig"
source "arch/x86/kvm/Kconfig"
source "lib/Kconfig"
+
+source "3rdparty/Kconfig"
-diff -Nurp linux-3.18-rc6/Makefile linux-3.18-rc6-3rdparty/Makefile
---- linux-3.18-rc6/Makefile 2014-11-29 21:37:34.352801890 +0200
-+++ linux-3.18-rc6-3rdparty/Makefile 2014-11-29 21:42:38.016594446 +0200
+diff -Nurp linux-4.1/Makefile linux-4.1-3rd/Makefile
+--- linux-4.1/Makefile 2015-06-22 07:05:43.000000000 +0200
++++ linux-4.1-3rd/Makefile 2015-06-25 20:44:03.231647227 +0200
@@ -556,7 +556,7 @@ scripts: scripts_basic include/config/au
# Objects we will link into vmlinux / subdirs we need to visit
@@ -83,87 +83,93 @@ diff -Nurp linux-3.18-rc6/Makefile linux-3.18-rc6-3rdparty/Makefile
net-y := net/
libs-y := lib/
core-y := usr/
-diff -Nurp linux-3.18-rc6/scripts/kconfig/Makefile linux-3.18-rc6-3rdparty/scripts/kconfig/Makefile
---- linux-3.18-rc6/scripts/kconfig/Makefile 2014-11-29 21:37:35.487808590 +0200
-+++ linux-3.18-rc6-3rdparty/scripts/kconfig/Makefile 2014-11-29 21:46:48.227071462 +0200
-@@ -14,29 +14,29 @@ endif
+diff -Nurp linux-4.1/scripts/kconfig/Makefile linux-4.1-3rd/scripts/kconfig/Makefile
+--- linux-4.1/scripts/kconfig/Makefile 2015-06-22 07:05:43.000000000 +0200
++++ linux-4.1-3rd/scripts/kconfig/Makefile 2015-06-25 20:47:50.109596717 +0200
+@@ -18,26 +18,26 @@ endif
# We need this, in case the user has it in its environment
unexport CONFIG_
-xconfig: $(obj)/qconf
+xconfig: $(obj)/qconf 3rdparty/Makefile
- $< $(Kconfig)
+ $< $(silent) $(Kconfig)
-gconfig: $(obj)/gconf
+gconfig: $(obj)/gconf 3rdparty/Makefile
- $< $(Kconfig)
+ $< $(silent) $(Kconfig)
-menuconfig: $(obj)/mconf
+menuconfig: $(obj)/mconf 3rdparty/Makefile
- $< $(Kconfig)
+ $< $(silent) $(Kconfig)
-config: $(obj)/conf
+config: $(obj)/conf 3rdparty/Makefile
- $< --oldaskconfig $(Kconfig)
+ $< $(silent) --oldaskconfig $(Kconfig)
-nconfig: $(obj)/nconf
+nconfig: $(obj)/nconf 3rdparty/Makefile
- $< $(Kconfig)
-
--oldconfig: $(obj)/conf
-+oldconfig: $(obj)/conf 3rdparty/Makefile
- $< --$@ $(Kconfig)
+ $< $(silent) $(Kconfig)
-silentoldconfig: $(obj)/conf
+silentoldconfig: $(obj)/conf 3rdparty/Makefile
$(Q)mkdir -p include/config include/generated
- $< --$@ $(Kconfig)
+ $< $(silent) --$@ $(Kconfig)
-localyesconfig localmodconfig: $(obj)/streamline_config.pl $(obj)/conf
+localyesconfig localmodconfig: $(obj)/streamline_config.pl $(obj)/conf 3rdparty/Makefile
$(Q)mkdir -p include/config include/generated
$(Q)perl $< --$@ $(srctree) $(Kconfig) > .tmp.config
$(Q)if [ -f .config ]; then \
-@@ -76,24 +76,24 @@ update-po-config: $(obj)/kxgettext $(obj
+@@ -80,7 +80,7 @@ simple-targets := oldconfig allnoconfig
+ alldefconfig randconfig listnewconfig olddefconfig
+ PHONY += $(simple-targets)
- PHONY += allnoconfig allyesconfig allmodconfig alldefconfig randconfig
-
--allnoconfig allyesconfig allmodconfig alldefconfig randconfig: $(obj)/conf
-+allnoconfig allyesconfig allmodconfig alldefconfig randconfig: $(obj)/conf 3rdparty/Makefile
- $< --$@ $(Kconfig)
-
- PHONY += listnewconfig olddefconfig oldnoconfig savedefconfig defconfig
-
--listnewconfig olddefconfig: $(obj)/conf
-+listnewconfig olddefconfig: $(obj)/conf 3rdparty/Makefile
- $< --$@ $(Kconfig)
+-$(simple-targets): $(obj)/conf
++$(simple-targets): $(obj)/conf 3rdparty/Makefile
+ $< $(silent) --$@ $(Kconfig)
+ PHONY += oldnoconfig savedefconfig defconfig
+@@ -88,12 +88,12 @@ PHONY += oldnoconfig savedefconfig defco
# oldnoconfig is an alias of olddefconfig, because people already are dependent
# on its behavior(sets new symbols to their default value but not 'n') with the
# counter-intuitive name.
--oldnoconfig: $(obj)/conf
-+oldnoconfig: $(obj)/conf 3rdparty/Makefile
- $< --olddefconfig $(Kconfig)
+-oldnoconfig: olddefconfig
++oldnoconfig: olddefconfig 3rdparty/Makefile
-savedefconfig: $(obj)/conf
+savedefconfig: $(obj)/conf 3rdparty/Makefile
- $< --$@=defconfig $(Kconfig)
+ $< $(silent) --$@=defconfig $(Kconfig)
-defconfig: $(obj)/conf
+defconfig: $(obj)/conf 3rdparty/Makefile
ifeq ($(KBUILD_DEFCONFIG),)
- $< --defconfig $(Kconfig)
+ $< $(silent) --defconfig $(Kconfig)
else
@@ -101,7 +101,7 @@ else
- $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig)
+ $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig)
endif
-%_defconfig: $(obj)/conf
+%_defconfig: $(obj)/conf 3rdparty/Makefile
- $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
+ $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
- configfiles=$(wildcard $(srctree)/kernel/configs/$(1).config $(srctree)/arch/$(SRCARCH)/configs/$(1).config)
-@@ -178,6 +178,9 @@ gconf-objs := gconf.o zconf.tab.o
+ configfiles=$(wildcard $(srctree)/kernel/configs/$@ $(srctree)/arch/$(SRCARCH)/configs/$@)
+@@ -112,12 +112,12 @@ configfiles=$(wildcard $(srctree)/kernel
+ +$(Q)yes "" | $(MAKE) -f $(srctree)/Makefile oldconfig
+
+ PHONY += kvmconfig
+-kvmconfig: kvm_guest.config
++kvmconfig: kvm_guest.config 3rdparty/Makefile
+ @:
+
+ PHONY += tinyconfig
+ tinyconfig:
+- $(Q)$(MAKE) -f $(srctree)/Makefile allnoconfig tiny.config
++ $(Q)$(MAKE) -f $(srctree)/Makefile allnoconfig tiny.config 3rdparty/Makefile
+
+ # Help text used by make help
+ help:
+@@ -176,6 +176,9 @@ gconf-objs := gconf.o zconf.tab.o
hostprogs-y := conf nconf mconf kxgettext qconf gconf
diff --git a/kernel/kernel/files/patches/mageia/3rd-ndiswrapper-4.0-buildfix.patch b/kernel/kernel/files/patches/mageia/3rd-ndiswrapper-4.0-buildfix.patch
new file mode 100644
index 00000000..52f39680
--- /dev/null
+++ b/kernel/kernel/files/patches/mageia/3rd-ndiswrapper-4.0-buildfix.patch
@@ -0,0 +1,32 @@
+
+Adapt for strnicmp has been replaced by strncasecmp,
+and removed upstream in v4.0-rc1~98:
+
+From af3cd13501eb04ca61d017ff4406f1cbffafdc04 Mon Sep 17 00:00:00 2001
+From: Rasmus Villemoes
+Date: Thu, 12 Feb 2015 15:02:15 -0800
+Subject: lib/string.c: remove strnicmp()
+
+
+Signed-off-by: Thomas Backlund
+
+--- linux/3rdparty/ndiswrapper/ndis.c.orig
++++ linux/3rdparty/ndiswrapper/ndis.c
+@@ -438,7 +438,7 @@ static int read_setting(struct nt_list *
+ struct wrap_device_setting *setting;
+ mutex_lock(&loader_mutex);
+ nt_list_for_each_entry(setting, setting_list, list) {
+- if (strnicmp(keyname, setting->name, length) == 0) {
++ if (strncasecmp(keyname, setting->name, length) == 0) {
+ TRACE2("setting %s='%s'", keyname, setting->value);
+ mutex_unlock(&loader_mutex);
+ *param = ndis_encode_setting(setting, type);
+@@ -502,7 +502,7 @@ wstdcall void WIN_FUNC(NdisWriteConfigur
+
+ mutex_lock(&loader_mutex);
+ nt_list_for_each_entry(setting, &nmb->wnd->wd->settings, list) {
+- if (strnicmp(keyname, setting->name, ansi.length) == 0) {
++ if (strncasecmp(keyname, setting->name, ansi.length) == 0) {
+ mutex_unlock(&loader_mutex);
+ if (ndis_decode_setting(setting, param))
+ *status = NDIS_STATUS_FAILURE;
diff --git a/kernel/kernel/files/patches/mageia/3rd-rtl8723bs-revert-4.0-changes.patch b/kernel/kernel/files/patches/mageia/3rd-rtl8723bs-revert-4.0-changes.patch
deleted file mode 100644
index fbea7652..00000000
--- a/kernel/kernel/files/patches/mageia/3rd-rtl8723bs-revert-4.0-changes.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-
-This reverts the parts of:
-
-commit 86fe2db84ba7b9a83b60323cd805198ff43136ec
-Author: Bastien Nocera
-Date: Fri Mar 20 18:28:08 2015 +0100
-
- cfg80211: Update for newest mac80211 API
-
-
-that breaks building with 3.19 series kernels.
-
-
-
-Signed-off-by: Thomas Backlund
-
-
-diff -Nurp linux/3rdparty/rtl8723bs.rev/include/ioctl_cfg80211.h linux/3rdparty/rtl8723bs/include/ioctl_cfg80211.h
---- linux/3rdparty/rtl8723bs.rev/include/ioctl_cfg80211.h 2015-05-07 17:46:55.000000000 +0300
-+++ linux/3rdparty/rtl8723bs/include/ioctl_cfg80211.h 2015-05-10 14:55:44.744038033 +0300
-@@ -22,10 +22,6 @@
-
- #include
-
--#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0))
--#error This driver only works with kernel 4.0
--#endif
--
- struct rtw_wdev_invit_info {
- u8 state; /* 0: req, 1:rep */
- u8 peer_mac[ETH_ALEN];
-diff -Nurp linux/3rdparty/rtl8723bs.rev/os_dep/ioctl_cfg80211.c linux/3rdparty/rtl8723bs/os_dep/ioctl_cfg80211.c
---- linux/3rdparty/rtl8723bs.rev/os_dep/ioctl_cfg80211.c 2015-05-10 14:54:53.241616597 +0300
-+++ linux/3rdparty/rtl8723bs/os_dep/ioctl_cfg80211.c 2015-05-10 14:49:42.766354711 +0300
-@@ -1289,16 +1289,16 @@ static int cfg80211_rtw_get_station(stru
- goto exit;
- }
-
-- sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
-+ sinfo->filled |= STATION_INFO_SIGNAL;
- sinfo->signal = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);
-
-- sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
-+ sinfo->filled |= STATION_INFO_TX_BITRATE;
- sinfo->txrate.legacy = rtw_get_cur_max_rate(padapter);
-
-- sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS);
-+ sinfo->filled |= STATION_INFO_RX_PACKETS;
- sinfo->rx_packets = sta_rx_data_pkts(psta);
-
-- sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS);
-+ sinfo->filled |= STATION_INFO_TX_PACKETS;
- sinfo->tx_packets = psta->sta_stats.tx_pkts;
-
- }
-@@ -2473,6 +2473,7 @@ void rtw_cfg80211_indicate_sta_assoc(_ad
- ie_offset = _REASOCREQ_IE_OFFSET_;
-
- sinfo.filled = 0;
-+ sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
- sinfo.assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset;
- sinfo.assoc_req_ies_len = frame_len - WLAN_HDR_A3_LEN - ie_offset;
- cfg80211_new_sta(ndev, GetAddr2Ptr(pmgmt_frame), &sinfo, GFP_ATOMIC);
-@@ -3078,7 +3079,8 @@ static int cfg80211_rtw_dump_station(str
- goto exit;
- }
- memcpy(mac, psta->hwaddr, ETH_ALEN);
-- sinfo->filled = BIT(NL80211_STA_INFO_SIGNAL);
-+ sinfo->filled = 0;
-+ sinfo->filled |= STATION_INFO_SIGNAL;
- sinfo->signal = psta->rssi;
-
- exit:
diff --git a/kernel/kernel/files/patches/mageia/Input-psmouse-disable-changing-resolution-rate-scale.patch b/kernel/kernel/files/patches/mageia/Input-psmouse-disable-changing-resolution-rate-scale.patch
deleted file mode 100644
index ef5539be..00000000
--- a/kernel/kernel/files/patches/mageia/Input-psmouse-disable-changing-resolution-rate-scale.patch
+++ /dev/null
@@ -1,128 +0,0 @@
-From 4ec212f003d2430b0b2748b8a3008255f39cfe13 Mon Sep 17 00:00:00 2001
-From: Mathias Gottschlag
-Date: Sat, 7 Mar 2015 13:31:45 -0800
-Subject: [PATCH 3/4] Input: psmouse - disable changing resolution/rate/scale
- for FocalTech
-
-These PS/2 commands make some touchpads stop responding, so this commit
-adds some dummy functions to replace the generic implementation. Because
-scale changes were not encapsulated in a method of struct psmouse yet, this
-commit adds a method set_scale to psmouse.
-
-Signed-off-by: Mathias Gottschlag
-Signed-off-by: Dmitry Torokhov
----
- drivers/input/mouse/focaltech.c | 25 +++++++++++++++++++++++++
- drivers/input/mouse/psmouse-base.c | 14 +++++++++++++-
- drivers/input/mouse/psmouse.h | 6 ++++++
- 3 files changed, 44 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/input/mouse/focaltech.c b/drivers/input/mouse/focaltech.c
-index c66e0e0..891a271 100644
---- a/drivers/input/mouse/focaltech.c
-+++ b/drivers/input/mouse/focaltech.c
-@@ -386,6 +386,23 @@ static int focaltech_read_size(struct psmouse *psmouse)
-
- return 0;
- }
-+
-+void focaltech_set_resolution(struct psmouse *psmouse, unsigned int resolution)
-+{
-+ /* not supported yet */
-+}
-+
-+static void focaltech_set_rate(struct psmouse *psmouse, unsigned int rate)
-+{
-+ /* not supported yet */
-+}
-+
-+static void focaltech_set_scale(struct psmouse *psmouse,
-+ enum psmouse_scale scale)
-+{
-+ /* not supported yet */
-+}
-+
- int focaltech_init(struct psmouse *psmouse)
- {
- struct focaltech_data *priv;
-@@ -420,6 +437,14 @@ int focaltech_init(struct psmouse *psmouse)
- psmouse->cleanup = focaltech_reset;
- /* resync is not supported yet */
- psmouse->resync_time = 0;
-+ /*
-+ * rate/resolution/scale changes are not supported yet, and
-+ * the generic implementations of these functions seem to
-+ * confuse some touchpads
-+ */
-+ psmouse->set_resolution = focaltech_set_resolution;
-+ psmouse->set_rate = focaltech_set_rate;
-+ psmouse->set_scale = focaltech_set_scale;
-
- return 0;
-
-diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
-index 4ccd01d..8bc6123 100644
---- a/drivers/input/mouse/psmouse-base.c
-+++ b/drivers/input/mouse/psmouse-base.c
-@@ -454,6 +454,17 @@ static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate)
- }
-
- /*
-+ * Here we set the mouse scaling.
-+ */
-+
-+static void psmouse_set_scale(struct psmouse *psmouse, enum psmouse_scale scale)
-+{
-+ ps2_command(&psmouse->ps2dev, NULL,
-+ scale == PSMOUSE_SCALE21 ? PSMOUSE_CMD_SETSCALE21 :
-+ PSMOUSE_CMD_SETSCALE11);
-+}
-+
-+/*
- * psmouse_poll() - default poll handler. Everyone except for ALPS uses it.
- */
-
-@@ -689,6 +700,7 @@ static void psmouse_apply_defaults(struct psmouse *psmouse)
-
- psmouse->set_rate = psmouse_set_rate;
- psmouse->set_resolution = psmouse_set_resolution;
-+ psmouse->set_scale = psmouse_set_scale;
- psmouse->poll = psmouse_poll;
- psmouse->protocol_handler = psmouse_process_byte;
- psmouse->pktsize = 3;
-@@ -1160,7 +1172,7 @@ static void psmouse_initialize(struct psmouse *psmouse)
- if (psmouse_max_proto != PSMOUSE_PS2) {
- psmouse->set_rate(psmouse, psmouse->rate);
- psmouse->set_resolution(psmouse, psmouse->resolution);
-- ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11);
-+ psmouse->set_scale(psmouse, PSMOUSE_SCALE11);
- }
- }
-
-diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
-index c2ff137..d02e1bd 100644
---- a/drivers/input/mouse/psmouse.h
-+++ b/drivers/input/mouse/psmouse.h
-@@ -36,6 +36,11 @@ typedef enum {
- PSMOUSE_FULL_PACKET
- } psmouse_ret_t;
-
-+enum psmouse_scale {
-+ PSMOUSE_SCALE11,
-+ PSMOUSE_SCALE21
-+};
-+
- struct psmouse {
- void *private;
- struct input_dev *dev;
-@@ -67,6 +72,7 @@ struct psmouse {
- psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse);
- void (*set_rate)(struct psmouse *psmouse, unsigned int rate);
- void (*set_resolution)(struct psmouse *psmouse, unsigned int resolution);
-+ void (*set_scale)(struct psmouse *psmouse, enum psmouse_scale scale);
-
- int (*reconnect)(struct psmouse *psmouse);
- void (*disconnect)(struct psmouse *psmouse);
---
-2.3.1
-
diff --git a/kernel/kernel/files/patches/mageia/Input-psmouse-disable-palm-detection-in-the-focaltec.patch b/kernel/kernel/files/patches/mageia/Input-psmouse-disable-palm-detection-in-the-focaltec.patch
deleted file mode 100644
index a149f053..00000000
--- a/kernel/kernel/files/patches/mageia/Input-psmouse-disable-palm-detection-in-the-focaltec.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 4eb8d6e7e5aa14572bc389e554aad9869188cdcd Mon Sep 17 00:00:00 2001
-From: Mathias Gottschlag
-Date: Sat, 7 Mar 2015 13:38:27 -0800
-Subject: [PATCH 4/4] Input: psmouse - disable "palm detection" in the
- focaltech driver
-
-Apparently, the threshold for large contact area seems to be rather low on
-some devices, causing the touchpad to frequently freeze during normal
-usage. Because we do now know how we are supposed to use the value in
-question, this commit just drops the related code completely.
-
-Signed-off-by: Mathias Gottschlag
-Signed-off-by: Dmitry Torokhov
----
- drivers/input/mouse/focaltech.c | 10 ----------
- 1 file changed, 10 deletions(-)
-
-diff --git a/drivers/input/mouse/focaltech.c b/drivers/input/mouse/focaltech.c
-index 891a271..23d2594 100644
---- a/drivers/input/mouse/focaltech.c
-+++ b/drivers/input/mouse/focaltech.c
-@@ -185,16 +185,6 @@ static void focaltech_process_abs_packet(struct psmouse *psmouse,
-
- state->pressed = (packet[0] >> 4) & 1;
-
-- /*
-- * packet[5] contains some kind of tool size in the most
-- * significant nibble. 0xff is a special value (latching) that
-- * signals a large contact area.
-- */
-- if (packet[5] == 0xff) {
-- state->fingers[finger].valid = false;
-- return;
-- }
--
- state->fingers[finger].x = ((packet[1] & 0xf) << 8) | packet[2];
- state->fingers[finger].y = (packet[3] << 8) | packet[4];
- state->fingers[finger].valid = true;
---
-2.3.1
-
diff --git a/kernel/kernel/files/patches/mageia/Input-psmouse-ensure-that-focaltech-reports-consiste.patch b/kernel/kernel/files/patches/mageia/Input-psmouse-ensure-that-focaltech-reports-consiste.patch
deleted file mode 100644
index 149d2d03..00000000
--- a/kernel/kernel/files/patches/mageia/Input-psmouse-ensure-that-focaltech-reports-consiste.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From 679d83ea9390636ded518f533af0cefbade317c7 Mon Sep 17 00:00:00 2001
-From: Mathias Gottschlag
-Date: Sat, 7 Mar 2015 13:26:43 -0800
-Subject: [PATCH 2/4] Input: psmouse - ensure that focaltech reports consistent
- coordinates
-
-We don't know whether x_max or y_max really hold the maximum possible
-coordinates, and we don't know for sure whether we correctly interpret the
-coordinates sent by the touchpad, so we clamp the reported values to
-prevent confusion in userspace code.
-
-Signed-off-by: Mathias Gottschlag
-Signed-off-by: Dmitry Torokhov
----
- drivers/input/mouse/focaltech.c | 12 ++++++++++--
- 1 file changed, 10 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/input/mouse/focaltech.c b/drivers/input/mouse/focaltech.c
-index e8fafe8..c66e0e0 100644
---- a/drivers/input/mouse/focaltech.c
-+++ b/drivers/input/mouse/focaltech.c
-@@ -126,9 +126,17 @@ static void focaltech_report_state(struct psmouse *psmouse)
- input_mt_slot(dev, i);
- input_mt_report_slot_state(dev, MT_TOOL_FINGER, active);
- if (active) {
-- input_report_abs(dev, ABS_MT_POSITION_X, finger->x);
-+ unsigned int clamped_x, clamped_y;
-+ /*
-+ * The touchpad might report invalid data, so we clamp
-+ * the resulting values so that we do not confuse
-+ * userspace.
-+ */
-+ clamped_x = clamp(finger->x, 0U, priv->x_max);
-+ clamped_y = clamp(finger->y, 0U, priv->y_max);
-+ input_report_abs(dev, ABS_MT_POSITION_X, clamped_x);
- input_report_abs(dev, ABS_MT_POSITION_Y,
-- priv->y_max - finger->y);
-+ priv->y_max - clamped_y);
- }
- }
- input_mt_report_pointer_emulation(dev, true);
---
-2.3.1
-
diff --git a/kernel/kernel/files/patches/mageia/Input-psmouse-remove-hardcoded-touchpad-size-from-th.patch b/kernel/kernel/files/patches/mageia/Input-psmouse-remove-hardcoded-touchpad-size-from-th.patch
deleted file mode 100644
index 4fbb78e2..00000000
--- a/kernel/kernel/files/patches/mageia/Input-psmouse-remove-hardcoded-touchpad-size-from-th.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 3e9845251926723319fb60c9e546fe42d3d11687 Mon Sep 17 00:00:00 2001
-From: Mathias Gottschlag
-Date: Sat, 7 Mar 2015 13:26:06 -0800
-Subject: [PATCH 1/4] Input: psmouse - remove hardcoded touchpad size from the
- focaltech driver
-
-The size has in most cases already been fetched from the touchpad, the
-hardcoded values should have been removed.
-
-Signed-off-by: Mathias Gottschlag
-Signed-off-by: Dmitry Torokhov
----
- drivers/input/mouse/focaltech.c | 5 +----
- 1 file changed, 1 insertion(+), 4 deletions(-)
-
-diff --git a/drivers/input/mouse/focaltech.c b/drivers/input/mouse/focaltech.c
-index 757f78a..e8fafe8 100644
---- a/drivers/input/mouse/focaltech.c
-+++ b/drivers/input/mouse/focaltech.c
-@@ -67,9 +67,6 @@ static void focaltech_reset(struct psmouse *psmouse)
-
- #define FOC_MAX_FINGERS 5
-
--#define FOC_MAX_X 2431
--#define FOC_MAX_Y 1663
--
- /*
- * Current state of a single finger on the touchpad.
- */
-@@ -131,7 +128,7 @@ static void focaltech_report_state(struct psmouse *psmouse)
- if (active) {
- input_report_abs(dev, ABS_MT_POSITION_X, finger->x);
- input_report_abs(dev, ABS_MT_POSITION_Y,
-- FOC_MAX_Y - finger->y);
-+ priv->y_max - finger->y);
- }
- }
- input_mt_report_pointer_emulation(dev, true);
---
-2.3.1
-
diff --git a/kernel/kernel/files/patches/mageia/Input-psmouse-support-for-the-FocalTech-PS-2-protoco.patch b/kernel/kernel/files/patches/mageia/Input-psmouse-support-for-the-FocalTech-PS-2-protoco.patch
deleted file mode 100644
index 8dde13fa..00000000
--- a/kernel/kernel/files/patches/mageia/Input-psmouse-support-for-the-FocalTech-PS-2-protoco.patch
+++ /dev/null
@@ -1,585 +0,0 @@
-From 05be1d079ec0b3691783e4384b1ada82149ff7d2 Mon Sep 17 00:00:00 2001
-From: Mathias Gottschlag
-Date: Mon, 29 Dec 2014 09:26:10 -0800
-Subject: [PATCH] Input: psmouse - support for the FocalTech PS/2 protocol
- extensions
-
-Most of the protocol for these touchpads has been reverse engineered. This
-commit adds a basic multitouch-capable driver.
-
-A lot of the protocol is still unknown. Especially, we don't know how to
-identify the device yet apart from the PNP ID.
-
-The previous workaround for these devices has been left in place in case
-the driver is not compiled into the kernel or in case some other device
-with the same PNP ID is not recognized by the driver yet still has the same
-problems with the device probing code.
-
-Signed-off-by: Mathias Gottschlag
-Reviewed-by: Hans de Goede
-Signed-off-by: Dmitry Torokhov
----
- drivers/input/mouse/Kconfig | 10 +
- drivers/input/mouse/focaltech.c | 408 ++++++++++++++++++++++++++++++++++++-
- drivers/input/mouse/focaltech.h | 2 +
- drivers/input/mouse/psmouse-base.c | 32 ++-
- drivers/input/mouse/psmouse.h | 1 +
- 5 files changed, 436 insertions(+), 17 deletions(-)
-
-diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
-index d8b46b0..2541bfa 100644
---- a/drivers/input/mouse/Kconfig
-+++ b/drivers/input/mouse/Kconfig
-@@ -146,6 +146,16 @@ config MOUSE_PS2_OLPC
-
- If unsure, say N.
-
-+config MOUSE_PS2_FOCALTECH
-+ bool "FocalTech PS/2 mouse protocol extension" if EXPERT
-+ default y
-+ depends on MOUSE_PS2
-+ help
-+ Say Y here if you have a FocalTech PS/2 TouchPad connected to
-+ your system.
-+
-+ If unsure, say Y.
-+
- config MOUSE_SERIAL
- tristate "Serial mouse"
- select SERIO
-diff --git a/drivers/input/mouse/focaltech.c b/drivers/input/mouse/focaltech.c
-index f4d657e..fca38ba 100644
---- a/drivers/input/mouse/focaltech.c
-+++ b/drivers/input/mouse/focaltech.c
-@@ -2,6 +2,7 @@
- * Focaltech TouchPad PS/2 mouse driver
- *
- * Copyright (c) 2014 Red Hat Inc.
-+ * Copyright (c) 2014 Mathias Gottschlag
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
-@@ -13,15 +14,14 @@
- * Hans de Goede
- */
-
--/*
-- * The Focaltech PS/2 touchpad protocol is unknown. This drivers deals with
-- * detection only, to avoid further detection attempts confusing the touchpad
-- * this way it at least works in PS/2 mouse compatibility mode.
-- */
-
- #include
- #include
-+#include
-+#include
-+#include
- #include "psmouse.h"
-+#include "focaltech.h"
-
- static const char * const focaltech_pnp_ids[] = {
- "FLT0101",
-@@ -30,6 +30,12 @@ static const char * const focaltech_pnp_ids[] = {
- NULL
- };
-
-+/*
-+ * Even if the kernel is built without support for Focaltech PS/2 touchpads (or
-+ * when the real driver fails to recognize the device), we still have to detect
-+ * them in order to avoid further detection attempts confusing the touchpad.
-+ * This way it at least works in PS/2 mouse compatibility mode.
-+ */
- int focaltech_detect(struct psmouse *psmouse, bool set_properties)
- {
- if (!psmouse_matches_pnp_id(psmouse, focaltech_pnp_ids))
-@@ -37,16 +43,404 @@ int focaltech_detect(struct psmouse *psmouse, bool set_properties)
-
- if (set_properties) {
- psmouse->vendor = "FocalTech";
-- psmouse->name = "FocalTech Touchpad in mouse emulation mode";
-+ psmouse->name = "FocalTech Touchpad";
- }
-
- return 0;
- }
-
--int focaltech_init(struct psmouse *psmouse)
-+static void focaltech_reset(struct psmouse *psmouse)
- {
- ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
- psmouse_reset(psmouse);
-+}
-+
-+#ifdef CONFIG_MOUSE_PS2_FOCALTECH
-+
-+/*
-+ * Packet types - the numbers are not consecutive, so we might be missing
-+ * something here.
-+ */
-+#define FOC_TOUCH 0x3 /* bitmap of active fingers */
-+#define FOC_ABS 0x6 /* absolute position of one finger */
-+#define FOC_REL 0x9 /* relative position of 1-2 fingers */
-+
-+#define FOC_MAX_FINGERS 5
-+
-+#define FOC_MAX_X 2431
-+#define FOC_MAX_Y 1663
-+
-+/*
-+ * Current state of a single finger on the touchpad.
-+ */
-+struct focaltech_finger_state {
-+ /* The touchpad has generated a touch event for the finger */
-+ bool active;
-+
-+ /*
-+ * The touchpad has sent position data for the finger. The
-+ * flag is 0 when the finger is not active, and there is a
-+ * time between the first touch event for the finger and the
-+ * following absolute position packet for the finger where the
-+ * touchpad has declared the finger to be valid, but we do not
-+ * have any valid position yet.
-+ */
-+ bool valid;
-+
-+ /*
-+ * Absolute position (from the bottom left corner) of the
-+ * finger.
-+ */
-+ unsigned int x;
-+ unsigned int y;
-+};
-+
-+/*
-+ * Description of the current state of the touchpad hardware.
-+ */
-+struct focaltech_hw_state {
-+ /*
-+ * The touchpad tracks the positions of the fingers for us,
-+ * the array indices correspond to the finger indices returned
-+ * in the report packages.
-+ */
-+ struct focaltech_finger_state fingers[FOC_MAX_FINGERS];
-+
-+ /* True if the clickpad has been pressed. */
-+ bool pressed;
-+};
-+
-+struct focaltech_data {
-+ unsigned int x_max, y_max;
-+ struct focaltech_hw_state state;
-+};
-+
-+static void focaltech_report_state(struct psmouse *psmouse)
-+{
-+ struct focaltech_data *priv = psmouse->private;
-+ struct focaltech_hw_state *state = &priv->state;
-+ struct input_dev *dev = psmouse->dev;
-+ int i;
-+
-+ for (i = 0; i < FOC_MAX_FINGERS; i++) {
-+ struct focaltech_finger_state *finger = &state->fingers[i];
-+ bool active = finger->active && finger->valid;
-+
-+ input_mt_slot(dev, i);
-+ input_mt_report_slot_state(dev, MT_TOOL_FINGER, active);
-+ if (active) {
-+ input_report_abs(dev, ABS_MT_POSITION_X, finger->x);
-+ input_report_abs(dev, ABS_MT_POSITION_Y,
-+ FOC_MAX_Y - finger->y);
-+ }
-+ }
-+ input_mt_report_pointer_emulation(dev, true);
-+
-+ input_report_key(psmouse->dev, BTN_LEFT, state->pressed);
-+ input_sync(psmouse->dev);
-+}
-+
-+static void focaltech_process_touch_packet(struct psmouse *psmouse,
-+ unsigned char *packet)
-+{
-+ struct focaltech_data *priv = psmouse->private;
-+ struct focaltech_hw_state *state = &priv->state;
-+ unsigned char fingers = packet[1];
-+ int i;
-+
-+ state->pressed = (packet[0] >> 4) & 1;
-+
-+ /* the second byte contains a bitmap of all fingers touching the pad */
-+ for (i = 0; i < FOC_MAX_FINGERS; i++) {
-+ state->fingers[i].active = fingers & 0x1;
-+ if (!state->fingers[i].active) {
-+ /*
-+ * Even when the finger becomes active again, we still
-+ * will have to wait for the first valid position.
-+ */
-+ state->fingers[i].valid = false;
-+ }
-+ fingers >>= 1;
-+ }
-+}
-+
-+static void focaltech_process_abs_packet(struct psmouse *psmouse,
-+ unsigned char *packet)
-+{
-+ struct focaltech_data *priv = psmouse->private;
-+ struct focaltech_hw_state *state = &priv->state;
-+ unsigned int finger;
-+
-+ finger = (packet[1] >> 4) - 1;
-+ if (finger >= FOC_MAX_FINGERS) {
-+ psmouse_err(psmouse, "Invalid finger in abs packet: %d\n",
-+ finger);
-+ return;
-+ }
-+
-+ state->pressed = (packet[0] >> 4) & 1;
-+
-+ /*
-+ * packet[5] contains some kind of tool size in the most
-+ * significant nibble. 0xff is a special value (latching) that
-+ * signals a large contact area.
-+ */
-+ if (packet[5] == 0xff) {
-+ state->fingers[finger].valid = false;
-+ return;
-+ }
-+
-+ state->fingers[finger].x = ((packet[1] & 0xf) << 8) | packet[2];
-+ state->fingers[finger].y = (packet[3] << 8) | packet[4];
-+ state->fingers[finger].valid = true;
-+}
-+
-+static void focaltech_process_rel_packet(struct psmouse *psmouse,
-+ unsigned char *packet)
-+{
-+ struct focaltech_data *priv = psmouse->private;
-+ struct focaltech_hw_state *state = &priv->state;
-+ int finger1, finger2;
-+
-+ state->pressed = packet[0] >> 7;
-+ finger1 = ((packet[0] >> 4) & 0x7) - 1;
-+ if (finger1 < FOC_MAX_FINGERS) {
-+ state->fingers[finger1].x += (char)packet[1];
-+ state->fingers[finger1].y += (char)packet[2];
-+ } else {
-+ psmouse_err(psmouse, "First finger in rel packet invalid: %d\n",
-+ finger1);
-+ }
-+
-+ /*
-+ * If there is an odd number of fingers, the last relative
-+ * packet only contains one finger. In this case, the second
-+ * finger index in the packet is 0 (we subtract 1 in the lines
-+ * above to create array indices, so the finger will overflow
-+ * and be above FOC_MAX_FINGERS).
-+ */
-+ finger2 = ((packet[3] >> 4) & 0x7) - 1;
-+ if (finger2 < FOC_MAX_FINGERS) {
-+ state->fingers[finger2].x += (char)packet[4];
-+ state->fingers[finger2].y += (char)packet[5];
-+ }
-+}
-+
-+static void focaltech_process_packet(struct psmouse *psmouse)
-+{
-+ unsigned char *packet = psmouse->packet;
-+
-+ switch (packet[0] & 0xf) {
-+ case FOC_TOUCH:
-+ focaltech_process_touch_packet(psmouse, packet);
-+ break;
-+
-+ case FOC_ABS:
-+ focaltech_process_abs_packet(psmouse, packet);
-+ break;
-+
-+ case FOC_REL:
-+ focaltech_process_rel_packet(psmouse, packet);
-+ break;
-+
-+ default:
-+ psmouse_err(psmouse, "Unknown packet type: %02x\n", packet[0]);
-+ break;
-+ }
-+
-+ focaltech_report_state(psmouse);
-+}
-+
-+static psmouse_ret_t focaltech_process_byte(struct psmouse *psmouse)
-+{
-+ if (psmouse->pktcnt >= 6) { /* Full packet received */
-+ focaltech_process_packet(psmouse);
-+ return PSMOUSE_FULL_PACKET;
-+ }
-+
-+ /*
-+ * We might want to do some validation of the data here, but
-+ * we do not know the protocol well enough
-+ */
-+ return PSMOUSE_GOOD_DATA;
-+}
-+
-+static int focaltech_switch_protocol(struct psmouse *psmouse)
-+{
-+ struct ps2dev *ps2dev = &psmouse->ps2dev;
-+ unsigned char param[3];
-+
-+ param[0] = 0;
-+ if (ps2_command(ps2dev, param, 0x10f8))
-+ return -EIO;
-+
-+ if (ps2_command(ps2dev, param, 0x10f8))
-+ return -EIO;
-+
-+ if (ps2_command(ps2dev, param, 0x10f8))
-+ return -EIO;
-+
-+ param[0] = 1;
-+ if (ps2_command(ps2dev, param, 0x10f8))
-+ return -EIO;
-+
-+ if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETSCALE11))
-+ return -EIO;
-+
-+ if (ps2_command(ps2dev, param, PSMOUSE_CMD_ENABLE))
-+ return -EIO;
-+
-+ return 0;
-+}
-+
-+static void focaltech_disconnect(struct psmouse *psmouse)
-+{
-+ focaltech_reset(psmouse);
-+ kfree(psmouse->private);
-+ psmouse->private = NULL;
-+}
-+
-+static int focaltech_reconnect(struct psmouse *psmouse)
-+{
-+ int error;
-+
-+ focaltech_reset(psmouse);
-+
-+ error = focaltech_switch_protocol(psmouse);
-+ if (error) {
-+ psmouse_err(psmouse, "Unable to initialize the device\n");
-+ return error;
-+ }
-+
-+ return 0;
-+}
-+
-+static void focaltech_set_input_params(struct psmouse *psmouse)
-+{
-+ struct input_dev *dev = psmouse->dev;
-+ struct focaltech_data *priv = psmouse->private;
-+
-+ /*
-+ * Undo part of setup done for us by psmouse core since touchpad
-+ * is not a relative device.
-+ */
-+ __clear_bit(EV_REL, dev->evbit);
-+ __clear_bit(REL_X, dev->relbit);
-+ __clear_bit(REL_Y, dev->relbit);
-+ __clear_bit(BTN_RIGHT, dev->keybit);
-+ __clear_bit(BTN_MIDDLE, dev->keybit);
-+
-+ /*
-+ * Now set up our capabilities.
-+ */
-+ __set_bit(EV_ABS, dev->evbit);
-+ input_set_abs_params(dev, ABS_MT_POSITION_X, 0, priv->x_max, 0, 0);
-+ input_set_abs_params(dev, ABS_MT_POSITION_Y, 0, priv->y_max, 0, 0);
-+ input_mt_init_slots(dev, 5, INPUT_MT_POINTER);
-+ __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit);
-+}
-+
-+static int focaltech_read_register(struct ps2dev *ps2dev, int reg,
-+ unsigned char *param)
-+{
-+ if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETSCALE11))
-+ return -EIO;
-+
-+ param[0] = 0;
-+ if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES))
-+ return -EIO;
-+
-+ if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES))
-+ return -EIO;
-+
-+ if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES))
-+ return -EIO;
-+
-+ param[0] = reg;
-+ if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES))
-+ return -EIO;
-+
-+ if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
-+ return -EIO;
-+
-+ return 0;
-+}
-+
-+static int focaltech_read_size(struct psmouse *psmouse)
-+{
-+ struct ps2dev *ps2dev = &psmouse->ps2dev;
-+ struct focaltech_data *priv = psmouse->private;
-+ char param[3];
-+
-+ if (focaltech_read_register(ps2dev, 2, param))
-+ return -EIO;
-+
-+ /* not sure whether this is 100% correct */
-+ priv->x_max = (unsigned char)param[1] * 128;
-+ priv->y_max = (unsigned char)param[2] * 128;
-+
-+ return 0;
-+}
-+int focaltech_init(struct psmouse *psmouse)
-+{
-+ struct focaltech_data *priv;
-+ int error;
-+
-+ psmouse->private = priv = kzalloc(sizeof(struct focaltech_data),
-+ GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ focaltech_reset(psmouse);
-+
-+ error = focaltech_read_size(psmouse);
-+ if (error) {
-+ psmouse_err(psmouse,
-+ "Unable to read the size of the touchpad\n");
-+ goto fail;
-+ }
-+
-+ error = focaltech_switch_protocol(psmouse);
-+ if (error) {
-+ psmouse_err(psmouse, "Unable to initialize the device\n");
-+ goto fail;
-+ }
-+
-+ focaltech_set_input_params(psmouse);
-+
-+ psmouse->protocol_handler = focaltech_process_byte;
-+ psmouse->pktsize = 6;
-+ psmouse->disconnect = focaltech_disconnect;
-+ psmouse->reconnect = focaltech_reconnect;
-+ psmouse->cleanup = focaltech_reset;
-+ /* resync is not supported yet */
-+ psmouse->resync_time = 0;
-
- return 0;
-+
-+fail:
-+ focaltech_reset(psmouse);
-+ kfree(priv);
-+ return error;
- }
-+
-+bool focaltech_supported(void)
-+{
-+ return true;
-+}
-+
-+#else /* CONFIG_MOUSE_PS2_FOCALTECH */
-+
-+int focaltech_init(struct psmouse *psmouse)
-+{
-+ focaltech_reset(psmouse);
-+
-+ return 0;
-+}
-+
-+bool focaltech_supported(void)
-+{
-+ return false;
-+}
-+
-+#endif /* CONFIG_MOUSE_PS2_FOCALTECH */
-diff --git a/drivers/input/mouse/focaltech.h b/drivers/input/mouse/focaltech.h
-index 498650c..71870a9 100644
---- a/drivers/input/mouse/focaltech.h
-+++ b/drivers/input/mouse/focaltech.h
-@@ -2,6 +2,7 @@
- * Focaltech TouchPad PS/2 mouse driver
- *
- * Copyright (c) 2014 Red Hat Inc.
-+ * Copyright (c) 2014 Mathias Gottschlag
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
-@@ -18,5 +19,6 @@
-
- int focaltech_detect(struct psmouse *psmouse, bool set_properties);
- int focaltech_init(struct psmouse *psmouse);
-+bool focaltech_supported(void);
-
- #endif
-diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
-index 26994f6..4a9de33 100644
---- a/drivers/input/mouse/psmouse-base.c
-+++ b/drivers/input/mouse/psmouse-base.c
-@@ -725,16 +725,19 @@ static int psmouse_extensions(struct psmouse *psmouse,
-
- /* Always check for focaltech, this is safe as it uses pnp-id matching */
- if (psmouse_do_detect(focaltech_detect, psmouse, set_properties) == 0) {
-- if (!set_properties || focaltech_init(psmouse) == 0) {
-- /*
-- * Not supported yet, use bare protocol.
-- * Note that we need to also restrict
-- * psmouse_max_proto so that psmouse_initialize()
-- * does not try to reset rate and resolution,
-- * because even that upsets the device.
-- */
-- psmouse_max_proto = PSMOUSE_PS2;
-- return PSMOUSE_PS2;
-+ if (max_proto > PSMOUSE_IMEX) {
-+ if (!set_properties || focaltech_init(psmouse) == 0) {
-+ if (focaltech_supported())
-+ return PSMOUSE_FOCALTECH;
-+ /*
-+ * Note that we need to also restrict
-+ * psmouse_max_proto so that psmouse_initialize()
-+ * does not try to reset rate and resolution,
-+ * because even that upsets the device.
-+ */
-+ psmouse_max_proto = PSMOUSE_PS2;
-+ return PSMOUSE_PS2;
-+ }
- }
- }
-
-@@ -1063,6 +1066,15 @@ static const struct psmouse_protocol psmouse_protocols[] = {
- .alias = "cortps",
- .detect = cortron_detect,
- },
-+#ifdef CONFIG_MOUSE_PS2_FOCALTECH
-+ {
-+ .type = PSMOUSE_FOCALTECH,
-+ .name = "FocalTechPS/2",
-+ .alias = "focaltech",
-+ .detect = focaltech_detect,
-+ .init = focaltech_init,
-+ },
-+#endif
- {
- .type = PSMOUSE_AUTO,
- .name = "auto",
-diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
-index f4cf664..c2ff137 100644
---- a/drivers/input/mouse/psmouse.h
-+++ b/drivers/input/mouse/psmouse.h
-@@ -96,6 +96,7 @@ enum psmouse_type {
- PSMOUSE_FSP,
- PSMOUSE_SYNAPTICS_RELATIVE,
- PSMOUSE_CYPRESS,
-+ PSMOUSE_FOCALTECH,
- PSMOUSE_AUTO /* This one should always be last */
- };
-
---
-2.3.1
-
diff --git a/kernel/kernel/files/patches/mageia/KVM-ia64-drop-kvm.h-from-installed-user-headers.patch b/kernel/kernel/files/patches/mageia/KVM-ia64-drop-kvm.h-from-installed-user-headers.patch
deleted file mode 100644
index e8cbed47..00000000
--- a/kernel/kernel/files/patches/mageia/KVM-ia64-drop-kvm.h-from-installed-user-headers.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 6557bada461afeaa920a189fae2cff7c8fdce39f Mon Sep 17 00:00:00 2001
-From: Mike Frysinger
-Date: Mon, 9 Feb 2015 14:24:47 -0500
-Subject: [PATCH] KVM: ia64: drop kvm.h from installed user headers
-
-The header was deleted, so stop trying to install it.
-
-Signed-off-by: Mike Frysinger
-Signed-off-by: Paolo Bonzini
----
- arch/ia64/include/uapi/asm/Kbuild | 1 -
- 1 file changed, 1 deletion(-)
-
-diff --git a/arch/ia64/include/uapi/asm/Kbuild b/arch/ia64/include/uapi/asm/Kbuild
-index 1b3f5eb..891002b 100644
---- a/arch/ia64/include/uapi/asm/Kbuild
-+++ b/arch/ia64/include/uapi/asm/Kbuild
-@@ -18,7 +18,6 @@ header-y += intrinsics.h
- header-y += ioctl.h
- header-y += ioctls.h
- header-y += ipcbuf.h
--header-y += kvm.h
- header-y += kvm_para.h
- header-y += mman.h
- header-y += msgbuf.h
---
-2.3.0
-
diff --git a/kernel/kernel/files/patches/mageia/acpi-ACPICA-Add-Windows-2015-string-to-_OSI-support.patch b/kernel/kernel/files/patches/mageia/acpi-ACPICA-Add-Windows-2015-string-to-_OSI-support.patch
deleted file mode 100644
index a665e11d..00000000
--- a/kernel/kernel/files/patches/mageia/acpi-ACPICA-Add-Windows-2015-string-to-_OSI-support.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From 796888e942b34cbbd738d9e5478b7d103ee38061 Mon Sep 17 00:00:00 2001
-From: Bob Moore
-Date: Mon, 13 Apr 2015 11:50:37 +0800
-Subject: [PATCH] ACPICA: Add "Windows 2015" string to _OSI support.
-
-ACPICA commit b293f602a67da478ae0bec129e68bd99787d9908
-
-This change adds this string for Windows 10.
-
-Link: https://github.com/acpica/acpica/commit/b293f602
-Signed-off-by: Bob Moore
-Signed-off-by: Lv Zheng
-Signed-off-by: Rafael J. Wysocki
----
- drivers/acpi/acpica/utosi.c | 1 +
- include/acpi/actypes.h | 1 +
- 2 files changed, 2 insertions(+)
-
-diff --git a/drivers/acpi/acpica/utosi.c b/drivers/acpi/acpica/utosi.c
-index 574cd31..44035ab 100644
---- a/drivers/acpi/acpica/utosi.c
-+++ b/drivers/acpi/acpica/utosi.c
-@@ -100,6 +100,7 @@ static struct acpi_interface_info acpi_default_supported_interfaces[] = {
- {"Windows 2009", NULL, 0, ACPI_OSI_WIN_7}, /* Windows 7 and Server 2008 R2 - Added 09/2009 */
- {"Windows 2012", NULL, 0, ACPI_OSI_WIN_8}, /* Windows 8 and Server 2012 - Added 08/2012 */
- {"Windows 2013", NULL, 0, ACPI_OSI_WIN_8}, /* Windows 8.1 and Server 2012 R2 - Added 01/2014 */
-+ {"Windows 2015", NULL, 0, ACPI_OSI_WIN_10}, /* Windows 10 - Added 03/2015 */
-
- /* Feature Group Strings */
-
-diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
-index f18b7a8..ace520f 100644
---- a/include/acpi/actypes.h
-+++ b/include/acpi/actypes.h
-@@ -1274,6 +1274,7 @@ struct acpi_memory_list {
- #define ACPI_OSI_WIN_VISTA_SP2 0x0A
- #define ACPI_OSI_WIN_7 0x0B
- #define ACPI_OSI_WIN_8 0x0C
-+#define ACPI_OSI_WIN_10 0x0D
-
- /* Definitions of file IO */
-
---
-2.3.2
-
diff --git a/kernel/kernel/files/patches/mageia/acpi-PNP-add-two-IDs-to-list-for-PNPACPI-device-enum.patch b/kernel/kernel/files/patches/mageia/acpi-PNP-add-two-IDs-to-list-for-PNPACPI-device-enum.patch
deleted file mode 100644
index 538e0036..00000000
--- a/kernel/kernel/files/patches/mageia/acpi-PNP-add-two-IDs-to-list-for-PNPACPI-device-enum.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 622532bb2fad8fe342fb685727ae0be566f6be5d Mon Sep 17 00:00:00 2001
-From: Witold Szczeponik
-Date: Fri, 1 May 2015 19:05:20 +0200
-Subject: [PATCH] ACPI / PNP: add two IDs to list for PNPACPI device
- enumeration
-
-Commit eec15edbb0e1 (ACPI / PNP: use device ID list for PNPACPI device
-enumeration) changed the way how ACPI devices are enumerated and when
-they are added to the PNP bus.
-
-However, it broke the sound card support on (at least) a vintage
-IBM ThinkPad 600E: with said commit applied, two of the necessary
-"CSC01xx" devices are not added to the PNP bus and hence can not be
-found during the initialization of the "snd-cs4236" module. As a
-consequence, loading "snd-cs4236" causes null pointer exceptions.
-The attached patch fixes the problem end re-enables sound on the
-IBM ThinkPad 600E.
-
-Fixes: eec15edbb0e1 (ACPI / PNP: use device ID list for PNPACPI device enumeration)
-Signed-off-by: Witold Szczeponik
-Cc: 3.16+ # 3.16+
-Signed-off-by: Rafael J. Wysocki
----
- drivers/acpi/acpi_pnp.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/drivers/acpi/acpi_pnp.c b/drivers/acpi/acpi_pnp.c
-index b193f84..ff6d8ad 100644
---- a/drivers/acpi/acpi_pnp.c
-+++ b/drivers/acpi/acpi_pnp.c
-@@ -304,6 +304,8 @@ static const struct acpi_device_id acpi_pnp_device_ids[] = {
- {"PNPb006"},
- /* cs423x-pnpbios */
- {"CSC0100"},
-+ {"CSC0103"},
-+ {"CSC0110"},
- {"CSC0000"},
- {"GIM0100"}, /* Guillemot Turtlebeach something appears to be cs4232 compatible */
- /* es18xx-pnpbios */
---
-2.3.2
-
diff --git a/kernel/kernel/files/patches/mageia/acpi-SBS-Add-5-us-delay-to-fix-SBS-hangs-on-MacBook.patch b/kernel/kernel/files/patches/mageia/acpi-SBS-Add-5-us-delay-to-fix-SBS-hangs-on-MacBook.patch
deleted file mode 100644
index 8e932279..00000000
--- a/kernel/kernel/files/patches/mageia/acpi-SBS-Add-5-us-delay-to-fix-SBS-hangs-on-MacBook.patch
+++ /dev/null
@@ -1,85 +0,0 @@
-From 3349fb64b2927407017d970dd5c4daf3c5ad69f8 Mon Sep 17 00:00:00 2001
-From: Chris Bainbridge
-Date: Wed, 29 Apr 2015 21:21:40 +0100
-Subject: [PATCH] ACPI / SBS: Add 5 us delay to fix SBS hangs on MacBook
-
-Commit 7bc5a2bad0b8 'ACPI: Support _OSI("Darwin") correctly' caused
-the MacBook firmware to expose the SBS, resulting in intermittent
-hangs of several minutes on boot, and failure to detect or report
-the battery. Fix this by adding a 5 us delay to the start of each
-SMBUS transaction. This timing is the result of experimentation -
-hangs were observed with 3 us but never with 5 us.
-
-Fixes: 7bc5a2bad0b8 'ACPI: Support _OSI("Darwin") correctly'
-Link: https://bugzilla.kernel.org/show_bug.cgi?id=94651
-Signed-off-by: Chris Bainbridge
-Cc: 3.18+ # 3.18+
-[ rjw: Subject and changelog ]
-Signed-off-by: Rafael J. Wysocki
----
- drivers/acpi/sbshc.c | 22 ++++++++++++++++++++++
- 1 file changed, 22 insertions(+)
-
-diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c
-index 26e5b50..bf034f8 100644
---- a/drivers/acpi/sbshc.c
-+++ b/drivers/acpi/sbshc.c
-@@ -14,6 +14,7 @@
- #include
- #include
- #include
-+#include
- #include "sbshc.h"
-
- #define PREFIX "ACPI: "
-@@ -87,6 +88,8 @@ enum acpi_smb_offset {
- ACPI_SMB_ALARM_DATA = 0x26, /* 2 bytes alarm data */
- };
-
-+static bool macbook;
-+
- static inline int smb_hc_read(struct acpi_smb_hc *hc, u8 address, u8 *data)
- {
- return ec_read(hc->offset + address, data);
-@@ -132,6 +135,8 @@ static int acpi_smbus_transaction(struct acpi_smb_hc *hc, u8 protocol,
- }
-
- mutex_lock(&hc->lock);
-+ if (macbook)
-+ udelay(5);
- if (smb_hc_read(hc, ACPI_SMB_PROTOCOL, &temp))
- goto end;
- if (temp) {
-@@ -257,12 +262,29 @@ extern int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
- acpi_handle handle, acpi_ec_query_func func,
- void *data);
-
-+static int macbook_dmi_match(const struct dmi_system_id *d)
-+{
-+ pr_debug("Detected MacBook, enabling workaround\n");
-+ macbook = true;
-+ return 0;
-+}
-+
-+static struct dmi_system_id acpi_smbus_dmi_table[] = {
-+ { macbook_dmi_match, "Apple MacBook", {
-+ DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
-+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBook") },
-+ },
-+ { },
-+};
-+
- static int acpi_smbus_hc_add(struct acpi_device *device)
- {
- int status;
- unsigned long long val;
- struct acpi_smb_hc *hc;
-
-+ dmi_check_system(acpi_smbus_dmi_table);
-+
- if (!device)
- return -EINVAL;
-
---
-2.3.2
-
diff --git a/kernel/kernel/files/patches/mageia/acpi-init-Fix-the-ordering-of-acpi_reserve_resources.patch b/kernel/kernel/files/patches/mageia/acpi-init-Fix-the-ordering-of-acpi_reserve_resources.patch
deleted file mode 100644
index a42c2876..00000000
--- a/kernel/kernel/files/patches/mageia/acpi-init-Fix-the-ordering-of-acpi_reserve_resources.patch
+++ /dev/null
@@ -1,56 +0,0 @@
-From b9a5e5e18fbf223502c0b2264c15024e393da928 Mon Sep 17 00:00:00 2001
-From: "Rafael J. Wysocki"
-Date: Thu, 7 May 2015 21:19:39 +0200
-Subject: ACPI / init: Fix the ordering of acpi_reserve_resources()
-
-Since acpi_reserve_resources() is defined as a device_initcall(),
-there's no guarantee that it will be executed in the right order
-with respect to the rest of the ACPI initialization code. On some
-systems this leads to breakage if, for example, the address range
-that should be reserved for the ACPI fixed registers is given to
-the PCI host bridge instead if the race is won by the wrong code
-path.
-
-Fix this by turning acpi_reserve_resources() into a void function
-and calling it directly from within the ACPI initialization sequence.
-
-Reported-and-tested-by: George McCollister
-Link: http://marc.info/?t=143092384600002&r=1&w=2
-Cc: All applicable
-Signed-off-by: Rafael J. Wysocki
-
-diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
-index 39748bb..7ccba39 100644
---- a/drivers/acpi/osl.c
-+++ b/drivers/acpi/osl.c
-@@ -182,7 +182,7 @@ static void __init acpi_request_region (struct acpi_generic_address *gas,
- request_mem_region(addr, length, desc);
- }
-
--static int __init acpi_reserve_resources(void)
-+static void __init acpi_reserve_resources(void)
- {
- acpi_request_region(&acpi_gbl_FADT.xpm1a_event_block, acpi_gbl_FADT.pm1_event_length,
- "ACPI PM1a_EVT_BLK");
-@@ -211,10 +211,7 @@ static int __init acpi_reserve_resources(void)
- if (!(acpi_gbl_FADT.gpe1_block_length & 0x1))
- acpi_request_region(&acpi_gbl_FADT.xgpe1_block,
- acpi_gbl_FADT.gpe1_block_length, "ACPI GPE1_BLK");
--
-- return 0;
- }
--device_initcall(acpi_reserve_resources);
-
- void acpi_os_printf(const char *fmt, ...)
- {
-@@ -1845,6 +1842,7 @@ acpi_status __init acpi_os_initialize(void)
-
- acpi_status __init acpi_os_initialize1(void)
- {
-+ acpi_reserve_resources();
- kacpid_wq = alloc_workqueue("kacpid", 0, 1);
- kacpi_notify_wq = alloc_workqueue("kacpi_notify", 0, 1);
- kacpi_hotplug_wq = alloc_ordered_workqueue("kacpi_hotplug", 0);
---
-cgit v0.10.2
-
diff --git a/kernel/kernel/files/patches/mageia/acpi-sbs-enable-battery-manager-when-present.patch b/kernel/kernel/files/patches/mageia/acpi-sbs-enable-battery-manager-when-present.patch
deleted file mode 100644
index f376d0a2..00000000
--- a/kernel/kernel/files/patches/mageia/acpi-sbs-enable-battery-manager-when-present.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 61f8ff693923e4b19748b0e8287b99778f2661c7 Mon Sep 17 00:00:00 2001
-From: Chris Bainbridge
-Date: Wed, 22 Apr 2015 16:40:21 +0100
-Subject: ACPI / SBS: Enable battery manager when present
-
-From: Chris Bainbridge
-
-commit 61f8ff693923e4b19748b0e8287b99778f2661c7 upstream.
-
-Commit 9faf6136ff46 (ACPI / SBS: Disable smart battery manager on
-Apple) introduced a regression disabling the SBS battery manager.
-The battery manager should be marked as present when
-acpi_manager_get_info() returns 0.
-
-Fixes: 9faf6136ff46 (ACPI / SBS: Disable smart battery manager on Apple)
-Signed-off-by: Chris Bainbridge
-Signed-off-by: Rafael J. Wysocki
-Signed-off-by: Greg Kroah-Hartman
-
----
- drivers/acpi/sbs.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/acpi/sbs.c
-+++ b/drivers/acpi/sbs.c
-@@ -670,7 +670,7 @@ static int acpi_sbs_add(struct acpi_devi
- if (!sbs_manager_broken) {
- result = acpi_manager_get_info(sbs);
- if (!result) {
-- sbs->manager_present = 0;
-+ sbs->manager_present = 1;
- for (id = 0; id < MAX_SBS_BAT; ++id)
- if ((sbs->batteries_supported & (1 << id)))
- acpi_battery_add(sbs, id);
diff --git a/kernel/kernel/files/patches/mageia/acpi-table-Use-pr_debug-instead-of-pr_info-for-MADT-.patch b/kernel/kernel/files/patches/mageia/acpi-table-Use-pr_debug-instead-of-pr_info-for-MADT-.patch
deleted file mode 100644
index ae6d55d1..00000000
--- a/kernel/kernel/files/patches/mageia/acpi-table-Use-pr_debug-instead-of-pr_info-for-MADT-.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-From 07f438df22886432ff50772446768f65fbbf3ee0 Mon Sep 17 00:00:00 2001
-From: Hanjun Guo
-Date: Tue, 24 Mar 2015 14:02:34 +0000
-Subject: [PATCH] ACPI / table: Use pr_debug() instead of pr_info() for MADT
- table scanning
-
-For a normal 8 cpu sockets system, it will up to 240 cpu threads (Xeon E7
-v2 family for now), and we need 240 entries for local apic or local x2apic
-in MADT table, so it will be much verbose information printed with a slow
-uart console when system booted, this will be even worse with large system
-with 16/32 cpu sockets.
-
-This patch just use pr_debug() instead of pr_info() for ioapic/iosapic,
-local apic/x2apic/sapic structures when scanning the MADT table to remove
-those verbose information, but leave other structures unchanged.
-
-CC: Rafael J Wysocki
-Acked-by: Rafael J. Wysocki
-Acked-by: Olof Johansson
-Acked-by: Grant Likely
-Tested-by: Timur Tabi
-Signed-off-by: Hanjun Guo
-Signed-off-by: Will Deacon
----
- drivers/acpi/tables.c | 30 ++++++++++++++++--------------
- 1 file changed, 16 insertions(+), 14 deletions(-)
-
-diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
-index 93b8152..f4e5b88 100644
---- a/drivers/acpi/tables.c
-+++ b/drivers/acpi/tables.c
-@@ -23,6 +23,8 @@
- *
- */
-
-+/* Uncomment next line to get verbose printout */
-+/* #define DEBUG */
- #define pr_fmt(fmt) "ACPI: " fmt
-
- #include
-@@ -61,9 +63,9 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
- {
- struct acpi_madt_local_apic *p =
- (struct acpi_madt_local_apic *)header;
-- pr_info("LAPIC (acpi_id[0x%02x] lapic_id[0x%02x] %s)\n",
-- p->processor_id, p->id,
-- (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
-+ pr_debug("LAPIC (acpi_id[0x%02x] lapic_id[0x%02x] %s)\n",
-+ p->processor_id, p->id,
-+ (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
- }
- break;
-
-@@ -71,9 +73,9 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
- {
- struct acpi_madt_local_x2apic *p =
- (struct acpi_madt_local_x2apic *)header;
-- pr_info("X2APIC (apic_id[0x%02x] uid[0x%02x] %s)\n",
-- p->local_apic_id, p->uid,
-- (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
-+ pr_debug("X2APIC (apic_id[0x%02x] uid[0x%02x] %s)\n",
-+ p->local_apic_id, p->uid,
-+ (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
- }
- break;
-
-@@ -81,8 +83,8 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
- {
- struct acpi_madt_io_apic *p =
- (struct acpi_madt_io_apic *)header;
-- pr_info("IOAPIC (id[0x%02x] address[0x%08x] gsi_base[%d])\n",
-- p->id, p->address, p->global_irq_base);
-+ pr_debug("IOAPIC (id[0x%02x] address[0x%08x] gsi_base[%d])\n",
-+ p->id, p->address, p->global_irq_base);
- }
- break;
-
-@@ -155,9 +157,9 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
- {
- struct acpi_madt_io_sapic *p =
- (struct acpi_madt_io_sapic *)header;
-- pr_info("IOSAPIC (id[0x%x] address[%p] gsi_base[%d])\n",
-- p->id, (void *)(unsigned long)p->address,
-- p->global_irq_base);
-+ pr_debug("IOSAPIC (id[0x%x] address[%p] gsi_base[%d])\n",
-+ p->id, (void *)(unsigned long)p->address,
-+ p->global_irq_base);
- }
- break;
-
-@@ -165,9 +167,9 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
- {
- struct acpi_madt_local_sapic *p =
- (struct acpi_madt_local_sapic *)header;
-- pr_info("LSAPIC (acpi_id[0x%02x] lsapic_id[0x%02x] lsapic_eid[0x%02x] %s)\n",
-- p->processor_id, p->id, p->eid,
-- (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
-+ pr_debug("LSAPIC (acpi_id[0x%02x] lsapic_id[0x%02x] lsapic_eid[0x%02x] %s)\n",
-+ p->processor_id, p->id, p->eid,
-+ (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
- }
- break;
-
---
-2.3.2
-
diff --git a/kernel/kernel/files/patches/mageia/acpi-video-Allow-forcing-native-backlight-on-non-win.patch b/kernel/kernel/files/patches/mageia/acpi-video-Allow-forcing-native-backlight-on-non-win.patch
deleted file mode 100644
index 676fb105..00000000
--- a/kernel/kernel/files/patches/mageia/acpi-video-Allow-forcing-native-backlight-on-non-win.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From ff92cfe7cbc05c6c62f5b06c7d9090f4c853cd51 Mon Sep 17 00:00:00 2001
-From: Aaron Lu
-Date: Wed, 11 Mar 2015 22:09:57 +0100
-Subject: [PATCH] ACPI / video: Allow forcing native backlight on non win8
- machines
-
-The native backlight behavior (so not registering both the acpi-video
-and the vendor backlight driver) can be useful on some non win8 machines
-too, so change the behavior of the video.use_native_backlight=1 or 0
-kernel cmdline option to be: if user has set video.use_native_backlight=1
-or 0, use that no matter if it is a win8 system or not. Also, we will
-put some known systems into the DMI table to make them either use native
-backlight interface or not, and the use_native_backlight_dmi is used to
-reflect that.
-
-Original-by: Hans de Goede
-Acked-by: Hans de Goede
-Signed-off-by: Aaron Lu
-Signed-off-by: Rafael J. Wysocki
----
- drivers/acpi/video.c | 19 +++++++++++++------
- 1 file changed, 13 insertions(+), 6 deletions(-)
-
-diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
-index 26eb70c..2f45dca 100644
---- a/drivers/acpi/video.c
-+++ b/drivers/acpi/video.c
-@@ -82,9 +82,15 @@ module_param(allow_duplicates, bool, 0644);
- * For Windows 8 systems: used to decide if video module
- * should skip registering backlight interface of its own.
- */
--static int use_native_backlight_param = -1;
-+enum {
-+ NATIVE_BACKLIGHT_NOT_SET = -1,
-+ NATIVE_BACKLIGHT_OFF,
-+ NATIVE_BACKLIGHT_ON,
-+};
-+
-+static int use_native_backlight_param = NATIVE_BACKLIGHT_NOT_SET;
- module_param_named(use_native_backlight, use_native_backlight_param, int, 0444);
--static bool use_native_backlight_dmi = true;
-+static int use_native_backlight_dmi = NATIVE_BACKLIGHT_NOT_SET;
-
- static int register_count;
- static struct mutex video_list_lock;
-@@ -237,15 +243,16 @@ static void acpi_video_switch_brightness(struct work_struct *work);
-
- static bool acpi_video_use_native_backlight(void)
- {
-- if (use_native_backlight_param != -1)
-+ if (use_native_backlight_param != NATIVE_BACKLIGHT_NOT_SET)
- return use_native_backlight_param;
-- else
-+ else if (use_native_backlight_dmi != NATIVE_BACKLIGHT_NOT_SET)
- return use_native_backlight_dmi;
-+ return acpi_osi_is_win8();
- }
-
- bool acpi_video_verify_backlight_support(void)
- {
-- if (acpi_osi_is_win8() && acpi_video_use_native_backlight() &&
-+ if (acpi_video_use_native_backlight() &&
- backlight_device_registered(BACKLIGHT_RAW))
- return false;
- return acpi_video_backlight_support();
-@@ -414,7 +421,7 @@ static int __init video_set_bqc_offset(const struct dmi_system_id *d)
-
- static int __init video_disable_native_backlight(const struct dmi_system_id *d)
- {
-- use_native_backlight_dmi = false;
-+ use_native_backlight_dmi = NATIVE_BACKLIGHT_OFF;
- return 0;
- }
-
---
-2.3.2
-
diff --git a/kernel/kernel/files/patches/mageia/alsa-emu10k1-emu10k2-32-bit-dma-mode.patch b/kernel/kernel/files/patches/mageia/alsa-emu10k1-emu10k2-32-bit-dma-mode.patch
deleted file mode 100644
index 3761d1dc..00000000
--- a/kernel/kernel/files/patches/mageia/alsa-emu10k1-emu10k2-32-bit-dma-mode.patch
+++ /dev/null
@@ -1,205 +0,0 @@
-From 7241ea558c6715501e777396b5fc312c372e11d9 Mon Sep 17 00:00:00 2001
-From: Peter Zubaj
-Date: Tue, 28 Apr 2015 21:57:29 +0200
-Subject: ALSA: emu10k1: Emu10k2 32 bit DMA mode
-
-From: Peter Zubaj
-
-commit 7241ea558c6715501e777396b5fc312c372e11d9 upstream.
-
-Looks like audigy emu10k2 (probably emu10k1 - sb live too) support two
-modes for DMA. Second mode is useful for 64 bit os with more then 2 GB
-of ram (fixes problems with big soundfont loading)
-
-1) 32MB from 2 GB address space using 8192 pages (used now as default)
-2) 16MB from 4 GB address space using 4096 pages
-
-Mode is set using HCFG_EXPANDED_MEM flag in HCFG register.
-Also format of emu10k2 page table is then different.
-
-Signed-off-by: Peter Zubaj
-Tested-by: Takashi Iwai
-Signed-off-by: Takashi Iwai
-Signed-off-by: Greg Kroah-Hartman
-
----
- include/sound/emu10k1.h | 14 +++++++++-----
- sound/pci/emu10k1/emu10k1_callback.c | 4 ++--
- sound/pci/emu10k1/emu10k1_main.c | 17 ++++++++++++-----
- sound/pci/emu10k1/emupcm.c | 2 +-
- sound/pci/emu10k1/memory.c | 11 ++++++-----
- 5 files changed, 30 insertions(+), 18 deletions(-)
-
---- a/include/sound/emu10k1.h
-+++ b/include/sound/emu10k1.h
-@@ -41,7 +41,8 @@
-
- #define EMUPAGESIZE 4096
- #define MAXREQVOICES 8
--#define MAXPAGES 8192
-+#define MAXPAGES0 4096 /* 32 bit mode */
-+#define MAXPAGES1 8192 /* 31 bit mode */
- #define RESERVED 0
- #define NUM_MIDI 16
- #define NUM_G 64 /* use all channels */
-@@ -50,8 +51,7 @@
-
- /* FIXME? - according to the OSS driver the EMU10K1 needs a 29 bit DMA mask */
- #define EMU10K1_DMA_MASK 0x7fffffffUL /* 31bit */
--#define AUDIGY_DMA_MASK 0x7fffffffUL /* 31bit FIXME - 32 should work? */
-- /* See ALSA bug #1276 - rlrevell */
-+#define AUDIGY_DMA_MASK 0xffffffffUL /* 32bit mode */
-
- #define TMEMSIZE 256*1024
- #define TMEMSIZEREG 4
-@@ -466,8 +466,11 @@
-
- #define MAPB 0x0d /* Cache map B */
-
--#define MAP_PTE_MASK 0xffffe000 /* The 19 MSBs of the PTE indexed by the PTI */
--#define MAP_PTI_MASK 0x00001fff /* The 13 bit index to one of the 8192 PTE dwords */
-+#define MAP_PTE_MASK0 0xfffff000 /* The 20 MSBs of the PTE indexed by the PTI */
-+#define MAP_PTI_MASK0 0x00000fff /* The 12 bit index to one of the 4096 PTE dwords */
-+
-+#define MAP_PTE_MASK1 0xffffe000 /* The 19 MSBs of the PTE indexed by the PTI */
-+#define MAP_PTI_MASK1 0x00001fff /* The 13 bit index to one of the 8192 PTE dwords */
-
- /* 0x0e, 0x0f: Not used */
-
-@@ -1704,6 +1707,7 @@ struct snd_emu10k1 {
- unsigned short model; /* subsystem id */
- unsigned int card_type; /* EMU10K1_CARD_* */
- unsigned int ecard_ctrl; /* ecard control bits */
-+ unsigned int address_mode; /* address mode */
- unsigned long dma_mask; /* PCI DMA mask */
- unsigned int delay_pcm_irq; /* in samples */
- int max_cache_pages; /* max memory size / PAGE_SIZE */
---- a/sound/pci/emu10k1/emu10k1_callback.c
-+++ b/sound/pci/emu10k1/emu10k1_callback.c
-@@ -415,7 +415,7 @@ start_voice(struct snd_emux_voice *vp)
- snd_emu10k1_ptr_write(hw, Z2, ch, 0);
-
- /* invalidate maps */
-- temp = (hw->silent_page.addr << 1) | MAP_PTI_MASK;
-+ temp = (hw->silent_page.addr << hw->address_mode) | (hw->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
- snd_emu10k1_ptr_write(hw, MAPA, ch, temp);
- snd_emu10k1_ptr_write(hw, MAPB, ch, temp);
- #if 0
-@@ -436,7 +436,7 @@ start_voice(struct snd_emux_voice *vp)
- snd_emu10k1_ptr_write(hw, CDF, ch, sample);
-
- /* invalidate maps */
-- temp = ((unsigned int)hw->silent_page.addr << 1) | MAP_PTI_MASK;
-+ temp = ((unsigned int)hw->silent_page.addr << hw_address_mode) | (hw->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
- snd_emu10k1_ptr_write(hw, MAPA, ch, temp);
- snd_emu10k1_ptr_write(hw, MAPB, ch, temp);
-
---- a/sound/pci/emu10k1/emu10k1_main.c
-+++ b/sound/pci/emu10k1/emu10k1_main.c
-@@ -282,7 +282,7 @@ static int snd_emu10k1_init(struct snd_e
- snd_emu10k1_ptr_write(emu, TCB, 0, 0); /* taken from original driver */
- snd_emu10k1_ptr_write(emu, TCBS, 0, 4); /* taken from original driver */
-
-- silent_page = (emu->silent_page.addr << 1) | MAP_PTI_MASK;
-+ silent_page = (emu->silent_page.addr << emu->address_mode) | (emu->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
- for (ch = 0; ch < NUM_G; ch++) {
- snd_emu10k1_ptr_write(emu, MAPA, ch, silent_page);
- snd_emu10k1_ptr_write(emu, MAPB, ch, silent_page);
-@@ -348,6 +348,11 @@ static int snd_emu10k1_init(struct snd_e
- outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG);
- }
-
-+ if (emu->address_mode == 0) {
-+ /* use 16M in 4G */
-+ outl(inl(emu->port + HCFG) | HCFG_EXPANDED_MEM, emu->port + HCFG);
-+ }
-+
- return 0;
- }
-
-@@ -1877,8 +1882,10 @@ int snd_emu10k1_create(struct snd_card *
-
- is_audigy = emu->audigy = c->emu10k2_chip;
-
-+ /* set addressing mode */
-+ emu->address_mode = is_audigy ? 0 : 1;
- /* set the DMA transfer mask */
-- emu->dma_mask = is_audigy ? AUDIGY_DMA_MASK : EMU10K1_DMA_MASK;
-+ emu->dma_mask = emu->address_mode ? EMU10K1_DMA_MASK : AUDIGY_DMA_MASK;
- if (pci_set_dma_mask(pci, emu->dma_mask) < 0 ||
- pci_set_consistent_dma_mask(pci, emu->dma_mask) < 0) {
- dev_err(card->dev,
-@@ -1903,7 +1910,7 @@ int snd_emu10k1_create(struct snd_card *
-
- emu->max_cache_pages = max_cache_bytes >> PAGE_SHIFT;
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
-- 32 * 1024, &emu->ptb_pages) < 0) {
-+ (emu->address_mode ? 32 : 16) * 1024, &emu->ptb_pages) < 0) {
- err = -ENOMEM;
- goto error;
- }
-@@ -2002,8 +2009,8 @@ int snd_emu10k1_create(struct snd_card *
-
- /* Clear silent pages and set up pointers */
- memset(emu->silent_page.area, 0, PAGE_SIZE);
-- silent_page = emu->silent_page.addr << 1;
-- for (idx = 0; idx < MAXPAGES; idx++)
-+ silent_page = emu->silent_page.addr << emu->address_mode;
-+ for (idx = 0; idx < (emu->address_mode ? MAXPAGES1 : MAXPAGES0); idx++)
- ((u32 *)emu->ptb_pages.area)[idx] = cpu_to_le32(silent_page | idx);
-
- /* set up voice indices */
---- a/sound/pci/emu10k1/emupcm.c
-+++ b/sound/pci/emu10k1/emupcm.c
-@@ -380,7 +380,7 @@ static void snd_emu10k1_pcm_init_voice(s
- snd_emu10k1_ptr_write(emu, Z1, voice, 0);
- snd_emu10k1_ptr_write(emu, Z2, voice, 0);
- /* invalidate maps */
-- silent_page = ((unsigned int)emu->silent_page.addr << 1) | MAP_PTI_MASK;
-+ silent_page = ((unsigned int)emu->silent_page.addr << emu->address_mode) | (emu->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
- snd_emu10k1_ptr_write(emu, MAPA, voice, silent_page);
- snd_emu10k1_ptr_write(emu, MAPB, voice, silent_page);
- /* modulation envelope */
---- a/sound/pci/emu10k1/memory.c
-+++ b/sound/pci/emu10k1/memory.c
-@@ -34,10 +34,11 @@
- * aligned pages in others
- */
- #define __set_ptb_entry(emu,page,addr) \
-- (((u32 *)(emu)->ptb_pages.area)[page] = cpu_to_le32(((addr) << 1) | (page)))
-+ (((u32 *)(emu)->ptb_pages.area)[page] = cpu_to_le32(((addr) << (emu->address_mode)) | (page)))
-
- #define UNIT_PAGES (PAGE_SIZE / EMUPAGESIZE)
--#define MAX_ALIGN_PAGES (MAXPAGES / UNIT_PAGES)
-+#define MAX_ALIGN_PAGES0 (MAXPAGES0 / UNIT_PAGES)
-+#define MAX_ALIGN_PAGES1 (MAXPAGES1 / UNIT_PAGES)
- /* get aligned page from offset address */
- #define get_aligned_page(offset) ((offset) >> PAGE_SHIFT)
- /* get offset address from aligned page */
-@@ -124,7 +125,7 @@ static int search_empty_map_area(struct
- }
- page = blk->mapped_page + blk->pages;
- }
-- size = MAX_ALIGN_PAGES - page;
-+ size = (emu->address_mode ? MAX_ALIGN_PAGES1 : MAX_ALIGN_PAGES0) - page;
- if (size >= max_size) {
- *nextp = pos;
- return page;
-@@ -181,7 +182,7 @@ static int unmap_memblk(struct snd_emu10
- q = get_emu10k1_memblk(p, mapped_link);
- end_page = q->mapped_page;
- } else
-- end_page = MAX_ALIGN_PAGES;
-+ end_page = (emu->address_mode ? MAX_ALIGN_PAGES1 : MAX_ALIGN_PAGES0);
-
- /* remove links */
- list_del(&blk->mapped_link);
-@@ -307,7 +308,7 @@ snd_emu10k1_alloc_pages(struct snd_emu10
- if (snd_BUG_ON(!emu))
- return NULL;
- if (snd_BUG_ON(runtime->dma_bytes <= 0 ||
-- runtime->dma_bytes >= MAXPAGES * EMUPAGESIZE))
-+ runtime->dma_bytes >= (emu->address_mode ? MAXPAGES1 : MAXPAGES0) * EMUPAGESIZE))
- return NULL;
- hdr = emu->memhdr;
- if (snd_BUG_ON(!hdr))
diff --git a/kernel/kernel/files/patches/mageia/alsa-emu10k1-fix-card-shortname-string-buffer-overflow.patch b/kernel/kernel/files/patches/mageia/alsa-emu10k1-fix-card-shortname-string-buffer-overflow.patch
deleted file mode 100644
index c40ddf8b..00000000
--- a/kernel/kernel/files/patches/mageia/alsa-emu10k1-fix-card-shortname-string-buffer-overflow.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From d02260824e2cad626fb2a9d62e27006d34b6dedc Mon Sep 17 00:00:00 2001
-From: Takashi Iwai
-Date: Mon, 27 Apr 2015 13:00:09 +0200
-Subject: ALSA: emu10k1: Fix card shortname string buffer overflow
-
-From: Takashi Iwai
-
-commit d02260824e2cad626fb2a9d62e27006d34b6dedc upstream.
-
-Some models provide too long string for the shortname that has 32bytes
-including the terminator, and it results in a non-terminated string
-exposed to the user-space. This isn't too critical, though, as the
-string is stopped at the succeeding longname string.
-
-This patch fixes such entries by dropping "SB" prefix (it's enough to
-fit within 32 bytes, so far). Meanwhile, it also changes strcpy()
-with strlcpy() to make sure that this kind of problem won't happen in
-future, too.
-
-Signed-off-by: Takashi Iwai
-Signed-off-by: Greg Kroah-Hartman
-
----
- sound/pci/emu10k1/emu10k1.c | 6 ++++--
- sound/pci/emu10k1/emu10k1_main.c | 4 ++--
- 2 files changed, 6 insertions(+), 4 deletions(-)
-
---- a/sound/pci/emu10k1/emu10k1.c
-+++ b/sound/pci/emu10k1/emu10k1.c
-@@ -183,8 +183,10 @@ static int snd_card_emu10k1_probe(struct
- }
- #endif
-
-- strcpy(card->driver, emu->card_capabilities->driver);
-- strcpy(card->shortname, emu->card_capabilities->name);
-+ strlcpy(card->driver, emu->card_capabilities->driver,
-+ sizeof(card->driver));
-+ strlcpy(card->shortname, emu->card_capabilities->name,
-+ sizeof(card->shortname));
- snprintf(card->longname, sizeof(card->longname),
- "%s (rev.%d, serial:0x%x) at 0x%lx, irq %i",
- card->shortname, emu->revision, emu->serial, emu->port, emu->irq);
---- a/sound/pci/emu10k1/emu10k1_main.c
-+++ b/sound/pci/emu10k1/emu10k1_main.c
-@@ -1421,7 +1421,7 @@ static struct snd_emu_chip_details emu_c
- *
- */
- {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x20011102,
-- .driver = "Audigy2", .name = "SB Audigy 2 ZS Notebook [SB0530]",
-+ .driver = "Audigy2", .name = "Audigy 2 ZS Notebook [SB0530]",
- .id = "Audigy2",
- .emu10k2_chip = 1,
- .ca0108_chip = 1,
-@@ -1571,7 +1571,7 @@ static struct snd_emu_chip_details emu_c
- .adc_1361t = 1, /* 24 bit capture instead of 16bit */
- .ac97_chip = 1} ,
- {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10051102,
-- .driver = "Audigy2", .name = "SB Audigy 2 Platinum EX [SB0280]",
-+ .driver = "Audigy2", .name = "Audigy 2 Platinum EX [SB0280]",
- .id = "Audigy2",
- .emu10k2_chip = 1,
- .ca0102_chip = 1,
diff --git a/kernel/kernel/files/patches/mageia/blk-mq-don-t-lose-requests-if-a-stopped-queue-restar.patch b/kernel/kernel/files/patches/mageia/blk-mq-don-t-lose-requests-if-a-stopped-queue-restar.patch
deleted file mode 100644
index ec8e4140..00000000
--- a/kernel/kernel/files/patches/mageia/blk-mq-don-t-lose-requests-if-a-stopped-queue-restar.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 9ba52e5812e53f20f23600d79449a3ec05a0254f Mon Sep 17 00:00:00 2001
-From: Shaohua Li
-Date: Mon, 4 May 2015 14:32:48 -0600
-Subject: [PATCH] blk-mq: don't lose requests if a stopped queue restarts
-
-Normally if driver is busy to dispatch a request the logic is like below:
-block layer: driver:
- __blk_mq_run_hw_queue
-a. blk_mq_stop_hw_queue
-b. rq add to ctx->dispatch
-
-later:
-1. blk_mq_start_hw_queue
-2. __blk_mq_run_hw_queue
-
-But it's possible step 1-2 runs between a and b. And since rq isn't in
-ctx->dispatch yet, step 2 will not run rq. The rq might get lost if
-there are no subsequent requests kick in.
-
-Signed-off-by: Shaohua Li
-Signed-off-by: Jens Axboe
----
- block/blk-mq.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
-diff --git a/block/blk-mq.c b/block/blk-mq.c
-index 76f460e..e68b71b 100644
---- a/block/blk-mq.c
-+++ b/block/blk-mq.c
-@@ -858,6 +858,16 @@ static void __blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx)
- spin_lock(&hctx->lock);
- list_splice(&rq_list, &hctx->dispatch);
- spin_unlock(&hctx->lock);
-+ /*
-+ * the queue is expected stopped with BLK_MQ_RQ_QUEUE_BUSY, but
-+ * it's possible the queue is stopped and restarted again
-+ * before this. Queue restart will dispatch requests. And since
-+ * requests in rq_list aren't added into hctx->dispatch yet,
-+ * the requests in rq_list might get lost.
-+ *
-+ * blk_mq_run_hw_queue() already checks the STOPPED bit
-+ **/
-+ blk_mq_run_hw_queue(hctx, true);
- }
- }
-
---
-2.3.2
-
diff --git a/kernel/kernel/files/patches/mageia/blk-mq-fix-CPU-hotplug-handling.patch b/kernel/kernel/files/patches/mageia/blk-mq-fix-CPU-hotplug-handling.patch
deleted file mode 100644
index 3f6f2fbf..00000000
--- a/kernel/kernel/files/patches/mageia/blk-mq-fix-CPU-hotplug-handling.patch
+++ /dev/null
@@ -1,97 +0,0 @@
-From 2a34c0872adf252f23a6fef2d051a169ac796cef Mon Sep 17 00:00:00 2001
-From: Ming Lei
-Date: Tue, 21 Apr 2015 10:00:20 +0800
-Subject: [PATCH] blk-mq: fix CPU hotplug handling
-
-hctx->tags has to be set as NULL in case that it is to be unmapped
-no matter if set->tags[hctx->queue_num] is NULL or not in blk_mq_map_swqueue()
-because shared tags can be freed already from another request queue.
-
-The same situation has to be considered during handling CPU online too.
-Unmapped hw queue can be remapped after CPU topo is changed, so we need
-to allocate tags for the hw queue in blk_mq_map_swqueue(). Then tags
-allocation for hw queue can be removed in hctx cpu online notifier, and it
-is reasonable to do that after mapping is updated.
-
-Cc:
-Reported-by: Dongsu Park
-Tested-by: Dongsu Park
-Signed-off-by: Ming Lei
-Signed-off-by: Jens Axboe
----
- block/blk-mq.c | 34 +++++++++++++---------------------
- 1 file changed, 13 insertions(+), 21 deletions(-)
-
-diff --git a/block/blk-mq.c b/block/blk-mq.c
-index 1fccb98..76f460e 100644
---- a/block/blk-mq.c
-+++ b/block/blk-mq.c
-@@ -1574,22 +1574,6 @@ static int blk_mq_hctx_cpu_offline(struc
- return NOTIFY_OK;
- }
-
--static int blk_mq_hctx_cpu_online(struct blk_mq_hw_ctx *hctx, int cpu)
--{
-- struct request_queue *q = hctx->queue;
-- struct blk_mq_tag_set *set = q->tag_set;
--
-- if (set->tags[hctx->queue_num])
-- return NOTIFY_OK;
--
-- set->tags[hctx->queue_num] = blk_mq_init_rq_map(set, hctx->queue_num);
-- if (!set->tags[hctx->queue_num])
-- return NOTIFY_STOP;
--
-- hctx->tags = set->tags[hctx->queue_num];
-- return NOTIFY_OK;
--}
--
- static int blk_mq_hctx_notify(void *data, unsigned long action,
- unsigned int cpu)
- {
-@@ -1597,8 +1581,11 @@ static int blk_mq_hctx_notify(void *data
-
- if (action == CPU_DEAD || action == CPU_DEAD_FROZEN)
- return blk_mq_hctx_cpu_offline(hctx, cpu);
-- else if (action == CPU_ONLINE || action == CPU_ONLINE_FROZEN)
-- return blk_mq_hctx_cpu_online(hctx, cpu);
-+
-+ /*
-+ * In case of CPU online, tags may be reallocated
-+ * in blk_mq_map_swqueue() after mapping is updated.
-+ */
-
- return NOTIFY_OK;
- }
-@@ -1780,6 +1767,7 @@ static void blk_mq_map_swqueue(struct re
- unsigned int i;
- struct blk_mq_hw_ctx *hctx;
- struct blk_mq_ctx *ctx;
-+ struct blk_mq_tag_set *set = q->tag_set;
-
- queue_for_each_hw_ctx(q, hctx, i) {
- cpumask_clear(hctx->cpumask);
-@@ -1806,16 +1794,20 @@ static void blk_mq_map_swqueue(struct re
- * disable it and free the request entries.
- */
- if (!hctx->nr_ctx) {
-- struct blk_mq_tag_set *set = q->tag_set;
--
- if (set->tags[i]) {
- blk_mq_free_rq_map(set, set->tags[i], i);
- set->tags[i] = NULL;
-- hctx->tags = NULL;
- }
-+ hctx->tags = NULL;
- continue;
- }
-
-+ /* unmapped hw queue can be remapped after CPU topo changed */
-+ if (!set->tags[i])
-+ set->tags[i] = blk_mq_init_rq_map(set, i);
-+ hctx->tags = set->tags[i];
-+ WARN_ON(!hctx->tags);
-+
- /*
- * Initialize batch roundrobin counts
- */
diff --git a/kernel/kernel/files/patches/mageia/blk-mq-fix-FUA-request-hang.patch b/kernel/kernel/files/patches/mageia/blk-mq-fix-FUA-request-hang.patch
deleted file mode 100644
index 46d66ddb..00000000
--- a/kernel/kernel/files/patches/mageia/blk-mq-fix-FUA-request-hang.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From b2387ddcced8de3e6471a2fb16a409577063016f Mon Sep 17 00:00:00 2001
-From: Shaohua Li
-Date: Fri, 1 May 2015 09:59:44 -0700
-Subject: [PATCH] blk-mq: fix FUA request hang
-
-When a FUA request enters its DATA stage of flush pipeline, the
-request is added to mq requeue list, the request will then be added to
-ctx->rq_list. blk_mq_attempt_merge() might merge the request with a bio.
-Later when the request is finished the flush pipeline, the
-request->__data_len is 0. Then I only saw the bio gets endio called, the
-original request never finish.
-
-Adding REQ_FLUSH_SEQ into REQ_NOMERGE_FLAGS looks an easy fix.
-
-stable: 3.15+
-
-Signed-off-by: Shaohua Li
-Signed-off-by: Jens Axboe
----
- include/linux/blk_types.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
-index a1b25e3..b7299fe 100644
---- a/include/linux/blk_types.h
-+++ b/include/linux/blk_types.h
-@@ -220,7 +220,7 @@ enum rq_flag_bits {
-
- /* This mask is used for both bio and request merge checking */
- #define REQ_NOMERGE_FLAGS \
-- (REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA)
-+ (REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA | REQ_FLUSH_SEQ)
-
- #define REQ_RAHEAD (1ULL << __REQ_RAHEAD)
- #define REQ_THROTTLED (1ULL << __REQ_THROTTLED)
---
-2.3.2
-
diff --git a/kernel/kernel/files/patches/mageia/blk-mq-fix-race-between-timeout-and-CPU-hotplug.patch b/kernel/kernel/files/patches/mageia/blk-mq-fix-race-between-timeout-and-CPU-hotplug.patch
deleted file mode 100644
index cedd2137..00000000
--- a/kernel/kernel/files/patches/mageia/blk-mq-fix-race-between-timeout-and-CPU-hotplug.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From f054b56c951bf1731ba7314a4c7f1cc0b2977cc9 Mon Sep 17 00:00:00 2001
-From: Ming Lei
-Date: Tue, 21 Apr 2015 10:00:19 +0800
-Subject: [PATCH] blk-mq: fix race between timeout and CPU hotplug
-
-Firstly during CPU hotplug, even queue is freezed, timeout
-handler still may come and access hctx->tags, which may cause
-use after free, so this patch deactivates timeout handler
-inside CPU hotplug notifier.
-
-Secondly, tags can be shared by more than one queues, so we
-have to check if the hctx has been unmapped, otherwise
-still use-after-free on tags can be triggered.
-
-Cc:
-Reported-by: Dongsu Park
-Tested-by: Dongsu Park
-Signed-off-by: Ming Lei
-Signed-off-by: Jens Axboe
----
- block/blk-mq.c | 16 +++++++++++++---
- 1 file changed, 13 insertions(+), 3 deletions(-)
-
-diff --git a/block/blk-mq.c b/block/blk-mq.c
-index ade8a2d..1fccb98 100644
---- a/block/blk-mq.c
-+++ b/block/blk-mq.c
-@@ -677,8 +677,11 @@ static void blk_mq_rq_timer(unsigned long priv)
- data.next = blk_rq_timeout(round_jiffies_up(data.next));
- mod_timer(&q->timeout, data.next);
- } else {
-- queue_for_each_hw_ctx(q, hctx, i)
-- blk_mq_tag_idle(hctx);
-+ queue_for_each_hw_ctx(q, hctx, i) {
-+ /* the hctx may be unmapped, so check it here */
-+ if (blk_mq_hw_queue_mapped(hctx))
-+ blk_mq_tag_idle(hctx);
-+ }
- }
- }
-
-@@ -2090,9 +2093,16 @@ static int blk_mq_queue_reinit_notify(struct notifier_block *nb,
- */
- list_for_each_entry(q, &all_q_list, all_q_node)
- blk_mq_freeze_queue_start(q);
-- list_for_each_entry(q, &all_q_list, all_q_node)
-+ list_for_each_entry(q, &all_q_list, all_q_node) {
- blk_mq_freeze_queue_wait(q);
-
-+ /*
-+ * timeout handler can't touch hw queue during the
-+ * reinitialization
-+ */
-+ del_timer_sync(&q->timeout);
-+ }
-+
- list_for_each_entry(q, &all_q_list, all_q_node)
- blk_mq_queue_reinit(q);
-
---
-2.3.2
-
diff --git a/kernel/kernel/files/patches/mageia/block-Make-CFQ-default-to-IOPS-mode-on-SSDs.patch b/kernel/kernel/files/patches/mageia/block-Make-CFQ-default-to-IOPS-mode-on-SSDs.patch
new file mode 100644
index 00000000..b26bf714
--- /dev/null
+++ b/kernel/kernel/files/patches/mageia/block-Make-CFQ-default-to-IOPS-mode-on-SSDs.patch
@@ -0,0 +1,58 @@
+From 41c0126b3f22ef36b97b3c38b8f29569848a5ce2 Mon Sep 17 00:00:00 2001
+From: Tahsin Erdogan
+Date: Tue, 19 May 2015 13:55:21 -0700
+Subject: block: Make CFQ default to IOPS mode on SSDs
+
+CFQ idling causes reduced IOPS throughput on non-rotational disks.
+Since disk head seeking is not applicable to SSDs, it doesn't really
+help performance by anticipating future near-by IO requests.
+
+By turning off idling (and switching to IOPS mode), we allow other
+processes to dispatch IO requests down to the driver and so increase IO
+throughput.
+
+Following FIO benchmark results were taken on a cloud SSD offering with
+idling on and off:
+
+Idling iops avg-lat(ms) stddev bw
+------------------------------------------------------
+ On 7054 90.107 38.697 28217KB/s
+ Off 29255 21.836 11.730 117022KB/s
+
+fio --name=temp --size=100G --time_based --ioengine=libaio \
+ --randrepeat=0 --direct=1 --invalidate=1 --verify=0 \
+ --verify_fatal=0 --rw=randread --blocksize=4k --group_reporting=1 \
+ --filename=/dev/sdb --runtime=10 --iodepth=64 --numjobs=10
+
+And the following is from a local SSD run:
+
+Idling iops avg-lat(ms) stddev bw
+------------------------------------------------------
+ On 19320 33.043 14.068 77281KB/s
+ Off 21626 29.465 12.662 86507KB/s
+
+fio --name=temp --size=5G --time_based --ioengine=libaio \
+ --randrepeat=0 --direct=1 --invalidate=1 --verify=0 \
+ --verify_fatal=0 --rw=randread --blocksize=4k --group_reporting=1 \
+ --filename=/fio_data --runtime=10 --iodepth=64 --numjobs=10
+
+Reviewed-by: Nauman Rafique
+Signed-off-by: Tahsin Erdogan
+Signed-off-by: Jens Axboe
+
+diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
+index 5da8e6e..402be01 100644
+--- a/block/cfq-iosched.c
++++ b/block/cfq-iosched.c
+@@ -4460,7 +4460,7 @@ static int cfq_init_queue(struct request_queue *q, struct elevator_type *e)
+ cfqd->cfq_slice[1] = cfq_slice_sync;
+ cfqd->cfq_target_latency = cfq_target_latency;
+ cfqd->cfq_slice_async_rq = cfq_slice_async_rq;
+- cfqd->cfq_slice_idle = cfq_slice_idle;
++ cfqd->cfq_slice_idle = blk_queue_nonrot(q) ? 0 : cfq_slice_idle;
+ cfqd->cfq_group_idle = cfq_group_idle;
+ cfqd->cfq_latency = 1;
+ cfqd->hw_tag = -1;
+--
+cgit v0.10.2
+
diff --git a/kernel/kernel/files/patches/mageia/block-cfq-iosched-fix-the-setting-of-IOPS-mode-on-SSDs.patch b/kernel/kernel/files/patches/mageia/block-cfq-iosched-fix-the-setting-of-IOPS-mode-on-SSDs.patch
new file mode 100644
index 00000000..7d188d69
--- /dev/null
+++ b/kernel/kernel/files/patches/mageia/block-cfq-iosched-fix-the-setting-of-IOPS-mode-on-SSDs.patch
@@ -0,0 +1,95 @@
+From 0bb979472a7401022109e81dd89d777adea58710 Mon Sep 17 00:00:00 2001
+From: Jens Axboe
+Date: Wed, 10 Jun 2015 08:01:20 -0600
+Subject: cfq-iosched: fix the setting of IOPS mode on SSDs
+
+A previous commit wanted to make CFQ default to IOPS mode on
+non-rotational storage, however it did so when the queue was
+initialized and the non-rotational flag is only set later on
+in the probe.
+
+Add an elevator hook that gets called off the add_disk() path,
+at that point we know that feature probing has finished, and
+we can reliably check for the various flags that drivers can
+set.
+
+Fixes: 41c0126b ("block: Make CFQ default to IOPS mode on SSDs")
+Tested-by: Romain Francoise
+Signed-off-by: Jens Axboe
+
+diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
+index c808ad8..d1d0cb2 100644
+--- a/block/cfq-iosched.c
++++ b/block/cfq-iosched.c
+@@ -4508,7 +4508,7 @@ static int cfq_init_queue(struct request_queue *q, struct elevator_type *e)
+ cfqd->cfq_slice[1] = cfq_slice_sync;
+ cfqd->cfq_target_latency = cfq_target_latency;
+ cfqd->cfq_slice_async_rq = cfq_slice_async_rq;
+- cfqd->cfq_slice_idle = blk_queue_nonrot(q) ? 0 : cfq_slice_idle;
++ cfqd->cfq_slice_idle = cfq_slice_idle;
+ cfqd->cfq_group_idle = cfq_group_idle;
+ cfqd->cfq_latency = 1;
+ cfqd->hw_tag = -1;
+@@ -4525,6 +4525,18 @@ out_free:
+ return ret;
+ }
+
++static void cfq_registered_queue(struct request_queue *q)
++{
++ struct elevator_queue *e = q->elevator;
++ struct cfq_data *cfqd = e->elevator_data;
++
++ /*
++ * Default to IOPS mode with no idling for SSDs
++ */
++ if (blk_queue_nonrot(q))
++ cfqd->cfq_slice_idle = 0;
++}
++
+ /*
+ * sysfs parts below -->
+ */
+@@ -4640,6 +4652,7 @@ static struct elevator_type iosched_cfq = {
+ .elevator_may_queue_fn = cfq_may_queue,
+ .elevator_init_fn = cfq_init_queue,
+ .elevator_exit_fn = cfq_exit_queue,
++ .elevator_registered_fn = cfq_registered_queue,
+ },
+ .icq_size = sizeof(struct cfq_io_cq),
+ .icq_align = __alignof__(struct cfq_io_cq),
+diff --git a/block/elevator.c b/block/elevator.c
+index 59794d0..5f04527 100644
+--- a/block/elevator.c
++++ b/block/elevator.c
+@@ -810,6 +810,8 @@ int elv_register_queue(struct request_queue *q)
+ }
+ kobject_uevent(&e->kobj, KOBJ_ADD);
+ e->registered = 1;
++ if (e->type->ops.elevator_registered_fn)
++ e->type->ops.elevator_registered_fn(q);
+ }
+ return error;
+ }
+diff --git a/include/linux/elevator.h b/include/linux/elevator.h
+index 45a9147..638b324 100644
+--- a/include/linux/elevator.h
++++ b/include/linux/elevator.h
+@@ -39,6 +39,7 @@ typedef void (elevator_deactivate_req_fn) (struct request_queue *, struct reques
+ typedef int (elevator_init_fn) (struct request_queue *,
+ struct elevator_type *e);
+ typedef void (elevator_exit_fn) (struct elevator_queue *);
++typedef void (elevator_registered_fn) (struct request_queue *);
+
+ struct elevator_ops
+ {
+@@ -68,6 +69,7 @@ struct elevator_ops
+
+ elevator_init_fn *elevator_init_fn;
+ elevator_exit_fn *elevator_exit_fn;
++ elevator_registered_fn *elevator_registered_fn;
+ };
+
+ #define ELV_NAME_MAX (16)
+--
+cgit v0.10.2
+
diff --git a/kernel/kernel/files/patches/mageia/bluetooth-hci_usb-disable-isoc-transfers.patch b/kernel/kernel/files/patches/mageia/bluetooth-hci_usb-disable-isoc-transfers.patch
deleted file mode 100644
index 34ced55d..00000000
--- a/kernel/kernel/files/patches/mageia/bluetooth-hci_usb-disable-isoc-transfers.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-Add quirk to disable ISOC transfers for device
-"ID 1131:1001 Integrated System Solution Corp. KY-BT100 Bluetooth Adapter"
-http://qa.mandriva.com/show_bug.cgi?id=30638
-
-Signed-off-by: Herton Ronaldo Krzesinski
----
- drivers/bluetooth/btusb.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-(status: submitted upstream to bluez-devel ML on 2007-09-29)
-
---- linux-2.6.28/drivers/bluetooth/btusb.c.orig 2009-02-11 10:29:20.000000000 -0500
-+++ linux-2.6.28/drivers/bluetooth/btusb.c 2009-02-11 10:30:27.000000000 -0500
-@@ -120,6 +120,9 @@ static struct usb_device_id blacklist_ta
- /* Kensington Bluetooth USB adapter */
- { USB_DEVICE(0x047d, 0x105e), .driver_info = BTUSB_WRONG_SCO_MTU },
-
-+ /* ISSC Bluetooth Adapter v3.1 */
-+ { USB_DEVICE(0x1131, 0x1001), .driver_info = BTUSB_BROKEN_ISOC },
-+
- /* RTX Telecom based adapters with buggy SCO support */
- { USB_DEVICE(0x0400, 0x0807), .driver_info = BTUSB_BROKEN_ISOC },
- { USB_DEVICE(0x0400, 0x080a), .driver_info = BTUSB_BROKEN_ISOC },
diff --git a/kernel/kernel/files/patches/mageia/firmware-efi-Fix-error-handling-in-add_sysfs_runtime_map_entr.patch b/kernel/kernel/files/patches/mageia/firmware-efi-Fix-error-handling-in-add_sysfs_runtime_map_entr.patch
deleted file mode 100644
index ae1c331d..00000000
--- a/kernel/kernel/files/patches/mageia/firmware-efi-Fix-error-handling-in-add_sysfs_runtime_map_entr.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From d67e199611b986b345ea3087ee2e4a15da1c98b3 Mon Sep 17 00:00:00 2001
-From: Dan Carpenter
-Date: Tue, 21 Apr 2015 16:46:28 +0300
-Subject: [PATCH] efi: Fix error handling in add_sysfs_runtime_map_entry()
-
-I spotted two (difficult to hit) bugs while reviewing this.
-
-1) There is a double free bug because we unregister "map_kset" in
- add_sysfs_runtime_map_entry() and also efi_runtime_map_init().
-2) If we fail to allocate "entry" then we should return
- ERR_PTR(-ENOMEM) instead of NULL.
-
-Signed-off-by: Dan Carpenter
-Cc: Dave Young
-Cc: Guangyu Sun
-Cc:
-Signed-off-by: Matt Fleming
----
- drivers/firmware/efi/runtime-map.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/drivers/firmware/efi/runtime-map.c b/drivers/firmware/efi/runtime-map.c
-index 87b8e3b..5c55227 100644
---- a/drivers/firmware/efi/runtime-map.c
-+++ b/drivers/firmware/efi/runtime-map.c
-@@ -120,7 +120,8 @@ add_sysfs_runtime_map_entry(struct kobject *kobj, int nr)
- entry = kzalloc(sizeof(*entry), GFP_KERNEL);
- if (!entry) {
- kset_unregister(map_kset);
-- return entry;
-+ map_kset = NULL;
-+ return ERR_PTR(-ENOMEM);
- }
-
- memcpy(&entry->md, efi_runtime_map + nr * efi_memdesc_size,
-@@ -132,6 +133,7 @@ add_sysfs_runtime_map_entry(struct kobject *kobj, int nr)
- if (ret) {
- kobject_put(&entry->kobj);
- kset_unregister(map_kset);
-+ map_kset = NULL;
- return ERR_PTR(ret);
- }
-
-@@ -195,8 +197,6 @@ out_add_entry:
- entry = *(map_entries + j);
- kobject_put(&entry->kobj);
- }
-- if (map_kset)
-- kset_unregister(map_kset);
- out:
- return ret;
- }
---
-2.3.2
-
diff --git a/kernel/kernel/files/patches/mageia/fs-aufs-3.19-modular.patch b/kernel/kernel/files/patches/mageia/fs-aufs4-modular.patch
similarity index 55%
rename from kernel/kernel/files/patches/mageia/fs-aufs-3.19-modular.patch
rename to kernel/kernel/files/patches/mageia/fs-aufs4-modular.patch
index d172ebbc..c1fa58a0 100644
--- a/kernel/kernel/files/patches/mageia/fs-aufs-3.19-modular.patch
+++ b/kernel/kernel/files/patches/mageia/fs-aufs4-modular.patch
@@ -1,20 +1,22 @@
fs/aufs/Kconfig | 2 +-
fs/dcache.c | 1 +
+ fs/file_table.c | 2 ++
fs/inode.c | 2 ++
fs/namespace.c | 2 ++
fs/notify/group.c | 4 ++++
fs/notify/mark.c | 4 ++++
- fs/open.c | 1 +
+ fs/open.c | 2 ++
+ fs/read_write.c | 2 ++
fs/splice.c | 2 ++
security/commoncap.c | 2 ++
security/device_cgroup.c | 2 ++
security/security.c | 10 ++++++++++
- 11 files changed, 31 insertions(+), 1 deletion(-)
+ 13 files changed, 36 insertions(+), 1 deletion(-)
-diff -Nurp linux-3.19-aufs/fs/aufs/Kconfig linux-3.19-aufs-modular/fs/aufs/Kconfig
---- linux-3.19-aufs/fs/aufs/Kconfig 2015-02-22 23:16:18.302926737 +0200
-+++ linux-3.19-aufs-modular/fs/aufs/Kconfig 2015-02-22 23:23:41.617919334 +0200
+diff -Nurp linux-4.1-aufs4/fs/aufs/Kconfig linux-4.1-aufs4-mod/fs/aufs/Kconfig
+--- linux-4.1-aufs4/fs/aufs/Kconfig 2015-06-25 20:09:18.250319377 +0200
++++ linux-4.1-aufs4-mod/fs/aufs/Kconfig 2015-06-25 20:11:30.629136790 +0200
@@ -1,5 +1,5 @@
config AUFS_FS
- bool "Aufs (Advanced multi layered unification filesystem) support"
@@ -22,10 +24,10 @@ diff -Nurp linux-3.19-aufs/fs/aufs/Kconfig linux-3.19-aufs-modular/fs/aufs/Kconf
help
Aufs is a stackable unification filesystem such as Unionfs,
which unifies several directories and provides a merged single
-diff -Nurp linux-3.19-aufs/fs/dcache.c linux-3.19-aufs-modular/fs/dcache.c
---- linux-3.19-aufs/fs/dcache.c 2015-02-22 23:16:18.313926786 +0200
-+++ linux-3.19-aufs-modular/fs/dcache.c 2015-02-22 23:23:41.620919348 +0200
-@@ -1124,6 +1124,7 @@ rename_retry:
+diff -Nurp linux-4.1-aufs4/fs/dcache.c linux-4.1-aufs4-mod/fs/dcache.c
+--- linux-4.1-aufs4/fs/dcache.c 2015-06-25 20:09:18.280319109 +0200
++++ linux-4.1-aufs4-mod/fs/dcache.c 2015-06-25 20:11:30.629136790 +0200
+@@ -1269,6 +1269,7 @@ rename_retry:
seq = 1;
goto again;
}
@@ -33,10 +35,29 @@ diff -Nurp linux-3.19-aufs/fs/dcache.c linux-3.19-aufs-modular/fs/dcache.c
/*
* Search for at least 1 mount point in the dentry's subdirs.
-diff -Nurp linux-3.19-aufs/fs/inode.c linux-3.19-aufs-modular/fs/inode.c
---- linux-3.19-aufs/fs/inode.c 2015-02-22 23:16:18.314926790 +0200
-+++ linux-3.19-aufs-modular/fs/inode.c 2015-02-22 23:23:41.617919334 +0200
-@@ -57,6 +57,7 @@ static struct hlist_head *inode_hashtabl
+diff -Nurp linux-4.1-aufs4/fs/file_table.c linux-4.1-aufs4-mod/fs/file_table.c
+--- linux-4.1-aufs4/fs/file_table.c 2015-06-22 07:05:43.000000000 +0200
++++ linux-4.1-aufs4-mod/fs/file_table.c 2015-06-25 23:47:57.011958835 +0200
+@@ -147,6 +147,7 @@ over:
+ }
+ return ERR_PTR(-ENFILE);
+ }
++EXPORT_SYMBOL(get_empty_filp);
+
+ /**
+ * alloc_file - allocate and initialize a 'struct file'
+@@ -308,6 +309,7 @@ void put_filp(struct file *file)
+ file_free(file);
+ }
+ }
++EXPORT_SYMBOL(put_filp);
+
+ void __init files_init(unsigned long mempages)
+ {
+diff -Nurp linux-4.1-aufs4/fs/inode.c linux-4.1-aufs4-mod/fs/inode.c
+--- linux-4.1-aufs4/fs/inode.c 2015-06-22 07:05:43.000000000 +0200
++++ linux-4.1-aufs4-mod/fs/inode.c 2015-06-25 22:45:45.000000000 +0200
+@@ -58,6 +58,7 @@ static struct hlist_head *inode_hashtabl
static __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_hash_lock);
__cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_sb_list_lock);
@@ -44,18 +65,18 @@ diff -Nurp linux-3.19-aufs/fs/inode.c linux-3.19-aufs-modular/fs/inode.c
/*
* Empty aops. Can be used for the cases where the user does not
-@@ -1515,6 +1516,7 @@ int update_time(struct inode *inode, str
- mark_inode_dirty_sync(inode);
- return 0;
+@@ -1575,6 +1576,7 @@ static int update_time(struct inode *ino
+
+ return update_time(inode, time, flags);
}
+EXPORT_SYMBOL(update_time);
/**
* touch_atime - update the access time
-diff -Nurp linux-3.19-aufs/fs/namespace.c linux-3.19-aufs-modular/fs/namespace.c
---- linux-3.19-aufs/fs/namespace.c 2015-02-09 04:54:22.000000000 +0200
-+++ linux-3.19-aufs-modular/fs/namespace.c 2015-02-22 23:23:41.618919339 +0200
-@@ -454,6 +454,7 @@ void __mnt_drop_write(struct vfsmount *m
+diff -Nurp linux-4.1-aufs4/fs/namespace.c linux-4.1-aufs4-mod/fs/namespace.c
+--- linux-4.1-aufs4/fs/namespace.c 2015-06-22 07:05:43.000000000 +0200
++++ linux-4.1-aufs4-mod/fs/namespace.c 2015-06-25 20:11:30.629136790 +0200
+@@ -463,6 +463,7 @@ void __mnt_drop_write(struct vfsmount *m
mnt_dec_writers(real_mount(mnt));
preempt_enable();
}
@@ -63,7 +84,7 @@ diff -Nurp linux-3.19-aufs/fs/namespace.c linux-3.19-aufs-modular/fs/namespace.c
/**
* mnt_drop_write - give up write access to a mount
-@@ -1728,6 +1729,7 @@ int iterate_mounts(int (*f)(struct vfsmo
+@@ -1768,6 +1769,7 @@ int iterate_mounts(int (*f)(struct vfsmo
}
return 0;
}
@@ -71,9 +92,9 @@ diff -Nurp linux-3.19-aufs/fs/namespace.c linux-3.19-aufs-modular/fs/namespace.c
static void cleanup_group_ids(struct mount *mnt, struct mount *end)
{
-diff -Nurp linux-3.19-aufs/fs/notify/group.c linux-3.19-aufs-modular/fs/notify/group.c
---- linux-3.19-aufs/fs/notify/group.c 2015-02-09 04:54:22.000000000 +0200
-+++ linux-3.19-aufs-modular/fs/notify/group.c 2015-02-22 23:23:41.618919339 +0200
+diff -Nurp linux-4.1-aufs4/fs/notify/group.c linux-4.1-aufs4-mod/fs/notify/group.c
+--- linux-4.1-aufs4/fs/notify/group.c 2015-06-22 07:05:43.000000000 +0200
++++ linux-4.1-aufs4-mod/fs/notify/group.c 2015-06-25 20:11:30.629136790 +0200
@@ -22,6 +22,7 @@
#include
#include
@@ -106,9 +127,9 @@ diff -Nurp linux-3.19-aufs/fs/notify/group.c linux-3.19-aufs-modular/fs/notify/g
int fsnotify_fasync(int fd, struct file *file, int on)
{
-diff -Nurp linux-3.19-aufs/fs/notify/mark.c linux-3.19-aufs-modular/fs/notify/mark.c
---- linux-3.19-aufs/fs/notify/mark.c 2015-02-09 04:54:22.000000000 +0200
-+++ linux-3.19-aufs-modular/fs/notify/mark.c 2015-02-22 23:23:41.618919339 +0200
+diff -Nurp linux-4.1-aufs4/fs/notify/mark.c linux-4.1-aufs4-mod/fs/notify/mark.c
+--- linux-4.1-aufs4/fs/notify/mark.c 2015-06-22 07:05:43.000000000 +0200
++++ linux-4.1-aufs4-mod/fs/notify/mark.c 2015-06-25 20:11:30.629136790 +0200
@@ -109,6 +109,7 @@ void fsnotify_put_mark(struct fsnotify_m
mark->free_mark(mark);
}
@@ -141,9 +162,9 @@ diff -Nurp linux-3.19-aufs/fs/notify/mark.c linux-3.19-aufs-modular/fs/notify/ma
static int fsnotify_mark_destroy(void *ignored)
{
-diff -Nurp linux-3.19-aufs/fs/open.c linux-3.19-aufs-modular/fs/open.c
---- linux-3.19-aufs/fs/open.c 2015-02-09 04:54:22.000000000 +0200
-+++ linux-3.19-aufs-modular/fs/open.c 2015-02-22 23:23:41.618919339 +0200
+diff -Nurp linux-4.1-aufs4/fs/open.c linux-4.1-aufs4-mod/fs/open.c
+--- linux-4.1-aufs4/fs/open.c 2015-06-22 07:05:43.000000000 +0200
++++ linux-4.1-aufs4-mod/fs/open.c 2015-06-25 23:49:02.741362661 +0200
@@ -62,6 +62,7 @@ int do_truncate(struct dentry *dentry, l
mutex_unlock(&dentry->d_inode->i_mutex);
return ret;
@@ -152,10 +173,37 @@ diff -Nurp linux-3.19-aufs/fs/open.c linux-3.19-aufs-modular/fs/open.c
long vfs_truncate(struct path *path, loff_t length)
{
-diff -Nurp linux-3.19-aufs/fs/splice.c linux-3.19-aufs-modular/fs/splice.c
---- linux-3.19-aufs/fs/splice.c 2015-02-22 23:16:18.315926795 +0200
-+++ linux-3.19-aufs-modular/fs/splice.c 2015-02-22 23:23:41.619919343 +0200
-@@ -1127,6 +1127,7 @@ long do_splice_from(struct pipe_inode_in
+@@ -676,6 +677,7 @@ int open_check_o_direct(struct file *f)
+ }
+ return 0;
+ }
++EXPORT_SYMBOL(open_check_o_direct);
+
+ static int do_dentry_open(struct file *f,
+ int (*open)(struct inode *, struct file *),
+diff -Nurp linux-4.1-aufs4/fs/read_write.c linux-4.1-aufs4-mod/fs/read_write.c
+--- linux-4.1-aufs4/fs/read_write.c 2015-06-25 20:09:18.280319109 +0200
++++ linux-4.1-aufs4-mod/fs/read_write.c 2015-06-25 23:43:56.804138140 +0200
+@@ -504,6 +504,7 @@ vfs_readf_t vfs_readf(struct file *file)
+ return new_sync_read;
+ return ERR_PTR(-ENOSYS);
+ }
++EXPORT_SYMBOL(vfs_readf);
+
+ vfs_writef_t vfs_writef(struct file *file)
+ {
+@@ -515,6 +516,7 @@ vfs_writef_t vfs_writef(struct file *fil
+ return new_sync_write;
+ return ERR_PTR(-ENOSYS);
+ }
++EXPORT_SYMBOL(vfs_writef);
+
+ ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos)
+ {
+diff -Nurp linux-4.1-aufs4/fs/splice.c linux-4.1-aufs4-mod/fs/splice.c
+--- linux-4.1-aufs4/fs/splice.c 2015-06-25 20:09:18.280319109 +0200
++++ linux-4.1-aufs4-mod/fs/splice.c 2015-06-25 20:11:30.629136790 +0200
+@@ -1114,6 +1114,7 @@ long do_splice_from(struct pipe_inode_in
return splice_write(pipe, out, ppos, len, flags);
}
@@ -163,7 +211,7 @@ diff -Nurp linux-3.19-aufs/fs/splice.c linux-3.19-aufs-modular/fs/splice.c
/*
* Attempt to initiate a splice from a file to a pipe.
-@@ -1153,6 +1154,7 @@ long do_splice_to(struct file *in, loff_
+@@ -1140,6 +1141,7 @@ long do_splice_to(struct file *in, loff_
return splice_read(in, ppos, pipe, len, flags);
}
@@ -171,10 +219,10 @@ diff -Nurp linux-3.19-aufs/fs/splice.c linux-3.19-aufs-modular/fs/splice.c
/**
* splice_direct_to_actor - splices data directly between two non-pipes
-diff -Nurp linux-3.19-aufs/security/commoncap.c linux-3.19-aufs-modular/security/commoncap.c
---- linux-3.19-aufs/security/commoncap.c 2015-02-09 04:54:22.000000000 +0200
-+++ linux-3.19-aufs-modular/security/commoncap.c 2015-02-22 23:23:41.619919343 +0200
-@@ -979,9 +979,11 @@ int cap_mmap_addr(unsigned long addr)
+diff -Nurp linux-4.1-aufs4/security/commoncap.c linux-4.1-aufs4-mod/security/commoncap.c
+--- linux-4.1-aufs4/security/commoncap.c 2015-06-22 07:05:43.000000000 +0200
++++ linux-4.1-aufs4-mod/security/commoncap.c 2015-06-25 20:11:30.629136790 +0200
+@@ -975,9 +975,11 @@ int cap_mmap_addr(unsigned long addr)
}
return ret;
}
@@ -186,9 +234,9 @@ diff -Nurp linux-3.19-aufs/security/commoncap.c linux-3.19-aufs-modular/security
return 0;
}
+EXPORT_SYMBOL(cap_mmap_file);
-diff -Nurp linux-3.19-aufs/security/device_cgroup.c linux-3.19-aufs-modular/security/device_cgroup.c
---- linux-3.19-aufs/security/device_cgroup.c 2015-02-09 04:54:22.000000000 +0200
-+++ linux-3.19-aufs-modular/security/device_cgroup.c 2015-02-22 23:23:41.619919343 +0200
+diff -Nurp linux-4.1-aufs4/security/device_cgroup.c linux-4.1-aufs4-mod/security/device_cgroup.c
+--- linux-4.1-aufs4/security/device_cgroup.c 2015-06-22 07:05:43.000000000 +0200
++++ linux-4.1-aufs4-mod/security/device_cgroup.c 2015-06-25 20:11:30.629136790 +0200
@@ -7,6 +7,7 @@
#include
#include
@@ -205,10 +253,10 @@ diff -Nurp linux-3.19-aufs/security/device_cgroup.c linux-3.19-aufs-modular/secu
int devcgroup_inode_mknod(int mode, dev_t dev)
{
-diff -Nurp linux-3.19-aufs/security/security.c linux-3.19-aufs-modular/security/security.c
---- linux-3.19-aufs/security/security.c 2015-02-09 04:54:22.000000000 +0200
-+++ linux-3.19-aufs-modular/security/security.c 2015-02-22 23:23:41.619919343 +0200
-@@ -407,6 +407,7 @@ int security_path_rmdir(struct path *dir
+diff -Nurp linux-4.1-aufs4/security/security.c linux-4.1-aufs4-mod/security/security.c
+--- linux-4.1-aufs4/security/security.c 2015-06-22 07:05:43.000000000 +0200
++++ linux-4.1-aufs4-mod/security/security.c 2015-06-25 20:11:30.629136790 +0200
+@@ -430,6 +430,7 @@ int security_path_rmdir(struct path *dir
return 0;
return security_ops->path_rmdir(dir, dentry);
}
@@ -216,7 +264,7 @@ diff -Nurp linux-3.19-aufs/security/security.c linux-3.19-aufs-modular/security/
int security_path_unlink(struct path *dir, struct dentry *dentry)
{
-@@ -423,6 +424,7 @@ int security_path_symlink(struct path *d
+@@ -446,6 +447,7 @@ int security_path_symlink(struct path *d
return 0;
return security_ops->path_symlink(dir, dentry, old_name);
}
@@ -224,7 +272,7 @@ diff -Nurp linux-3.19-aufs/security/security.c linux-3.19-aufs-modular/security/
int security_path_link(struct dentry *old_dentry, struct path *new_dir,
struct dentry *new_dentry)
-@@ -431,6 +433,7 @@ int security_path_link(struct dentry *ol
+@@ -454,6 +456,7 @@ int security_path_link(struct dentry *ol
return 0;
return security_ops->path_link(old_dentry, new_dir, new_dentry);
}
@@ -232,7 +280,7 @@ diff -Nurp linux-3.19-aufs/security/security.c linux-3.19-aufs-modular/security/
int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
struct path *new_dir, struct dentry *new_dentry,
-@@ -458,6 +461,7 @@ int security_path_truncate(struct path *
+@@ -481,6 +484,7 @@ int security_path_truncate(struct path *
return 0;
return security_ops->path_truncate(path);
}
@@ -240,7 +288,7 @@ diff -Nurp linux-3.19-aufs/security/security.c linux-3.19-aufs-modular/security/
int security_path_chmod(struct path *path, umode_t mode)
{
-@@ -465,6 +469,7 @@ int security_path_chmod(struct path *pat
+@@ -488,6 +492,7 @@ int security_path_chmod(struct path *pat
return 0;
return security_ops->path_chmod(path, mode);
}
@@ -248,7 +296,7 @@ diff -Nurp linux-3.19-aufs/security/security.c linux-3.19-aufs-modular/security/
int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
{
-@@ -472,6 +477,7 @@ int security_path_chown(struct path *pat
+@@ -495,6 +500,7 @@ int security_path_chown(struct path *pat
return 0;
return security_ops->path_chown(path, uid, gid);
}
@@ -256,7 +304,7 @@ diff -Nurp linux-3.19-aufs/security/security.c linux-3.19-aufs-modular/security/
int security_path_chroot(struct path *path)
{
-@@ -557,6 +563,7 @@ int security_inode_readlink(struct dentr
+@@ -580,6 +586,7 @@ int security_inode_readlink(struct dentr
return 0;
return security_ops->inode_readlink(dentry);
}
@@ -264,7 +312,7 @@ diff -Nurp linux-3.19-aufs/security/security.c linux-3.19-aufs-modular/security/
int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd)
{
-@@ -571,6 +578,7 @@ int security_inode_permission(struct ino
+@@ -594,6 +601,7 @@ int security_inode_permission(struct ino
return 0;
return security_ops->inode_permission(inode, mask);
}
@@ -272,7 +320,7 @@ diff -Nurp linux-3.19-aufs/security/security.c linux-3.19-aufs-modular/security/
int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
{
-@@ -693,6 +701,7 @@ int security_file_permission(struct file
+@@ -716,6 +724,7 @@ int security_file_permission(struct file
return fsnotify_perm(file, mask);
}
@@ -280,7 +328,7 @@ diff -Nurp linux-3.19-aufs/security/security.c linux-3.19-aufs-modular/security/
int security_file_alloc(struct file *file)
{
-@@ -753,6 +762,7 @@ int security_mmap_file(struct file *file
+@@ -775,6 +784,7 @@ int security_mmap_file(struct file *file
return ret;
return ima_file_mmap(file, prot);
}
diff --git a/kernel/kernel/files/patches/mageia/fs-aufs-3.19.patch b/kernel/kernel/files/patches/mageia/fs-aufs4.patch
similarity index 93%
rename from kernel/kernel/files/patches/mageia/fs-aufs-3.19.patch
rename to kernel/kernel/files/patches/mageia/fs-aufs4.patch
index 858eaefb..0025b6e6 100644
--- a/kernel/kernel/files/patches/mageia/fs-aufs-3.19.patch
+++ b/kernel/kernel/files/patches/mageia/fs-aufs4.patch
@@ -1,102 +1,103 @@
Documentation/ABI/testing/debugfs-aufs | 50 +
Documentation/ABI/testing/sysfs-aufs | 31 +
- Documentation/filesystems/aufs/README | 389 +++++
- Documentation/filesystems/aufs/design/01intro.txt | 148 ++
- Documentation/filesystems/aufs/design/02struct.txt | 238 +++
- Documentation/filesystems/aufs/design/03lookup.txt | 120 ++
- Documentation/filesystems/aufs/design/04branch.txt | 62 +
+ Documentation/filesystems/aufs/README | 383 ++++
+ Documentation/filesystems/aufs/design/01intro.txt | 157 ++
+ Documentation/filesystems/aufs/design/02struct.txt | 245 +++
+ .../filesystems/aufs/design/03atomic_open.txt | 72 +
+ Documentation/filesystems/aufs/design/03lookup.txt | 100 ++
+ Documentation/filesystems/aufs/design/04branch.txt | 61 +
.../filesystems/aufs/design/05wbr_policy.txt | 51 +
Documentation/filesystems/aufs/design/06fhsm.txt | 105 ++
- Documentation/filesystems/aufs/design/06mmap.txt | 33 +
+ Documentation/filesystems/aufs/design/06mmap.txt | 59 +
Documentation/filesystems/aufs/design/06xattr.txt | 81 +
Documentation/filesystems/aufs/design/07export.txt | 45 +
Documentation/filesystems/aufs/design/08shwh.txt | 39 +
- Documentation/filesystems/aufs/design/10dynop.txt | 33 +
- Documentation/filesystems/aufs/design/99plan.txt | 45 +
- MAINTAINERS | 14 +
+ Documentation/filesystems/aufs/design/10dynop.txt | 34 +
+ MAINTAINERS | 13 +
drivers/block/loop.c | 18 +
fs/Kconfig | 1 +
fs/Makefile | 1 +
fs/aufs/Kconfig | 185 ++
fs/aufs/Makefile | 36 +
fs/aufs/aufs.h | 46 +
- fs/aufs/branch.c | 1397 +++++++++++++++
- fs/aufs/branch.h | 254 +++
- fs/aufs/cpup.c | 1290 ++++++++++++++
+ fs/aufs/branch.c | 1401 +++++++++++++++
+ fs/aufs/branch.h | 266 +++
+ fs/aufs/cpup.c | 1306 ++++++++++++++
fs/aufs/cpup.h | 81 +
fs/aufs/dbgaufs.c | 419 +++++
fs/aufs/dbgaufs.h | 35 +
fs/aufs/dcsub.c | 211 +++
- fs/aufs/dcsub.h | 112 ++
- fs/aufs/debug.c | 509 ++++++
- fs/aufs/debug.h | 249 +++
- fs/aufs/dentry.c | 1083 ++++++++++++
+ fs/aufs/dcsub.h | 123 ++
+ fs/aufs/debug.c | 427 +++++
+ fs/aufs/debug.h | 212 +++
+ fs/aufs/dentry.c | 1092 ++++++++++++
fs/aufs/dentry.h | 220 +++
- fs/aufs/dinfo.c | 531 ++++++
- fs/aufs/dir.c | 632 +++++++
- fs/aufs/dir.h | 117 ++
- fs/aufs/dynop.c | 366 ++++
- fs/aufs/dynop.h | 62 +
- fs/aufs/export.c | 818 +++++++++
- fs/aufs/f_op.c | 801 +++++++++
+ fs/aufs/dinfo.c | 537 ++++++
+ fs/aufs/dir.c | 740 ++++++++
+ fs/aufs/dir.h | 118 ++
+ fs/aufs/dynop.c | 356 ++++
+ fs/aufs/dynop.h | 61 +
+ fs/aufs/export.c | 819 +++++++++
+ fs/aufs/f_op.c | 725 ++++++++
fs/aufs/fhsm.c | 412 +++++
- fs/aufs/file.c | 816 +++++++++
- fs/aufs/file.h | 271 +++
- fs/aufs/finfo.c | 143 ++
- fs/aufs/fstype.h | 456 +++++
+ fs/aufs/file.c | 828 +++++++++
+ fs/aufs/file.h | 278 +++
+ fs/aufs/finfo.c | 144 ++
+ fs/aufs/fstype.h | 387 +++++
fs/aufs/hfsnotify.c | 275 +++
fs/aufs/hfsplus.c | 43 +
- fs/aufs/hnotify.c | 701 ++++++++
- fs/aufs/i_op.c | 1286 ++++++++++++++
- fs/aufs/i_op_add.c | 878 ++++++++++
- fs/aufs/i_op_del.c | 494 ++++++
- fs/aufs/i_op_ren.c | 1021 +++++++++++
+ fs/aufs/hnotify.c | 697 ++++++++
+ fs/aufs/i_op.c | 1434 +++++++++++++++
+ fs/aufs/i_op_add.c | 919 ++++++++++
+ fs/aufs/i_op_del.c | 497 ++++++
+ fs/aufs/i_op_ren.c | 1004 +++++++++++
fs/aufs/iinfo.c | 264 +++
- fs/aufs/inode.c | 483 +++++
- fs/aufs/inode.h | 654 +++++++
+ fs/aufs/inode.c | 487 ++++++
+ fs/aufs/inode.h | 660 +++++++
fs/aufs/ioctl.c | 206 +++
fs/aufs/loop.c | 132 ++
fs/aufs/loop.h | 39 +
- fs/aufs/magic.mk | 54 +
+ fs/aufs/magic.mk | 30 +
fs/aufs/module.c | 196 +++
fs/aufs/module.h | 91 +
fs/aufs/mvdown.c | 681 ++++++++
- fs/aufs/opts.c | 1837 ++++++++++++++++++++
- fs/aufs/opts.h | 200 +++
- fs/aufs/plink.c | 519 ++++++
- fs/aufs/poll.c | 42 +
+ fs/aufs/opts.c | 1822 ++++++++++++++++++++
+ fs/aufs/opts.h | 197 +++
+ fs/aufs/plink.c | 515 ++++++
+ fs/aufs/poll.c | 39 +
fs/aufs/posix_acl.c | 86 +
fs/aufs/procfs.c | 156 ++
fs/aufs/rdu.c | 375 ++++
fs/aufs/rwsem.h | 178 ++
- fs/aufs/sbinfo.c | 340 ++++
+ fs/aufs/sbinfo.c | 343 ++++
fs/aufs/spl.h | 98 ++
- fs/aufs/super.c | 996 +++++++++++
- fs/aufs/super.h | 628 +++++++
+ fs/aufs/super.c | 991 +++++++++++
+ fs/aufs/super.h | 622 +++++++
fs/aufs/sysaufs.c | 91 +
fs/aufs/sysaufs.h | 88 +
fs/aufs/sysfs.c | 336 ++++
fs/aufs/sysrq.c | 144 ++
- fs/aufs/vdir.c | 876 ++++++++++
- fs/aufs/vfsub.c | 783 +++++++++
- fs/aufs/vfsub.h | 288 +++
+ fs/aufs/vdir.c | 875 ++++++++++
+ fs/aufs/vfsub.c | 835 +++++++++
+ fs/aufs/vfsub.h | 273 +++
fs/aufs/wbr_policy.c | 752 ++++++++
- fs/aufs/whout.c | 1048 +++++++++++
+ fs/aufs/whout.c | 1050 +++++++++++
fs/aufs/whout.h | 72 +
fs/aufs/wkq.c | 200 +++
fs/aufs/wkq.h | 78 +
- fs/aufs/xattr.c | 321 ++++
- fs/aufs/xino.c | 1305 ++++++++++++++
+ fs/aufs/xattr.c | 331 ++++
+ fs/aufs/xino.c | 1284 ++++++++++++++
fs/buffer.c | 2 +-
fs/dcache.c | 2 +-
- fs/inode.c | 2 +-
fs/proc/base.c | 2 +-
fs/proc/nommu.c | 5 +-
fs/proc/task_mmu.c | 7 +-
fs/proc/task_nommu.c | 5 +-
+ fs/read_write.c | 22 +
fs/splice.c | 10 +-
- include/linux/fs.h | 1 +
+ include/linux/file.h | 1 +
+ include/linux/fs.h | 6 +
include/linux/mm.h | 22 +
include/linux/mm_types.h | 2 +
include/linux/splice.h | 6 +
@@ -105,14 +106,13 @@
kernel/fork.c | 2 +-
mm/Makefile | 2 +-
mm/filemap.c | 2 +-
- mm/fremap.c | 16 +-
mm/madvise.c | 4 +-
mm/memory.c | 2 +-
- mm/mmap.c | 12 +-
+ mm/mmap.c | 17 +-
mm/msync.c | 4 +-
mm/nommu.c | 10 +-
mm/prfile.c | 86 +
- 113 files changed, 32970 insertions(+), 34 deletions(-)
+ 113 files changed, 33091 insertions(+), 34 deletions(-)
diff --git a/Documentation/ABI/testing/debugfs-aufs b/Documentation/ABI/testing/debugfs-aufs
new file mode 100644
@@ -209,12 +209,12 @@ index 0000000..82f9518
+ will be empty. About XINO files, see the aufs manual.
diff --git a/Documentation/filesystems/aufs/README b/Documentation/filesystems/aufs/README
new file mode 100644
-index 0000000..b81588a
+index 0000000..27faa06f
--- /dev/null
+++ b/Documentation/filesystems/aufs/README
-@@ -0,0 +1,389 @@
+@@ -0,0 +1,383 @@
+
-+Aufs3 -- advanced multi layered unification filesystem version 3.x
++Aufs4 -- advanced multi layered unification filesystem version 4.x
+http://aufs.sf.net
+Junjiro R. Okajima
+
@@ -222,7 +222,7 @@ index 0000000..b81588a
+0. Introduction
+----------------------------------------
+In the early days, aufs was entirely re-designed and re-implemented
-+Unionfs Version 1.x series. After many original ideas, approaches,
++Unionfs Version 1.x series. Adding many original ideas, approaches,
+improvements and implementations, it becomes totally different from
+Unionfs while keeping the basic features.
+Recently, Unionfs Version 2.x series begin taking some of the same
@@ -230,7 +230,7 @@ index 0000000..b81588a
+Unionfs is being developed by Professor Erez Zadok at Stony Brook
+University and his team.
+
-+Aufs3 supports linux-3.0 and later.
++Aufs4 supports linux-4.0 and later, and for linux-3.x series try aufs3.
+If you want older kernel version support, try aufs2-2.6.git or
+aufs2-standalone.git repository, aufs1 from CVS on SourceForge.
+
@@ -257,7 +257,12 @@ index 0000000..b81588a
+- dynamic branch manipulation, add, del.
+- etc...
+
-+Also there are many enhancements in aufs1, such as:
++Also there are many enhancements in aufs, such as:
++- test only the highest one for the directory permission (dirperm1)
++- copyup on open (coo=)
++- 'move' policy for copy-up between two writable branches, after
++ checking free space.
++- xattr, acl
+- readdir(3) in userspace.
+- keep inode number by external inode number table
+- keep the timestamps of file/dir in internal copyup operation
@@ -287,93 +292,82 @@ index 0000000..b81588a
+- userspace wrapper for pathconf(3)/fpathconf(3) with _PC_LINK_MAX.
+- and more...
+
-+Currently these features are dropped temporary from aufs3.
++Currently these features are dropped temporary from aufs4.
+See design/08plan.txt in detail.
-+- test only the highest one for the directory permission (dirperm1)
-+- copyup on open (coo=)
+- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs
+ (robr)
+- statistics of aufs thread (/sys/fs/aufs/stat)
-+- delegation mode (dlgt)
-+ a delegation of the internal branch access to support task I/O
-+ accounting, which also supports Linux Security Modules (LSM) mainly
-+ for Suse AppArmor.
-+- intent.open/create (file open in a single lookup)
+
+Features or just an idea in the future (see also design/*.txt),
+- reorder the branch index without del/re-add.
+- permanent xino files for NFSD
+- an option for refreshing the opened files after add/del branches
-+- 'move' policy for copy-up between two writable branches, after
-+ checking free space.
+- light version, without branch manipulation. (unnecessary?)
+- copyup in userspace
+- inotify in userspace
+- readv/writev
-+- xattr, acl
+
+
+2. Download
+----------------------------------------
-+There were three GIT trees for aufs3, aufs3-linux.git,
-+aufs3-standalone.git, and aufs-util.git. Note that there is no "3" in
++There are three GIT trees for aufs4, aufs4-linux.git,
++aufs4-standalone.git, and aufs-util.git. Note that there is no "4" in
+"aufs-util.git."
-+While the aufs-util is always necessary, you need either of aufs3-linux
-+or aufs3-standalone.
++While the aufs-util is always necessary, you need either of aufs4-linux
++or aufs4-standalone.
+
-+The aufs3-linux tree includes the whole linux mainline GIT tree,
++The aufs4-linux tree includes the whole linux mainline GIT tree,
+git://git.kernel.org/.../torvalds/linux.git.
+And you cannot select CONFIG_AUFS_FS=m for this version, eg. you cannot
-+build aufs3 as an external kernel module.
++build aufs4 as an external kernel module.
+Several extra patches are not included in this tree. Only
-+aufs3-standalong tree contains them. They are describe in the later
++aufs4-standalone tree contains them. They are describe in the later
+section "Configuration and Compilation."
+
-+On the other hand, the aufs3-standalone tree has only aufs source files
++On the other hand, the aufs4-standalone tree has only aufs source files
+and necessary patches, and you can select CONFIG_AUFS_FS=m.
+But you need to apply all aufs patches manually.
+
-+You will find GIT branches whose name is in form of "aufs3.x" where "x"
-+represents the linux kernel version, "linux-3.x". For instance,
-+"aufs3.0" is for linux-3.0. For latest "linux-3.x-rcN", use
-+"aufs3.x-rcN" branch.
++You will find GIT branches whose name is in form of "aufs4.x" where "x"
++represents the linux kernel version, "linux-4.x". For instance,
++"aufs4.0" is for linux-4.0. For latest "linux-4.x-rcN", use
++"aufs4.x-rcN" branch.
+
-+o aufs3-linux tree
++o aufs4-linux tree
+$ git clone --reference /your/linux/git/tree \
-+ git://git.code.sf.net/p/aufs/aufs3-linux aufs3-linux.git
++ git://github.com/sfjro/aufs4-linux.git aufs4-linux.git
+- if you don't have linux GIT tree, then remove "--reference ..."
-+$ cd aufs3-linux.git
-+$ git checkout origin/aufs3.0
++$ cd aufs4-linux.git
++$ git checkout origin/aufs4.0
+
+Or You may want to directly git-pull aufs into your linux GIT tree, and
+leave the patch-work to GIT.
+$ cd /your/linux/git/tree
-+$ git remote add aufs3 https://github.com/sfjro/aufs3-linux.git
-+- aufs3-linux.git tree also exists on github.
-+$ git fetch aufs3
-+$ git checkout -b my3.14 v3.14
-+$ (add your change...)
-+$ git pull aufs3 aufs3.14
-+- now you have v3.14 + your_changes + aufs3.14 in you my3.14 branch.
++$ git remote add aufs4 git://github.com/sfjro/aufs4-linux.git
++$ git fetch aufs4
++$ git checkout -b my4.0 v4.0
++$ (add your local change...)
++$ git pull aufs4 aufs4.0
++- now you have v4.0 + your_changes + aufs4.0 in you my4.0 branch.
+- you may need to solve some conflicts between your_changes and
-+ aufs3.14. in this case, git-rerere is recommended so that you can
-+ solve the similar confilicts automatically when you upgrade to 3.15 or
++ aufs4.0. in this case, git-rerere is recommended so that you can
++ solve the similar conflicts automatically when you upgrade to 4.1 or
+ later in the future.
+
-+o aufs3-standalone tree
-+$ git clone git://git.code.sf.net/p/aufs/aufs3-standalone \
-+ aufs3-standalone.git
-+$ cd aufs3-standalone.git
-+$ git checkout origin/aufs3.0
++o aufs4-standalone tree
++$ git clone git://github.com/sfjro/aufs4-standalone.git aufs4-standalone.git
++$ cd aufs4-standalone.git
++$ git checkout origin/aufs4.0
+
+o aufs-util tree
-+$ git clone git://git.code.sf.net/p/aufs/aufs-util \
-+ aufs-util.git
++$ git clone git://git.code.sf.net/p/aufs/aufs-util aufs-util.git
++- note that the public aufs-util.git is on SourceForge instead of
++ GitHUB.
+$ cd aufs-util.git
-+$ git checkout origin/aufs3.0
++$ git checkout origin/aufs4.0
+
-+Note: The 3.x-rcN branch is to be used with `rc' kernel versions ONLY.
-+The minor version number, 'x' in '3.x', of aufs may not always
++Note: The 4.x-rcN branch is to be used with `rc' kernel versions ONLY.
++The minor version number, 'x' in '4.x', of aufs may not always
+follow the minor version number of the kernel.
+Because changes in the kernel that cause the use of a new
+minor version number do not always require changes to aufs-util.
@@ -385,8 +379,8 @@ index 0000000..b81588a
+nearest lower number.
+
+For (an unreleased) example:
-+If you are using "linux-3.10" and the "aufs3.10" branch
-+does not exist in aufs-util repository, then "aufs3.9", "aufs3.8"
++If you are using "linux-4.10" and the "aufs4.10" branch
++does not exist in aufs-util repository, then "aufs4.9", "aufs4.8"
+or something numerically smaller is the branch for your kernel.
+
+Also you can view all branches by
@@ -397,19 +391,19 @@ index 0000000..b81588a
+----------------------------------------
+Make sure you have git-checkout'ed the correct branch.
+
-+For aufs3-linux tree,
++For aufs4-linux tree,
+- enable CONFIG_AUFS_FS.
+- set other aufs configurations if necessary.
+
-+For aufs3-standalone tree,
++For aufs4-standalone tree,
+There are several ways to build.
+
+1.
-+- apply ./aufs3-kbuild.patch to your kernel source files.
-+- apply ./aufs3-base.patch too.
-+- apply ./aufs3-mmap.patch too.
-+- apply ./aufs3-standalone.patch too, if you have a plan to set
-+ CONFIG_AUFS_FS=m. otherwise you don't need ./aufs3-standalone.patch.
++- apply ./aufs4-kbuild.patch to your kernel source files.
++- apply ./aufs4-base.patch too.
++- apply ./aufs4-mmap.patch too.
++- apply ./aufs4-standalone.patch too, if you have a plan to set
++ CONFIG_AUFS_FS=m. otherwise you don't need ./aufs4-standalone.patch.
+- copy ./{Documentation,fs,include/uapi/linux/aufs_type.h} files to your
+ kernel source tree. Never copy $PWD/include/uapi/linux/Kbuild.
+- enable CONFIG_AUFS_FS, you can select either
@@ -426,9 +420,9 @@ index 0000000..b81588a
+
+2.
+- module only (CONFIG_AUFS_FS=m).
-+- apply ./aufs3-base.patch to your kernel source files.
-+- apply ./aufs3-mmap.patch too.
-+- apply ./aufs3-standalone.patch too.
++- apply ./aufs4-base.patch to your kernel source files.
++- apply ./aufs4-mmap.patch too.
++- apply ./aufs4-standalone.patch too.
+- build your kernel, don't forget "make headers_install", and reboot.
+- edit ./config.mk and set other aufs configurations if necessary.
+ Note: You should read $PWD/fs/aufs/Kconfig carefully which describes
@@ -447,7 +441,7 @@ index 0000000..b81588a
+ available in aufs standalone version's Makefile only), or copy
+ $PWD/usr/include/linux/aufs_type.h to /usr/include/linux or wherever
+ you like manually. By default, the target directory is $PWD/usr.
-+- no need to apply aufs3-kbuild.patch, nor copying source files to your
++- no need to apply aufs4-kbuild.patch, nor copying source files to your
+ kernel source tree.
+
+Note: The header file aufs_type.h is necessary to build aufs-util
@@ -467,9 +461,9 @@ index 0000000..b81588a
+ then run "make install_ulib" too. And refer to the aufs manual in
+ detail.
+
-+There several other patches in aufs3-standalone.git. They are all
++There several other patches in aufs4-standalone.git. They are all
+optional. When you meet some problems, they will help you.
-+- aufs3-loopback.patch
++- aufs4-loopback.patch
+ Supports a nested loopback mount in a branch-fs. This patch is
+ unnecessary until aufs produces a message like "you may want to try
+ another patch for loopback file".
@@ -604,10 +598,10 @@ index 0000000..b81588a
+# End: ;
diff --git a/Documentation/filesystems/aufs/design/01intro.txt b/Documentation/filesystems/aufs/design/01intro.txt
new file mode 100644
-index 0000000..7f491fb
+index 0000000..02a8c7b
--- /dev/null
+++ b/Documentation/filesystems/aufs/design/01intro.txt
-@@ -0,0 +1,148 @@
+@@ -0,0 +1,157 @@
+
+# Copyright (C) 2005-2015 Junjiro R. Okajima
+
@@ -625,7 +619,7 @@ index 0000000..7f491fb
+- multi layered stackable unification filesystem, the member directory
+ is called as a branch.
+- branch permission and attribute, 'readonly', 'real-readonly',
-+ 'readwrite', 'whiteout-able', 'link-able whiteout' and their
++ 'readwrite', 'whiteout-able', 'link-able whiteout', etc. and their
+ combination.
+- internal "file copy-on-write".
+- logical deletion, whiteout.
@@ -676,11 +670,16 @@ index 0000000..7f491fb
+- unnecessary copy-up may happen, for example mmap(MAP_PRIVATE) after
+ open(O_RDWR).
+
-+Unionfs has a longer history. When I started implementing a stacking filesystem
-+(Aug 2005), it already existed. It has virtual super_block, inode,
-+dentry and file objects and they have an array pointing lower same kind
-+objects. After contributing many patches for Unionfs, I re-started my
-+project AUFS (Jun 2006).
++In linux-3.18, "overlay" filesystem (formerly known as "overlayfs") was
++merged into mainline. This is another implementation of UnionMount as a
++separated filesystem. All the limitations and known problems which
++UnionMount are equally inherited to "overlay" filesystem.
++
++Unionfs has a longer history. When I started implementing a stackable
++filesystem (Aug 2005), it already existed. It has virtual super_block,
++inode, dentry and file objects and they have an array pointing lower
++same kind objects. After contributing many patches for Unionfs, I
++re-started my project AUFS (Jun 2006).
+
+In AUFS, the structure of filesystem resembles to Unionfs, but I
+implemented my own ideas, approaches and enhancements and it became
@@ -702,11 +701,14 @@ index 0000000..7f491fb
+- DM snapshot-merge may help a lot when users try merging. in the
+ fs-layer union, users will use rsync(1).
+
++You may want to read my old paper "Filesystems in LiveCD"
++(http://aufs.sourceforge.net/aufs2/report/sq/sq.pdf).
+
-+Several characters/aspects of aufs
++
++Several characters/aspects/persona of aufs
+----------------------------------------------------------------------
+
-+Aufs has several characters or aspects.
++Aufs has several characters, aspects or persona.
+1. a filesystem, callee of VFS helper
+2. sub-VFS, caller of VFS helper for branches
+3. a virtual filesystem which maintains persistent inode number
@@ -737,10 +739,11 @@ index 0000000..7f491fb
+numbers. This is particularly important to support exporting a
+filesystem via NFS. Aufs is a virtual filesystem which doesn't have a
+backend block device for its own. But some storage is necessary to
-+maintain inode number. It may be a large space and may not suit to keep
-+in memory. Aufs rents some space from its first writable branch
-+filesystem (by default) and creates file(s) on it. These files are
-+created by aufs internally and removed soon (currently) keeping opened.
++keep and maintain the inode numbers. It may be a large space and may not
++suit to keep in memory. Aufs rents some space from its first writable
++branch filesystem (by default) and creates file(s) on it. These files
++are created by aufs internally and removed soon (currently) keeping
++opened.
+Note: Because these files are removed, they are totally gone after
+ unmounting aufs. It means the inode numbers are not persistent
+ across unmount or reboot. I have a plan to make them really
@@ -758,10 +761,10 @@ index 0000000..7f491fb
+about it. But currently I have implemented it in kernel space.
diff --git a/Documentation/filesystems/aufs/design/02struct.txt b/Documentation/filesystems/aufs/design/02struct.txt
new file mode 100644
-index 0000000..f185393
+index 0000000..1a5e5d0
--- /dev/null
+++ b/Documentation/filesystems/aufs/design/02struct.txt
-@@ -0,0 +1,238 @@
+@@ -0,0 +1,245 @@
+
+# Copyright (C) 2005-2015 Junjiro R. Okajima
+
@@ -780,18 +783,18 @@ index 0000000..f185393
+
+Aufs lookup operation finds /ro/fileA and gets dentry for that. These
+pointers are stored in a aufs dentry. The array in aufs dentry will be,
-+- [0] = NULL
++- [0] = NULL (because /rw/fileA doesn't exist)
+- [1] = /ro/fileA
+
+This style of an array is essentially same to the aufs
+superblock/inode/dentry/file objects.
+
+Because aufs supports manipulating branches, ie. add/delete/change
-+dynamically, these objects has its own generation. When branches are
-+changed, the generation in aufs superblock is incremented. And a
-+generation in other object are compared when it is accessed.
-+When a generation in other objects are obsoleted, aufs refreshes the
-+internal array.
++branches dynamically, these objects has its own generation. When
++branches are changed, the generation in aufs superblock is
++incremented. And a generation in other object are compared when it is
++accessed. When a generation in other objects are obsoleted, aufs
++refreshes the internal array.
+
+
+Superblock
@@ -799,8 +802,8 @@ index 0000000..f185393
+Additionally aufs superblock has some data for policies to select one
+among multiple writable branches, XIB files, pseudo-links and kobject.
+See below in detail.
-+About the policies which supports copy-down a directory, see policy.txt
-+too.
++About the policies which supports copy-down a directory, see
++wbr_policy.txt too.
+
+
+Branch and XINO(External Inode Number Translation Table)
@@ -820,13 +823,20 @@ index 0000000..f185393
+might appear. If your branch filesystem consumes disk space for such
+holes, then you should specify 'xino=' option at mounting aufs.
+
++Aufs has a mount option to free the disk blocks for such holes in XINO
++files on tmpfs or ramdisk. But it is not so effective actually. If you
++meet a problem of disk shortage due to XINO files, then you should try
++"tmpfs-ino.patch" (and "vfs-ino.patch" too) in aufs4-standalone.git.
++The patch localizes the assignment inumbers per tmpfs-mount and avoid
++the holes in XINO files.
++
+Also a writable branch has three kinds of "whiteout bases". All these
-+are existed when the branch is joined to aufs and the names are
++are existed when the branch is joined to aufs, and their names are
+whiteout-ed doubly, so that users will never see their names in aufs
+hierarchy.
-+1. a regular file which will be linked to all whiteouts.
++1. a regular file which will be hardlinked to all whiteouts.
+2. a directory to store a pseudo-link.
-+3. a directory to store an "orphan-ed" file temporary.
++3. a directory to store an "orphan"-ed file temporary.
+
+1. Whiteout Base
+ When you remove a file on a readonly branch, aufs handles it as a
@@ -843,8 +853,8 @@ index 0000000..f185393
+ creating a file under this dir, the file is unlinked.
+
+Because aufs supports manipulating branches, ie. add/delete/change
-+dynamically, a branch has its own id. When the branch order changes, aufs
-+finds the new index by searching the branch id.
++dynamically, a branch has its own id. When the branch order changes,
++aufs finds the new index by searching the branch id.
+
+
+Pseudo-link
@@ -857,7 +867,7 @@ index 0000000..f185393
+simple list. If fileB is read after unlinking fileA, aufs returns
+filedata from the pseudo-link instead of the lower readonly
+branch. Because the pseudo-link is based upon the inode, to keep the
-+inode number by xino (see above) is important.
++inode number by xino (see above) is essentially necessary.
+
+All the hardlinks under the Pseudo-link Directory of the writable branch
+should be restored in a proper location later. Aufs provides a utility
@@ -875,12 +885,13 @@ index 0000000..f185393
+XIB(external inode number bitmap)
+----------------------------------------------------------------------
+Addition to the xino file per a branch, aufs has an external inode number
-+bitmap in a superblock object. It is also a file such like a xino file.
++bitmap in a superblock object. It is also an internal file such like a
++xino file.
+It is a simple bitmap to mark whether the aufs inode number is in-use or
+not.
+To reduce the file I/O, aufs prepares a single memory page to cache xib.
+
-+Aufs implements a feature to truncate/refresh both of xino and xib to
++As well as XINO files, aufs has a feature to truncate/refresh XIB to
+reduce the number of consumed disk blocks for these files.
+
+
@@ -892,7 +903,7 @@ index 0000000..f185393
+with eliminating the whiteout-ed ones, and sets it to file (dir)
+object. So the file object has its entry list until it is closed. The
+entry list will be updated when the file position is zero and becomes
-+old. This decision is made in aufs automatically.
++obsoleted. This decision is made in aufs automatically.
+
+The dynamically allocated memory block for the name of entries has a
+unit of 512 bytes (by default) and stores the names contiguously (no
@@ -931,9 +942,8 @@ index 0000000..f185393
+its completion. This approach solves a problem of a signal handler
+simply.
+If aufs didn't adopt the workqueue and changed the privilege of the
-+process, and if the mkdir/write call arises SIGXFSZ or other signal,
-+then the user process might gain a privilege or the generated core file
-+was owned by a superuser.
++process, then the process may receive the unexpected SIGXFSZ or other
++signals.
+
+Also aufs uses the system global workqueue ("events" kernel thread) too
+for asynchronous tasks, such like handling inotify/fsnotify, re-creating a
@@ -951,7 +961,7 @@ index 0000000..f185393
+
+Basically the whiteout represents "logical deletion" which stops aufs to
+lookup further, but also it represents "dir is opaque" which also stop
-+lookup.
++further lookup.
+
+In aufs, rmdir(2) and rename(2) for dir uses whiteout alternatively.
+In order to make several functions in a single systemcall to be
@@ -959,7 +969,7 @@ index 0000000..f185393
+unique whiteouted name.
+For example, in rename(2) dir where the target dir already existed, aufs
+renames the target dir to a temporary unique whiteouted name before the
-+actual rename on a branch and then handles other actions (make it opaque,
++actual rename on a branch, and then handles other actions (make it opaque,
+update the attributes, etc). If an error happens in these actions, aufs
+simply renames the whiteouted name back and returns an error. If all are
+succeeded, aufs registers a function to remove the whiteouted unique
@@ -989,7 +999,7 @@ index 0000000..f185393
+- diropq for the ancestor directories may exist on the upper branch.
+- free space on the lower branch will reduce.
+- another access to the file may happen during moving-down, including
-+ UDBA.
++ UDBA (see "Revalidate Dentry and UDBA").
+- the file should not be hard-linked nor pseudo-linked. they should be
+ handled by auplink utility later.
+
@@ -1000,35 +1010,103 @@ index 0000000..f185393
+- etc.
+
+For this purpose, use "aumvdown" command in aufs-util.git.
+diff --git a/Documentation/filesystems/aufs/design/03atomic_open.txt b/Documentation/filesystems/aufs/design/03atomic_open.txt
+new file mode 100644
+index 0000000..d2c9834
+--- /dev/null
++++ b/Documentation/filesystems/aufs/design/03atomic_open.txt
+@@ -0,0 +1,72 @@
++
++# Copyright (C) 2015 Junjiro R. Okajima
++
++Support for a branch who has its ->atomic_open()
++----------------------------------------------------------------------
++The filesystems who implement its ->atomic_open() are not majority. For
++example NFSv4 does, and aufs should call NFSv4 ->atomic_open,
++particularly for open(O_CREAT|O_EXCL, 0400) case. Other than
++->atomic_open(), NFSv4 returns an error for this open(2). While I am not
++sure whether all filesystems who have ->atomic_open() behave like this,
++but NFSv4 surely returns the error.
++
++In order to support ->atomic_open() for aufs, there are a few
++approaches.
++
++A. Introduce aufs_atomic_open()
++ - calls one of VFS:do_last(), lookup_open() or atomic_open() for
++ branch fs.
++B. Introduce aufs_atomic_open() calling create, open and chmod. this is
++ an aufs user Pip Cet's approach
++ - calls aufs_create(), VFS finish_open() and notify_change().
++ - pass fake-mode to finish_open(), and then correct the mode by
++ notify_change().
++C. Extend aufs_open() to call branch fs's ->atomic_open()
++ - no aufs_atomic_open().
++ - aufs_lookup() registers the TID to an aufs internal object.
++ - aufs_create() does nothing when the matching TID is registered, but
++ registers the mode.
++ - aufs_open() calls branch fs's ->atomic_open() when the matching
++ TID is registered.
++D. Extend aufs_open() to re-try branch fs's ->open() with superuser's
++ credential
++ - no aufs_atomic_open().
++ - aufs_create() registers the TID to an internal object. this info
++ represents "this process created this file just now."
++ - when aufs gets EACCES from branch fs's ->open(), then confirm the
++ registered TID and re-try open() with superuser's credential.
++
++Pros and cons for each approach.
++
++A.
++ - straightforward but highly depends upon VFS internal.
++ - the atomic behavaiour is kept.
++ - some of parameters such as nameidata are hard to reproduce for
++ branch fs.
++ - large overhead.
++B.
++ - easy to implement.
++ - the atomic behavaiour is lost.
++C.
++ - the atomic behavaiour is kept.
++ - dirty and tricky.
++ - VFS checks whether the file is created correctly after calling
++ ->create(), which means this approach doesn't work.
++D.
++ - easy to implement.
++ - the atomic behavaiour is lost.
++ - to open a file with superuser's credential and give it to a user
++ process is a bad idea, since the file object keeps the credential
++ in it. It may affect LSM or something. This approach doesn't work
++ either.
++
++The approach A is ideal, but it hard to implement. So here is a
++variation of A, which is to be implemented.
++
++A-1. Introduce aufs_atomic_open()
++ - calls branch fs ->atomic_open() if exists. otherwise calls
++ vfs_create() and finish_open().
++ - the demerit is that the several checks after branch fs
++ ->atomic_open() are lost. in the ordinary case, the checks are
++ done by VFS:do_last(), lookup_open() and atomic_open(). some can
++ be implemented in aufs, but not all I am afraid.
diff --git a/Documentation/filesystems/aufs/design/03lookup.txt b/Documentation/filesystems/aufs/design/03lookup.txt
new file mode 100644
-index 0000000..55ade95
+index 0000000..7adf4cc
--- /dev/null
+++ b/Documentation/filesystems/aufs/design/03lookup.txt
-@@ -0,0 +1,120 @@
+@@ -0,0 +1,100 @@
+
+# Copyright (C) 2005-2015 Junjiro R. Okajima
+
+Lookup in a Branch
+----------------------------------------------------------------------
+Since aufs has a character of sub-VFS (see Introduction), it operates
-+lookup for branches as VFS does. It may be a heavy work. Generally
-+speaking struct nameidata is a bigger structure and includes many
-+information. But almost all lookup operation in aufs is the simplest
-+case, ie. lookup only an entry directly connected to its parent. Digging
-+down the directory hierarchy is unnecessary.
++lookup for branches as VFS does. It may be a heavy work. But almost all
++lookup operation in aufs is the simplest case, ie. lookup only an entry
++directly connected to its parent. Digging down the directory hierarchy
++is unnecessary. VFS has a function lookup_one_len() for that use, and
++aufs calls it.
+
-+VFS has a function lookup_one_len() for that use, but it is not usable
-+for a branch filesystem which requires struct nameidata. So aufs
-+implements a simple lookup wrapper function. When a branch filesystem
-+allows NULL as nameidata, it calls lookup_one_len(). Otherwise it builds
-+a simplest nameidata and calls lookup_hash().
-+Here aufs applies "a principle in NFSD", ie. if the filesystem supports
-+NFS-export, then it has to support NULL as a nameidata parameter for
-+->create(), ->lookup() and ->d_revalidate(). So the lookup wrapper in
-+aufs tests if ->s_export_op in the branch is NULL or not.
-+
-+When a branch is a remote filesystem, aufs basically trusts its
++When a branch is a remote filesystem, aufs basically relies upon its
+->d_revalidate(), also aufs forces the hardest revalidate tests for
+them.
+For d_revalidate, aufs implements three levels of revalidate tests. See
@@ -1043,7 +1121,7 @@ index 0000000..55ade95
+- "dirA" exists under /ro, but /rw. and its mode is 0700.
+- user invoked "chmod a+rx /au/dirA"
+- the internal copy-up is activated and "/rw/dirA" is created and its
-+ permission bits are set to world readble.
++ permission bits are set to world readable.
+- then "/au/dirA" becomes world readable?
+
+In this case, /ro/dirA is still 0700 since it exists in readonly branch,
@@ -1052,8 +1130,9 @@ index 0000000..55ade95
+allowed it by chmod. Should really aufs rejects showing the entries
+under /ro/dirA?
+
-+To be honest, I don't have a best solution for this case. So aufs
-+implements 'dirperm1' and 'nodirperm1' and leave it to users.
++To be honest, I don't have a good solution for this case. So aufs
++implements 'dirperm1' and 'nodirperm1' mount options, and leave it to
++users.
+When dirperm1 is specified, aufs checks only the highest one for the
+directory permission, and shows the entries. Otherwise, as usual, checks
+every dir existing on all branches and rejects the request.
@@ -1063,17 +1142,6 @@ index 0000000..55ade95
+branch is many.
+
+
-+Loopback Mount
-+----------------------------------------------------------------------
-+Basically aufs supports any type of filesystem and block device for a
-+branch (actually there are some exceptions). But it is prohibited to add
-+a loopback mounted one whose backend file exists in a filesystem which is
-+already added to aufs. The reason is to protect aufs from a recursive
-+lookup. If it was allowed, the aufs lookup operation might re-enter a
-+lookup for the loopback mounted branch in the same context, and will
-+cause a deadlock.
-+
-+
+Revalidate Dentry and UDBA (User's Direct Branch Access)
+----------------------------------------------------------------------
+Generally VFS helpers re-validate a dentry as a part of lookup.
@@ -1123,15 +1191,15 @@ index 0000000..55ade95
+ itself.
+3. No Extra Validation
+ This is the simplest test and doesn't add any additional revalidation
-+ test, and skip therevalidatin in step 4. It is useful and improves
++ test, and skip the revalidation in step 4. It is useful and improves
+ aufs performance when system surely hide the aufs branches from user,
+ by over-mounting something (or another method).
diff --git a/Documentation/filesystems/aufs/design/04branch.txt b/Documentation/filesystems/aufs/design/04branch.txt
new file mode 100644
-index 0000000..644ceb1
+index 0000000..1d11dbe
--- /dev/null
+++ b/Documentation/filesystems/aufs/design/04branch.txt
-@@ -0,0 +1,62 @@
+@@ -0,0 +1,61 @@
+
+# Copyright (C) 2005-2015 Junjiro R. Okajima
+
@@ -1144,8 +1212,7 @@ index 0000000..644ceb1
+Add a Branch
+----------------------------------------------------------------------
+o Confirm the adding dir exists outside of aufs, including loopback
-+ mount.
-+- and other various attributes...
++ mount, and its various attributes.
+o Initialize the xino file and whiteout bases if necessary.
+ See struct.txt.
+
@@ -1160,7 +1227,7 @@ index 0000000..644ceb1
+ writable branch, and the writable branch is world-writable, then a
+ malicious guy may create /etc/passwd on the writable branch directly
+ and the infected file will be valid in aufs.
-+ I am afraid it can be a security issue, but nothing to do except
++ I am afraid it can be a security issue, but aufs can do nothing except
+ producing a warning.
+
+
@@ -1196,7 +1263,7 @@ index 0000000..644ceb1
+ same named entry on the upper branch.
diff --git a/Documentation/filesystems/aufs/design/05wbr_policy.txt b/Documentation/filesystems/aufs/design/05wbr_policy.txt
new file mode 100644
-index 0000000..fc64d70
+index 0000000..0419a90
--- /dev/null
+++ b/Documentation/filesystems/aufs/design/05wbr_policy.txt
@@ -0,0 +1,51 @@
@@ -1210,9 +1277,9 @@ index 0000000..fc64d70
+writable branch which has the parent (or ancestor) dir of the target
+file is chosen (top-down-parent policy).
+By user's request, aufs implements some other policies to select the
-+writable branch, for file creation two policies, round-robin and
-+most-free-space policies. For copy-up three policies, top-down-parent,
-+bottom-up-parent and bottom-up policies.
++writable branch, for file creation several policies, round-robin,
++most-free-space, and other policies. For copy-up, top-down-parent,
++bottom-up-parent, bottom-up and others.
+
+As expected, the round-robin policy selects the branch in circular. When
+you have two writable branches and creates 10 new files, 5 files will be
@@ -1253,7 +1320,7 @@ index 0000000..fc64d70
+ copyup policy.
diff --git a/Documentation/filesystems/aufs/design/06fhsm.txt b/Documentation/filesystems/aufs/design/06fhsm.txt
new file mode 100644
-index 0000000..6cf01ae
+index 0000000..0eb7a82
--- /dev/null
+++ b/Documentation/filesystems/aufs/design/06fhsm.txt
@@ -0,0 +1,105 @@
@@ -1264,9 +1331,9 @@ index 0000000..6cf01ae
+----------------------------------------------------------------------
+Hierarchical Storage Management (or HSM) is a well-known feature in the
+storage world. Aufs provides this feature as file-based with multiple
-+writable branches, based upon the principle of "Colder-Lower".
++writable branches, based upon the principle of "Colder, the Lower".
+Here the word "colder" means that the less used files, and "lower" means
-+that the position in the order of the stacked branches.
++that the position in the order of the stacked branches vertically.
+These multiple writable branches are prioritized, ie. the topmost one
+should be the fastest drive and be used heavily.
+
@@ -1364,10 +1431,10 @@ index 0000000..6cf01ae
+should restore the original file state after an error happens.
diff --git a/Documentation/filesystems/aufs/design/06mmap.txt b/Documentation/filesystems/aufs/design/06mmap.txt
new file mode 100644
-index 0000000..9abea60
+index 0000000..f22d2a1
--- /dev/null
+++ b/Documentation/filesystems/aufs/design/06mmap.txt
-@@ -0,0 +1,33 @@
+@@ -0,0 +1,59 @@
+
+# Copyright (C) 2005-2015 Junjiro R. Okajima
+
@@ -1377,7 +1444,7 @@ index 0000000..9abea60
+interaction with aufs. It means aufs_mmap() calls the branch fs's
+->mmap().
+This approach is simple and good, but there is one problem.
-+Under /proc, several entries show the mmap-ped files by its path (with
++Under /proc, several entries show the mmapped files by its path (with
+device and inode number), and the printed path will be the path on the
+branch fs's instead of virtual aufs's.
+This is not a problem in most cases, but some utilities lsof(1) (and its
@@ -1394,16 +1461,42 @@ index 0000000..9abea60
+ incremented.
+- merging vma maintains the ref count too.
+
-+This is not a good approach. It just faking the printed path. But it
++This is not a good approach. It just fakes the printed path. But it
+leaves all behaviour around f_mapping unchanged. This is surely an
+advantage.
+Actually aufs had adopted another complicated approach which calls
+generic_file_mmap() and handles struct vm_operations_struct. In this
+approach, aufs met a hard problem and I could not solve it without
+switching the approach.
++
++There may be one more another approach which is
++- bind-mount the branch-root onto the aufs-root internally
++- grab the new vfsmount (ie. struct mount)
++- lazy-umount the branch-root internally
++- in open(2) the aufs-file, open the branch-file with the hidden
++ vfsmount (instead of the original branch's vfsmount)
++- ideally this "bind-mount and lazy-umount" should be done atomically,
++ but it may be possible from userspace by the mount helper.
++
++Adding the internal hidden vfsmount and using it in opening a file, the
++file path under /proc will be printed correctly. This approach looks
++smarter, but is not possible I am afraid.
++- aufs-root may be bind-mount later. when it happens, another hidden
++ vfsmount will be required.
++- it is hard to get the chance to bind-mount and lazy-umount
++ + in kernel-space, FS can have vfsmount in open(2) via
++ file->f_path, and aufs can know its vfsmount. But several locks are
++ already acquired, and if aufs tries to bind-mount and lazy-umount
++ here, then it may cause a deadlock.
++ + in user-space, bind-mount doesn't invoke the mount helper.
++- since /proc shows dev and ino, aufs has to give vma these info. it
++ means a new member vm_prinode will be necessary. this is essentially
++ equivalent to vm_prfile described above.
++
++I have to give up this "looks-smater" approach.
diff --git a/Documentation/filesystems/aufs/design/06xattr.txt b/Documentation/filesystems/aufs/design/06xattr.txt
new file mode 100644
-index 0000000..d16f822
+index 0000000..ec1e68c
--- /dev/null
+++ b/Documentation/filesystems/aufs/design/06xattr.txt
@@ -0,0 +1,81 @@
@@ -1414,7 +1507,7 @@ index 0000000..d16f822
+----------------------------------------------------------------------
+For the inode standard attributes (owner, group, timestamps, etc.), aufs
+shows the values from the topmost existing file. This behaviour is good
-+for the non-dir entreis since the bahaviour exactly matches the shown
++for the non-dir entries since the bahaviour exactly matches the shown
+information. But for the directories, aufs considers all the same named
+entries on the lower branches. Which means, if one of the lower entry
+rejects readdir call, then aufs returns an error even if the topmost
@@ -1427,14 +1520,14 @@ index 0000000..d16f822
+
+A similar issue can happen around XATTR.
+getxattr(2) and listxattr(2) families behave as if dirperm1 option is
-+always set. Otherwise these very unpleasant situation can happen.
-+- listxattr(2) may return the duplicated entires.
++always set. Otherwise these very unpleasant situation would happen.
++- listxattr(2) may return the duplicated entries.
+- users may not be able to remove or reset the XATTR forever,
+
+
+XATTR/EA support in the internal (copy,move)-(up,down)
+----------------------------------------------------------------------
-+Generally the extended attributes of inode are categorazied as these.
++Generally the extended attributes of inode are categorized as these.
+- "security" for LSM and capability.
+- "system" for posix ACL, 'acl' mount option is required for the branch
+ fs generally.
@@ -1448,12 +1541,12 @@ index 0000000..d16f822
+
+In copy-up, the support for XATTR on the dst branch may differ from the
+src branch. In this case, the copy-up operation will get an error and
-+the original user operation which triggered the copy-up fails. It can
-+happen that even all copy-up will fail.
++the original user operation which triggered the copy-up will fail. It
++can happen that even all copy-up will fail.
+When both of src and dst branches support XATTR and if an error occurs
+during copying XATTR, then the copy-up should fail obviously. That is a
+good reason and aufs should return an error to userspace. But when only
-+the src branch support XATTR, aufs should not return an error.
++the src branch support that XATTR, aufs should not return an error.
+For example, the src branch supports ACL but the dst branch doesn't
+because the dst branch may natively un-support it or temporary
+un-support it due to "noacl" mount option. Of course, the dst branch fs
@@ -1467,15 +1560,15 @@ index 0000000..d16f822
+
+For the copy-up operation, there two basic approaches.
+- copy the specified XATTR only (by category above), and return the
-+ error if it happens inconditionally.
++ error unconditionally if it happens.
+- copy all XATTR, and ignore the error on the specified category only.
+
+In order to support XATTR and to implement the correct behaviour, aufs
-+chooses the latter approach and introduces some attributes for its
-+branch, "icexsec", "icexsys", "icextr", "icexusr", and "icexoth".
++chooses the latter approach and introduces some new branch attributes,
++"icexsec", "icexsys", "icextr", "icexusr", and "icexoth".
+They correspond to the XATTR namespaces (see above). Additionally, to be
-+convenient, "icex" is also provided which means all "ix*" attributes are
-+set.
++convenient, "icex" is also provided which means all "icex*" attributes
++are set (here the word "icex" stands for "ignore copy-error on XATTR").
+
+The meaning of these attributes is to ignore the error from setting
+XATTR on that branch.
@@ -1490,7 +1583,7 @@ index 0000000..d16f822
+now, aufs implements the branch attributes to ignore the error.
diff --git a/Documentation/filesystems/aufs/design/07export.txt b/Documentation/filesystems/aufs/design/07export.txt
new file mode 100644
-index 0000000..50744ea
+index 0000000..221d70c
--- /dev/null
+++ b/Documentation/filesystems/aufs/design/07export.txt
@@ -0,0 +1,45 @@
@@ -1521,10 +1614,10 @@ index 0000000..50744ea
+ + find the index of a branch from its id in handle, and check it is
+ still exist in aufs.
+ + 1st level: get the inode number from handle and search it in cache.
-+ + 2nd level: if not found, get the parent inode number from handle and
-+ search it in cache. and then open the parent dir, find the matching
-+ inode number by vfs_readdir() and get its name, and call
-+ lookup_one_len() for the target dentry.
++ + 2nd level: if not found in cache, get the parent inode number from
++ the handle and search it in cache. and then open the found parent
++ dir, find the matching inode number by vfs_readdir() and get its
++ name, and call lookup_one_len() for the target dentry.
+ + 3rd level: if the parent dir is not cached, call
+ exportfs_decode_fh() for a branch and get the parent on a branch,
+ build a pathname of it, convert it a pathname in aufs, call
@@ -1586,10 +1679,10 @@ index 0000000..181dc02
+initramfs will use it to replace the old one at the next boot.
diff --git a/Documentation/filesystems/aufs/design/10dynop.txt b/Documentation/filesystems/aufs/design/10dynop.txt
new file mode 100644
-index 0000000..0e40da0
+index 0000000..9d502b5
--- /dev/null
+++ b/Documentation/filesystems/aufs/design/10dynop.txt
-@@ -0,0 +1,33 @@
+@@ -0,0 +1,34 @@
+
+# Copyright (C) 2010-2015 Junjiro R. Okajima
+
@@ -1601,84 +1694,34 @@ index 0000000..0e40da0
+operation. Some FS have multiple sets of them. For instance, ext2 has
+three sets, one for XIP, for NOBH, and for normal.
+Since aufs overrides and redirects these operations, sometimes aufs has
-+to change its behaviour according to the branch FS type. More imporantly
++to change its behaviour according to the branch FS type. More importantly
+VFS acts differently if a function (member in the struct) is set or
+not. It means aufs should have several sets of operations and select one
+among them according to the branch FS definition.
+
-+In order to solve this problem and not to affect the behavour of VFS,
++In order to solve this problem and not to affect the behaviour of VFS,
+aufs defines these operations dynamically. For instance, aufs defines
-+aio_read function for struct file_operations, but it may not be set to
-+the file_operations. When the branch FS doesn't have it, aufs doesn't
-+set it to its file_operations while the function definition itself is
-+still alive. So the behaviour of io_submit(2) will not change, and it
-+will return an error when aio_read is not defined.
++dummy direct_IO function for struct address_space_operations, but it may
++not be set to the address_space_operations actually. When the branch FS
++doesn't have it, aufs doesn't set it to its address_space_operations
++while the function definition itself is still alive. So the behaviour
++itself will not change, and it will return an error when direct_IO is
++not set.
+
+The lifetime of these dynamically generated operation object is
+maintained by aufs branch object. When the branch is removed from aufs,
+the reference counter of the object is decremented. When it reaches
+zero, the dynamically generated operation object will be freed.
+
-+This approach is designed to support AIO (io_submit), Direcit I/O and
-+XIP mainly.
-+Currently this approach is applied to file_operations and
-+vm_operations_struct for regular files only.
-diff --git a/Documentation/filesystems/aufs/design/99plan.txt b/Documentation/filesystems/aufs/design/99plan.txt
-new file mode 100644
-index 0000000..73a8fae
---- /dev/null
-+++ b/Documentation/filesystems/aufs/design/99plan.txt
-@@ -0,0 +1,45 @@
-+
-+# Copyright (C) 2005-2015 Junjiro R. Okajima
-+
-+Plan
-+
-+Restoring some features which was implemented in aufs1.
-+They were dropped in aufs2 in order to make source files simpler and
-+easier to be reviewed.
-+
-+
-+Being Another Aufs's Readonly Branch (robr)
-+----------------------------------------------------------------------
-+Aufs1 allows aufs to be another aufs's readonly branch.
-+This feature was developed by a user's request. But it may not be used
-+currecnly.
-+
-+
-+Refresh the Opened File (refrof)
-+----------------------------------------------------------------------
-+This option is implemented in aufs1 but incomplete.
-+
-+When user reads from a file, he expects to get its latest filedata
-+generally. If the file is removed and a new same named file is created,
-+the content he gets is unchanged, ie. the unlinked filedata.
-+
-+Let's try case study again.
-+- aufs has two branches.
-+ /au = /rw + /ro
-+- "fileA" exists under /ro, but /rw.
-+- user opened "/au/fileA".
-+- he or someone else inserts a branch (/new) between /rw and /ro.
-+ /au = /rw + /new + /ro
-+- the new branch has "fileA".
-+- user reads from the opened "fileA"
-+- which filedata should aufs return, from /ro or /new?
-+
-+Some people says it has to be "from /ro" and it is a semantics of Unix.
-+The others say it should be "from /new" because the file is not removed
-+and it is equivalent to the case of someone else modifies the file.
-+
-+Here again I don't have a best and final answer. I got an idea to
-+implement 'refrof' and 'norefrof' option. When 'refrof' (REFResh the
-+Opened File) is specified (by default), aufs returns the filedata from
-+/new.
-+Otherwise from /new.
++This approach is designed to support AIO (io_submit), Direct I/O and
++XIP (DAX) mainly.
++Currently this approach is applied to address_space_operations for
++regular files only.
diff --git a/MAINTAINERS b/MAINTAINERS
-index d66a97d..1c113a4 100644
+index d8afd29..feac5ea 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
-@@ -1833,6 +1833,20 @@ F: include/linux/audit.h
+@@ -1880,6 +1880,19 @@ F: include/linux/audit.h
F: include/uapi/linux/audit.h
F: kernel/audit*
@@ -1687,8 +1730,7 @@ index d66a97d..1c113a4 100644
+L: linux-unionfs@vger.kernel.org
+L: aufs-users@lists.sourceforge.net (members only)
+W: http://aufs.sourceforge.net
-+T: git://git.code.sf.net/p/aufs/aufs3-linux
-+T: git://github.com/sfjro/aufs3-linux.git
++T: git://github.com/sfjro/aufs4-linux.git
+S: Supported
+F: Documentation/filesystems/aufs/
+F: Documentation/ABI/testing/debugfs-aufs
@@ -1700,10 +1742,10 @@ index d66a97d..1c113a4 100644
M: Miguel Ojeda Sandonis
W: http://miguelojeda.es/auxdisplay.htm
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
-index 6cb1beb..30efd68 100644
+index d7173cb..0160952 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
-@@ -692,6 +692,24 @@ static inline int is_loop_device(struct file *file)
+@@ -540,6 +540,24 @@ static inline int is_loop_device(struct file *file)
return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR;
}
@@ -1729,22 +1771,22 @@ index 6cb1beb..30efd68 100644
static ssize_t loop_attr_show(struct device *dev, char *page,
diff --git a/fs/Kconfig b/fs/Kconfig
-index 664991a..1481093 100644
+index 011f433..b1083f6 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
-@@ -210,6 +210,7 @@ source "fs/ufs/Kconfig"
+@@ -218,6 +218,7 @@ source "fs/pstore/Kconfig"
+ source "fs/sysv/Kconfig"
+ source "fs/ufs/Kconfig"
source "fs/exofs/Kconfig"
- source "fs/f2fs/Kconfig"
- source "fs/efivarfs/Kconfig"
+source "fs/aufs/Kconfig"
endif # MISC_FILESYSTEMS
diff --git a/fs/Makefile b/fs/Makefile
-index bedff48..9e7c0b7 100644
+index cb92fd4..8c2df12 100644
--- a/fs/Makefile
+++ b/fs/Makefile
-@@ -126,3 +126,4 @@ obj-y += exofs/ # Multiple modules
+@@ -127,3 +127,4 @@ obj-y += exofs/ # Multiple modules
obj-$(CONFIG_CEPH_FS) += ceph/
obj-$(CONFIG_PSTORE) += pstore/
obj-$(CONFIG_EFIVAR_FS) += efivarfs/
@@ -2036,10 +2078,10 @@ index 0000000..75290bd
+#endif /* __AUFS_H__ */
diff --git a/fs/aufs/branch.c b/fs/aufs/branch.c
new file mode 100644
-index 0000000..cf61201
+index 0000000..d34e789
--- /dev/null
+++ b/fs/aufs/branch.c
-@@ -0,0 +1,1397 @@
+@@ -0,0 +1,1401 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -2154,6 +2196,7 @@ index 0000000..cf61201
+{
+ struct au_branch *add_branch;
+ struct dentry *root;
++ struct inode *inode;
+ int err;
+
+ err = -ENOMEM;
@@ -2185,8 +2228,10 @@ index 0000000..cf61201
+ err = au_sbr_realloc(au_sbi(sb), new_nbranch);
+ if (!err)
+ err = au_di_realloc(au_di(root), new_nbranch);
-+ if (!err)
-+ err = au_ii_realloc(au_ii(root->d_inode), new_nbranch);
++ if (!err) {
++ inode = d_inode(root);
++ err = au_ii_realloc(au_ii(inode), new_nbranch);
++ }
+ if (!err)
+ return add_branch; /* success */
+
@@ -2228,7 +2273,7 @@ index 0000000..cf61201
+{
+ int err;
+ aufs_bindex_t bend, bindex;
-+ struct dentry *root;
++ struct dentry *root, *h_dentry;
+ struct inode *inode, *h_inode;
+
+ root = sb->s_root;
@@ -2256,7 +2301,7 @@ index 0000000..cf61201
+ goto out;
+ }
+
-+ inode = add->path.dentry->d_inode;
++ inode = d_inode(add->path.dentry);
+ err = -ENOENT;
+ if (unlikely(!inode->i_nlink)) {
+ pr_err("no existence %s\n", add->pathname);
@@ -2281,7 +2326,7 @@ index 0000000..cf61201
+ goto out;
+ }
+
-+ err = test_br(add->path.dentry->d_inode, add->perm, add->pathname);
++ err = test_br(d_inode(add->path.dentry), add->perm, add->pathname);
+ if (unlikely(err))
+ goto out;
+
@@ -2298,7 +2343,8 @@ index 0000000..cf61201
+
+ err = 0;
+ if (au_opt_test(au_mntflags(sb), WARN_PERM)) {
-+ h_inode = au_h_dptr(root, 0)->d_inode;
++ h_dentry = au_h_dptr(root, 0);
++ h_inode = d_inode(h_dentry);
+ if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO)
+ || !uid_eq(h_inode->i_uid, inode->i_uid)
+ || !gid_eq(h_inode->i_gid, inode->i_gid))
@@ -2325,6 +2371,7 @@ index 0000000..cf61201
+ struct mutex *h_mtx;
+ struct au_wbr *wbr;
+ struct au_hinode *hdir;
++ struct dentry *h_dentry;
+
+ err = vfsub_mnt_want_write(au_br_mnt(br));
+ if (unlikely(err))
@@ -2337,10 +2384,11 @@ index 0000000..cf61201
+ h_mtx = NULL;
+ bindex = au_br_index(sb, br->br_id);
+ if (0 <= bindex) {
-+ hdir = au_hi(sb->s_root->d_inode, bindex);
++ hdir = au_hi(d_inode(sb->s_root), bindex);
+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
+ } else {
-+ h_mtx = &au_br_dentry(br)->d_inode->i_mutex;
++ h_dentry = au_br_dentry(br);
++ h_mtx = &d_inode(h_dentry)->i_mutex;
+ mutex_lock_nested(h_mtx, AuLsc_I_PARENT);
+ }
+ if (!wbr)
@@ -2403,6 +2451,7 @@ index 0000000..cf61201
+ struct au_opt_add *add)
+{
+ int err;
++ struct inode *h_inode;
+
+ err = 0;
+ memset(&br->br_xino, 0, sizeof(br->br_xino));
@@ -2423,7 +2472,8 @@ index 0000000..cf61201
+ }
+
+ if (au_opt_test(au_mntflags(sb), XINO)) {
-+ err = au_xino_br(sb, br, add->path.dentry->d_inode->i_ino,
++ h_inode = d_inode(add->path.dentry);
++ err = au_xino_br(sb, br, h_inode->i_ino,
+ au_sbr(sb, 0)->br_xino.xi_file, /*do_test*/1);
+ if (unlikely(err)) {
+ AuDebugOn(br->br_xino.xi_file);
@@ -2492,11 +2542,11 @@ index 0000000..cf61201
+ aufs_bindex_t bindex)
+{
+ struct dentry *root, *h_dentry;
-+ struct inode *root_inode;
++ struct inode *root_inode, *h_inode;
+ aufs_bindex_t bend, amount;
+
+ root = sb->s_root;
-+ root_inode = root->d_inode;
++ root_inode = d_inode(root);
+ bend = au_sbend(sb);
+ amount = bend + 1 - bindex;
+ h_dentry = au_br_dentry(br);
@@ -2505,8 +2555,8 @@ index 0000000..cf61201
+ au_br_do_add_hdp(au_di(root), bindex, bend, amount);
+ au_br_do_add_hip(au_ii(root_inode), bindex, bend, amount);
+ au_set_h_dptr(root, bindex, dget(h_dentry));
-+ au_set_h_iptr(root_inode, bindex, au_igrab(h_dentry->d_inode),
-+ /*flags*/0);
++ h_inode = d_inode(h_dentry);
++ au_set_h_iptr(root_inode, bindex, au_igrab(h_inode), /*flags*/0);
+ au_sbilist_unlock();
+}
+
@@ -2519,7 +2569,7 @@ index 0000000..cf61201
+ struct au_branch *add_branch;
+
+ root = sb->s_root;
-+ root_inode = root->d_inode;
++ root_inode = d_inode(root);
+ IMustLock(root_inode);
+ err = test_add(sb, add, remount);
+ if (unlikely(err < 0))
@@ -2555,7 +2605,7 @@ index 0000000..cf61201
+ au_cpup_attr_all(root_inode, /*force*/1);
+ sb->s_maxbytes = h_dentry->d_sb->s_maxbytes;
+ } else
-+ au_add_nlink(root_inode, h_dentry->d_inode);
++ au_add_nlink(root_inode, d_inode(h_dentry));
+
+ /*
+ * this test/set prevents aufs from handling unnecesary notify events
@@ -2642,7 +2692,7 @@ index 0000000..cf61201
+static int au_test_dbusy(struct dentry *dentry, aufs_bindex_t bstart,
+ aufs_bindex_t bend)
+{
-+ return au_test_ibusy(dentry->d_inode, bstart, bend);
++ return au_test_ibusy(d_inode(dentry), bstart, bend);
+}
+
+/*
@@ -2775,7 +2825,7 @@ index 0000000..cf61201
+
+ sigen = au_sigen(root->d_sb);
+ DiMustNoWaiters(root);
-+ IiMustNoWaiters(root->d_inode);
++ IiMustNoWaiters(d_inode(root));
+ di_write_unlock(root);
+ err = test_dentry_busy(root, bindex, sigen, verbose);
+ if (!err)
@@ -2831,7 +2881,6 @@ index 0000000..cf61201
+ unsigned long long ull, max;
+ aufs_bindex_t bstart;
+ struct file *file, **array;
-+ struct inode *inode;
+ struct dentry *root;
+ struct au_hfile *hfile;
+
@@ -2852,8 +2901,7 @@ index 0000000..cf61201
+ /* AuDbg("%pD\n", file); */
+ fi_read_lock(file);
+ bstart = au_fbstart(file);
-+ inode = file_inode(file);
-+ if (!S_ISDIR(inode->i_mode)) {
++ if (!d_is_dir(file->f_path.dentry)) {
+ hfile = &au_fi(file)->fi_htop;
+ if (hfile->hf_br->br_id == br_id)
+ err = -EBUSY;
@@ -2886,7 +2934,7 @@ index 0000000..cf61201
+ break;
+
+ /* AuDbg("%pD\n", file); */
-+ AuDebugOn(!S_ISDIR(file_inode(file)->i_mode));
++ AuDebugOn(!d_is_dir(file->f_path.dentry));
+ bfound = -1;
+ fidir = au_fi(file)->fi_hdir;
+ AuDebugOn(!fidir);
@@ -2988,7 +3036,7 @@ index 0000000..cf61201
+ SiMustWriteLock(sb);
+
+ root = sb->s_root;
-+ inode = root->d_inode;
++ inode = d_inode(root);
+ sbinfo = au_sbi(sb);
+ bend = sbinfo->si_bend;
+
@@ -3104,10 +3152,10 @@ index 0000000..cf61201
+ }
+
+ if (!bindex) {
-+ au_cpup_attr_all(root->d_inode, /*force*/1);
++ au_cpup_attr_all(d_inode(root), /*force*/1);
+ sb->s_maxbytes = au_sbr_sb(sb, 0)->s_maxbytes;
+ } else
-+ au_sub_nlink(root->d_inode, del->h_path.dentry->d_inode);
++ au_sub_nlink(d_inode(root), d_inode(del->h_path.dentry));
+ if (au_opt_test(mnt_flags, PLINK))
+ au_plink_half_refresh(sb, br_id);
+
@@ -3231,7 +3279,6 @@ index 0000000..cf61201
+ aufs_bindex_t br_id;
+ unsigned char verbose, writer;
+ struct file *file, *hf, **array;
-+ struct inode *inode;
+ struct au_hfile *hfile;
+
+ mnt_flags = au_mntflags(sb);
@@ -3260,10 +3307,9 @@ index 0000000..cf61201
+ goto out_array;
+ }
+
-+ inode = file_inode(file);
+ hfile = &au_fi(file)->fi_htop;
+ hf = hfile->hf_file;
-+ if (!S_ISREG(inode->i_mode)
++ if (!d_is_reg(file->f_path.dentry)
+ || !(file->f_mode & FMODE_WRITE)
+ || hfile->hf_br->br_id != br_id
+ || !(hf->f_mode & FMODE_WRITE))
@@ -3336,7 +3382,7 @@ index 0000000..cf61201
+ }
+ AuDbg("bindex b%d\n", bindex);
+
-+ err = test_br(mod->h_root->d_inode, mod->perm, mod->path);
++ err = test_br(d_inode(mod->h_root), mod->perm, mod->path);
+ if (unlikely(err))
+ goto out;
+
@@ -3364,7 +3410,7 @@ index 0000000..cf61201
+ if (!au_br_writable(mod->perm)) {
+ /* rw --> ro, file might be mmapped */
+ DiMustNoWaiters(root);
-+ IiMustNoWaiters(root->d_inode);
++ IiMustNoWaiters(d_inode(root));
+ di_write_unlock(root);
+ err = au_br_mod_files_ro(sb, bindex);
+ /* aufs_write_lock() calls ..._child() */
@@ -3439,10 +3485,10 @@ index 0000000..cf61201
+}
diff --git a/fs/aufs/branch.h b/fs/aufs/branch.h
new file mode 100644
-index 0000000..61f5ca1
+index 0000000..7b9e7c9
--- /dev/null
+++ b/fs/aufs/branch.h
-@@ -0,0 +1,254 @@
+@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -3582,6 +3628,18 @@ index 0000000..61f5ca1
+#endif
+}
+
++static inline int au_br_test_oflag(int oflag, struct au_branch *br)
++{
++ int err, exec_flag;
++
++ err = 0;
++ exec_flag = oflag & __FMODE_EXEC;
++ if (unlikely(exec_flag && (au_br_mnt(br)->mnt_flags & MNT_NOEXEC)))
++ err = -EACCES;
++
++ return err;
++}
++
+/* ---------------------------------------------------------------------- */
+
+/* branch.c */
@@ -3606,10 +3664,10 @@ index 0000000..61f5ca1
+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,
++ssize_t xino_fread(vfs_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);
++ssize_t xino_fwrite(vfs_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);
@@ -3699,10 +3757,10 @@ index 0000000..61f5ca1
+#endif /* __AUFS_BRANCH_H__ */
diff --git a/fs/aufs/cpup.c b/fs/aufs/cpup.c
new file mode 100644
-index 0000000..26ee630
+index 0000000..f6f6818
--- /dev/null
+++ b/fs/aufs/cpup.c
-@@ -0,0 +1,1290 @@
+@@ -0,0 +1,1306 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -3822,7 +3880,7 @@ index 0000000..26ee630
+
+ dt->dt_dentry = dentry;
+ dt->dt_h_path = *h_path;
-+ h_inode = h_path->dentry->d_inode;
++ h_inode = d_inode(h_path->dentry);
+ dt->dt_atime = h_inode->i_atime;
+ dt->dt_mtime = h_inode->i_mtime;
+ /* smp_mb(); */
@@ -3858,6 +3916,8 @@ index 0000000..26ee630
+ struct au_cpup_reg_attr *h_src_attr)
+{
+ int err, sbits, icex;
++ unsigned int mnt_flags;
++ unsigned char verbose;
+ struct iattr ia;
+ struct path h_path;
+ struct inode *h_isrc, *h_idst;
@@ -3865,10 +3925,10 @@ index 0000000..26ee630
+ struct au_branch *br;
+
+ h_path.dentry = au_h_dptr(dst, bindex);
-+ h_idst = h_path.dentry->d_inode;
++ h_idst = d_inode(h_path.dentry);
+ br = au_sbr(dst->d_sb, bindex);
+ h_path.mnt = au_br_mnt(br);
-+ h_isrc = h_src->d_inode;
++ h_isrc = d_inode(h_src);
+ ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID
+ | ATTR_ATIME | ATTR_MTIME
+ | ATTR_ATIME_SET | ATTR_MTIME_SET;
@@ -3909,8 +3969,11 @@ index 0000000..26ee630
+ }
+
+ icex = br->br_perm & AuBrAttr_ICEX;
-+ if (!err)
-+ err = au_cpup_xattr(h_path.dentry, h_src, icex);
++ if (!err) {
++ mnt_flags = au_mntflags(dst->d_sb);
++ verbose = !!au_opt_test(mnt_flags, VERBOSE);
++ err = au_cpup_xattr(h_path.dentry, h_src, icex, verbose);
++ }
+
+ return err;
+}
@@ -4094,7 +4157,7 @@ index 0000000..26ee630
+ }
+
+ /* try stopping to update while we copyup */
-+ IMustLock(file[SRC].dentry->d_inode);
++ IMustLock(d_inode(file[SRC].dentry));
+ err = au_copy_file(file[DST].file, file[SRC].file, cpg->len);
+
+ fput(file[DST].file);
@@ -4116,7 +4179,7 @@ index 0000000..26ee630
+ struct inode *h_src_inode, *h_dst_inode;
+
+ err = 0;
-+ h_src_inode = au_h_iptr(cpg->dentry->d_inode, cpg->bsrc);
++ h_src_inode = au_h_iptr(d_inode(cpg->dentry), cpg->bsrc);
+ l = i_size_read(h_src_inode);
+ if (cpg->len == -1 || l < cpg->len)
+ cpg->len = l;
@@ -4128,7 +4191,13 @@ index 0000000..26ee630
+ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
+ h_path.mnt = au_sbr_mnt(cpg->dentry->d_sb, cpg->bsrc);
+ h_src_attr->iflags = h_src_inode->i_flags;
-+ err = vfs_getattr(&h_path, &h_src_attr->st);
++ if (!au_test_nfs(h_src_inode->i_sb))
++ err = vfs_getattr(&h_path, &h_src_attr->st);
++ else {
++ mutex_unlock(&h_src_inode->i_mutex);
++ err = vfs_getattr(&h_path, &h_src_attr->st);
++ mutex_lock_nested(&h_src_inode->i_mutex, AuLsc_I_CHILD);
++ }
+ if (unlikely(err)) {
+ mutex_unlock(&h_src_inode->i_mutex);
+ goto out;
@@ -4142,7 +4211,7 @@ index 0000000..26ee630
+ }
+ if (!err && (h_src_inode->i_state & I_LINKABLE)) {
+ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bdst);
-+ h_dst_inode = h_path.dentry->d_inode;
++ h_dst_inode = d_inode(h_path.dentry);
+ spin_lock(&h_dst_inode->i_lock);
+ h_dst_inode->i_state |= I_LINKABLE;
+ spin_unlock(&h_dst_inode->i_lock);
@@ -4161,9 +4230,11 @@ index 0000000..26ee630
+ char *k;
+ char __user *u;
+ } sym;
++ struct inode *h_inode = d_inode(h_src);
++ const struct inode_operations *h_iop = h_inode->i_op;
+
+ err = -ENOSYS;
-+ if (unlikely(!h_src->d_inode->i_op->readlink))
++ if (unlikely(!h_iop->readlink))
+ goto out;
+
+ err = -ENOMEM;
@@ -4174,7 +4245,7 @@ index 0000000..26ee630
+ /* unnecessary to support mmap_sem since symlink is not mmap-able */
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
-+ symlen = h_src->d_inode->i_op->readlink(h_src, sym.u, PATH_MAX);
++ symlen = h_iop->readlink(h_src, sym.u, PATH_MAX);
+ err = symlen;
+ set_fs(old_fs);
+
@@ -4200,13 +4271,13 @@ index 0000000..26ee630
+ struct au_dtime dt;
+ struct path h_path;
+ struct dentry *h_src, *h_dst, *h_parent;
-+ struct inode *h_inode, *h_dir;
++ struct inode *h_inode, *h_dir, *dir, *inode;
+ struct super_block *sb;
+
+ /* bsrc branch can be ro/rw. */
+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
-+ h_inode = h_src->d_inode;
-+ AuDebugOn(h_inode != au_h_iptr(cpg->dentry->d_inode, cpg->bsrc));
++ h_inode = d_inode(h_src);
++ AuDebugOn(h_inode != au_h_iptr(d_inode(cpg->dentry), cpg->bsrc));
+
+ /* try stopping to be referenced while we are creating */
+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
@@ -4214,7 +4285,7 @@ index 0000000..26ee630
+ AuDebugOn(strncmp(h_dst->d_name.name, AUFS_WH_PFX,
+ AUFS_WH_PFX_LEN));
+ h_parent = h_dst->d_parent; /* dir inode is locked */
-+ h_dir = h_parent->d_inode;
++ h_dir = d_inode(h_parent);
+ IMustLock(h_dir);
+ AuDebugOn(h_parent != h_dst->d_parent);
+
@@ -4245,10 +4316,11 @@ index 0000000..26ee630
+ * strange behaviour from the users view,
+ * particularry setattr case
+ */
-+ if (au_ibstart(dst_parent->d_inode) == cpg->bdst)
-+ au_cpup_attr_nlink(dst_parent->d_inode,
-+ /*force*/1);
-+ au_cpup_attr_nlink(cpg->dentry->d_inode, /*force*/1);
++ dir = d_inode(dst_parent);
++ if (au_ibstart(dir) == cpg->bdst)
++ au_cpup_attr_nlink(dir, /*force*/1);
++ inode = d_inode(cpg->dentry);
++ au_cpup_attr_nlink(inode, /*force*/1);
+ }
+ break;
+ case S_IFLNK:
@@ -4274,7 +4346,7 @@ index 0000000..26ee630
+ && (h_inode->i_nlink == 1
+ || (h_inode->i_state & I_LINKABLE))
+ /* todo: unnecessary? */
-+ /* && cpg->dentry->d_inode->i_nlink == 1 */
++ /* && d_inode(cpg->dentry)->i_nlink == 1 */
+ && cpg->bdst < cpg->bsrc
+ && !au_ftest_cpup(cpg->flags, KEEPLINO))
+ au_xino_write(sb, cpg->bsrc, h_inode->i_ino, /*ino*/0);
@@ -4325,7 +4397,7 @@ index 0000000..26ee630
+ goto out;
+
+ h_parent = h_dentry->d_parent; /* dir inode is locked */
-+ h_dir = h_parent->d_inode;
++ h_dir = d_inode(h_parent);
+ IMustLock(h_dir);
+ AuDbg("%pd %pd\n", h_dentry, h_path->dentry);
+ /* no delegation since it is just created */
@@ -4349,7 +4421,7 @@ index 0000000..26ee630
+ aufs_bindex_t old_ibstart;
+ unsigned char isdir, plink;
+ struct dentry *h_src, *h_dst, *h_parent;
-+ struct inode *dst_inode, *h_dir, *inode, *delegated;
++ struct inode *dst_inode, *h_dir, *inode, *delegated, *src_inode;
+ struct super_block *sb;
+ struct au_branch *br;
+ /* to reuduce stack size */
@@ -4370,11 +4442,11 @@ index 0000000..26ee630
+ a->h_path.mnt = au_br_mnt(br);
+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
+ h_parent = h_dst->d_parent; /* dir inode is locked */
-+ h_dir = h_parent->d_inode;
++ h_dir = d_inode(h_parent);
+ IMustLock(h_dir);
+
+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
-+ inode = cpg->dentry->d_inode;
++ inode = d_inode(cpg->dentry);
+
+ if (!dst_parent)
+ dst_parent = dget_parent(cpg->dentry);
@@ -4399,7 +4471,7 @@ index 0000000..26ee630
+ err = PTR_ERR(h_src);
+ if (IS_ERR(h_src))
+ goto out_parent;
-+ if (unlikely(!h_src->d_inode)) {
++ if (unlikely(d_is_negative(h_src))) {
+ err = -EIO;
+ AuIOErr("i%lu exists on a upper branch "
+ "but not pseudo-linked\n",
@@ -4438,7 +4510,7 @@ index 0000000..26ee630
+ err = cpup_entry(cpg, dst_parent, &a->h_src_attr);
+ if (unlikely(err))
+ goto out_rev;
-+ dst_inode = h_dst->d_inode;
++ dst_inode = d_inode(h_dst);
+ mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2);
+ /* todo: necessary? */
+ /* au_pin_hdir_unlock(cpg->pin); */
@@ -4473,9 +4545,10 @@ index 0000000..26ee630
+ if (unlikely(err))
+ goto out_rev;
+
++ src_inode = d_inode(h_src);
+ if (!isdir
-+ && (h_src->d_inode->i_nlink > 1
-+ || h_src->d_inode->i_state & I_LINKABLE)
++ && (src_inode->i_nlink > 1
++ || src_inode->i_state & I_LINKABLE)
+ && plink)
+ au_plink_append(inode, cpg->bdst, h_dst);
+
@@ -4492,7 +4565,7 @@ index 0000000..26ee630
+ au_dtime_store(&a->dt, dst_parent, &a->h_path);
+ a->h_path.dentry = h_dst;
+ rerr = 0;
-+ if (h_dst->d_inode) {
++ if (d_is_positive(h_dst)) {
+ if (!isdir) {
+ /* no delegation since it is just created */
+ rerr = vfsub_unlink(h_dir, &a->h_path,
@@ -4512,7 +4585,7 @@ index 0000000..26ee630
+ return err;
+}
+
-+#if 0 /* unused */
++#if 0 /* reserved */
+struct au_cpup_single_args {
+ int *errp;
+ struct au_cp_generic *cpg;
@@ -4568,14 +4641,14 @@ index 0000000..26ee630
+ return do_sio;
+}
+
-+#if 0 /* unused */
++#if 0 /* reserved */
+int au_sio_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent)
+{
+ int err, wkq_err;
+ struct dentry *h_dentry;
+
+ h_dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
-+ if (!au_cpup_sio_test(pin, h_dentry->d_inode->i_mode))
++ if (!au_cpup_sio_test(pin, d_inode(h_dentry)->i_mode))
+ err = au_cpup_single(cpg, dst_parent);
+ else {
+ struct au_cpup_single_args args = {
@@ -4656,9 +4729,9 @@ index 0000000..26ee630
+ }
+
+ parent = dget_parent(dentry);
-+ h_dir = au_h_iptr(parent->d_inode, cpg->bdst);
++ h_dir = au_h_iptr(d_inode(parent), cpg->bdst);
+ if (!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE)
-+ && !au_cpup_sio_test(cpg->pin, dentry->d_inode->i_mode))
++ && !au_cpup_sio_test(cpg->pin, d_inode(dentry)->i_mode))
+ err = au_cpup_simple(cpg);
+ else {
+ struct au_cpup_simple_args args = {
@@ -4689,7 +4762,7 @@ index 0000000..26ee630
+ for (bsrc = cpg->bdst + 1; bsrc <= bend; bsrc++) {
+ h_dentry = au_h_dptr(dentry, bsrc);
+ if (h_dentry) {
-+ AuDebugOn(!h_dentry->d_inode);
++ AuDebugOn(d_is_negative(h_dentry));
+ break;
+ }
+ }
@@ -4779,19 +4852,19 @@ index 0000000..26ee630
+
+ dget(wh_dentry);
+ h_path.dentry = wh_dentry;
-+ if (!S_ISDIR(wh_dentry->d_inode->i_mode)) {
++ if (!d_is_dir(wh_dentry)) {
+ /* no delegation since it is just created */
-+ err = vfsub_unlink(h_parent->d_inode, &h_path,
++ err = vfsub_unlink(d_inode(h_parent), &h_path,
+ /*delegated*/NULL, /*force*/0);
+ } else
-+ err = vfsub_rmdir(h_parent->d_inode, &h_path);
++ err = vfsub_rmdir(d_inode(h_parent), &h_path);
+ if (unlikely(err)) {
+ AuIOErr("failed remove copied-up tmp file %pd(%d)\n",
+ wh_dentry, err);
+ err = -EIO;
+ }
+ au_dtime_revert(&dt);
-+ au_set_hi_wh(dentry->d_inode, bdst, wh_dentry);
++ au_set_hi_wh(d_inode(dentry), bdst, wh_dentry);
+
+out_wh:
+ dput(wh_dentry);
@@ -4827,7 +4900,7 @@ index 0000000..26ee630
+ dentry = cpg->dentry;
+ bdst = cpg->bdst;
+ parent = dget_parent(dentry);
-+ dir = parent->d_inode;
++ dir = d_inode(parent);
+ h_orph = NULL;
+ h_parent = NULL;
+ h_dir = au_igrab(au_h_iptr(dir, bdst));
@@ -4839,7 +4912,7 @@ index 0000000..26ee630
+
+ h_parent = dget(au_h_dptr(parent, bdst));
+ au_set_h_dptr(parent, bdst, dget(h_orph));
-+ h_tmpdir = h_orph->d_inode;
++ h_tmpdir = d_inode(h_orph);
+ au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0);
+
+ mutex_lock_nested(&h_tmpdir->i_mutex, AuLsc_I_PARENT3);
@@ -4852,7 +4925,7 @@ index 0000000..26ee630
+ }
+
+ if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE)
-+ && !au_cpup_sio_test(cpg->pin, dentry->d_inode->i_mode))
++ && !au_cpup_sio_test(cpg->pin, d_inode(dentry)->i_mode))
+ err = au_cpup_wh(cpg, file);
+ else {
+ struct au_cpup_wh_args args = {
@@ -4893,7 +4966,7 @@ index 0000000..26ee630
+{
+ int err;
+ struct au_pin pin;
-+ struct dentry *d, *parent, *h_parent, *real_parent;
++ struct dentry *d, *parent, *h_parent, *real_parent, *h_dentry;
+
+ err = 0;
+ parent = dget_parent(dentry);
@@ -4926,8 +4999,9 @@ index 0000000..26ee630
+ di_write_lock_child3(d);
+
+ /* somebody else might create while we were sleeping */
-+ if (!au_h_dptr(d, bdst) || !au_h_dptr(d, bdst)->d_inode) {
-+ if (au_h_dptr(d, bdst))
++ h_dentry = au_h_dptr(d, bdst);
++ if (!h_dentry || d_is_negative(h_dentry)) {
++ if (h_dentry)
+ au_update_dbstart(d);
+
+ au_pin_set_dentry(&pin, d);
@@ -4977,7 +5051,7 @@ index 0000000..26ee630
+ struct inode *dir;
+
+ parent = dget_parent(dentry);
-+ dir = parent->d_inode;
++ dir = d_inode(parent);
+ err = 0;
+ if (au_h_iptr(dir, bdst))
+ goto out;
@@ -5082,7 +5156,7 @@ index 0000000..3355f08
+#endif /* __AUFS_CPUP_H__ */
diff --git a/fs/aufs/dbgaufs.c b/fs/aufs/dbgaufs.c
new file mode 100644
-index 0000000..68af344
+index 0000000..c7c612c
--- /dev/null
+++ b/fs/aufs/dbgaufs.c
@@ -0,0 +1,419 @@
@@ -5432,7 +5506,7 @@ index 0000000..68af344
+void dbgaufs_si_fin(struct au_sbinfo *sbinfo)
+{
+ /*
-+ * This function is a dynamic '__init' function actually,
++ * This function is a dynamic '__fin' function actually,
+ * so the tiny check for si_rwsem is unnecessary.
+ */
+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
@@ -5765,10 +5839,10 @@ index 0000000..f9d9d52
+}
diff --git a/fs/aufs/dcsub.h b/fs/aufs/dcsub.h
new file mode 100644
-index 0000000..3d18314
+index 0000000..2aa87ac
--- /dev/null
+++ b/fs/aufs/dcsub.h
-@@ -0,0 +1,112 @@
+@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -5785,8 +5859,6 @@ index 0000000..3d18314
+#include
+#include
+
-+struct dentry;
-+
+struct au_dpage {
+ int ndentry;
+ struct dentry **dentries;
@@ -5821,10 +5893,12 @@ index 0000000..3d18314
+static inline int au_d_hashed_positive(struct dentry *d)
+{
+ int err;
-+ struct inode *inode = d->d_inode;
++ struct inode *inode = d_inode(d);
+
+ err = 0;
-+ if (unlikely(d_unhashed(d) || !inode || !inode->i_nlink))
++ if (unlikely(d_unhashed(d)
++ || d_is_negative(d)
++ || !inode->i_nlink))
+ err = -ENOENT;
+ return err;
+}
@@ -5832,11 +5906,11 @@ index 0000000..3d18314
+static inline int au_d_linkable(struct dentry *d)
+{
+ int err;
-+ struct inode *inode = d->d_inode;
++ struct inode *inode = d_inode(d);
+
+ err = au_d_hashed_positive(d);
+ if (err
-+ && inode
++ && d_is_positive(d)
+ && (inode->i_state & I_LINKABLE))
+ err = 0;
+ return err;
@@ -5851,8 +5925,10 @@ index 0000000..3d18314
+ if (!IS_ROOT(d))
+ err = au_d_hashed_positive(d);
+ else {
-+ inode = d->d_inode;
-+ if (unlikely(d_unlinked(d) || !inode || !inode->i_nlink))
++ inode = d_inode(d);
++ if (unlikely(d_unlinked(d)
++ || d_is_negative(d)
++ || !inode->i_nlink))
+ err = -ENOENT;
+ }
+ return err;
@@ -5863,7 +5939,7 @@ index 0000000..3d18314
+ int err;
+
+ err = au_d_alive(d);
-+ if (unlikely(err || IS_DEADDIR(d->d_inode)))
++ if (unlikely(err || IS_DEADDIR(d_inode(d))))
+ err = -ENOENT;
+ return err;
+}
@@ -5874,6 +5950,15 @@ index 0000000..3d18314
+ && !memcmp(a->name, b->name, a->len);
+}
+
++/*
++ * by the commit
++ * 360f547 2015-01-25 dcache: let the dentry count go down to zero without
++ * taking d_lock
++ * the type of d_lockref.count became int, but the inlined function d_count()
++ * still returns unsigned int.
++ * I don't know why. Maybe it is for every d_count() users?
++ * Anyway au_dcount() lives on.
++ */
+static inline int au_dcount(struct dentry *d)
+{
+ return (int)d_count(d);
@@ -5883,10 +5968,10 @@ index 0000000..3d18314
+#endif /* __AUFS_DCSUB_H__ */
diff --git a/fs/aufs/debug.c b/fs/aufs/debug.c
new file mode 100644
-index 0000000..b60f242
+index 0000000..e553cef
--- /dev/null
+++ b/fs/aufs/debug.c
-@@ -0,0 +1,509 @@
+@@ -0,0 +1,427 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -5895,7 +5980,6 @@ index 0000000..b60f242
+ * debug print functions
+ */
+
-+#include
+#include "aufs.h"
+
+/* Returns 0, or -errno. arg is in kp->arg. */
@@ -6068,14 +6152,16 @@ index 0000000..b60f242
+ au_dcount(dentry), dentry->d_flags,
+ d_unhashed(dentry) ? "un" : "");
+ hn = -1;
-+ if (bindex >= 0 && dentry->d_inode && au_test_aufs(dentry->d_sb)) {
-+ iinfo = au_ii(dentry->d_inode);
++ if (bindex >= 0
++ && d_is_positive(dentry)
++ && au_test_aufs(dentry->d_sb)) {
++ iinfo = au_ii(d_inode(dentry));
+ 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);
++ do_pri_inode(bindex, d_inode(dentry), hn, wh);
+ return 0;
+}
+
@@ -6114,7 +6200,7 @@ index 0000000..b60f242
+ }
+ a[0] = 0;
+ if (bindex < 0
-+ && file->f_path.dentry
++ && !IS_ERR_OR_NULL(file->f_path.dentry)
+ && au_test_aufs(file->f_path.dentry->d_sb)
+ && au_fi(file))
+ snprintf(a, sizeof(a), ", gen %d, mmapped %d",
@@ -6122,7 +6208,7 @@ index 0000000..b60f242
+ 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_path.dentry)
++ if (!IS_ERR_OR_NULL(file->f_path.dentry))
+ do_pri_dentry(bindex, file->f_path.dentry);
+ return 0;
+}
@@ -6137,7 +6223,7 @@ index 0000000..b60f242
+
+ err = do_pri_file(-1, file);
+ if (err
-+ || !file->f_path.dentry
++ || IS_ERR_OR_NULL(file->f_path.dentry)
+ || !au_test_aufs(file->f_path.dentry->d_sb))
+ return;
+
@@ -6228,45 +6314,9 @@ index 0000000..b60f242
+
+/* ---------------------------------------------------------------------- */
+
-+void au_dbg_sleep_jiffy(int jiffy)
-+{
-+ while (jiffy)
-+ jiffy = schedule_timeout_uninterruptible(jiffy);
-+}
-+
-+void au_dbg_iattr(struct iattr *ia)
-+{
-+#define AuBit(name) \
-+ do { \
-+ if (ia->ia_valid & ATTR_ ## name) \
-+ dpri(#name "\n"); \
-+ } while (0)
-+ 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 inode *h_inode, *inode = d_inode(dentry);
+ struct dentry *h_dentry;
+ aufs_bindex_t bindex, bend, bi;
+
@@ -6287,7 +6337,7 @@ index 0000000..b60f242
+ if (!h_dentry)
+ continue;
+ h_inode = au_h_iptr(inode, bindex);
-+ if (unlikely(h_inode != h_dentry->d_inode)) {
++ if (unlikely(h_inode != d_inode(h_dentry))) {
+ au_debug_on();
+ AuDbg("b%d, %s:%d\n", bindex, func, line);
+ AuDbgDentry(dentry);
@@ -6298,29 +6348,6 @@ index 0000000..b60f242
+ }
+}
+
-+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;
@@ -6355,26 +6382,6 @@ index 0000000..b60f242
+
+/* ---------------------------------------------------------------------- */
+
-+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;
@@ -6390,18 +6397,14 @@ index 0000000..b60f242
+ pr_warn("CONFIG_4KSTACKS is defined.\n");
+#endif
+
-+#ifdef AuForceNoBrs
-+ sysaufs_brs = 0;
-+#endif
-+
+ return 0;
+}
diff --git a/fs/aufs/debug.h b/fs/aufs/debug.h
new file mode 100644
-index 0000000..67a34f7
+index 0000000..0a2e7e7
--- /dev/null
+++ b/fs/aufs/debug.h
-@@ -0,0 +1,249 @@
+@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -6497,8 +6500,6 @@ index 0000000..67a34f7
+
+/* ---------------------------------------------------------------------- */
+
-+struct au_sbinfo;
-+struct au_finfo;
+struct dentry;
+#ifdef CONFIG_AUFS_DEBUG
+extern struct mutex au_dbg_mtx;
@@ -6516,19 +6517,13 @@ index 0000000..67a34f7
+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 { \
+ mutex_lock(&au_dbg_mtx); \
+ AuDbg(#w "\n"); \
@@ -6578,41 +6573,16 @@ index 0000000..67a34f7
+ mutex_unlock(&au_dbg_mtx); \
+} 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)
@@ -6621,11 +6591,7 @@ index 0000000..67a34f7
+#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 */
+
+/* ---------------------------------------------------------------------- */
@@ -6653,10 +6619,10 @@ index 0000000..67a34f7
+#endif /* __AUFS_DEBUG_H__ */
diff --git a/fs/aufs/dentry.c b/fs/aufs/dentry.c
new file mode 100644
-index 0000000..dd7514b
+index 0000000..993c95e
--- /dev/null
+++ b/fs/aufs/dentry.c
-@@ -0,0 +1,1083 @@
+@@ -0,0 +1,1092 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -6691,7 +6657,7 @@ index 0000000..dd7514b
+ struct au_do_lookup_args *args)
+{
+ struct dentry *h_dentry;
-+ struct inode *h_inode, *inode;
++ struct inode *h_inode;
+ struct au_branch *br;
+ int wh_found, opq;
+ unsigned char wh_able;
@@ -6721,11 +6687,15 @@ index 0000000..dd7514b
+ h_dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
+ else
+ h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent);
-+ if (IS_ERR(h_dentry))
++ if (IS_ERR(h_dentry)) {
++ if (PTR_ERR(h_dentry) == -ENAMETOOLONG
++ && !allow_neg)
++ h_dentry = NULL;
+ goto out;
++ }
+
-+ h_inode = h_dentry->d_inode;
-+ if (!h_inode) {
++ h_inode = d_inode(h_dentry);
++ if (d_is_negative(h_dentry)) {
+ if (!allow_neg)
+ goto out_neg;
+ } else if (wh_found
@@ -6738,9 +6708,9 @@ index 0000000..dd7514b
+ au_set_dbstart(dentry, bindex);
+ au_set_h_dptr(dentry, bindex, h_dentry);
+
-+ inode = dentry->d_inode;
-+ if (!h_inode || !S_ISDIR(h_inode->i_mode) || !wh_able
-+ || (inode && !S_ISDIR(inode->i_mode)))
++ if (!d_is_dir(h_dentry)
++ || !wh_able
++ || (d_really_is_positive(dentry) && !d_is_dir(dentry)))
+ goto out; /* success */
+
+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
@@ -6786,7 +6756,6 @@ index 0000000..dd7514b
+ };
+ const struct qstr *name = &dentry->d_name;
+ struct dentry *parent;
-+ struct inode *inode;
+ struct super_block *sb;
+
+ sb = dentry->d_sb;
@@ -6798,8 +6767,7 @@ index 0000000..dd7514b
+ if (unlikely(err))
+ goto out;
+
-+ inode = dentry->d_inode;
-+ isdir = !!(inode && S_ISDIR(inode->i_mode));
++ isdir = !!d_is_dir(dentry);
+ if (!type)
+ au_fset_lkup(args.flags, ALLOW_NEG);
+ dirperm1 = !!au_opt_test(au_mntflags(sb), DIRPERM1);
@@ -6813,19 +6781,17 @@ index 0000000..dd7514b
+
+ h_dentry = au_h_dptr(dentry, bindex);
+ if (h_dentry) {
-+ if (h_dentry->d_inode)
++ if (d_is_positive(h_dentry))
+ npositive++;
+ if (type != S_IFDIR)
+ break;
+ continue;
+ }
+ h_parent = au_h_dptr(parent, bindex);
-+ if (!h_parent)
-+ continue;
-+ h_dir = h_parent->d_inode;
-+ if (!h_dir || !S_ISDIR(h_dir->i_mode))
++ if (!h_parent || !d_is_dir(h_parent))
+ continue;
+
++ h_dir = d_inode(h_parent);
+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
+ h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname,
+ &args);
@@ -6833,7 +6799,8 @@ index 0000000..dd7514b
+ err = PTR_ERR(h_dentry);
+ if (IS_ERR(h_dentry))
+ goto out_parent;
-+ au_fclr_lkup(args.flags, ALLOW_NEG);
++ if (h_dentry)
++ au_fclr_lkup(args.flags, ALLOW_NEG);
+ if (dirperm1)
+ au_fset_lkup(args.flags, IGNORE_PERM);
+
@@ -6841,9 +6808,9 @@ index 0000000..dd7514b
+ break;
+ if (!h_dentry)
+ continue;
-+ h_inode = h_dentry->d_inode;
-+ if (!h_inode)
++ if (d_is_negative(h_dentry))
+ continue;
++ h_inode = d_inode(h_dentry);
+ npositive++;
+ if (!args.type)
+ args.type = h_inode->i_mode & S_IFMT;
@@ -6881,7 +6848,7 @@ index 0000000..dd7514b
+ struct dentry *dentry;
+ int wkq_err;
+
-+ if (!au_test_h_perm_sio(parent->d_inode, MAY_EXEC))
++ if (!au_test_h_perm_sio(d_inode(parent), MAY_EXEC))
+ dentry = vfsub_lkup_one(name, parent);
+ else {
+ struct vfsub_lkup_one_args args = {
@@ -6917,7 +6884,7 @@ index 0000000..dd7514b
+ err = PTR_ERR(h_dentry);
+ if (IS_ERR(h_dentry))
+ goto out;
-+ if (unlikely(h_dentry->d_inode)) {
++ if (unlikely(d_is_positive(h_dentry))) {
+ err = -EIO;
+ AuIOErr("%pd should be negative on b%d.\n", h_dentry, bindex);
+ dput(h_dentry);
@@ -6992,10 +6959,11 @@ index 0000000..dd7514b
+ err = 0;
+ memset(&ia, -1, sizeof(ia));
+ h_sb = h_dentry->d_sb;
-+ h_inode = h_dentry->d_inode;
-+ if (h_inode)
++ h_inode = NULL;
++ if (d_is_positive(h_dentry)) {
++ h_inode = d_inode(h_dentry);
+ au_iattr_save(&ia, h_inode);
-+ else if (au_test_nfs(h_sb) || au_test_fuse(h_sb))
++ } else if (au_test_nfs(h_sb) || au_test_fuse(h_sb))
+ /* nfs d_revalidate may return 0 for negative dentry */
+ /* fuse d_revalidate always return 0 for negative dentry */
+ goto out;
@@ -7008,7 +6976,7 @@ index 0000000..dd7514b
+
+ err = 0;
+ if (unlikely(h_d != h_dentry
-+ || h_d->d_inode != h_inode
++ || d_inode(h_d) != h_inode
+ || (h_inode && au_iattr_test(&ia, h_inode))))
+ err = au_busy_or_stale();
+ dput(h_d);
@@ -7027,7 +6995,7 @@ index 0000000..dd7514b
+ if (udba == AuOpt_UDBA_REVAL
+ && !au_test_fs_remote(h_dentry->d_sb)) {
+ IMustLock(h_dir);
-+ err = (h_dentry->d_parent->d_inode != h_dir);
++ err = (d_inode(h_dentry->d_parent) != h_dir);
+ } else if (udba != AuOpt_UDBA_NONE)
+ err = au_h_verify_dentry(h_dentry, h_parent, br);
+
@@ -7119,9 +7087,9 @@ index 0000000..dd7514b
+{
+ struct inode *inode;
+
-+ inode = dentry->d_inode;
-+ if (inode) {
-+ if (!S_ISDIR(inode->i_mode)) {
++ if (d_really_is_positive(dentry)) {
++ inode = d_inode(dentry);
++ if (!d_is_dir(dentry)) {
+ if (inode->i_nlink && !d_unhashed(dentry))
+ drop_nlink(inode);
+ } else {
@@ -7168,11 +7136,9 @@ index 0000000..dd7514b
+static void au_hide(struct dentry *dentry)
+{
+ int err;
-+ struct inode *inode;
+
+ AuDbgDentry(dentry);
-+ inode = dentry->d_inode;
-+ if (inode && S_ISDIR(inode->i_mode)) {
++ if (d_is_dir(dentry)) {
+ /* shrink_dcache_parent(dentry); */
+ err = au_hide_children(dentry);
+ if (unlikely(err))
@@ -7220,20 +7186,26 @@ index 0000000..dd7514b
+
+ err = 0;
+ AuDebugOn(dinfo->di_bstart < 0);
-+ orig_h.dentry = dinfo->di_hdentry[dinfo->di_bstart].hd_dentry;
-+ orig_h.inode = orig_h.dentry->d_inode;
+ orig_h.mode = 0;
-+ if (orig_h.inode)
++ orig_h.dentry = dinfo->di_hdentry[dinfo->di_bstart].hd_dentry;
++ orig_h.inode = NULL;
++ if (d_is_positive(orig_h.dentry)) {
++ orig_h.inode = d_inode(orig_h.dentry);
+ orig_h.mode = orig_h.inode->i_mode & S_IFMT;
++ }
+ memset(&tmp_h, 0, sizeof(tmp_h));
+ if (tmp->di_bstart >= 0) {
+ tmp_h.dentry = tmp->di_hdentry[tmp->di_bstart].hd_dentry;
-+ tmp_h.inode = tmp_h.dentry->d_inode;
-+ if (tmp_h.inode)
++ tmp_h.inode = NULL;
++ if (d_is_positive(tmp_h.dentry)) {
++ tmp_h.inode = d_inode(tmp_h.dentry);
+ tmp_h.mode = tmp_h.inode->i_mode & S_IFMT;
++ }
+ }
+
-+ inode = dentry->d_inode;
++ inode = NULL;
++ if (d_really_is_positive(dentry))
++ inode = d_inode(dentry);
+ if (!orig_h.inode) {
+ AuDbg("nagative originally\n");
+ if (inode) {
@@ -7313,8 +7285,8 @@ index 0000000..dd7514b
+ h_dentry = hd[bindex].hd_dentry;
+ if (!h_dentry)
+ continue;
-+ h_inode = h_dentry->d_inode;
-+ AuDebugOn(!h_inode);
++ AuDebugOn(d_is_negative(h_dentry));
++ h_inode = d_inode(h_dentry);
+ AuDebugOn(orig_h.mode
+ != (h_inode->i_mode
+ & S_IFMT));
@@ -7348,10 +7320,9 @@ index 0000000..dd7514b
+
+ DiMustWriteLock(dentry);
+ AuDebugOn(IS_ROOT(dentry));
-+ AuDebugOn(!parent->d_inode);
++ AuDebugOn(d_really_is_negative(parent));
+
+ sb = dentry->d_sb;
-+ inode = dentry->d_inode;
+ sigen = au_sigen(sb);
+ err = au_digen_test(parent, sigen);
+ if (unlikely(err))
@@ -7367,8 +7338,10 @@ index 0000000..dd7514b
+
+ if (d_unhashed(dentry) || ebrange /* || dinfo->di_tmpfile */) {
+ AuDebugOn(au_dbstart(dentry) < 0 && au_dbend(dentry) >= 0);
-+ if (inode)
++ if (d_really_is_positive(dentry)) {
++ inode = d_inode(dentry);
+ err = au_refresh_hinode_self(inode);
++ }
+ au_dbg_verify_dinode(dentry);
+ if (!err)
+ goto out_dgen; /* success */
@@ -7525,10 +7498,12 @@ index 0000000..dd7514b
+ continue;
+
+ /* UDBA tests */
-+ h_inode = h_dentry->d_inode;
-+ if (unlikely(!!inode != !!h_inode))
++ if (unlikely(!!inode != d_is_positive(h_dentry)))
+ goto err;
+
++ h_inode = NULL;
++ if (d_is_positive(h_dentry))
++ h_inode = d_inode(h_dentry);
+ h_plus = plus;
+ h_mode = mode;
+ h_cached_inode = h_inode;
@@ -7587,7 +7562,6 @@ index 0000000..dd7514b
+{
+ int err;
+ struct dentry *d, *parent;
-+ struct inode *inode;
+
+ if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR))
+ return simple_reval_dpath(dentry, sigen);
@@ -7606,7 +7580,6 @@ index 0000000..dd7514b
+ d = parent;
+ }
+
-+ inode = d->d_inode;
+ if (d != dentry)
+ di_write_lock_child2(d);
+
@@ -7663,7 +7636,9 @@ index 0000000..dd7514b
+ AuTraceErr(err);
+ goto out;
+ }
-+ inode = dentry->d_inode;
++ inode = NULL;
++ if (d_really_is_positive(dentry))
++ inode = d_inode(dentry);
+ if (unlikely(inode && is_bad_inode(inode))) {
+ err = -EINVAL;
+ AuTraceErr(err);
@@ -7968,10 +7943,10 @@ index 0000000..6516146
+#endif /* __AUFS_DENTRY_H__ */
diff --git a/fs/aufs/dinfo.c b/fs/aufs/dinfo.c
new file mode 100644
-index 0000000..cd29ce0
+index 0000000..25b971b
--- /dev/null
+++ b/fs/aufs/dinfo.c
-@@ -0,0 +1,531 @@
+@@ -0,0 +1,537 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -8181,24 +8156,30 @@ index 0000000..cd29ce0
+
+void di_read_lock(struct dentry *d, int flags, unsigned int lsc)
+{
++ struct inode *inode;
++
+ au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc);
-+ if (d->d_inode) {
++ if (d_really_is_positive(d)) {
++ inode = d_inode(d);
+ if (au_ftest_lock(flags, IW))
-+ do_ii_write_lock(d->d_inode, lsc);
++ do_ii_write_lock(inode, lsc);
+ else if (au_ftest_lock(flags, IR))
-+ do_ii_read_lock(d->d_inode, lsc);
++ do_ii_read_lock(inode, lsc);
+ }
+}
+
+void di_read_unlock(struct dentry *d, int flags)
+{
-+ if (d->d_inode) {
++ struct inode *inode;
++
++ if (d_really_is_positive(d)) {
++ inode = d_inode(d);
+ if (au_ftest_lock(flags, IW)) {
+ au_dbg_verify_dinode(d);
-+ ii_write_unlock(d->d_inode);
++ ii_write_unlock(inode);
+ } else if (au_ftest_lock(flags, IR)) {
+ au_dbg_verify_dinode(d);
-+ ii_read_unlock(d->d_inode);
++ ii_read_unlock(inode);
+ }
+ }
+ au_rw_read_unlock(&au_di(d)->di_rwsem);
@@ -8206,30 +8187,30 @@ index 0000000..cd29ce0
+
+void di_downgrade_lock(struct dentry *d, int flags)
+{
-+ if (d->d_inode && au_ftest_lock(flags, IR))
-+ ii_downgrade_lock(d->d_inode);
++ if (d_really_is_positive(d) && au_ftest_lock(flags, IR))
++ ii_downgrade_lock(d_inode(d));
+ 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);
++ if (d_really_is_positive(d))
++ do_ii_write_lock(d_inode(d), lsc);
+}
+
+void di_write_unlock(struct dentry *d)
+{
+ au_dbg_verify_dinode(d);
-+ if (d->d_inode)
-+ ii_write_unlock(d->d_inode);
++ if (d_really_is_positive(d))
++ ii_write_unlock(d_inode(d));
+ 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
++ || d_inode(d1) == d_inode(d2)
+ || d1->d_sb != d2->d_sb);
+
+ if (isdir && au_test_subdir(d1, d2)) {
@@ -8245,7 +8226,7 @@ index 0000000..cd29ce0
+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir)
+{
+ AuDebugOn(d1 == d2
-+ || d1->d_inode == d2->d_inode
++ || d_inode(d1) == d_inode(d2)
+ || d1->d_sb != d2->d_sb);
+
+ if (isdir && au_test_subdir(d1, d2)) {
@@ -8261,7 +8242,7 @@ index 0000000..cd29ce0
+void di_write_unlock2(struct dentry *d1, struct dentry *d2)
+{
+ di_write_unlock(d1);
-+ if (d1->d_inode == d2->d_inode)
++ if (d_inode(d1) == d_inode(d2))
+ au_rw_write_unlock(&au_di(d2)->di_rwsem);
+ else
+ di_write_unlock(d2);
@@ -8293,8 +8274,7 @@ index 0000000..cd29ce0
+ struct dentry *h_dentry;
+ struct inode *inode, *h_inode;
+
-+ inode = dentry->d_inode;
-+ AuDebugOn(!inode);
++ AuDebugOn(d_really_is_negative(dentry));
+
+ h_dentry = NULL;
+ if (au_dbstart(dentry) <= bindex
@@ -8305,6 +8285,7 @@ index 0000000..cd29ce0
+ goto out; /* success */
+ }
+
++ inode = d_inode(dentry);
+ AuDebugOn(bindex < au_ibstart(inode));
+ AuDebugOn(au_ibend(inode) < bindex);
+ h_inode = au_h_iptr(inode, bindex);
@@ -8404,7 +8385,7 @@ index 0000000..cd29ce0
+
+ err = 0;
+ if (unlikely(au_digen(dentry) != sigen
-+ || au_iigen_test(dentry->d_inode, sigen)))
++ || au_iigen_test(d_inode(dentry), sigen)))
+ err = -EIO;
+
+ return err;
@@ -8435,7 +8416,7 @@ index 0000000..cd29ce0
+ 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)
++ if (h_d && d_is_negative(h_d))
+ au_set_h_dptr(dentry, bindex, NULL);
+ }
+ }
@@ -8467,7 +8448,7 @@ index 0000000..cd29ce0
+ h_dentry = au_h_dptr(dentry, bindex);
+ if (!h_dentry)
+ continue;
-+ if (h_dentry->d_inode) {
++ if (d_is_positive(h_dentry)) {
+ au_set_dbstart(dentry, bindex);
+ return;
+ }
@@ -8485,7 +8466,7 @@ index 0000000..cd29ce0
+ h_dentry = au_h_dptr(dentry, bindex);
+ if (!h_dentry)
+ continue;
-+ if (h_dentry->d_inode) {
++ if (d_is_positive(h_dentry)) {
+ au_set_dbend(dentry, bindex);
+ return;
+ }
@@ -8505,10 +8486,10 @@ index 0000000..cd29ce0
+}
diff --git a/fs/aufs/dir.c b/fs/aufs/dir.c
new file mode 100644
-index 0000000..ffee6b4
+index 0000000..6308190
--- /dev/null
+++ b/fs/aufs/dir.c
-@@ -0,0 +1,632 @@
+@@ -0,0 +1,740 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -8559,8 +8540,7 @@ index 0000000..ffee6b4
+
+ sz = 0;
+ if (file) {
-+ AuDebugOn(!file_inode(file));
-+ AuDebugOn(!S_ISDIR(file_inode(file)->i_mode));
++ AuDebugOn(!d_is_dir(file->f_path.dentry));
+
+ bend = au_fbend_dir(file);
+ for (bindex = au_fbstart(file);
@@ -8572,16 +8552,15 @@ index 0000000..ffee6b4
+ }
+ } else {
+ AuDebugOn(!dentry);
-+ AuDebugOn(!dentry->d_inode);
-+ AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode));
++ AuDebugOn(!d_is_dir(dentry));
+
+ 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 (h_dentry && d_is_positive(h_dentry))
++ sz += i_size_read(d_inode(h_dentry));
+ }
+ }
+ if (sz < KMALLOC_MAX_SIZE)
@@ -8595,6 +8574,110 @@ index 0000000..ffee6b4
+ return sz;
+}
+
++struct au_dir_ts_arg {
++ struct dentry *dentry;
++ aufs_bindex_t brid;
++};
++
++static void au_do_dir_ts(void *arg)
++{
++ struct au_dir_ts_arg *a = arg;
++ struct au_dtime dt;
++ struct path h_path;
++ struct inode *dir, *h_dir;
++ struct super_block *sb;
++ struct au_branch *br;
++ struct au_hinode *hdir;
++ int err;
++ aufs_bindex_t bstart, bindex;
++
++ sb = a->dentry->d_sb;
++ if (d_really_is_negative(a->dentry))
++ goto out;
++ aufs_read_lock(a->dentry, AuLock_DW | AuLock_DIR); /* noflush */
++
++ /* no dir->i_mutex lock */
++ dir = d_inode(a->dentry);
++ bstart = au_ibstart(dir);
++ bindex = au_br_index(sb, a->brid);
++ if (bindex < bstart)
++ goto out_unlock;
++
++ br = au_sbr(sb, bindex);
++ h_path.dentry = au_h_dptr(a->dentry, bindex);
++ if (!h_path.dentry)
++ goto out_unlock;
++ h_path.mnt = au_br_mnt(br);
++ au_dtime_store(&dt, a->dentry, &h_path);
++
++ br = au_sbr(sb, bstart);
++ if (!au_br_writable(br->br_perm))
++ goto out_unlock;
++ h_path.dentry = au_h_dptr(a->dentry, bstart);
++ h_path.mnt = au_br_mnt(br);
++ err = vfsub_mnt_want_write(h_path.mnt);
++ if (err)
++ goto out_unlock;
++ hdir = au_hi(dir, bstart);
++ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
++ h_dir = au_h_iptr(dir, bstart);
++ if (h_dir->i_nlink
++ && timespec_compare(&h_dir->i_mtime, &dt.dt_mtime) < 0) {
++ dt.dt_h_path = h_path;
++ au_dtime_revert(&dt);
++ }
++ au_hn_imtx_unlock(hdir);
++ vfsub_mnt_drop_write(h_path.mnt);
++ au_cpup_attr_timesizes(dir);
++
++out_unlock:
++ aufs_read_unlock(a->dentry, AuLock_DW);
++out:
++ dput(a->dentry);
++ au_nwt_done(&au_sbi(sb)->si_nowait);
++ kfree(arg);
++}
++
++void au_dir_ts(struct inode *dir, aufs_bindex_t bindex)
++{
++ int perm, wkq_err;
++ aufs_bindex_t bstart;
++ struct au_dir_ts_arg *arg;
++ struct dentry *dentry;
++ struct super_block *sb;
++
++ IMustLock(dir);
++
++ dentry = d_find_any_alias(dir);
++ AuDebugOn(!dentry);
++ sb = dentry->d_sb;
++ bstart = au_ibstart(dir);
++ if (bstart == bindex) {
++ au_cpup_attr_timesizes(dir);
++ goto out;
++ }
++
++ perm = au_sbr_perm(sb, bstart);
++ if (!au_br_writable(perm))
++ goto out;
++
++ arg = kmalloc(sizeof(*arg), GFP_NOFS);
++ if (!arg)
++ goto out;
++
++ arg->dentry = dget(dentry); /* will be dput-ted by au_do_dir_ts() */
++ arg->brid = au_sbr_id(sb, bindex);
++ wkq_err = au_wkq_nowait(au_do_dir_ts, arg, sb, /*flags*/0);
++ if (unlikely(wkq_err)) {
++ pr_err("wkq %d\n", wkq_err);
++ dput(dentry);
++ kfree(arg);
++ }
++
++out:
++ dput(dentry);
++}
++
+/* ---------------------------------------------------------------------- */
+
+static int reopen_dir(struct file *file)
@@ -8641,18 +8724,18 @@ index 0000000..ffee6b4
+ return err;
+}
+
-+static int do_open_dir(struct file *file, int flags)
++static int do_open_dir(struct file *file, int flags, struct file *h_file)
+{
+ int err;
+ aufs_bindex_t bindex, btail;
+ struct dentry *dentry, *h_dentry;
-+ struct file *h_file;
+
+ FiMustWriteLock(file);
++ AuDebugOn(h_file);
+
+ err = 0;
+ dentry = file->f_path.dentry;
-+ file->f_version = dentry->d_inode->i_version;
++ file->f_version = d_inode(dentry)->i_version;
+ bindex = au_dbstart(dentry);
+ au_set_fbstart(file, bindex);
+ btail = au_dbtaildir(dentry);
@@ -8696,7 +8779,11 @@ index 0000000..ffee6b4
+ si_read_lock(sb, AuLock_FLUSH);
+ fidir = au_fidir_alloc(sb);
+ if (fidir) {
-+ err = au_do_open(file, do_open_dir, fidir);
++ struct au_do_open_args args = {
++ .open = do_open_dir,
++ .fidir = fidir
++ };
++ err = au_do_open(file, &args);
+ if (unlikely(err))
+ kfree(fidir);
+ }
@@ -8772,7 +8859,7 @@ index 0000000..ffee6b4
+
+ err = 0;
+ sb = dentry->d_sb;
-+ inode = dentry->d_inode;
++ inode = d_inode(dentry);
+ IMustLock(inode);
+ bend = au_dbend(dentry);
+ for (bindex = au_dbstart(dentry); !err && bindex <= bend; bindex++) {
@@ -8803,8 +8890,8 @@ index 0000000..ffee6b4
+ if (unlikely(err))
+ goto out;
+
-+ sb = file->f_path.dentry->d_sb;
+ inode = file_inode(file);
++ sb = inode->i_sb;
+ bend = au_fbend_dir(file);
+ for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
+ h_file = au_hf_dir(file, bindex);
@@ -8826,12 +8913,14 @@ index 0000000..ffee6b4
+{
+ int err;
+ struct dentry *dentry;
++ struct inode *inode;
+ struct super_block *sb;
+ struct mutex *mtx;
+
+ err = 0;
+ dentry = file->f_path.dentry;
-+ mtx = &dentry->d_inode->i_mutex;
++ inode = d_inode(dentry);
++ mtx = &inode->i_mutex;
+ mutex_lock(mtx);
+ sb = dentry->d_sb;
+ si_noflush_read_lock(sb);
@@ -8841,7 +8930,7 @@ index 0000000..ffee6b4
+ di_write_lock_child(dentry);
+ err = au_do_fsync_dir_no_file(dentry, datasync);
+ }
-+ au_cpup_attr_timesizes(dentry->d_inode);
++ au_cpup_attr_timesizes(inode);
+ di_write_unlock(dentry);
+ if (file)
+ fi_write_unlock(file);
@@ -8863,7 +8952,7 @@ index 0000000..ffee6b4
+ AuDbg("%pD, ctx{%pf, %llu}\n", file, ctx->actor, ctx->pos);
+
+ dentry = file->f_path.dentry;
-+ inode = dentry->d_inode;
++ inode = d_inode(dentry);
+ IMustLock(inode);
+
+ sb = dentry->d_sb;
@@ -9019,7 +9108,7 @@ index 0000000..ffee6b4
+ struct inode *h_inode;
+
+ h_dentry = au_h_dptr(dentry, arg->bindex);
-+ h_inode = h_dentry->d_inode;
++ h_inode = d_inode(h_dentry);
+ /* 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);
@@ -9084,7 +9173,7 @@ index 0000000..ffee6b4
+ struct dentry *h_dentry;
+
+ h_dentry = au_h_dptr(dentry, bindex);
-+ if (h_dentry && h_dentry->d_inode) {
++ if (h_dentry && d_is_positive(h_dentry)) {
+ arg.bindex = bindex;
+ err = test_empty(dentry, &arg);
+ }
@@ -9116,7 +9205,7 @@ index 0000000..ffee6b4
+ struct dentry *h_dentry;
+
+ h_dentry = au_h_dptr(dentry, bindex);
-+ if (h_dentry && h_dentry->d_inode) {
++ if (h_dentry && d_is_positive(h_dentry)) {
+ arg.bindex = bindex;
+ err = sio_test_empty(dentry, &arg);
+ }
@@ -9143,10 +9232,10 @@ index 0000000..ffee6b4
+};
diff --git a/fs/aufs/dir.h b/fs/aufs/dir.h
new file mode 100644
-index 0000000..cefad5a
+index 0000000..803a0f1
--- /dev/null
+++ b/fs/aufs/dir.h
-@@ -0,0 +1,117 @@
+@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -9226,6 +9315,7 @@ index 0000000..cefad5a
+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);
++void au_dir_ts(struct inode *dir, aufs_bindex_t bsrc);
+int au_test_empty_lower(struct dentry *dentry);
+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist);
+
@@ -9266,10 +9356,10 @@ index 0000000..cefad5a
+#endif /* __AUFS_DIR_H__ */
diff --git a/fs/aufs/dynop.c b/fs/aufs/dynop.c
new file mode 100644
-index 0000000..b1052e9
+index 0000000..1f12838
--- /dev/null
+++ b/fs/aufs/dynop.c
-@@ -0,0 +1,366 @@
+@@ -0,0 +1,356 @@
+/*
+ * Copyright (C) 2010-2015 Junjiro R. Okajima
+ */
@@ -9445,9 +9535,8 @@ index 0000000..b1052e9
+ DySetAop(invalidatepage);
+ DySetAop(releasepage);
+ DySetAop(freepage);
-+ /* these two will be changed according to an aufs mount option */
++ /* this one 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);
@@ -9457,7 +9546,6 @@ index 0000000..b1052e9
+ DySetAop(swap_deactivate);
+
+ DyDbgSize(cnt, *h_aop);
-+ dyaop->da_get_xip_mem = h_aop->get_xip_mem;
+}
+
+/* ---------------------------------------------------------------------- */
@@ -9521,21 +9609,13 @@ index 0000000..b1052e9
+ * 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) {
++ if (!do_dx)
+ dyaop->da_op.direct_IO = NULL;
-+ dyaop->da_op.get_xip_mem = NULL;
-+ } else {
++ 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,
@@ -9638,10 +9718,10 @@ index 0000000..b1052e9
+}
diff --git a/fs/aufs/dynop.h b/fs/aufs/dynop.h
new file mode 100644
-index 0000000..d68ec7a
+index 0000000..6d739c1
--- /dev/null
+++ b/fs/aufs/dynop.h
-@@ -0,0 +1,62 @@
+@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2010-2015 Junjiro R. Okajima
+ */
@@ -9655,7 +9735,8 @@ index 0000000..d68ec7a
+
+#ifdef __KERNEL__
+
-+#include "inode.h"
++#include
++#include
+
+enum {AuDy_AOP, AuDyLast};
+
@@ -9685,8 +9766,6 @@ index 0000000..d68ec7a
+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 *);
+};
+
+/* ---------------------------------------------------------------------- */
@@ -9706,10 +9785,10 @@ index 0000000..d68ec7a
+#endif /* __AUFS_DYNOP_H__ */
diff --git a/fs/aufs/export.c b/fs/aufs/export.c
new file mode 100644
-index 0000000..61501e1
+index 0000000..3026f39
--- /dev/null
+++ b/fs/aufs/export.c
-@@ -0,0 +1,818 @@
+@@ -0,0 +1,819 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -9945,7 +10024,7 @@ index 0000000..61501e1
+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) {
+ spin_lock(&d->d_lock);
+ if (!au_test_anon(d)
-+ && d->d_parent->d_inode->i_ino == dir_ino) {
++ && d_inode(d->d_parent)->i_ino == dir_ino) {
+ dentry = dget_dlock(d);
+ spin_unlock(&d->d_lock);
+ break;
@@ -10104,7 +10183,7 @@ index 0000000..61501e1
+ goto out_name;
+
+ /* do not call vfsub_lkup_one() */
-+ dir = parent->d_inode;
++ dir = d_inode(parent);
+ mutex_lock(&dir->i_mutex);
+ dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen);
+ mutex_unlock(&dir->i_mutex);
@@ -10112,7 +10191,7 @@ index 0000000..61501e1
+ if (IS_ERR(dentry))
+ goto out_name;
+ AuDebugOn(au_test_anon(dentry));
-+ if (unlikely(!dentry->d_inode)) {
++ if (unlikely(d_really_is_negative(dentry))) {
+ dput(dentry);
+ dentry = ERR_PTR(-ENOENT);
+ }
@@ -10253,10 +10332,10 @@ index 0000000..61501e1
+
+ dentry = ERR_PTR(-ENOENT);
+ AuDebugOn(au_test_anon(path.dentry));
-+ if (unlikely(!path.dentry->d_inode))
++ if (unlikely(d_really_is_negative(path.dentry)))
+ goto out_path;
+
-+ if (ino != path.dentry->d_inode->i_ino)
++ if (ino != d_inode(path.dentry)->i_ino)
+ dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL);
+ else
+ dentry = dget(path.dentry);
@@ -10337,7 +10416,7 @@ index 0000000..61501e1
+
+accept:
+ if (!au_digen_test(dentry, au_sigen(sb))
-+ && dentry->d_inode->i_generation == fh[Fh_igen])
++ && d_inode(dentry)->i_generation == fh[Fh_igen])
+ goto out_unlock; /* success */
+
+ dput(dentry);
@@ -10421,7 +10500,8 @@ index 0000000..61501e1
+ dput(dentry);
+ if (unlikely(!parent))
+ goto out_unlock;
-+ dir = parent->d_inode;
++ if (d_really_is_positive(parent))
++ dir = d_inode(parent);
+ }
+
+ ii_read_lock_parent(dir);
@@ -10530,10 +10610,10 @@ index 0000000..61501e1
+}
diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c
new file mode 100644
-index 0000000..41c4c4a
+index 0000000..91c2ce7
--- /dev/null
+++ b/fs/aufs/f_op.c
-@@ -0,0 +1,801 @@
+@@ -0,0 +1,725 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -10548,11 +10628,10 @@ index 0000000..41c4c4a
+#include
+#include "aufs.h"
+
-+int au_do_open_nondir(struct file *file, int flags)
++int au_do_open_nondir(struct file *file, int flags, struct file *h_file)
+{
+ int err;
+ aufs_bindex_t bindex;
-+ struct file *h_file;
+ struct dentry *dentry;
+ struct au_finfo *finfo;
+ struct inode *h_inode;
@@ -10561,11 +10640,15 @@ index 0000000..41c4c4a
+
+ err = 0;
+ dentry = file->f_path.dentry;
++ AuDebugOn(IS_ERR_OR_NULL(dentry));
+ 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, /*force_wr*/0);
++ if (!h_file)
++ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
++ else
++ get_file(h_file);
+ if (IS_ERR(h_file))
+ err = PTR_ERR(h_file);
+ else {
@@ -10591,13 +10674,16 @@ index 0000000..41c4c4a
+{
+ int err;
+ struct super_block *sb;
++ struct au_do_open_args args = {
++ .open = au_do_open_nondir
++ };
+
+ AuDbg("%pD, f_flags 0x%x, f_mode 0x%x\n",
+ file, vfsub_file_flags(file), file->f_mode);
+
+ sb = file->f_path.dentry->d_sb;
+ si_read_lock(sb, AuLock_FLUSH);
-+ err = au_do_open(file, au_do_open_nondir, /*fidir*/NULL);
++ err = au_do_open(file, &args);
+ si_read_unlock(sb);
+ return err;
+}
@@ -10646,33 +10732,122 @@ index 0000000..41c4c4a
+ * read functions after [fdi]_rwsem are released, but it should be harmless.
+ */
+
++/* Callers should call au_read_post() or fput() in the end */
++struct file *au_read_pre(struct file *file, int keep_fi)
++{
++ struct file *h_file;
++ int err;
++
++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
++ if (!err) {
++ di_read_unlock(file->f_path.dentry, AuLock_IR);
++ h_file = au_hf_top(file);
++ get_file(h_file);
++ if (!keep_fi)
++ fi_read_unlock(file);
++ } else
++ h_file = ERR_PTR(err);
++
++ return h_file;
++}
++
++static void au_read_post(struct inode *inode, struct file *h_file)
++{
++ /* update without lock, I don't think it a problem */
++ fsstack_copy_attr_atime(inode, file_inode(h_file));
++ fput(h_file);
++}
++
++struct au_write_pre {
++ blkcnt_t blks;
++ aufs_bindex_t bstart;
++};
++
++/*
++ * return with iinfo is write-locked
++ * callers should call au_write_post() or iinfo_write_unlock() + fput() in the
++ * end
++ */
++static struct file *au_write_pre(struct file *file, int do_ready,
++ struct au_write_pre *wpre)
++{
++ struct file *h_file;
++ struct dentry *dentry;
++ int err;
++ struct au_pin pin;
++
++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
++ h_file = ERR_PTR(err);
++ if (unlikely(err))
++ goto out;
++
++ dentry = file->f_path.dentry;
++ if (do_ready) {
++ err = au_ready_to_write(file, -1, &pin);
++ if (unlikely(err)) {
++ h_file = ERR_PTR(err);
++ di_write_unlock(dentry);
++ goto out_fi;
++ }
++ }
++
++ di_downgrade_lock(dentry, /*flags*/0);
++ if (wpre)
++ wpre->bstart = au_fbstart(file);
++ h_file = au_hf_top(file);
++ get_file(h_file);
++ if (wpre)
++ wpre->blks = file_inode(h_file)->i_blocks;
++ if (do_ready)
++ au_unpin(&pin);
++ di_read_unlock(dentry, /*flags*/0);
++
++out_fi:
++ fi_write_unlock(file);
++out:
++ return h_file;
++}
++
++static void au_write_post(struct inode *inode, struct file *h_file,
++ struct au_write_pre *wpre, ssize_t written)
++{
++ struct inode *h_inode;
++
++ au_cpup_attr_timesizes(inode);
++ AuDebugOn(au_ibstart(inode) != wpre->bstart);
++ h_inode = file_inode(h_file);
++ inode->i_mode = h_inode->i_mode;
++ ii_write_unlock(inode);
++ fput(h_file);
++
++ /* AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks); */
++ if (written > 0)
++ au_fhsm_wrote(inode->i_sb, wpre->bstart,
++ /*force*/h_inode->i_blocks > wpre->blks);
++}
++
+static ssize_t aufs_read(struct file *file, char __user *buf, size_t count,
+ loff_t *ppos)
+{
+ ssize_t err;
-+ struct dentry *dentry;
++ struct inode *inode;
+ struct file *h_file;
+ struct super_block *sb;
+
-+ dentry = file->f_path.dentry;
-+ sb = dentry->d_sb;
++ inode = file_inode(file);
++ sb = inode->i_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);
++ h_file = au_read_pre(file, /*keep_fi*/0);
++ err = PTR_ERR(h_file);
++ if (IS_ERR(h_file))
++ goto out;
+
+ /* 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, file_inode(h_file));
-+ fput(h_file);
++ au_read_post(inode, h_file);
+
+out:
+ si_read_unlock(sb);
@@ -10705,53 +10880,24 @@ index 0000000..41c4c4a
+ size_t count, loff_t *ppos)
+{
+ ssize_t err;
-+ blkcnt_t blks;
-+ aufs_bindex_t bstart;
-+ struct au_pin pin;
-+ struct dentry *dentry;
-+ struct inode *inode, *h_inode;
-+ struct super_block *sb;
++ struct au_write_pre wpre;
++ struct inode *inode;
+ struct file *h_file;
+ char __user *buf = (char __user *)ubuf;
+
-+ dentry = file->f_path.dentry;
-+ sb = dentry->d_sb;
-+ inode = dentry->d_inode;
++ inode = file_inode(file);
+ au_mtx_and_read_lock(inode);
+
-+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
-+ if (unlikely(err))
++ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
++ err = PTR_ERR(h_file);
++ if (IS_ERR(h_file))
+ 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;
-+ }
-+
-+ bstart = au_fbstart(file);
-+ h_file = au_hf_top(file);
-+ get_file(h_file);
-+ h_inode = file_inode(h_file);
-+ blks = h_inode->i_blocks;
-+ 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 = file_inode(h_file)->i_mode;
-+ AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks);
-+ if (err > 0)
-+ au_fhsm_wrote(sb, bstart, /*force*/h_inode->i_blocks > blks);
-+ ii_write_unlock(inode);
-+ fput(h_file);
++ au_write_post(inode, h_file, &wpre, err);
+
+out:
-+ si_read_unlock(sb);
++ si_read_unlock(inode->i_sb);
+ mutex_unlock(&inode->i_mutex);
+ return err;
+}
@@ -10762,8 +10908,6 @@ index 0000000..41c4c4a
+ ssize_t err;
+ struct file *file;
+ ssize_t (*iter)(struct kiocb *, struct iov_iter *);
-+ ssize_t (*aio)(struct kiocb *, const struct iovec *, unsigned long,
-+ loff_t);
+
+ err = security_file_permission(h_file, rw);
+ if (unlikely(err))
@@ -10771,14 +10915,10 @@ index 0000000..41c4c4a
+
+ err = -ENOSYS;
+ iter = NULL;
-+ aio = NULL;
-+ if (rw == MAY_READ) {
++ if (rw == MAY_READ)
+ iter = h_file->f_op->read_iter;
-+ aio = h_file->f_op->aio_read;
-+ } else if (rw == MAY_WRITE) {
++ else if (rw == MAY_WRITE)
+ iter = h_file->f_op->write_iter;
-+ aio = h_file->f_op->aio_write;
-+ }
+
+ file = kio->ki_filp;
+ kio->ki_filp = h_file;
@@ -10786,10 +10926,6 @@ index 0000000..41c4c4a
+ lockdep_off();
+ err = iter(kio, iov_iter);
+ lockdep_on();
-+ } else if (aio) {
-+ lockdep_off();
-+ err = aio(kio, iov_iter->iov, iov_iter->nr_segs, kio->ki_pos);
-+ lockdep_on();
+ } else
+ /* currently there is no such fs */
+ WARN_ON_ONCE(1);
@@ -10803,28 +10939,23 @@ index 0000000..41c4c4a
+{
+ ssize_t err;
+ struct file *file, *h_file;
-+ struct dentry *dentry;
++ struct inode *inode;
+ struct super_block *sb;
+
+ file = kio->ki_filp;
-+ dentry = file->f_path.dentry;
-+ sb = dentry->d_sb;
++ inode = file_inode(file);
++ sb = inode->i_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);
++ h_file = au_read_pre(file, /*keep_fi*/0);
++ err = PTR_ERR(h_file);
++ if (IS_ERR(h_file))
++ goto out;
+
+ err = au_do_iter(h_file, MAY_READ, kio, iov_iter);
+ /* 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, file_inode(h_file));
-+ fput(h_file);
++ au_read_post(inode, h_file);
+
+out:
+ si_read_unlock(sb);
@@ -10834,53 +10965,24 @@ index 0000000..41c4c4a
+static ssize_t aufs_write_iter(struct kiocb *kio, struct iov_iter *iov_iter)
+{
+ ssize_t err;
-+ blkcnt_t blks;
-+ aufs_bindex_t bstart;
-+ struct au_pin pin;
-+ struct dentry *dentry;
-+ struct inode *inode, *h_inode;
++ struct au_write_pre wpre;
++ struct inode *inode;
+ struct file *file, *h_file;
-+ struct super_block *sb;
+
+ file = kio->ki_filp;
-+ dentry = file->f_path.dentry;
-+ sb = dentry->d_sb;
-+ inode = dentry->d_inode;
++ inode = file_inode(file);
+ au_mtx_and_read_lock(inode);
+
-+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
-+ if (unlikely(err))
++ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
++ err = PTR_ERR(h_file);
++ if (IS_ERR(h_file))
+ 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;
-+ }
-+
-+ bstart = au_fbstart(file);
-+ h_file = au_hf_top(file);
-+ get_file(h_file);
-+ h_inode = file_inode(h_file);
-+ blks = h_inode->i_blocks;
-+ au_unpin(&pin);
-+ di_read_unlock(dentry, AuLock_IR);
-+ fi_write_unlock(file);
-+
+ err = au_do_iter(h_file, MAY_WRITE, kio, iov_iter);
-+ ii_write_lock_child(inode);
-+ au_cpup_attr_timesizes(inode);
-+ inode->i_mode = file_inode(h_file)->i_mode;
-+ AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks);
-+ if (err > 0)
-+ au_fhsm_wrote(sb, bstart, /*force*/h_inode->i_blocks > blks);
-+ ii_write_unlock(inode);
-+ fput(h_file);
++ au_write_post(inode, h_file, &wpre, err);
+
+out:
-+ si_read_unlock(sb);
++ si_read_unlock(inode->i_sb);
+ mutex_unlock(&inode->i_mutex);
+ return err;
+}
@@ -10891,19 +10993,18 @@ index 0000000..41c4c4a
+{
+ ssize_t err;
+ struct file *h_file;
-+ struct dentry *dentry;
++ struct inode *inode;
+ struct super_block *sb;
+
-+ dentry = file->f_path.dentry;
-+ sb = dentry->d_sb;
++ inode = file_inode(file);
++ sb = inode->i_sb;
+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
-+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
-+ if (unlikely(err))
++
++ h_file = au_read_pre(file, /*keep_fi*/1);
++ err = PTR_ERR(h_file);
++ if (IS_ERR(h_file))
+ 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_path.dentry->d_sb);
+ if (file->f_mapping != h_file->f_mapping) {
@@ -10911,15 +11012,12 @@ index 0000000..41c4c4a
+ 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, file_inode(h_file));
-+ fput(h_file);
++ au_read_post(inode, h_file);
+
+out:
+ si_read_unlock(sb);
@@ -10931,52 +11029,23 @@ index 0000000..41c4c4a
+ size_t len, unsigned int flags)
+{
+ ssize_t err;
-+ blkcnt_t blks;
-+ aufs_bindex_t bstart;
-+ struct au_pin pin;
-+ struct dentry *dentry;
-+ struct inode *inode, *h_inode;
-+ struct super_block *sb;
++ struct au_write_pre wpre;
++ struct inode *inode;
+ struct file *h_file;
+
-+ dentry = file->f_path.dentry;
-+ sb = dentry->d_sb;
-+ inode = dentry->d_inode;
++ inode = file_inode(file);
+ au_mtx_and_read_lock(inode);
+
-+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
-+ if (unlikely(err))
++ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
++ err = PTR_ERR(h_file);
++ if (IS_ERR(h_file))
+ 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;
-+ }
-+
-+ bstart = au_fbstart(file);
-+ h_file = au_hf_top(file);
-+ get_file(h_file);
-+ h_inode = file_inode(h_file);
-+ blks = h_inode->i_blocks;
-+ 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 = file_inode(h_file)->i_mode;
-+ AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks);
-+ if (err > 0)
-+ au_fhsm_wrote(sb, bstart, /*force*/h_inode->i_blocks > blks);
-+ ii_write_unlock(inode);
-+ fput(h_file);
++ au_write_post(inode, h_file, &wpre, err);
+
+out:
-+ si_read_unlock(sb);
++ si_read_unlock(inode->i_sb);
+ mutex_unlock(&inode->i_mutex);
+ return err;
+}
@@ -10985,46 +11054,25 @@ index 0000000..41c4c4a
+ loff_t len)
+{
+ long err;
-+ struct au_pin pin;
-+ struct dentry *dentry;
-+ struct super_block *sb;
++ struct au_write_pre wpre;
+ struct inode *inode;
+ struct file *h_file;
+
-+ dentry = file->f_path.dentry;
-+ sb = dentry->d_sb;
-+ inode = dentry->d_inode;
++ inode = file_inode(file);
+ au_mtx_and_read_lock(inode);
+
-+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
-+ if (unlikely(err))
++ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
++ err = PTR_ERR(h_file);
++ if (IS_ERR(h_file))
+ 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);
-+
+ lockdep_off();
+ err = vfs_fallocate(h_file, mode, offset, len);
+ lockdep_on();
-+ ii_write_lock_child(inode);
-+ au_cpup_attr_timesizes(inode);
-+ inode->i_mode = file_inode(h_file)->i_mode;
-+ ii_write_unlock(inode);
-+ fput(h_file);
++ au_write_post(inode, h_file, &wpre, /*written*/1);
+
+out:
-+ si_read_unlock(sb);
++ si_read_unlock(inode->i_sb);
+ mutex_unlock(&inode->i_mutex);
+ return err;
+}
@@ -11089,44 +11137,27 @@ index 0000000..41c4c4a
+static int aufs_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ int err;
-+ 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;
++ struct inode *inode;
+
+ AuDbgVmRegion(file, vma);
+
-+ dentry = file->f_path.dentry;
-+ sb = dentry->d_sb;
++ inode = file_inode(file);
++ sb = inode->i_sb;
+ lockdep_off();
+ si_read_lock(sb, AuLock_NOPLMW);
-+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
-+ if (unlikely(err))
++
++ h_file = au_write_pre(file, wlock, /*wpre*/NULL);
++ lockdep_on();
++ err = PTR_ERR(h_file);
++ if (IS_ERR(h_file))
+ 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);
++ err = 0;
+ au_set_mmapped(file);
-+ fi_write_unlock(file);
-+ lockdep_on();
-+
+ au_vm_file_reset(vma, h_file);
+ /*
+ * we cannot call security_mmap_file() here since it may acquire
@@ -11137,21 +11168,21 @@ index 0000000..41c4c4a
+ */
+ 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_inode(file), file_inode(h_file));
-+ goto out_fput; /* success */
-+
-+out_reset:
++ if (!err) {
++ au_vm_prfile_set(vma, file);
++ fsstack_copy_attr_atime(inode, file_inode(h_file));
++ goto out_fput; /* success */
++ }
+ au_unset_mmapped(file);
+ au_vm_file_reset(vma, file);
++
+out_fput:
-+ fput(h_file);
+ lockdep_off();
++ ii_write_unlock(inode);
++ lockdep_on();
++ fput(h_file);
+out:
++ lockdep_off();
+ si_read_unlock(sb);
+ lockdep_on();
+ AuTraceErr(err);
@@ -11164,45 +11195,29 @@ index 0000000..41c4c4a
+ int datasync)
+{
+ int err;
-+ struct au_pin pin;
-+ struct dentry *dentry;
++ struct au_write_pre wpre;
+ struct inode *inode;
+ struct file *h_file;
-+ struct super_block *sb;
-+
-+ dentry = file->f_path.dentry;
-+ inode = dentry->d_inode;
-+ sb = dentry->d_sb;
-+ mutex_lock(&inode->i_mutex);
-+ 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;
++ goto out;
+
-+ err = au_ready_to_write(file, -1, &pin);
-+ di_downgrade_lock(dentry, AuLock_IR);
-+ if (unlikely(err))
++ inode = file_inode(file);
++ au_mtx_and_read_lock(inode);
++
++ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
++ err = PTR_ERR(h_file);
++ if (IS_ERR(h_file))
+ 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);
++ au_write_post(inode, h_file, &wpre, /*written*/0);
+
+out_unlock:
-+ di_read_unlock(dentry, AuLock_IR);
-+ fi_write_unlock(file);
-+out_si:
-+ si_read_unlock(sb);
-+out:
++ si_read_unlock(inode->i_sb);
+ mutex_unlock(&inode->i_mutex);
++out:
+ return err;
+}
+
@@ -11211,28 +11226,22 @@ index 0000000..41c4c4a
+static int aufs_aio_fsync_nondir(struct kiocb *kio, int datasync)
+{
+ int err;
-+ struct au_pin pin;
-+ struct dentry *dentry;
++ struct au_write_pre wpre;
+ struct inode *inode;
+ struct file *file, *h_file;
+
-+ file = kio->ki_filp;
-+ dentry = file->f_path.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))
++ file = kio->ki_filp;
++ inode = file_inode(file);
++ au_mtx_and_read_lock(inode);
++
++ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
++ err = PTR_ERR(h_file);
++ if (IS_ERR(h_file))
+ goto out_unlock;
-+ au_unpin(&pin);
+
+ err = -ENOSYS;
+ h_file = au_hf_top(file);
@@ -11250,16 +11259,14 @@ index 0000000..41c4c4a
+ if (!err)
+ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL);
+ /*ignore*/
-+ au_cpup_attr_timesizes(inode);
+ mutex_unlock(h_mtx);
+ }
++ au_write_post(inode, h_file, &wpre, /*written*/0);
+
+out_unlock:
-+ di_read_unlock(dentry, AuLock_IR);
-+ fi_write_unlock(file);
-+out:
+ si_read_unlock(inode->sb);
+ mutex_unlock(&inode->i_mutex);
++out:
+ return err;
+}
+#endif
@@ -11268,22 +11275,19 @@ index 0000000..41c4c4a
+{
+ int err;
+ struct file *h_file;
-+ struct dentry *dentry;
+ struct super_block *sb;
+
-+ dentry = file->f_path.dentry;
-+ sb = dentry->d_sb;
++ sb = file->f_path.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))
++
++ h_file = au_read_pre(file, /*keep_fi*/0);
++ err = PTR_ERR(h_file);
++ if (IS_ERR(h_file))
+ goto out;
+
-+ h_file = au_hf_top(file);
+ if (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);
++ fput(h_file); /* instead of au_read_post() */
+
+out:
+ si_read_unlock(sb);
@@ -11755,10 +11759,10 @@ index 0000000..47106cb
+}
diff --git a/fs/aufs/file.c b/fs/aufs/file.c
new file mode 100644
-index 0000000..cf680cb
+index 0000000..8b17fba
--- /dev/null
+++ b/fs/aufs/file.c
-@@ -0,0 +1,816 @@
+@@ -0,0 +1,828 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -11791,20 +11795,17 @@ index 0000000..cf680cb
+ struct super_block *sb;
+ struct au_branch *br;
+ struct path h_path;
-+ int err, exec_flag;
++ int err;
+
+ /* 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)
++ if (au_test_nfsd() && (!h_dentry || d_is_negative(h_dentry)))
+ goto out;
++ h_inode = d_inode(h_dentry);
+ spin_lock(&h_dentry->d_lock);
+ err = (!d_unhashed(dentry) && d_unlinked(h_dentry))
-+ || !h_inode
-+ /* || !dentry->d_inode->i_nlink */
++ /* || !d_inode(dentry)->i_nlink */
+ ;
+ spin_unlock(&h_dentry->d_lock);
+ if (unlikely(err))
@@ -11812,13 +11813,13 @@ index 0000000..cf680cb
+
+ sb = dentry->d_sb;
+ br = au_sbr(sb, bindex);
-+ h_file = ERR_PTR(-EACCES);
-+ exec_flag = flags & __FMODE_EXEC;
-+ if (exec_flag && (au_br_mnt(br)->mnt_flags & MNT_NOEXEC))
++ err = au_br_test_oflag(flags, br);
++ h_file = ERR_PTR(err);
++ if (unlikely(err))
+ goto out;
+
+ /* drop flags for writing */
-+ if (au_test_ro(sb, bindex, dentry->d_inode)) {
++ if (au_test_ro(sb, bindex, d_inode(dentry))) {
+ if (force_wr && !(flags & O_WRONLY))
+ force_wr = 0;
+ flags = au_file_roflags(flags);
@@ -11840,7 +11841,7 @@ index 0000000..cf680cb
+ if (IS_ERR(h_file))
+ goto out_br;
+
-+ if (exec_flag) {
++ if (flags & __FMODE_EXEC) {
+ err = deny_write_access(h_file);
+ if (unlikely(err)) {
+ fput(h_file);
@@ -11871,7 +11872,7 @@ index 0000000..cf680cb
+ .pin = &pin,
+ .flags = AuCpup_DTIME | AuCpup_HOPEN
+ };
-+ struct inode *inode, *delegated;
++ struct inode *delegated;
+ struct super_block *sb;
+ struct au_sbinfo *sbinfo;
+ struct au_fhsm *fhsm;
@@ -11881,8 +11882,7 @@ index 0000000..cf680cb
+ struct au_hinode *hdir;
+
+ DiMustWriteLock(dentry);
-+ inode = dentry->d_inode;
-+ IiMustWriteLock(inode);
++ IiMustWriteLock(d_inode(dentry));
+
+ err = 0;
+ if (IS_ROOT(dentry))
@@ -11904,7 +11904,7 @@ index 0000000..cf680cb
+ cmoo = au_br_cmoo(br->br_perm);
+ if (!cmoo)
+ goto out;
-+ if (!S_ISREG(inode->i_mode))
++ if (!d_is_reg(dentry))
+ cmoo &= AuBrAttr_COO_ALL;
+ if (!cmoo)
+ goto out;
@@ -11945,7 +11945,7 @@ index 0000000..cf680cb
+
+ h_path.mnt = au_br_mnt(br);
+ h_path.dentry = au_h_dptr(dentry, cpg.bsrc);
-+ hdir = au_hi(parent->d_inode, cpg.bsrc);
++ hdir = au_hi(d_inode(parent), cpg.bsrc);
+ delegated = NULL;
+ err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated, /*force*/1);
+ au_unpin(&pin);
@@ -11972,24 +11972,43 @@ index 0000000..cf680cb
+ return err;
+}
+
-+int au_do_open(struct file *file, int (*open)(struct file *file, int flags),
-+ struct au_fidir *fidir)
++int au_do_open(struct file *file, struct au_do_open_args *args)
+{
-+ int err;
++ int err, no_lock = args->no_lock;
+ struct dentry *dentry;
+ struct au_finfo *finfo;
+
-+ err = au_finfo_init(file, fidir);
++ if (!no_lock)
++ err = au_finfo_init(file, args->fidir);
++ else {
++ lockdep_off();
++ err = au_finfo_init(file, args->fidir);
++ lockdep_on();
++ }
+ if (unlikely(err))
+ goto out;
+
+ dentry = file->f_path.dentry;
-+ di_write_lock_child(dentry);
-+ err = au_cmoo(dentry);
-+ di_downgrade_lock(dentry, AuLock_IR);
-+ if (!err)
-+ err = open(file, vfsub_file_flags(file));
-+ di_read_unlock(dentry, AuLock_IR);
++ AuDebugOn(IS_ERR_OR_NULL(dentry));
++ if (!no_lock) {
++ di_write_lock_child(dentry);
++ err = au_cmoo(dentry);
++ di_downgrade_lock(dentry, AuLock_IR);
++ if (!err)
++ err = args->open(file, vfsub_file_flags(file), NULL);
++ di_read_unlock(dentry, AuLock_IR);
++ } else {
++ err = au_cmoo(dentry);
++ if (!err)
++ err = args->open(file, vfsub_file_flags(file),
++ args->h_file);
++ if (!err && au_fbstart(file) != au_dbstart(dentry))
++ /*
++ * cmoo happens after h_file was opened.
++ * need to refresh file later.
++ */
++ atomic_dec(&au_fi(file)->fi_generation);
++ }
+
+ finfo = au_fi(file);
+ if (!err) {
@@ -11997,7 +12016,13 @@ index 0000000..cf680cb
+ au_sphl_add(&finfo->fi_hlist,
+ &au_sbi(file->f_path.dentry->d_sb)->si_files);
+ }
-+ fi_write_unlock(file);
++ if (!no_lock)
++ fi_write_unlock(file);
++ else {
++ lockdep_off();
++ fi_write_unlock(file);
++ lockdep_on();
++ }
+ if (unlikely(err)) {
+ finfo->fi_hdir = NULL;
+ au_finfo_fin(file);
@@ -12104,13 +12129,13 @@ index 0000000..cf680cb
+ };
+
+ au_update_dbstart(cpg.dentry);
-+ inode = cpg.dentry->d_inode;
++ inode = d_inode(cpg.dentry);
+ h_inode = NULL;
+ if (au_dbstart(cpg.dentry) <= bcpup
+ && au_dbend(cpg.dentry) >= bcpup) {
+ h_dentry = au_h_dptr(cpg.dentry, bcpup);
-+ if (h_dentry)
-+ h_inode = h_dentry->d_inode;
++ if (h_dentry && d_is_positive(h_dentry))
++ h_inode = d_inode(h_dentry);
+ }
+ hi_wh = au_hi_wh(inode, bcpup);
+ if (!hi_wh && !h_inode)
@@ -12149,7 +12174,7 @@ index 0000000..cf680cb
+ };
+
+ sb = cpg.dentry->d_sb;
-+ inode = cpg.dentry->d_inode;
++ inode = d_inode(cpg.dentry);
+ cpg.bsrc = au_fbstart(file);
+ err = au_test_ro(sb, cpg.bsrc, inode);
+ if (!err && (au_hf_top(file)->f_mode & FMODE_WRITE)) {
@@ -12270,7 +12295,7 @@ index 0000000..cf680cb
+ err = 0;
+ finfo = au_fi(file);
+ sb = cpg.dentry->d_sb;
-+ inode = cpg.dentry->d_inode;
++ inode = d_inode(cpg.dentry);
+ cpg.bdst = au_ibstart(inode);
+ if (cpg.bdst == finfo->fi_btop || IS_ROOT(cpg.dentry))
+ goto out;
@@ -12450,7 +12475,7 @@ index 0000000..cf680cb
+
+ err = 0;
+ dentry = file->f_path.dentry;
-+ inode = dentry->d_inode;
++ inode = d_inode(dentry);
+ sigen = au_sigen(dentry->d_sb);
+ fi_write_lock(file);
+ figen = au_figen(file);
@@ -12498,16 +12523,8 @@ index 0000000..cf680cb
+}
+
+/* it will never be called, but necessary to support O_DIRECT */
-+static ssize_t aufs_direct_IO(int rw, struct kiocb *iocb,
-+ struct iov_iter *iter, loff_t offset)
-+{ 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)
++static ssize_t aufs_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
++ loff_t offset)
+{ BUG(); return 0; }
+
+/* they will never be called. */
@@ -12555,7 +12572,6 @@ index 0000000..cf680cb
+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 */
@@ -12577,10 +12593,10 @@ index 0000000..cf680cb
+};
diff --git a/fs/aufs/file.h b/fs/aufs/file.h
new file mode 100644
-index 0000000..643c6f4
+index 0000000..488473e
--- /dev/null
+++ b/fs/aufs/file.h
-@@ -0,0 +1,271 @@
+@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -12643,8 +12659,14 @@ index 0000000..643c6f4
+unsigned int au_file_roflags(unsigned int flags);
+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
+ struct file *file, int force_wr);
-+int au_do_open(struct file *file, int (*open)(struct file *file, int flags),
-+ struct au_fidir *fidir);
++struct au_do_open_args {
++ int no_lock;
++ int (*open)(struct file *file, int flags,
++ struct file *h_file);
++ struct au_fidir *fidir;
++ struct file *h_file;
++};
++int au_do_open(struct file *file, struct au_do_open_args *args);
+int au_reopen_nondir(struct file *file);
+struct au_pin;
+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin);
@@ -12673,8 +12695,9 @@ index 0000000..643c6f4
+
+/* f_op.c */
+extern const struct file_operations aufs_file_fop;
-+int au_do_open_nondir(struct file *file, int flags);
++int au_do_open_nondir(struct file *file, int flags, struct file *h_file);
+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file);
++struct file *au_read_pre(struct file *file, int keep_fi);
+
+/* finfo.c */
+void au_hfput(struct au_hfile *hf, struct file *file);
@@ -12854,10 +12877,10 @@ index 0000000..643c6f4
+#endif /* __AUFS_FILE_H__ */
diff --git a/fs/aufs/finfo.c b/fs/aufs/finfo.c
new file mode 100644
-index 0000000..61e39eb
+index 0000000..05732c9
--- /dev/null
+++ b/fs/aufs/finfo.c
-@@ -0,0 +1,143 @@
+@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -12896,6 +12919,7 @@ index 0000000..61e39eb
+ au_hfput(hf, file);
+ if (val) {
+ FiMustWriteLock(file);
++ AuDebugOn(IS_ERR_OR_NULL(file->f_path.dentry));
+ hf->hf_file = val;
+ hf->hf_br = au_sbr(file->f_path.dentry->d_sb, bindex);
+ }
@@ -13003,10 +13027,10 @@ index 0000000..61e39eb
+}
diff --git a/fs/aufs/fstype.h b/fs/aufs/fstype.h
new file mode 100644
-index 0000000..6893432
+index 0000000..6c3e1de
--- /dev/null
+++ b/fs/aufs/fstype.h
-@@ -0,0 +1,456 @@
+@@ -0,0 +1,387 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -13023,6 +13047,7 @@ index 0000000..6893432
+#include
+#include
+#include
++#include
+
+static inline int au_test_aufs(struct super_block *sb)
+{
@@ -13105,60 +13130,6 @@ index 0000000..6893432
+#endif
+}
+
-+static inline int au_test_ocfs2(struct super_block *sb __maybe_unused)
-+{
-+#if defined(CONFIG_OCFS2_FS) || defined(CONFIG_OCFS2_FS_MODULE)
-+ return sb->s_magic == OCFS2_SUPER_MAGIC;
-+#else
-+ return 0;
-+#endif
-+}
-+
-+static inline int au_test_ocfs2_dlmfs(struct super_block *sb __maybe_unused)
-+{
-+#if defined(CONFIG_OCFS2_FS_O2CB) || defined(CONFIG_OCFS2_FS_O2CB_MODULE)
-+ return sb->s_magic == DLMFS_MAGIC;
-+#else
-+ return 0;
-+#endif
-+}
-+
-+static inline int au_test_coda(struct super_block *sb __maybe_unused)
-+{
-+#if defined(CONFIG_CODA_FS) || defined(CONFIG_CODA_FS_MODULE)
-+ return sb->s_magic == CODA_SUPER_MAGIC;
-+#else
-+ return 0;
-+#endif
-+}
-+
-+static inline int au_test_v9fs(struct super_block *sb __maybe_unused)
-+{
-+#if defined(CONFIG_9P_FS) || defined(CONFIG_9P_FS_MODULE)
-+ return sb->s_magic == V9FS_MAGIC;
-+#else
-+ return 0;
-+#endif
-+}
-+
-+static inline int au_test_ext4(struct super_block *sb __maybe_unused)
-+{
-+#if defined(CONFIG_EXT4_FS) || defined(CONFIG_EXT4_FS_MODULE)
-+ return sb->s_magic == EXT4_SUPER_MAGIC;
-+#else
-+ return 0;
-+#endif
-+}
-+
-+static inline int au_test_sysv(struct super_block *sb __maybe_unused)
-+{
-+#if defined(CONFIG_SYSV_FS) || defined(CONFIG_SYSV_FS_MODULE)
-+ return !strcmp(au_sbtype(sb), "sysv");
-+#else
-+ return 0;
-+#endif
-+}
-+
+static inline int au_test_ramfs(struct super_block *sb)
+{
+ return sb->s_magic == RAMFS_MAGIC;
@@ -13213,15 +13184,6 @@ index 0000000..6893432
+#endif
+}
+
-+static inline int au_test_cifs(struct super_block *sb __maybe_unused)
-+{
-+#if defined(CONFIG_CIFS_FS) || defined(CONFIGCIFS_FS_MODULE)
-+ return sb->s_magic == CIFS_MAGIC_NUMBER;
-+#else
-+ return 0;
-+#endif
-+}
-+
+static inline int au_test_fat(struct super_block *sb __maybe_unused)
+{
+#if defined(CONFIG_FAT_FS) || defined(CONFIG_FAT_FS_MODULE)
@@ -13351,10 +13313,7 @@ index 0000000..6893432
+{
+ return au_test_nfs(sb)
+ || au_test_fuse(sb)
-+ /* || au_test_ocfs2(sb) */ /* untested */
+ /* || au_test_btrfs(sb) */ /* untested */
-+ /* || au_test_coda(sb) */ /* untested */
-+ /* || au_test_v9fs(sb) */ /* untested */
+ ;
+}
+
@@ -13367,10 +13326,6 @@ index 0000000..6893432
+ || au_test_btrfs(sb)
+ || au_test_ubifs(sb)
+ || au_test_hfsplus(sb) /* maintained, but incorrect */
-+ /* || au_test_ext4(sb) */ /* untested */
-+ /* || au_test_ocfs2(sb) */ /* untested */
-+ /* || au_test_ocfs2_dlmfs(sb) */ /* untested */
-+ /* || au_test_sysv(sb) */ /* untested */
+ /* || au_test_minix(sb) */ /* untested */
+ ;
+}
@@ -13382,7 +13337,6 @@ index 0000000..6893432
+static inline int au_test_fs_bad_iattr(struct super_block *sb)
+{
+ return au_test_fs_bad_iattr_size(sb)
-+ /* || au_test_cifs(sb) */ /* untested */
+ || au_test_fat(sb)
+ || au_test_msdos(sb)
+ || au_test_vfat(sb);
@@ -13407,19 +13361,9 @@ index 0000000..6893432
+ return au_test_nfs(sb)
+ || au_test_fuse(sb)
+ || au_test_ubifs(sb)
-+ /* || au_test_cifs(sb) */ /* untested */
+ ;
+}
+
-+/*
-+ * filesystems which requires replacing i_mapping.
-+ */
-+static inline int au_test_fs_bad_mapping(struct super_block *sb)
-+{
-+ return au_test_fuse(sb)
-+ || au_test_ubifs(sb);
-+}
-+
+/* temporary support for i#1 in cramfs */
+static inline int au_test_fs_unique_ino(struct inode *inode)
+{
@@ -13461,11 +13405,22 @@ index 0000000..6893432
+ || au_test_romfs(sb);
+}
+
++/*
++ * test if the @inode is nfs with 'noacl' option
++ * NFS always sets MS_POSIXACL regardless its mount option 'noacl.'
++ */
++static inline int au_test_nfs_noacl(struct inode *inode)
++{
++ return au_test_nfs(inode->i_sb)
++ /* && IS_POSIXACL(inode) */
++ && !nfs_server_capable(inode, NFS_CAP_ACLS);
++}
++
+#endif /* __KERNEL__ */
+#endif /* __AUFS_FSTYPE_H__ */
diff --git a/fs/aufs/hfsnotify.c b/fs/aufs/hfsnotify.c
new file mode 100644
-index 0000000..2dd7419
+index 0000000..5c370196
--- /dev/null
+++ b/fs/aufs/hfsnotify.c
@@ -0,0 +1,275 @@
@@ -13597,7 +13552,7 @@ index 0000000..2dd7419
+ test_ret(FS_UNMOUNT);
+ test_ret(FS_Q_OVERFLOW);
+ test_ret(FS_IN_IGNORED);
-+ test_ret(FS_IN_ISDIR);
++ test_ret(FS_ISDIR);
+ test_ret(FS_IN_ONESHOT);
+ test_ret(FS_EVENT_ON_CHILD);
+ return "";
@@ -13746,7 +13701,7 @@ index 0000000..2dd7419
+};
diff --git a/fs/aufs/hfsplus.c b/fs/aufs/hfsplus.c
new file mode 100644
-index 0000000..78ec26f
+index 0000000..34c1f1a
--- /dev/null
+++ b/fs/aufs/hfsplus.c
@@ -0,0 +1,43 @@
@@ -13774,11 +13729,11 @@ index 0000000..78ec26f
+
+ h_dentry = au_h_dptr(dentry, bindex);
+ AuDebugOn(!h_dentry);
-+ AuDebugOn(!h_dentry->d_inode);
++ AuDebugOn(d_is_negative(h_dentry));
+
+ h_file = NULL;
+ if (au_test_hfsplus(h_dentry->d_sb)
-+ && S_ISREG(h_dentry->d_inode->i_mode))
++ && d_is_reg(h_dentry))
+ h_file = au_h_open(dentry, bindex,
+ O_RDONLY | O_NOATIME | O_LARGEFILE,
+ /*file*/NULL, force_wr);
@@ -13795,10 +13750,10 @@ index 0000000..78ec26f
+}
diff --git a/fs/aufs/hnotify.c b/fs/aufs/hnotify.c
new file mode 100644
-index 0000000..a07e4f2
+index 0000000..3943dc4
--- /dev/null
+++ b/fs/aufs/hnotify.c
-@@ -0,0 +1,701 @@
+@@ -0,0 +1,697 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -13959,10 +13914,10 @@ index 0000000..a07e4f2
+ continue;
+
+ au_digen_dec(d);
-+ if (d->d_inode)
++ if (d_really_is_positive(d))
+ /* todo: reset children xino?
+ cached children only? */
-+ au_iigen_dec(d->d_inode);
++ au_iigen_dec(d_inode(d));
+ }
+ }
+
@@ -14040,12 +13995,8 @@ index 0000000..a07e4f2
+static int hn_gen_by_name(struct dentry *dentry, const unsigned int isdir)
+{
+ int err;
-+ struct inode *inode;
+
-+ inode = dentry->d_inode;
-+ if (IS_ROOT(dentry)
-+ /* || (inode && inode->i_ino == AUFS_ROOT_INO) */
-+ ) {
++ if (IS_ROOT(dentry)) {
+ pr_warn("branch root dir was changed\n");
+ return 0;
+ }
@@ -14053,11 +14004,11 @@ index 0000000..a07e4f2
+ err = 0;
+ if (!isdir) {
+ au_digen_dec(dentry);
-+ if (inode)
-+ au_iigen_dec(inode);
++ if (d_really_is_positive(dentry))
++ au_iigen_dec(d_inode(dentry));
+ } else {
+ au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR);
-+ if (inode)
++ if (d_really_is_positive(dentry))
+ err = hn_gen_tree(dentry);
+ }
+
@@ -14277,8 +14228,8 @@ index 0000000..a07e4f2
+ dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen,
+ a->dir);
+ try_iput = 0;
-+ if (dentry)
-+ inode = dentry->d_inode;
++ if (dentry && d_really_is_positive(dentry))
++ inode = d_inode(dentry);
+ if (xino && !inode && h_ino
+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], XINO0)
+ || au_ftest_hnjob(a->flags[AuHn_CHILD], TRYXINO0)
@@ -14502,10 +14453,10 @@ index 0000000..a07e4f2
+}
diff --git a/fs/aufs/i_op.c b/fs/aufs/i_op.c
new file mode 100644
-index 0000000..e33cbec
+index 0000000..20f26b2
--- /dev/null
+++ b/fs/aufs/i_op.c
-@@ -0,0 +1,1286 @@
+@@ -0,0 +1,1434 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -14539,13 +14490,19 @@ index 0000000..e33cbec
+ * - skip the lower fs test in the case of write to ro branch.
+ * - nfs dir permission write check is optimized, but a policy for
+ * link/rename requires a real check.
++ * - nfs always sets MS_POSIXACL regardless its mount option 'noacl.'
++ * in this case, generic_permission() returns -EOPNOTSUPP.
+ */
+ if ((write_mask && !au_br_writable(brperm))
+ || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode)
+ && write_mask && !(mask & MAY_READ))
+ || !h_inode->i_op->permission) {
+ /* AuLabel(generic_permission); */
++ /* AuDbg("get_acl %pf\n", h_inode->i_op->get_acl); */
+ err = generic_permission(h_inode, mask);
++ if (err == -EOPNOTSUPP && au_test_nfs_noacl(h_inode))
++ err = h_inode->i_op->permission(h_inode, mask);
++ AuTraceErr(err);
+ } else {
+ /* AuLabel(h_inode->permission); */
+ err = h_inode->i_op->permission(h_inode, mask);
@@ -14749,6 +14706,149 @@ index 0000000..e33cbec
+
+/* ---------------------------------------------------------------------- */
+
++struct aopen_node {
++ struct hlist_node hlist;
++ struct file *file, *h_file;
++};
++
++static int au_do_aopen(struct inode *inode, struct file *file)
++{
++ struct au_sphlhead *aopen;
++ struct aopen_node *node;
++ struct au_do_open_args args = {
++ .no_lock = 1,
++ .open = au_do_open_nondir
++ };
++
++ aopen = &au_sbi(inode->i_sb)->si_aopen;
++ spin_lock(&aopen->spin);
++ hlist_for_each_entry(node, &aopen->head, hlist)
++ if (node->file == file) {
++ args.h_file = node->h_file;
++ break;
++ }
++ spin_unlock(&aopen->spin);
++ /* AuDebugOn(!args.h_file); */
++
++ return au_do_open(file, &args);
++}
++
++static int aufs_atomic_open(struct inode *dir, struct dentry *dentry,
++ struct file *file, unsigned int open_flag,
++ umode_t create_mode, int *opened)
++{
++ int err, h_opened = *opened;
++ struct dentry *parent;
++ struct dentry *d;
++ struct au_sphlhead *aopen;
++ struct vfsub_aopen_args args = {
++ .open_flag = open_flag,
++ .create_mode = create_mode,
++ .opened = &h_opened
++ };
++ struct aopen_node aopen_node = {
++ .file = file
++ };
++
++ IMustLock(dir);
++ AuDbg("open_flag 0x%x\n", open_flag);
++ AuDbgDentry(dentry);
++
++ err = 0;
++ if (!au_di(dentry)) {
++ d = aufs_lookup(dir, dentry, /*flags*/0);
++ if (IS_ERR(d)) {
++ err = PTR_ERR(d);
++ goto out;
++ } else if (d) {
++ /*
++ * obsoleted dentry found.
++ * another error will be returned later.
++ */
++ d_drop(d);
++ dput(d);
++ AuDbgDentry(d);
++ }
++ AuDbgDentry(dentry);
++ }
++
++ if (d_is_positive(dentry)
++ || d_unhashed(dentry)
++ || d_unlinked(dentry)
++ || !(open_flag & O_CREAT))
++ goto out_no_open;
++
++ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
++ if (unlikely(err))
++ goto out;
++
++ parent = dentry->d_parent; /* dir is locked */
++ di_write_lock_parent(parent);
++ err = au_lkup_dentry(dentry, /*bstart*/0, /*type*/0);
++ if (unlikely(err))
++ goto out_unlock;
++
++ AuDbgDentry(dentry);
++ if (d_is_positive(dentry))
++ goto out_unlock;
++
++ args.file = get_empty_filp();
++ err = PTR_ERR(args.file);
++ if (IS_ERR(args.file))
++ goto out_unlock;
++
++ args.file->f_flags = file->f_flags;
++ err = au_aopen_or_create(dir, dentry, &args);
++ AuTraceErr(err);
++ AuDbgFile(args.file);
++ if (unlikely(err < 0)) {
++ if (h_opened & FILE_OPENED)
++ fput(args.file);
++ else
++ put_filp(args.file);
++ goto out_unlock;
++ }
++
++ /* some filesystems don't set FILE_CREATED while succeeded? */
++ *opened |= FILE_CREATED;
++ if (h_opened & FILE_OPENED)
++ aopen_node.h_file = args.file;
++ else {
++ put_filp(args.file);
++ args.file = NULL;
++ }
++ aopen = &au_sbi(dir->i_sb)->si_aopen;
++ au_sphl_add(&aopen_node.hlist, aopen);
++ err = finish_open(file, dentry, au_do_aopen, opened);
++ au_sphl_del(&aopen_node.hlist, aopen);
++ AuTraceErr(err);
++ AuDbgFile(file);
++ if (aopen_node.h_file)
++ fput(aopen_node.h_file);
++
++out_unlock:
++ di_write_unlock(parent);
++ aufs_read_unlock(dentry, AuLock_DW);
++ AuDbgDentry(dentry);
++ if (unlikely(err))
++ goto out;
++out_no_open:
++ if (!err && !(*opened & FILE_CREATED)) {
++ AuLabel(out_no_open);
++ dget(dentry);
++ err = finish_no_open(file, dentry);
++ }
++out:
++ AuDbg("%pd%s%s\n", dentry,
++ (*opened & FILE_CREATED) ? " created" : "",
++ (*opened & FILE_OPENED) ? " opened" : "");
++ AuTraceErr(err);
++ return err;
++}
++
++
++/* ---------------------------------------------------------------------- */
++
+static int au_wr_dir_cpup(struct dentry *dentry, struct dentry *parent,
+ const unsigned char add_entry, aufs_bindex_t bcpup,
+ aufs_bindex_t bstart)
@@ -14758,7 +14858,7 @@ index 0000000..e33cbec
+ struct inode *h_dir;
+
+ if (add_entry)
-+ IMustLock(parent->d_inode);
++ IMustLock(d_inode(parent));
+ else
+ di_write_lock_parent(parent);
+
@@ -14773,16 +14873,15 @@ index 0000000..e33cbec
+ }
+ if (!err && add_entry && !au_ftest_wrdir(add_entry, TMPFILE)) {
+ h_parent = au_h_dptr(parent, bcpup);
-+ h_dir = h_parent->d_inode;
++ h_dir = d_inode(h_parent);
+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
-+ err = au_lkup_neg(dentry, bcpup,
-+ au_ftest_wrdir(add_entry, TMP_WHENTRY));
++ err = au_lkup_neg(dentry, bcpup, /*wh*/0);
+ /* todo: no unlock here */
+ mutex_unlock(&h_dir->i_mutex);
+
+ AuDbg("bcpup %d\n", bcpup);
+ if (!err) {
-+ if (!dentry->d_inode)
++ if (d_really_is_negative(dentry))
+ au_set_h_dptr(dentry, bstart, NULL);
+ au_update_dbrange(dentry, /*do_put_zero*/0);
+ }
@@ -14810,7 +14909,6 @@ index 0000000..e33cbec
+ aufs_bindex_t bcpup, bstart, src_bstart;
+ const unsigned char add_entry
+ = au_ftest_wrdir(args->flags, ADD_ENTRY)
-+ | au_ftest_wrdir(args->flags, TMP_WHENTRY)
+ | au_ftest_wrdir(args->flags, TMPFILE);
+ struct super_block *sb;
+ struct dentry *parent;
@@ -14834,7 +14932,7 @@ index 0000000..e33cbec
+ bcpup = err;
+ }
+
-+ if (bcpup < 0 || au_test_ro(sb, bcpup, dentry->d_inode)) {
++ if (bcpup < 0 || au_test_ro(sb, bcpup, d_inode(dentry))) {
+ if (add_entry)
+ err = AuWbrCopyup(sbinfo, dentry);
+ else {
@@ -14851,7 +14949,7 @@ index 0000000..e33cbec
+ }
+ } else {
+ bcpup = args->force_btgt;
-+ AuDebugOn(au_test_ro(sb, bcpup, dentry->d_inode));
++ AuDebugOn(au_test_ro(sb, bcpup, d_inode(dentry)));
+ }
+
+ AuDbg("bstart %d, bcpup %d\n", bstart, bcpup);
@@ -14862,7 +14960,7 @@ index 0000000..e33cbec
+ /* copyup the new parent into the branch we process */
+ err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, bstart);
+ if (err >= 0) {
-+ if (!dentry->d_inode) {
++ if (d_really_is_negative(dentry)) {
+ au_set_h_dptr(dentry, bstart, NULL);
+ au_set_dbstart(dentry, bcpup);
+ au_set_dbend(dentry, bcpup);
@@ -14897,7 +14995,7 @@ index 0000000..e33cbec
+ au_hn_imtx_lock_nested(p->hdir, p->lsc_hi);
+
+ err = -EBUSY;
-+ if (unlikely(p->hdir->hi_inode != p->h_parent->d_inode))
++ if (unlikely(p->hdir->hi_inode != d_inode(p->h_parent)))
+ goto out;
+
+ err = 0;
@@ -14925,9 +15023,10 @@ index 0000000..e33cbec
+ for (i = 0; !err && i < sizeof(h_d)/sizeof(*h_d); i++) {
+ if (!h_d[i])
+ continue;
-+ h_i = h_d[i]->d_inode;
-+ if (h_i)
++ if (d_is_positive(h_d[i])) {
++ h_i = d_inode(h_d[i]);
+ err = !h_i->i_nlink;
++ }
+ }
+
+out:
@@ -15015,7 +15114,7 @@ index 0000000..e33cbec
+
+ h_dir = NULL;
+ p->h_parent = au_h_dptr(p->parent, p->bindex);
-+ p->hdir = au_hi(p->parent->d_inode, p->bindex);
++ p->hdir = au_hi(d_inode(p->parent), p->bindex);
+ if (p->hdir)
+ h_dir = p->hdir->hi_inode;
+
@@ -15102,11 +15201,9 @@ index 0000000..e33cbec
+int au_reval_for_attr(struct dentry *dentry, unsigned int sigen)
+{
+ int err;
-+ struct inode *inode;
+ struct dentry *parent;
+
+ err = 0;
-+ inode = dentry->d_inode;
+ if (au_digen_test(dentry, sigen)) {
+ parent = dget_parent(dentry);
+ di_read_lock_parent(parent, AuLock_IR);
@@ -15132,11 +15229,11 @@ index 0000000..e33cbec
+ .flags = 0
+ };
+
-+ bstart = au_dbstart(dentry);
-+ inode = dentry->d_inode;
-+ if (S_ISDIR(inode->i_mode))
++ if (d_is_dir(dentry))
+ au_fset_wrdir(wr_dir_args.flags, ISDIR);
+ /* plink or hi_wh() case */
++ bstart = au_dbstart(dentry);
++ inode = d_inode(dentry);
+ ibstart = au_ibstart(inode);
+ if (bstart != ibstart && !au_test_ro(inode->i_sb, ibstart, inode))
+ wr_dir_args.force_btgt = ibstart;
@@ -15161,8 +15258,8 @@ index 0000000..e33cbec
+ goto out_parent;
+
+ a->h_path.dentry = au_h_dptr(dentry, bstart);
-+ a->h_inode = a->h_path.dentry->d_inode;
+ sz = -1;
++ a->h_inode = d_inode(a->h_path.dentry);
+ if (ia && (ia->ia_valid & ATTR_SIZE)) {
+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
+ if (ia->ia_size < i_size_read(a->h_inode))
@@ -15216,7 +15313,7 @@ index 0000000..e33cbec
+ a->h_path.dentry = hi_wh; /* do not dget here */
+
+out_unlock:
-+ a->h_inode = a->h_path.dentry->d_inode;
++ a->h_inode = d_inode(a->h_path.dentry);
+ if (!err)
+ goto out; /* success */
+ au_unpin(&a->pin);
@@ -15239,7 +15336,7 @@ index 0000000..e33cbec
+ struct file *file;
+ struct au_icpup_args *a;
+
-+ inode = dentry->d_inode;
++ inode = d_inode(dentry);
+ IMustLock(inode);
+
+ err = -ENOMEM;
@@ -15258,7 +15355,7 @@ index 0000000..e33cbec
+
+ if (ia->ia_valid & ATTR_FILE) {
+ /* currently ftruncate(2) only */
-+ AuDebugOn(!S_ISREG(inode->i_mode));
++ AuDebugOn(!d_is_reg(dentry));
+ file = ia->ia_file;
+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
+ if (unlikely(err))
@@ -15387,7 +15484,7 @@ index 0000000..e33cbec
+ struct au_icpup_args *a;
+ struct inode *inode, *h_inode;
+
-+ inode = dentry->d_inode;
++ inode = d_inode(dentry);
+ IMustLock(inode);
+
+ err = -ENOMEM;
@@ -15418,7 +15515,7 @@ index 0000000..e33cbec
+ break;
+ case AU_ACL_SET:
+ err = -EOPNOTSUPP;
-+ h_inode = h_path.dentry->d_inode;
++ h_inode = d_inode(h_path.dentry);
+ if (h_inode->i_op->set_acl)
+ err = h_inode->i_op->set_acl(h_inode,
+ arg->u.acl_set.acl,
@@ -15521,7 +15618,7 @@ index 0000000..e33cbec
+ } else
+ di_read_lock_child(dentry, AuLock_IR);
+
-+ inode = dentry->d_inode;
++ inode = d_inode(dentry);
+ bindex = au_ibstart(inode);
+ h_path->mnt = au_sbr_mnt(sb, bindex);
+ h_sb = h_path->mnt->mnt_sb;
@@ -15554,7 +15651,7 @@ index 0000000..e33cbec
+ struct inode *inode;
+ struct super_block *sb;
+
-+ inode = dentry->d_inode;
++ inode = d_inode(dentry);
+ sb = dentry->d_sb;
+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
+ if (unlikely(err))
@@ -15566,13 +15663,13 @@ index 0000000..e33cbec
+ /* illegally overlapped or something */
+ goto out_fill; /* pretending success */
+
-+ positive = !!h_path.dentry->d_inode;
++ positive = d_is_positive(h_path.dentry);
+ if (positive)
+ err = vfs_getattr(&h_path, st);
+ if (!err) {
+ if (positive)
+ au_refresh_iattr(inode, st,
-+ h_path.dentry->d_inode->i_nlink);
++ d_inode(h_path.dentry)->i_nlink);
+ goto out_fill; /* success */
+ }
+ AuTraceErr(err);
@@ -15597,10 +15694,12 @@ index 0000000..e33cbec
+ int err;
+ struct super_block *sb;
+ struct dentry *h_dentry;
++ struct inode *inode, *h_inode;
+
+ err = -EINVAL;
+ h_dentry = au_h_dptr(dentry, bindex);
-+ if (unlikely(!h_dentry->d_inode->i_op->readlink))
++ h_inode = d_inode(h_dentry);
++ if (unlikely(!h_inode->i_op->readlink))
+ goto out;
+
+ err = security_inode_readlink(h_dentry);
@@ -15608,11 +15707,12 @@ index 0000000..e33cbec
+ goto out;
+
+ sb = dentry->d_sb;
-+ if (!au_test_ro(sb, bindex, dentry->d_inode)) {
++ inode = d_inode(dentry);
++ if (!au_test_ro(sb, bindex, inode)) {
+ vfsub_touch_atime(au_sbr_mnt(sb, bindex), h_dentry);
-+ fsstack_copy_attr_atime(dentry->d_inode, h_dentry->d_inode);
++ fsstack_copy_attr_atime(inode, h_inode);
+ }
-+ err = h_dentry->d_inode->i_op->readlink(h_dentry, buf, bufsiz);
++ err = h_inode->i_op->readlink(h_dentry, buf, bufsiz);
+
+out:
+ return err;
@@ -15768,8 +15868,7 @@ index 0000000..e33cbec
+#endif
+
+ .update_time = aufs_update_time,
-+ /* no support for atomic_open() */
-+
++ .atomic_open = aufs_atomic_open,
+ .tmpfile = aufs_tmpfile
+};
+
@@ -15794,10 +15893,10 @@ index 0000000..e33cbec
+};
diff --git a/fs/aufs/i_op_add.c b/fs/aufs/i_op_add.c
new file mode 100644
-index 0000000..a76e11d6
+index 0000000..0c3530e
--- /dev/null
+++ b/fs/aufs/i_op_add.c
-@@ -0,0 +1,878 @@
+@@ -0,0 +1,919 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -15827,7 +15926,7 @@ index 0000000..a76e11d6
+ bwh = -1;
+ sb = dir->i_sb;
+ if (wh_dentry) {
-+ h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
++ h_dir = d_inode(wh_dentry->d_parent); /* dir inode is locked */
+ IMustLock(h_dir);
+ AuDebugOn(au_h_iptr(dir, bindex) != h_dir);
+ bwh = au_dbwh(dentry);
@@ -15842,10 +15941,9 @@ index 0000000..a76e11d6
+ inode = au_new_inode(dentry, /*must_new*/1);
+ if (!IS_ERR(inode)) {
+ d_instantiate(dentry, inode);
-+ dir = dentry->d_parent->d_inode; /* dir inode is locked */
++ dir = d_inode(dentry->d_parent); /* dir inode is locked */
+ IMustLock(dir);
-+ if (au_ibstart(dir) == au_dbstart(dentry))
-+ au_cpup_attr_timesizes(dir);
++ au_dir_ts(dir, bindex);
+ dir->i_version++;
+ au_fhsm_wrote(sb, bindex, /*force*/0);
+ return 0; /* success */
@@ -15877,7 +15975,7 @@ index 0000000..a76e11d6
+ err = 0;
+ if (unlikely(d_unhashed(dentry)))
+ err = -ENOENT;
-+ if (unlikely(dentry->d_inode))
++ if (unlikely(d_really_is_positive(dentry)))
+ err = -EEXIST;
+ return err;
+}
@@ -15899,15 +15997,17 @@ index 0000000..a76e11d6
+ goto out;
+
+ h_dentry = au_h_dptr(dentry, bindex);
-+ h_inode = h_dentry->d_inode;
-+ if (!dentry->d_inode) {
++ if (d_really_is_negative(dentry)) {
+ err = -EEXIST;
-+ if (unlikely(h_inode))
++ if (unlikely(d_is_positive(h_dentry)))
+ goto out;
+ } else {
+ /* rename(2) case */
+ err = -EIO;
-+ if (unlikely(!h_inode || !h_inode->i_nlink))
++ if (unlikely(d_is_negative(h_dentry)))
++ goto out;
++ h_inode = d_inode(h_dentry);
++ if (unlikely(!h_inode->i_nlink))
+ goto out;
+
+ h_mode = h_inode->i_mode;
@@ -15988,6 +16088,11 @@ index 0000000..a76e11d6
+ if (bcpup != au_dbwh(dentry))
+ goto out; /* success */
+
++ /*
++ * ENAMETOOLONG here means that if we allowed create such name, then it
++ * would not be able to removed in the future. So we don't allow such
++ * name here and we don't handle ENAMETOOLONG differently here.
++ */
+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
+
+out_unpin:
@@ -16004,8 +16109,10 @@ index 0000000..a76e11d6
+ int type;
+ union {
+ struct {
-+ umode_t mode;
-+ bool want_excl;
++ umode_t mode;
++ bool want_excl;
++ bool try_aopen;
++ struct vfsub_aopen_args *aopen;
+ } c;
+ struct {
+ const char *symname;
@@ -16023,8 +16130,12 @@ index 0000000..a76e11d6
+ int err, rerr;
+ aufs_bindex_t bstart;
+ unsigned char created;
++ const unsigned char try_aopen
++ = (arg->type == Creat && arg->u.c.try_aopen);
+ struct dentry *wh_dentry, *parent;
+ struct inode *h_dir;
++ struct super_block *sb;
++ struct au_branch *br;
+ /* to reuduce stack size */
+ struct {
+ struct au_dtime dt;
@@ -16044,13 +16155,16 @@ index 0000000..a76e11d6
+ a->wr_dir_args.flags = AuWrDir_ADD_ENTRY;
+
+ parent = dentry->d_parent; /* dir inode is locked */
-+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
-+ if (unlikely(err))
-+ goto out_free;
++ if (!try_aopen) {
++ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
++ if (unlikely(err))
++ goto out_free;
++ }
+ err = au_d_may_add(dentry);
+ if (unlikely(err))
+ goto out_unlock;
-+ di_write_lock_parent(parent);
++ if (!try_aopen)
++ di_write_lock_parent(parent);
+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
+ &a->pin, &a->wr_dir_args);
+ err = PTR_ERR(wh_dentry);
@@ -16058,13 +16172,20 @@ index 0000000..a76e11d6
+ goto out_parent;
+
+ bstart = au_dbstart(dentry);
++ sb = dentry->d_sb;
++ br = au_sbr(sb, bstart);
+ a->h_path.dentry = au_h_dptr(dentry, bstart);
-+ a->h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
++ a->h_path.mnt = au_br_mnt(br);
+ h_dir = au_pinned_h_dir(&a->pin);
+ switch (arg->type) {
+ case Creat:
-+ err = vfsub_create(h_dir, &a->h_path, arg->u.c.mode,
-+ arg->u.c.want_excl);
++ err = 0;
++ if (!try_aopen || !h_dir->i_op->atomic_open)
++ err = vfsub_create(h_dir, &a->h_path, arg->u.c.mode,
++ arg->u.c.want_excl);
++ else
++ err = vfsub_atomic_open(h_dir, a->h_path.dentry,
++ arg->u.c.aopen, br);
+ break;
+ case Symlink:
+ err = vfsub_symlink(h_dir, &a->h_path, arg->u.s.symname);
@@ -16081,7 +16202,7 @@ index 0000000..a76e11d6
+ err = epilog(dir, bstart, wh_dentry, dentry);
+
+ /* revert */
-+ if (unlikely(created && err && a->h_path.dentry->d_inode)) {
++ if (unlikely(created && err && d_is_positive(a->h_path.dentry))) {
+ /* no delegation since it is just created */
+ rerr = vfsub_unlink(h_dir, &a->h_path, /*delegated*/NULL,
+ /*force*/0);
@@ -16093,17 +16214,22 @@ index 0000000..a76e11d6
+ au_dtime_revert(&a->dt);
+ }
+
++ if (!err && try_aopen && !h_dir->i_op->atomic_open)
++ *arg->u.c.aopen->opened |= FILE_CREATED;
++
+ au_unpin(&a->pin);
+ dput(wh_dentry);
+
+out_parent:
-+ di_write_unlock(parent);
++ if (!try_aopen)
++ di_write_unlock(parent);
+out_unlock:
+ if (unlikely(err)) {
+ au_update_dbstart(dentry);
+ d_drop(dentry);
+ }
-+ aufs_read_unlock(dentry, AuLock_DW);
++ if (!try_aopen)
++ aufs_read_unlock(dentry, AuLock_DW);
+out_free:
+ kfree(a);
+out:
@@ -16145,6 +16271,21 @@ index 0000000..a76e11d6
+ return add_simple(dir, dentry, &arg);
+}
+
++int au_aopen_or_create(struct inode *dir, struct dentry *dentry,
++ struct vfsub_aopen_args *aopen_args)
++{
++ struct simple_arg arg = {
++ .type = Creat,
++ .u.c = {
++ .mode = aopen_args->create_mode,
++ .want_excl = aopen_args->open_flag & O_EXCL,
++ .try_aopen = true,
++ .aopen = aopen_args
++ }
++ };
++ return add_simple(dir, dentry, &arg);
++}
++
+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
+{
+ int err;
@@ -16174,7 +16315,7 @@ index 0000000..a76e11d6
+ parent = d_find_any_alias(dir);
+ AuDebugOn(!parent);
+ di_write_lock_parent(parent);
-+ if (unlikely(parent->d_inode != dir))
++ if (unlikely(d_inode(parent) != dir))
+ goto out_parent;
+
+ err = au_digen_test(parent, au_sigen(sb));
@@ -16200,7 +16341,7 @@ index 0000000..a76e11d6
+ goto out_parent;
+
+ h_parent = au_h_dptr(parent, bindex);
-+ err = inode_permission(h_parent->d_inode, MAY_WRITE | MAY_EXEC);
++ err = inode_permission(d_inode(h_parent), MAY_WRITE | MAY_EXEC);
+ if (unlikely(err))
+ goto out_mnt;
+
@@ -16317,7 +16458,7 @@ index 0000000..a76e11d6
+ plink = 0;
+ h_inode = NULL;
+ sb = src_dentry->d_sb;
-+ inode = src_dentry->d_inode;
++ inode = d_inode(src_dentry);
+ if (au_ibstart(inode) <= a->bdst)
+ h_inode = au_h_iptr(inode, a->bdst);
+ if (!h_inode || !h_inode->i_nlink) {
@@ -16331,7 +16472,7 @@ index 0000000..a76e11d6
+ au_set_h_dptr(dentry, a->bdst, NULL);
+ AuDbg("temporary d_inode...\n");
+ spin_lock(&dentry->d_lock);
-+ dentry->d_inode = src_dentry->d_inode; /* tmp */
++ dentry->d_inode = d_inode(src_dentry); /* tmp */
+ spin_unlock(&dentry->d_lock);
+ h_file = au_h_open_pre(dentry, a->bsrc, /*force_wr*/0);
+ if (IS_ERR(h_file))
@@ -16370,7 +16511,7 @@ index 0000000..a76e11d6
+ if (IS_ERR(h_src_dentry))
+ goto out;
+
-+ if (unlikely(!h_src_dentry->d_inode)) {
++ if (unlikely(d_is_negative(h_src_dentry))) {
+ dput(h_src_dentry);
+ h_src_dentry = NULL;
+ }
@@ -16416,7 +16557,7 @@ index 0000000..a76e11d6
+ };
+
+ IMustLock(dir);
-+ inode = src_dentry->d_inode;
++ inode = d_inode(src_dentry);
+ IMustLock(inode);
+
+ err = -ENOMEM;
@@ -16502,7 +16643,7 @@ index 0000000..a76e11d6
+ if (!err) {
+ h_src_dentry = au_h_dptr(src_dentry, a->bdst);
+ err = -ENOENT;
-+ if (h_src_dentry && h_src_dentry->d_inode) {
++ if (h_src_dentry && d_is_positive(h_src_dentry)) {
+ delegated = NULL;
+ err = vfsub_link(h_src_dentry,
+ au_pinned_h_dir(&a->pin),
@@ -16527,9 +16668,8 @@ index 0000000..a76e11d6
+ goto out_revert;
+ }
+
++ au_dir_ts(dir, a->bdst);
+ dir->i_version++;
-+ if (au_ibstart(dir) == au_dbstart(dentry))
-+ au_cpup_attr_timesizes(dir);
+ inc_nlink(inode);
+ inode->i_ctime = dir->i_ctime;
+ d_instantiate(dentry, au_igrab(inode));
@@ -16619,7 +16759,7 @@ index 0000000..a76e11d6
+
+ /* make the dir opaque */
+ diropq = 0;
-+ h_mtx = &h_path.dentry->d_inode->i_mutex;
++ h_mtx = &d_inode(h_path.dentry)->i_mutex;
+ if (wh_dentry
+ || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) {
+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
@@ -16678,10 +16818,10 @@ index 0000000..a76e11d6
+}
diff --git a/fs/aufs/i_op_del.c b/fs/aufs/i_op_del.c
new file mode 100644
-index 0000000..fcf377f
+index 0000000..3cd4c7b
--- /dev/null
+++ b/fs/aufs/i_op_del.c
-@@ -0,0 +1,494 @@
+@@ -0,0 +1,497 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -16712,7 +16852,7 @@ index 0000000..fcf377f
+ bstart = au_dbstart(dentry);
+ if (*bcpup < 0) {
+ *bcpup = bstart;
-+ if (au_test_ro(sb, bstart, dentry->d_inode)) {
++ if (au_test_ro(sb, bstart, d_inode(dentry))) {
+ err = AuWbrCopyup(au_sbi(sb), dentry);
+ *bcpup = err;
+ if (unlikely(err < 0))
@@ -16720,7 +16860,7 @@ index 0000000..fcf377f
+ }
+ } else
+ AuDebugOn(bstart < *bcpup
-+ || au_test_ro(sb, *bcpup, dentry->d_inode));
++ || au_test_ro(sb, *bcpup, d_inode(dentry)));
+ AuDbg("bcpup %d, bstart %d\n", *bcpup, bstart);
+
+ if (*bcpup != bstart) {
@@ -16764,10 +16904,12 @@ index 0000000..fcf377f
+ struct inode *h_inode;
+
+ h_dentry = au_h_dptr(dentry, bindex);
-+ h_inode = h_dentry->d_inode;
-+ if (dentry->d_inode) {
++ if (d_really_is_positive(dentry)) {
+ err = -ENOENT;
-+ if (unlikely(!h_inode || !h_inode->i_nlink))
++ if (unlikely(d_is_negative(h_dentry)))
++ goto out;
++ h_inode = d_inode(h_dentry);
++ if (unlikely(!h_inode->i_nlink))
+ goto out;
+
+ h_mode = h_inode->i_mode;
@@ -16782,7 +16924,7 @@ index 0000000..fcf377f
+ } else {
+ /* rename(2) case */
+ err = -EIO;
-+ if (unlikely(h_inode))
++ if (unlikely(d_is_positive(h_dentry)))
+ goto out;
+ }
+
@@ -16798,7 +16940,7 @@ index 0000000..fcf377f
+ */
+ err = -EACCES;
+ if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1)
-+ && au_test_h_perm(h_parent->d_inode,
++ && au_test_h_perm(d_inode(h_parent),
+ MAY_EXEC | MAY_WRITE)))
+ goto out;
+
@@ -16888,6 +17030,7 @@ index 0000000..fcf377f
+ int rmdir_later, err, dirwh;
+ struct dentry *h_dentry;
+ struct super_block *sb;
++ struct inode *inode;
+
+ sb = dentry->d_sb;
+ SiMustAnyLock(sb);
@@ -16897,7 +17040,8 @@ index 0000000..fcf377f
+ goto out;
+
+ /* stop monitoring */
-+ au_hn_free(au_hi(dentry->d_inode, bindex));
++ inode = d_inode(dentry);
++ au_hn_free(au_hi(inode, bindex));
+
+ if (!au_test_fs_remote(h_dentry->d_sb)) {
+ dirwh = au_sbi(sb)->si_dirwh;
@@ -16930,12 +17074,11 @@ index 0000000..fcf377f
+{
+ struct inode *inode;
+
-+ inode = dentry->d_inode;
++ inode = d_inode(dentry);
+ d_drop(dentry);
+ inode->i_ctime = dir->i_ctime;
+
-+ if (au_ibstart(dir) == bindex)
-+ au_cpup_attr_timesizes(dir);
++ au_dir_ts(dir, bindex);
+ dir->i_version++;
+}
+
@@ -16991,10 +17134,10 @@ index 0000000..fcf377f
+ err = au_d_hashed_positive(dentry);
+ if (unlikely(err))
+ goto out_unlock;
-+ inode = dentry->d_inode;
++ inode = d_inode(dentry);
+ IMustLock(inode);
+ err = -EISDIR;
-+ if (unlikely(S_ISDIR(inode->i_mode)))
++ if (unlikely(d_is_dir(dentry)))
+ goto out_unlock; /* possible? */
+
+ bstart = au_dbstart(dentry);
@@ -17022,7 +17165,7 @@ index 0000000..fcf377f
+ }
+ } else {
+ /* dir inode is locked */
-+ h_dir = wh_dentry->d_parent->d_inode;
++ h_dir = d_inode(wh_dentry->d_parent);
+ IMustLock(h_dir);
+ err = 0;
+ }
@@ -17035,7 +17178,7 @@ index 0000000..fcf377f
+ if (bindex == bstart) {
+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL);
+ /*ignore*/
-+ inode->i_ctime = a->h_path.dentry->d_inode->i_ctime;
++ inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime;
+ } else
+ /* todo: this timestamp may be reverted later */
+ inode->i_ctime = h_dir->i_ctime;
@@ -17092,10 +17235,10 @@ index 0000000..fcf377f
+ err = au_alive_dir(dentry);
+ if (unlikely(err))
+ goto out_unlock;
-+ inode = dentry->d_inode;
++ inode = d_inode(dentry);
+ IMustLock(inode);
+ err = -ENOTDIR;
-+ if (unlikely(!S_ISDIR(inode->i_mode)))
++ if (unlikely(!d_is_dir(dentry)))
+ goto out_unlock; /* possible? */
+
+ err = -ENOMEM;
@@ -17132,7 +17275,7 @@ index 0000000..fcf377f
+ au_hn_free(au_hi(inode, bstart));
+
+ /* dir inode is locked */
-+ IMustLock(wh_dentry->d_parent->d_inode);
++ IMustLock(d_inode(wh_dentry->d_parent));
+ err = 0;
+ }
+
@@ -17178,10 +17321,10 @@ index 0000000..fcf377f
+}
diff --git a/fs/aufs/i_op_ren.c b/fs/aufs/i_op_ren.c
new file mode 100644
-index 0000000..cbe78c8
+index 0000000..1323012
--- /dev/null
+++ b/fs/aufs/i_op_ren.c
-@@ -0,0 +1,1021 @@
+@@ -0,0 +1,1004 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -17203,7 +17346,6 @@ index 0000000..cbe78c8
+#define AuRen_MNT_WRITE (1 << 4)
+#define AuRen_DT_DSTDIR (1 << 5)
+#define AuRen_DIROPQ (1 << 6)
-+#define AuRen_CPUP (1 << 7)
+#define au_ftest_ren(flags, name) ((flags) & AuRen_##name)
+#define au_fset_ren(flags, name) \
+ do { (flags) |= AuRen_##name; } while (0)
@@ -17314,20 +17456,6 @@ index 0000000..cbe78c8
+ RevertFailure("rename %pd", a->src_dentry);
+}
+
-+static void au_ren_rev_cpup(int err, struct au_ren_args *a)
-+{
-+ int rerr;
-+
-+ a->h_path.dentry = a->dst_h_dentry;
-+ /* no delegation since it is just created */
-+ rerr = vfsub_unlink(a->dst_h_dir, &a->h_path, /*delegated*/NULL,
-+ /*force*/0);
-+ au_set_h_dptr(a->src_dentry, a->btgt, NULL);
-+ au_set_dbstart(a->src_dentry, a->src_bstart);
-+ if (rerr)
-+ RevertFailure("unlink %pd", a->dst_h_dentry);
-+}
-+
+static void au_ren_rev_whtmp(int err, struct au_ren_args *a)
+{
+ int rerr;
@@ -17340,7 +17468,7 @@ index 0000000..cbe78c8
+ RevertFailure("lkup one %pd", a->dst_dentry);
+ return;
+ }
-+ if (a->h_path.dentry->d_inode) {
++ if (d_is_positive(a->h_path.dentry)) {
+ d_drop(a->h_path.dentry);
+ dput(a->h_path.dentry);
+ return;
@@ -17466,7 +17594,7 @@ index 0000000..cbe78c8
+
+ /* prepare workqueue args for asynchronous rmdir */
+ h_d = a->dst_h_dentry;
-+ if (au_ftest_ren(a->flags, ISDIR) && h_d->d_inode) {
++ if (au_ftest_ren(a->flags, ISDIR) && d_is_positive(h_d)) {
+ err = -ENOMEM;
+ a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb, GFP_NOFS);
+ if (unlikely(!a->thargs))
@@ -17492,7 +17620,7 @@ index 0000000..cbe78c8
+ err = PTR_ERR(h_d);
+ if (IS_ERR(h_d))
+ goto out_whsrc;
-+ if (!h_d->d_inode)
++ if (d_is_negative(h_d))
+ dput(h_d);
+ else
+ a->dst_wh_dentry = h_d;
@@ -17512,7 +17640,7 @@ index 0000000..cbe78c8
+ a->dst_h_dentry = au_h_dptr(d, a->btgt);
+ }
+
-+ BUG_ON(a->dst_h_dentry->d_inode && a->src_bstart != a->btgt);
++ BUG_ON(d_is_positive(a->dst_h_dentry) && a->src_bstart != a->btgt);
+
+ /* rename by vfs_rename or cpup */
+ d = a->dst_dentry;
@@ -17539,7 +17667,7 @@ index 0000000..cbe78c8
+ AuDebugOn(au_dbstart(a->src_dentry) != a->btgt);
+ a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt);
+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/
-+ a->src_inode->i_ctime = a->h_path.dentry->d_inode->i_ctime;
++ a->src_inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime;
+
+ /* remove whiteout for dentry */
+ if (a->dst_wh_dentry) {
@@ -17562,10 +17690,7 @@ index 0000000..cbe78c8
+ if (au_ftest_ren(a->flags, DIROPQ))
+ au_ren_rev_diropq(err, a);
+out_rename:
-+ if (!au_ftest_ren(a->flags, CPUP))
-+ au_ren_rev_rename(err, a);
-+ else
-+ au_ren_rev_cpup(err, a);
++ au_ren_rev_rename(err, a);
+ dput(a->h_dst);
+out_whtmp:
+ if (a->thargs)
@@ -17715,20 +17840,18 @@ index 0000000..cbe78c8
+ goto out;
+
+ err = -EIO;
-+ h_inode = a->dst_h_dentry->d_inode;
+ isdir = !!au_ftest_ren(a->flags, ISDIR);
-+ if (!a->dst_dentry->d_inode) {
-+ if (unlikely(h_inode))
-+ goto out;
-+ err = au_may_add(a->dst_dentry, a->btgt, a->dst_h_parent,
-+ isdir);
++ if (d_really_is_negative(a->dst_dentry)) {
++ if (d_is_negative(a->dst_h_dentry))
++ err = au_may_add(a->dst_dentry, a->btgt,
++ a->dst_h_parent, isdir);
+ } else {
-+ if (unlikely(!h_inode || !h_inode->i_nlink))
-+ goto out;
-+ err = au_may_del(a->dst_dentry, a->btgt, a->dst_h_parent,
-+ isdir);
-+ if (unlikely(err))
++ if (unlikely(d_is_negative(a->dst_h_dentry)))
+ goto out;
++ h_inode = d_inode(a->dst_h_dentry);
++ if (h_inode->i_nlink)
++ err = au_may_del(a->dst_dentry, a->btgt,
++ a->dst_h_parent, isdir);
+ }
+
+out:
@@ -17789,16 +17912,16 @@ index 0000000..cbe78c8
+ a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir,
+ a->dst_h_parent, a->dst_hdir);
+ udba = au_opt_udba(a->src_dentry->d_sb);
-+ if (unlikely(a->src_hdir->hi_inode != a->src_h_parent->d_inode
-+ || a->dst_hdir->hi_inode != a->dst_h_parent->d_inode))
++ if (unlikely(a->src_hdir->hi_inode != d_inode(a->src_h_parent)
++ || a->dst_hdir->hi_inode != d_inode(a->dst_h_parent)))
+ err = au_busy_or_stale();
+ if (!err && au_dbstart(a->src_dentry) == a->btgt)
+ err = au_h_verify(a->src_h_dentry, udba,
-+ a->src_h_parent->d_inode, a->src_h_parent,
++ d_inode(a->src_h_parent), a->src_h_parent,
+ a->br);
+ if (!err && au_dbstart(a->dst_dentry) == a->btgt)
+ err = au_h_verify(a->dst_h_dentry, udba,
-+ a->dst_h_parent->d_inode, a->dst_h_parent,
++ d_inode(a->dst_h_parent), a->dst_h_parent,
+ a->br);
+ if (!err)
+ goto out; /* success */
@@ -17824,8 +17947,7 @@ index 0000000..cbe78c8
+ au_cpup_attr_nlink(dir, /*force*/1);
+ }
+
-+ if (au_ibstart(dir) == a->btgt)
-+ au_cpup_attr_timesizes(dir);
++ au_dir_ts(dir, a->btgt);
+
+ if (au_ftest_ren(a->flags, ISSAMEDIR))
+ return;
@@ -17834,8 +17956,7 @@ index 0000000..cbe78c8
+ dir->i_version++;
+ if (au_ftest_ren(a->flags, ISDIR))
+ au_cpup_attr_nlink(dir, /*force*/1);
-+ if (au_ibstart(dir) == a->btgt)
-+ au_cpup_attr_timesizes(dir);
++ au_dir_ts(dir, a->btgt);
+}
+
+static void au_ren_refresh(struct au_ren_args *a)
@@ -17907,7 +18028,7 @@ index 0000000..cbe78c8
+ struct au_branch *br;
+
+ parent = dentry->d_parent;
-+ IMustLock(parent->d_inode); /* dir is locked */
++ IMustLock(d_inode(parent)); /* dir is locked */
+
+ bdiropq = au_dbdiropq(parent);
+ bwh = au_dbwh(dentry);
@@ -17959,7 +18080,7 @@ index 0000000..cbe78c8
+
+ a->h_path.dentry = a->src_h_dentry;
+ au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path);
-+ if (a->dst_h_dentry->d_inode) {
++ if (d_is_positive(a->dst_h_dentry)) {
+ au_fset_ren(a->flags, DT_DSTDIR);
+ a->h_path.dentry = a->dst_h_dentry;
+ au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path);
@@ -17977,14 +18098,14 @@ index 0000000..cbe78c8
+
+ if (au_ftest_ren(a->flags, ISDIR) && err != -EIO) {
+ h_d = a->src_dt[AuCHILD].dt_h_path.dentry;
-+ h_mtx = &h_d->d_inode->i_mutex;
++ h_mtx = &d_inode(h_d)->i_mutex;
+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
+ au_dtime_revert(a->src_dt + AuCHILD);
+ mutex_unlock(h_mtx);
+
+ if (au_ftest_ren(a->flags, DT_DSTDIR)) {
+ h_d = a->dst_dt[AuCHILD].dt_h_path.dentry;
-+ h_mtx = &h_d->d_inode->i_mutex;
++ h_mtx = &d_inode(h_d)->i_mutex;
+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
+ au_dtime_revert(a->dst_dt + AuCHILD);
+ mutex_unlock(h_mtx);
@@ -18013,11 +18134,15 @@ index 0000000..cbe78c8
+
+ a->src_dir = _src_dir;
+ a->src_dentry = _src_dentry;
-+ a->src_inode = a->src_dentry->d_inode;
++ a->src_inode = NULL;
++ if (d_really_is_positive(a->src_dentry))
++ a->src_inode = d_inode(a->src_dentry);
+ a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */
+ a->dst_dir = _dst_dir;
+ a->dst_dentry = _dst_dentry;
-+ a->dst_inode = a->dst_dentry->d_inode;
++ a->dst_inode = NULL;
++ if (d_really_is_positive(a->dst_dentry))
++ a->dst_inode = d_inode(a->dst_dentry);
+ a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */
+ if (a->dst_inode) {
+ IMustLock(a->dst_inode);
@@ -18026,9 +18151,10 @@ index 0000000..cbe78c8
+
+ err = -ENOTDIR;
+ flags = AuLock_FLUSH | AuLock_NOPLM | AuLock_GEN;
-+ if (S_ISDIR(a->src_inode->i_mode)) {
++ if (d_is_dir(a->src_dentry)) {
+ au_fset_ren(a->flags, ISDIR);
-+ if (unlikely(a->dst_inode && !S_ISDIR(a->dst_inode->i_mode)))
++ if (unlikely(d_really_is_positive(a->dst_dentry)
++ && !d_is_dir(a->dst_dentry)))
+ goto out_free;
+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
+ AuLock_DIR | flags);
@@ -18064,7 +18190,7 @@ index 0000000..cbe78c8
+ * there may exist a problem somewhere else.
+ */
+ err = -EINVAL;
-+ if (unlikely(a->dst_parent->d_inode == a->src_dentry->d_inode))
++ if (unlikely(d_inode(a->dst_parent) == d_inode(a->src_dentry)))
+ goto out_unlock;
+
+ au_fset_ren(a->flags, ISSAMEDIR); /* temporary */
@@ -18475,10 +18601,10 @@ index 0000000..b8efd45
+}
diff --git a/fs/aufs/inode.c b/fs/aufs/inode.c
new file mode 100644
-index 0000000..f58367d
+index 0000000..559da33
--- /dev/null
+++ b/fs/aufs/inode.c
-@@ -0,0 +1,483 @@
+@@ -0,0 +1,487 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -18602,18 +18728,19 @@ index 0000000..f58367d
+ flags = au_hi_flags(inode, isdir);
+ bend = au_dbend(dentry);
+ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
-+ struct inode *h_i;
++ struct inode *h_i, *h_inode;
+ struct dentry *h_d;
+
+ h_d = au_h_dptr(dentry, bindex);
-+ if (!h_d || !h_d->d_inode)
++ if (!h_d || d_is_negative(h_d))
+ continue;
+
-+ AuDebugOn(mode != (h_d->d_inode->i_mode & S_IFMT));
++ h_inode = d_inode(h_d);
++ AuDebugOn(mode != (h_inode->i_mode & S_IFMT));
+ if (iinfo->ii_bstart <= bindex && bindex <= iinfo->ii_bend) {
+ h_i = au_h_iptr(inode, bindex);
+ if (h_i) {
-+ if (h_i == h_d->d_inode)
++ if (h_i == h_inode)
+ continue;
+ err = -EIO;
+ break;
@@ -18623,7 +18750,7 @@ index 0000000..f58367d
+ iinfo->ii_bstart = bindex;
+ if (iinfo->ii_bend < bindex)
+ iinfo->ii_bend = bindex;
-+ au_set_h_iptr(inode, bindex, au_igrab(h_d->d_inode), flags);
++ au_set_h_iptr(inode, bindex, au_igrab(h_inode), flags);
+ update = 1;
+ }
+ au_update_ibrange(inode, /*do_put_zero*/0);
@@ -18654,7 +18781,8 @@ index 0000000..f58367d
+ err = 0;
+ isdir = 0;
+ bstart = au_dbstart(dentry);
-+ h_inode = au_h_dptr(dentry, bstart)->d_inode;
++ h_dentry = au_h_dptr(dentry, bstart);
++ h_inode = d_inode(h_dentry);
+ mode = h_inode->i_mode;
+ switch (mode & S_IFMT) {
+ case S_IFREG:
@@ -18703,7 +18831,7 @@ index 0000000..f58367d
+ h_dentry = au_h_dptr(dentry, bindex);
+ if (h_dentry)
+ au_set_h_iptr(inode, bindex,
-+ au_igrab(h_dentry->d_inode), flags);
++ au_igrab(d_inode(h_dentry)), flags);
+ }
+ au_cpup_attr_all(inode, /*force*/1);
+ /*
@@ -18728,6 +18856,7 @@ index 0000000..f58367d
+ struct au_iigen iigen;
+ aufs_bindex_t bindex, bend;
+ struct inode *h_inode, *h_dinode;
++ struct dentry *h_dentry;
+
+ /*
+ * before this function, if aufs got any iinfo lock, it must be only
@@ -18740,7 +18869,8 @@ index 0000000..f58367d
+
+ err = 1;
+ ii_write_lock_new_child(inode);
-+ h_dinode = au_h_dptr(dentry, au_dbstart(dentry))->d_inode;
++ h_dentry = au_h_dptr(dentry, au_dbstart(dentry));
++ h_dinode = d_inode(h_dentry);
+ bend = au_ibend(inode);
+ for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
+ h_inode = au_h_iptr(inode, bindex);
@@ -18813,7 +18943,7 @@ index 0000000..f58367d
+ sb = dentry->d_sb;
+ bstart = au_dbstart(dentry);
+ h_dentry = au_h_dptr(dentry, bstart);
-+ h_inode = h_dentry->d_inode;
++ h_inode = d_inode(h_dentry);
+ h_ino = h_inode->i_ino;
+
+ /*
@@ -18821,7 +18951,7 @@ index 0000000..f58367d
+ * parents.
+ */
+ mtx = NULL;
-+ if (!S_ISDIR(h_inode->i_mode))
++ if (!d_is_dir(h_dentry))
+ mtx = &au_sbr(sb, bstart)->br_xino.xi_nondir_mtx;
+
+new_ino:
@@ -18849,10 +18979,10 @@ index 0000000..f58367d
+ AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW));
+ if (inode->i_state & I_NEW) {
+ /* verbose coding for lock class name */
-+ if (unlikely(S_ISLNK(h_inode->i_mode)))
++ if (unlikely(d_is_symlink(h_dentry)))
+ au_rw_class(&au_ii(inode)->ii_rwsem,
+ au_lc_key + AuLcSymlink_IIINFO);
-+ else if (unlikely(S_ISDIR(h_inode->i_mode)))
++ else if (unlikely(d_is_dir(h_dentry)))
+ au_rw_class(&au_ii(inode)->ii_rwsem,
+ au_lc_key + AuLcDir_IIINFO);
+ else /* likely */
@@ -18897,7 +19027,7 @@ index 0000000..f58367d
+ mutex_lock(mtx);
+ }
+
-+ if (unlikely(au_test_fs_unique_ino(h_dentry->d_inode)))
++ if (unlikely(au_test_fs_unique_ino(h_inode)))
+ AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir,"
+ " b%d, %s, %pd, hi%lu, i%lu.\n",
+ bstart, au_sbtype(h_dentry->d_sb), dentry,
@@ -18964,10 +19094,10 @@ index 0000000..f58367d
+}
diff --git a/fs/aufs/inode.h b/fs/aufs/inode.h
new file mode 100644
-index 0000000..7552346
+index 0000000..003534a
--- /dev/null
+++ b/fs/aufs/inode.h
-@@ -0,0 +1,654 @@
+@@ -0,0 +1,660 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -19112,9 +19242,8 @@ index 0000000..7552346
+
+/* au_wr_dir flags */
+#define AuWrDir_ADD_ENTRY 1
-+#define AuWrDir_TMP_WHENTRY (1 << 1)
-+#define AuWrDir_ISDIR (1 << 2)
-+#define AuWrDir_TMPFILE (1 << 3)
++#define AuWrDir_ISDIR (1 << 1)
++#define AuWrDir_TMPFILE (1 << 2)
+#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name)
+#define au_fset_wrdir(flags, name) \
+ do { (flags) |= AuWrDir_##name; } while (0)
@@ -19168,6 +19297,9 @@ index 0000000..7552346
+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
+ bool want_excl);
++struct vfsub_aopen_args;
++int au_aopen_or_create(struct inode *dir, struct dentry *dentry,
++ struct vfsub_aopen_args *args);
+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode);
+int aufs_link(struct dentry *src_dentry, struct inode *dir,
+ struct dentry *dentry);
@@ -19220,6 +19352,7 @@ index 0000000..7552346
+#ifdef CONFIG_PROC_FS
+/* plink.c */
+int au_plink_maint(struct super_block *sb, int flags);
++struct au_sbinfo;
+void au_plink_maint_leave(struct au_sbinfo *sbinfo);
+int au_plink_maint_enter(struct super_block *sb);
+#ifdef CONFIG_AUFS_DEBUG
@@ -19251,7 +19384,8 @@ index 0000000..7552346
+
+#ifdef CONFIG_AUFS_XATTR
+/* xattr.c */
-+int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags);
++int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags,
++ unsigned int verbose);
+ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size);
+ssize_t aufs_getxattr(struct dentry *dentry, const char *name, void *value,
+ size_t size);
@@ -19262,7 +19396,7 @@ index 0000000..7552346
+/* void au_xattr_init(struct super_block *sb); */
+#else
+AuStubInt0(au_cpup_xattr, struct dentry *h_dst, struct dentry *h_src,
-+ int ignore_flags);
++ int ignore_flags, unsigned int verbose);
+/* AuStubVoid(au_xattr_init, struct super_block *sb); */
+#endif
+
@@ -19512,6 +19646,7 @@ index 0000000..7552346
+ }
+}
+
++#if 0 /* reserved */
+static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent)
+{
+ if (pin) {
@@ -19519,6 +19654,7 @@ index 0000000..7552346
+ pin->parent = dget(parent);
+ }
+}
++#endif
+
+/* ---------------------------------------------------------------------- */
+
@@ -20019,10 +20155,10 @@ index 0000000..6d9864d
+#endif /* __AUFS_LOOP_H__ */
diff --git a/fs/aufs/magic.mk b/fs/aufs/magic.mk
new file mode 100644
-index 0000000..3e6387b
+index 0000000..4f83bdf
--- /dev/null
+++ b/fs/aufs/magic.mk
-@@ -0,0 +1,54 @@
+@@ -0,0 +1,30 @@
+
+# defined in ${srctree}/fs/fuse/inode.c
+# tristate
@@ -20030,24 +20166,6 @@ index 0000000..3e6387b
+ccflags-y += -DFUSE_SUPER_MAGIC=0x65735546
+endif
+
-+# defined in ${srctree}/fs/ocfs2/ocfs2_fs.h
-+# tristate
-+ifdef CONFIG_OCFS2_FS
-+ccflags-y += -DOCFS2_SUPER_MAGIC=0x7461636f
-+endif
-+
-+# defined in ${srctree}/fs/ocfs2/dlm/userdlm.h
-+# tristate
-+ifdef CONFIG_OCFS2_FS_O2CB
-+ccflags-y += -DDLMFS_MAGIC=0x76a9f425
-+endif
-+
-+# defined in ${srctree}/fs/cifs/cifsfs.c
-+# tristate
-+ifdef CONFIG_CIFS_FS
-+ccflags-y += -DCIFS_MAGIC_NUMBER=0xFF534D42
-+endif
-+
+# defined in ${srctree}/fs/xfs/xfs_sb.h
+# tristate
+ifdef CONFIG_XFS_FS
@@ -20060,12 +20178,6 @@ index 0000000..3e6387b
+ccflags-y += -DCONFIGFS_MAGIC=0x62656570
+endif
+
-+# defined in ${srctree}/fs/9p/v9fs.h
-+# tristate
-+ifdef CONFIG_9P_FS
-+ccflags-y += -DV9FS_MAGIC=0x01021997
-+endif
-+
+# defined in ${srctree}/fs/ubifs/ubifs.h
+# tristate
+ifdef CONFIG_UBIFS_FS
@@ -20378,7 +20490,7 @@ index 0000000..adee827
+#endif /* __AUFS_MODULE_H__ */
diff --git a/fs/aufs/mvdown.c b/fs/aufs/mvdown.c
new file mode 100644
-index 0000000..ca4e078
+index 0000000..bec20d3
--- /dev/null
+++ b/fs/aufs/mvdown.c
@@ -0,0 +1,681 @@
@@ -20521,7 +20633,7 @@ index 0000000..ca4e078
+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
+ err = au_do_pin(&a->mvd_pin_src);
+ AuTraceErr(err);
-+ a->mvd_h_src_dir = a->mvd_h_src_parent->d_inode;
++ a->mvd_h_src_dir = d_inode(a->mvd_h_src_parent);
+ if (unlikely(err)) {
+ AU_MVD_PR(dmsg, "pin_src failed\n");
+ goto out_dst;
@@ -20535,7 +20647,7 @@ index 0000000..ca4e078
+ au_opt_udba(a->sb),
+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
+ AuTraceErr(err);
-+ a->mvd_h_src_dir = a->mvd_h_src_parent->d_inode;
++ a->mvd_h_src_dir = d_inode(a->mvd_h_src_parent);
+ if (unlikely(err)) {
+ AU_MVD_PR(dmsg, "pin_src failed\n");
+ au_pin_hdir_lock(&a->mvd_pin_dst);
@@ -20629,10 +20741,10 @@ index 0000000..ca4e078
+ }
+
+ err = 0;
-+ if (h_path.dentry->d_inode) {
++ if (d_is_positive(h_path.dentry)) {
+ h_path.mnt = au_br_mnt(br);
+ delegated = NULL;
-+ err = vfsub_unlink(a->mvd_h_dst_parent->d_inode, &h_path,
++ err = vfsub_unlink(d_inode(a->mvd_h_dst_parent), &h_path,
+ &delegated, /*force*/0);
+ if (unlikely(err == -EWOULDBLOCK)) {
+ pr_warn("cannot retry for NFSv4 delegation"
@@ -21014,13 +21126,13 @@ index 0000000..ca4e078
+ args->mvdown.flags &= ~(AUFS_MVDOWN_ROLOWER_R | AUFS_MVDOWN_ROUPPER_R);
+ args->mvdown.au_errno = 0;
+ args->dentry = dentry;
-+ args->inode = dentry->d_inode;
++ args->inode = d_inode(dentry);
+ args->sb = dentry->d_sb;
+
+ err = -ENOENT;
+ dmsg = !!(args->mvdown.flags & AUFS_MVDOWN_DMSG);
+ args->parent = dget_parent(dentry);
-+ args->dir = args->parent->d_inode;
++ args->dir = d_inode(args->parent);
+ mutex_lock_nested(&args->dir->i_mutex, I_MUTEX_PARENT);
+ dput(args->parent);
+ if (unlikely(args->parent != dentry->d_parent)) {
@@ -21065,10 +21177,10 @@ index 0000000..ca4e078
+}
diff --git a/fs/aufs/opts.c b/fs/aufs/opts.c
new file mode 100644
-index 0000000..78bb06c
+index 0000000..90098fe
--- /dev/null
+++ b/fs/aufs/opts.c
-@@ -0,0 +1,1837 @@
+@@ -0,0 +1,1822 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -21086,11 +21198,11 @@ index 0000000..78bb06c
+
+enum {
+ Opt_br,
-+ Opt_add, Opt_del, Opt_mod, Opt_reorder, Opt_append, Opt_prepend,
-+ Opt_idel, Opt_imod, Opt_ireorder,
-+ Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash, Opt_rendir,
++ Opt_add, Opt_del, Opt_mod, Opt_append, Opt_prepend,
++ Opt_idel, Opt_imod,
++ Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash,
+ Opt_rdblk_def, Opt_rdhash_def,
-+ Opt_xino, Opt_zxino, Opt_noxino,
++ Opt_xino, Opt_noxino,
+ Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino,
+ Opt_trunc_xino_path, Opt_itrunc_xino,
+ Opt_trunc_xib, Opt_notrunc_xib,
@@ -21098,13 +21210,10 @@ index 0000000..78bb06c
+ Opt_plink, Opt_noplink, Opt_list_plink,
+ Opt_udba,
+ Opt_dio, Opt_nodio,
-+ /* Opt_lock, Opt_unlock, */
-+ Opt_cmd, Opt_cmd_args,
+ Opt_diropq_a, Opt_diropq_w,
+ Opt_warn_perm, Opt_nowarn_perm,
+ Opt_wbr_copyup, Opt_wbr_create,
+ Opt_fhsm_sec,
-+ Opt_refrof, Opt_norefrof,
+ Opt_verbose, Opt_noverbose,
+ Opt_sum, Opt_nosum, Opt_wsum,
+ Opt_dirperm1, Opt_nodirperm1,
@@ -21188,11 +21297,6 @@ index 0000000..78bb06c
+ {Opt_dirperm1, "dirperm1"},
+ {Opt_nodirperm1, "nodirperm1"},
+
-+ {Opt_rendir, "rendir=%d"},
-+
-+ {Opt_refrof, "refrof"},
-+ {Opt_norefrof, "norefrof"},
-+
+ {Opt_verbose, "verbose"},
+ {Opt_verbose, "v"},
+ {Opt_noverbose, "noverbose"},
@@ -21262,14 +21366,19 @@ index 0000000..78bb06c
+ int v;
+
+ v = *val;
++ if (!v)
++ goto out;
+ p = tbl;
-+ while (p->token) {
-+ if ((v & p->token) == p->token) {
++ while (p->pattern) {
++ if (p->token
++ && (v & p->token) == p->token) {
+ *val &= ~p->token;
+ return p->pattern;
+ }
+ p++;
+ }
++
++out:
+ return NULL;
+}
+
@@ -21288,13 +21397,17 @@ index 0000000..78bb06c
+ {AuBrAttr_COO_ALL, AUFS_BRATTR_COO_ALL},
+ /* 'unpin' attrib is meaningless since linux-3.18-rc1 */
+ {AuBrAttr_UNPIN, AUFS_BRATTR_UNPIN},
++#ifdef CONFIG_AUFS_FHSM
+ {AuBrAttr_FHSM, AUFS_BRATTR_FHSM},
++#endif
++#ifdef CONFIG_AUFS_XATTR
+ {AuBrAttr_ICEX, AUFS_BRATTR_ICEX},
+ {AuBrAttr_ICEX_SEC, AUFS_BRATTR_ICEX_SEC},
+ {AuBrAttr_ICEX_SYS, AUFS_BRATTR_ICEX_SYS},
+ {AuBrAttr_ICEX_TR, AUFS_BRATTR_ICEX_TR},
+ {AuBrAttr_ICEX_USR, AUFS_BRATTR_ICEX_USR},
+ {AuBrAttr_ICEX_OTH, AUFS_BRATTR_ICEX_OTH},
++#endif
+
+ /* ro/rr branch */
+ {AuBrRAttr_WH, AUFS_BRRATTR_WH},
@@ -21697,7 +21810,6 @@ index 0000000..78bb06c
+ u.xino_itrunc = &opt->xino_itrunc;
+ AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex);
+ break;
-+
+ case Opt_noxino:
+ AuLabel(noxino);
+ break;
@@ -21750,12 +21862,6 @@ index 0000000..78bb06c
+ case Opt_nowarn_perm:
+ AuLabel(nowarn_perm);
+ break;
-+ case Opt_refrof:
-+ AuLabel(refrof);
-+ break;
-+ case Opt_norefrof:
-+ AuLabel(norefrof);
-+ break;
+ case Opt_verbose:
+ AuLabel(verbose);
+ break;
@@ -22242,8 +22348,6 @@ index 0000000..78bb06c
+ case Opt_diropq_w:
+ case Opt_warn_perm:
+ case Opt_nowarn_perm:
-+ case Opt_refrof:
-+ case Opt_norefrof:
+ case Opt_verbose:
+ case Opt_noverbose:
+ case Opt_sum:
@@ -22433,13 +22537,6 @@ index 0000000..78bb06c
+ au_opt_clr(sbinfo->si_mntflags, WARN_PERM);
+ break;
+
-+ case Opt_refrof:
-+ au_opt_set(sbinfo->si_mntflags, REFROF);
-+ break;
-+ case Opt_norefrof:
-+ au_opt_clr(sbinfo->si_mntflags, REFROF);
-+ break;
-+
+ case Opt_verbose:
+ au_opt_set(sbinfo->si_mntflags, VERBOSE);
+ break;
@@ -22672,7 +22769,7 @@ index 0000000..78bb06c
+ err = 0;
+ fhsm = 0;
+ root = sb->s_root;
-+ dir = root->d_inode;
++ dir = d_inode(root);
+ do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK);
+ bend = au_sbend(sb);
+ for (bindex = 0; !err && bindex <= bend; bindex++) {
@@ -22845,7 +22942,7 @@ index 0000000..78bb06c
+ /* go on even if err */
+ }
+ if (au_opt_test(tmp, UDBA_HNOTIFY)) {
-+ dir = sb->s_root->d_inode;
++ dir = d_inode(sb->s_root);
+ au_hn_reset(dir, au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO);
+ }
+
@@ -22863,7 +22960,7 @@ index 0000000..78bb06c
+
+ SiMustWriteLock(sb);
+
-+ dir = sb->s_root->d_inode;
++ dir = d_inode(sb->s_root);
+ sbinfo = au_sbi(sb);
+ err = 0;
+ opt_xino = NULL;
@@ -22908,10 +23005,10 @@ index 0000000..78bb06c
+}
diff --git a/fs/aufs/opts.h b/fs/aufs/opts.h
new file mode 100644
-index 0000000..929ebc3
+index 0000000..da552ff
--- /dev/null
+++ b/fs/aufs/opts.h
-@@ -0,0 +1,200 @@
+@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -22926,7 +23023,6 @@ index 0000000..929ebc3
+#ifdef __KERNEL__
+
+#include
-+#include "branch.h"
+
+struct file;
+struct super_block;
@@ -22944,7 +23040,6 @@ index 0000000..929ebc3
+#define AuOpt_PLINK (1 << 6) /* pseudo-link */
+#define AuOpt_DIRPERM1 (1 << 7) /* ignore the lower dir's perm
+ bits */
-+#define AuOpt_REFROF (1 << 8) /* unimplemented */
+#define AuOpt_ALWAYS_DIROPQ (1 << 9) /* policy to creating diropq */
+#define AuOpt_SUM (1 << 10) /* summation for statfs(2) */
+#define AuOpt_SUM_W (1 << 11) /* unimplemented */
@@ -23094,6 +23189,7 @@ index 0000000..929ebc3
+
+/* ---------------------------------------------------------------------- */
+
++/* opts.c */
+void au_optstr_br_perm(au_br_perm_str_t *str, int perm);
+const char *au_optstr_udba(int udba);
+const char *au_optstr_wbr_copyup(int wbr_copyup);
@@ -23108,16 +23204,14 @@ index 0000000..929ebc3
+
+unsigned int au_opt_udba(struct super_block *sb);
+
-+/* ---------------------------------------------------------------------- */
-+
+#endif /* __KERNEL__ */
+#endif /* __AUFS_OPTS_H__ */
diff --git a/fs/aufs/plink.c b/fs/aufs/plink.c
new file mode 100644
-index 0000000..3e4fe87
+index 0000000..af2246c
--- /dev/null
+++ b/fs/aufs/plink.c
-@@ -0,0 +1,519 @@
+@@ -0,0 +1,515 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -23309,7 +23403,7 @@ index 0000000..3e4fe87
+ struct dentry *h_dentry;
+ struct mutex *h_mtx;
+
-+ h_mtx = &h_parent->d_inode->i_mutex;
++ h_mtx = &d_inode(h_parent)->i_mutex;
+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
+ h_dentry = vfsub_lkup_one(tgtname, h_parent);
+ mutex_unlock(h_mtx);
@@ -23327,7 +23421,6 @@ index 0000000..3e4fe87
+{
+ struct dentry *h_dentry, *h_parent;
+ struct au_branch *br;
-+ struct inode *h_dir;
+ int wkq_err;
+ char a[PLINK_NAME_LEN];
+ struct qstr tgtname = QSTR_INIT(a, 0);
@@ -23336,7 +23429,6 @@ index 0000000..3e4fe87
+
+ br = au_sbr(inode->i_sb, bindex);
+ h_parent = br->br_wbr->wbr_plink;
-+ h_dir = h_parent->d_inode;
+ tgtname.len = plink_name(a, sizeof(a), inode, bindex);
+
+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
@@ -23366,7 +23458,7 @@ index 0000000..3e4fe87
+ };
+ struct inode *h_dir, *delegated;
+
-+ h_dir = h_parent->d_inode;
++ h_dir = d_inode(h_parent);
+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2);
+again:
+ h_path.dentry = vfsub_lkup_one(tgt, h_parent);
@@ -23377,8 +23469,8 @@ index 0000000..3e4fe87
+ err = 0;
+ /* wh.plink dir is not monitored */
+ /* todo: is it really safe? */
-+ if (h_path.dentry->d_inode
-+ && h_path.dentry->d_inode != h_dentry->d_inode) {
++ if (d_is_positive(h_path.dentry)
++ && d_inode(h_path.dentry) != d_inode(h_dentry)) {
+ delegated = NULL;
+ err = vfsub_unlink(h_dir, &h_path, &delegated, /*force*/0);
+ if (unlikely(err == -EWOULDBLOCK)) {
@@ -23391,7 +23483,7 @@ index 0000000..3e4fe87
+ if (!err)
+ goto again;
+ }
-+ if (!err && !h_path.dentry->d_inode) {
++ if (!err && d_is_negative(h_path.dentry)) {
+ delegated = NULL;
+ err = vfsub_link(h_dentry, h_dir, &h_path, &delegated);
+ if (unlikely(err == -EWOULDBLOCK)) {
@@ -23427,13 +23519,11 @@ index 0000000..3e4fe87
+ int err, wkq_err;
+ struct au_wbr *wbr;
+ struct dentry *h_parent;
-+ struct inode *h_dir;
+ char a[PLINK_NAME_LEN];
+ struct qstr tgtname = QSTR_INIT(a, 0);
+
+ wbr = au_sbr(inode->i_sb, bindex)->br_wbr;
+ h_parent = wbr->wbr_plink;
-+ h_dir = h_parent->d_inode;
+ tgtname.len = plink_name(a, sizeof(a), inode, bindex);
+
+ /* always superio. */
@@ -23639,10 +23729,10 @@ index 0000000..3e4fe87
+}
diff --git a/fs/aufs/poll.c b/fs/aufs/poll.c
new file mode 100644
-index 0000000..9a1fbbd
+index 0000000..c324fc7
--- /dev/null
+++ b/fs/aufs/poll.c
-@@ -0,0 +1,42 @@
+@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -23659,26 +23749,23 @@ index 0000000..9a1fbbd
+ unsigned int mask;
+ int err;
+ struct file *h_file;
-+ struct dentry *dentry;
+ struct super_block *sb;
+
+ /* We should pretend an error happened. */
+ mask = POLLERR /* | POLLIN | POLLOUT */;
-+ dentry = file->f_path.dentry;
-+ sb = dentry->d_sb;
++ sb = file->f_path.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))
++
++ h_file = au_read_pre(file, /*keep_fi*/0);
++ err = PTR_ERR(h_file);
++ if (IS_ERR(h_file))
+ goto out;
+
+ /* it is not an error if h_file has no operation */
+ mask = DEFAULT_POLLMASK;
-+ h_file = au_hf_top(file);
+ if (h_file->f_op->poll)
+ mask = h_file->f_op->poll(h_file, wait);
-+
-+ di_read_unlock(dentry, AuLock_IR);
-+ fi_read_unlock(file);
++ fput(h_file); /* instead of au_read_post() */
+
+out:
+ si_read_unlock(sb);
@@ -23941,7 +24028,7 @@ index 0000000..ead2a00
+}
diff --git a/fs/aufs/rdu.c b/fs/aufs/rdu.c
new file mode 100644
-index 0000000..6a34e48
+index 0000000..f11d9bb
--- /dev/null
+++ b/fs/aufs/rdu.c
@@ -0,0 +1,375 @@
@@ -24091,7 +24178,7 @@ index 0000000..6a34e48
+ goto out;
+
+ dentry = file->f_path.dentry;
-+ inode = dentry->d_inode;
++ inode = d_inode(dentry);
+#if 1
+ mutex_lock(&inode->i_mutex);
+#else
@@ -24506,10 +24593,10 @@ index 0000000..171ee0c
+#endif /* __AUFS_RWSEM_H__ */
diff --git a/fs/aufs/sbinfo.c b/fs/aufs/sbinfo.c
new file mode 100644
-index 0000000..34ef9fb
+index 0000000..5793673
--- /dev/null
+++ b/fs/aufs/sbinfo.c
-@@ -0,0 +1,340 @@
+@@ -0,0 +1,343 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -24607,6 +24694,8 @@ index 0000000..34ef9fb
+ sbinfo->si_xino_brid = -1;
+ /* leave si_xib_last_pindex and si_xib_next_bit */
+
++ au_sphl_init(&sbinfo->si_aopen);
++
+ sbinfo->si_rdcache = msecs_to_jiffies(AUFS_RDCACHE_DEF * MSEC_PER_SEC);
+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
+ sbinfo->si_rdhash = AUFS_RDHASH_DEF;
@@ -24623,7 +24712,6 @@ index 0000000..34ef9fb
+ sbinfo->si_sb = sb;
+ sb->s_fs_info = sbinfo;
+ si_pid_set(sb);
-+ au_debug_sbinfo_init(sbinfo);
+ return 0; /* success */
+
+out_br:
@@ -24661,13 +24749,15 @@ index 0000000..34ef9fb
+unsigned int au_sigen_inc(struct super_block *sb)
+{
+ unsigned int gen;
++ struct inode *inode;
+
+ SiMustWriteLock(sb);
+
+ gen = ++au_sbi(sb)->si_generation;
+ au_update_digen(sb->s_root);
-+ au_update_iigen(sb->s_root->d_inode, /*half*/0);
-+ sb->s_root->d_inode->i_version++;
++ inode = d_inode(sb->s_root);
++ au_update_iigen(inode, /*half*/0);
++ inode->i_version++;
+ return gen;
+}
+
@@ -24956,10 +25046,10 @@ index 0000000..a66d39e
+#endif /* __AUFS_SPL_H__ */
diff --git a/fs/aufs/super.c b/fs/aufs/super.c
new file mode 100644
-index 0000000..9acda0e
+index 0000000..ee5780d
--- /dev/null
+++ b/fs/aufs/super.c
-@@ -0,0 +1,996 @@
+@@ -0,0 +1,991 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -24969,11 +25059,9 @@ index 0000000..9acda0e
+ */
+
+#include
-+#include
+#include
+#include
+#include
-+#include
+#include "aufs.h"
+
+/*
@@ -25209,7 +25297,6 @@ index 0000000..9acda0e
+ AuBool(PLINK, plink);
+ AuBool(DIO, dio);
+ AuBool(DIRPERM1, dirperm1);
-+ /* AuBool(REFROF, refrof); */
+
+ v = sbinfo->si_wbr_create;
+ if (v != AuWbrCreate_Def)
@@ -25524,7 +25611,7 @@ index 0000000..9acda0e
+ di_read_lock_parent(parent, AuLock_IR);
+ err = au_refresh_dentry(dentry, parent);
+ if (!err && dir_flags)
-+ au_hn_reset(dentry->d_inode, dir_flags);
++ au_hn_reset(d_inode(dentry), dir_flags);
+ di_read_unlock(parent, AuLock_IR);
+ di_write_unlock(dentry);
+
@@ -25537,14 +25624,12 @@ index 0000000..9acda0e
+{
+ int err;
+ struct dentry *parent;
-+ struct inode *inode;
+
+ err = 0;
+ parent = dget_parent(dentry);
+ if (!au_digen_test(parent, sigen) && au_digen_test(dentry, sigen)) {
-+ inode = dentry->d_inode;
-+ if (inode) {
-+ if (!S_ISDIR(inode->i_mode))
++ if (d_really_is_positive(dentry)) {
++ if (!d_is_dir(dentry))
+ err = au_do_refresh(dentry, /*dir_flags*/0,
+ parent);
+ else {
@@ -25571,7 +25656,7 @@ index 0000000..9acda0e
+ struct dentry **dentries, *d;
+ struct au_sbinfo *sbinfo;
+ struct dentry *root = sb->s_root;
-+ const unsigned int dir_flags = au_hi_flags(root->d_inode, /*isdir*/1);
++ const unsigned int dir_flags = au_hi_flags(d_inode(root), /*isdir*/1);
+
+ err = au_dpages_init(&dpages, GFP_NOFS);
+ if (unlikely(err))
@@ -25652,7 +25737,7 @@ index 0000000..9acda0e
+
+ root = sb->s_root;
+ DiMustNoWaiters(root);
-+ inode = root->d_inode;
++ inode = d_inode(root);
+ IiMustNoWaiters(inode);
+
+ udba = au_opt_udba(sb);
@@ -25732,7 +25817,7 @@ index 0000000..9acda0e
+ goto out_opts;
+
+ sbinfo = au_sbi(sb);
-+ inode = root->d_inode;
++ inode = d_inode(root);
+ mutex_lock(&inode->i_mutex);
+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
+ if (unlikely(err))
@@ -25858,7 +25943,7 @@ index 0000000..9acda0e
+ goto out_info;
+ }
+ root = sb->s_root;
-+ inode = root->d_inode;
++ inode = d_inode(root);
+
+ /*
+ * actually we can parse options regardless aufs lock here.
@@ -25958,10 +26043,10 @@ index 0000000..9acda0e
+};
diff --git a/fs/aufs/super.h b/fs/aufs/super.h
new file mode 100644
-index 0000000..0514a13
+index 0000000..f37d89d
--- /dev/null
+++ b/fs/aufs/super.h
-@@ -0,0 +1,628 @@
+@@ -0,0 +1,622 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -25976,14 +26061,11 @@ index 0000000..0514a13
+#ifdef __KERNEL__
+
+#include
++#include
+#include "rwsem.h"
+#include "spl.h"
+#include "wkq.h"
+
-+typedef ssize_t (*au_readf_t)(struct file *, char __user *, size_t, loff_t *);
-+typedef ssize_t (*au_writef_t)(struct file *, const char __user *, size_t,
-+ loff_t *);
-+
+/* policies to select one among multiple writable branches */
+struct au_wbr_copyup_operations {
+ int (*copyup)(struct dentry *dentry);
@@ -26068,7 +26150,7 @@ index 0000000..0514a13
+ /* branch management */
+ unsigned int si_generation;
+
-+ /* see above flags */
++ /* see AuSi_ flags */
+ unsigned char au_si_status;
+
+ aufs_bindex_t si_bend;
@@ -26098,8 +26180,8 @@ index 0000000..0514a13
+ unsigned int si_mntflags;
+
+ /* external inode number (bitmap and translation table) */
-+ au_readf_t si_xread;
-+ au_writef_t si_xwrite;
++ vfs_readf_t si_xread;
++ vfs_writef_t si_xwrite;
+ struct file *si_xib;
+ struct mutex si_xib_mtx; /* protect xib members */
+ unsigned long *si_xib_buf;
@@ -26117,6 +26199,9 @@ index 0000000..0514a13
+ atomic_t si_xigen_next;
+#endif
+
++ /* dirty trick to suppoer atomic_open */
++ struct au_sphlhead si_aopen;
++
+ /* vdir parameters */
+ unsigned long si_rdcache; /* max cache time in jiffies */
+ unsigned int si_rdblk; /* deblk size */
@@ -26130,12 +26215,6 @@ index 0000000..0514a13
+ */
+ unsigned int si_dirwh;
+
-+ /*
-+ * rename(2) a directory with all children.
-+ */
-+ /* reserved for future use */
-+ /* int si_rendir; */
-+
+ /* pseudo_link list */
+ struct au_sphlhead si_plink[AuPlink_NHASH];
+ wait_queue_head_t si_plink_wq;
@@ -26490,7 +26569,7 @@ index 0000000..0514a13
+ return locked;
+}
+
-+#if 0 /* unused */
++#if 0 /* reserved */
+static inline int si_read_trylock(struct super_block *sb, int flags)
+{
+ if (au_ftest_lock(flags, FLUSH))
@@ -26505,7 +26584,7 @@ index 0000000..0514a13
+ __si_read_unlock(sb);
+}
+
-+#if 0 /* unused */
++#if 0 /* reserved */
+static inline int si_write_trylock(struct super_block *sb, int flags)
+{
+ if (au_ftest_lock(flags, FLUSH))
@@ -26520,7 +26599,7 @@ index 0000000..0514a13
+ __si_write_unlock(sb);
+}
+
-+#if 0 /* unused */
++#if 0 /* reserved */
+static inline void si_downgrade_lock(struct super_block *sb)
+{
+ __si_downgrade_lock(sb);
@@ -27125,7 +27204,7 @@ index 0000000..75cc82a
+}
diff --git a/fs/aufs/sysrq.c b/fs/aufs/sysrq.c
new file mode 100644
-index 0000000..e9fd963
+index 0000000..dcfa824
--- /dev/null
+++ b/fs/aufs/sysrq.c
@@ -0,0 +1,144 @@
@@ -27166,7 +27245,7 @@ index 0000000..e9fd963
+ pr("root dentry\n");
+ au_dpri_dentry(sb->s_root);
+ pr("root inode\n");
-+ au_dpri_inode(sb->s_root->d_inode);
++ au_dpri_inode(d_inode(sb->s_root));
+#endif
+
+#if 0
@@ -27275,10 +27354,10 @@ index 0000000..e9fd963
+}
diff --git a/fs/aufs/vdir.c b/fs/aufs/vdir.c
new file mode 100644
-index 0000000..c61a77f
+index 0000000..c3f6a74
--- /dev/null
+++ b/fs/aufs/vdir.c
-@@ -0,0 +1,876 @@
+@@ -0,0 +1,875 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -27736,7 +27815,6 @@ index 0000000..c61a77f
+ || au_nhash_test_known_wh(&arg->whlist, name, nlen))
+ goto out; /* already exists or whiteouted */
+
-+ sb = arg->file->f_path.dentry->d_sb;
+ arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino);
+ if (!arg->err) {
+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
@@ -28157,10 +28235,10 @@ index 0000000..c61a77f
+}
diff --git a/fs/aufs/vfsub.c b/fs/aufs/vfsub.c
new file mode 100644
-index 0000000..b233552
+index 0000000..da0df5a
--- /dev/null
+++ b/fs/aufs/vfsub.c
-@@ -0,0 +1,783 @@
+@@ -0,0 +1,835 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -28169,7 +28247,6 @@ index 0000000..b233552
+ * sub-routines for VFS
+ */
+
-+#include
+#include
+#include
+#include
@@ -28205,7 +28282,7 @@ index 0000000..b233552
+ current_cred());
+ if (!IS_ERR_OR_NULL(file)
+ && (file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
-+ i_readcount_inc(path->dentry->d_inode);
++ i_readcount_inc(d_inode(path->dentry));
+
+ return file;
+}
@@ -28227,12 +28304,63 @@ index 0000000..b233552
+ return file;
+}
+
++/*
++ * Ideally this function should call VFS:do_last() in order to keep all its
++ * checkings. But it is very hard for aufs to regenerate several VFS internal
++ * structure such as nameidata. This is a second (or third) best approach.
++ * cf. linux/fs/namei.c:do_last(), lookup_open() and atomic_open().
++ */
++int vfsub_atomic_open(struct inode *dir, struct dentry *dentry,
++ struct vfsub_aopen_args *args, struct au_branch *br)
++{
++ int err;
++ struct file *file = args->file;
++ /* copied from linux/fs/namei.c:atomic_open() */
++ struct dentry *const DENTRY_NOT_SET = (void *)-1UL;
++
++ IMustLock(dir);
++ AuDebugOn(!dir->i_op->atomic_open);
++
++ err = au_br_test_oflag(args->open_flag, br);
++ if (unlikely(err))
++ goto out;
++
++ args->file->f_path.dentry = DENTRY_NOT_SET;
++ args->file->f_path.mnt = au_br_mnt(br);
++ err = dir->i_op->atomic_open(dir, dentry, file, args->open_flag,
++ args->create_mode, args->opened);
++ if (err >= 0) {
++ /* some filesystems don't set FILE_CREATED while succeeded? */
++ if (*args->opened & FILE_CREATED)
++ fsnotify_create(dir, dentry);
++ } else
++ goto out;
++
++
++ if (!err) {
++ /* todo: call VFS:may_open() here */
++ err = open_check_o_direct(file);
++ /* todo: ima_file_check() too? */
++ if (!err && (args->open_flag & __FMODE_EXEC))
++ err = deny_write_access(file);
++ if (unlikely(err))
++ /* note that the file is created and still opened */
++ goto out;
++ }
++
++ atomic_inc(&br->br_count);
++ fsnotify_open(file);
++
++out:
++ return err;
++}
++
+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path)
+{
+ int err;
+
+ err = kern_path(name, flags, path);
-+ if (!err && path->dentry->d_inode)
++ if (!err && d_is_positive(path->dentry))
+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
+ return err;
+}
@@ -28245,12 +28373,12 @@ index 0000000..b233552
+ };
+
+ /* VFS checks it too, but by WARN_ON_ONCE() */
-+ IMustLock(parent->d_inode);
++ IMustLock(d_inode(parent));
+
+ path.dentry = lookup_one_len(name, parent, len);
+ if (IS_ERR(path.dentry))
+ goto out;
-+ if (path.dentry->d_inode)
++ if (d_is_positive(path.dentry))
+ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
+
+out:
@@ -28411,7 +28539,7 @@ index 0000000..b233552
+
+ IMustLock(dir);
+
-+ err = au_test_nlink(src_dentry->d_inode);
++ err = au_test_nlink(d_inode(src_dentry));
+ if (unlikely(err))
+ return err;
+
@@ -28709,7 +28837,7 @@ index 0000000..b233552
+ goto out;
+ }
+
-+ h_inode = h_path->dentry->d_inode;
++ h_inode = d_inode(h_path->dentry);
+ h_sb = h_inode->i_sb;
+ lockdep_off();
+ sb_start_write(h_sb);
@@ -28818,7 +28946,7 @@ index 0000000..b233552
+ struct notify_change_args *a = args;
+ struct inode *h_inode;
+
-+ h_inode = a->path->dentry->d_inode;
++ h_inode = d_inode(a->path->dentry);
+ IMustLock(h_inode);
+
+ *a->errp = -EPERM;
@@ -28894,9 +29022,11 @@ index 0000000..b233552
+
+ if (!stop_sillyrename)
+ dget(d);
-+ h_inode = d->d_inode;
-+ if (h_inode)
++ h_inode = NULL;
++ if (d_is_positive(d)) {
++ h_inode = d_inode(d);
+ ihold(h_inode);
++ }
+
+ lockdep_off();
+ *a->errp = vfs_unlink(a->dir, d, a->delegated_inode);
@@ -28946,10 +29076,10 @@ index 0000000..b233552
+}
diff --git a/fs/aufs/vfsub.h b/fs/aufs/vfsub.h
new file mode 100644
-index 0000000..6493d90
+index 0000000..778ea20
--- /dev/null
+++ b/fs/aufs/vfsub.h
-@@ -0,0 +1,288 @@
+@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -28964,7 +29094,6 @@ index 0000000..6493d90
+#ifdef __KERNEL__
+
+#include
-+#include
+#include
+#include
+#include "debug.h"
@@ -28973,6 +29102,7 @@ index 0000000..6493d90
+/* todo: BAD approach!! */
+extern void __mnt_drop_write(struct vfsmount *);
+extern spinlock_t inode_sb_list_lock;
++extern int open_check_o_direct(struct file *f);
+
+/* ---------------------------------------------------------------------- */
+
@@ -29021,6 +29151,15 @@ index 0000000..6493d90
+int vfsub_update_h_iattr(struct path *h_path, int *did);
+struct file *vfsub_dentry_open(struct path *path, int flags);
+struct file *vfsub_filp_open(const char *path, int oflags, int mode);
++struct vfsub_aopen_args {
++ struct file *file;
++ unsigned int open_flag;
++ umode_t create_mode;
++ int *opened;
++};
++struct au_branch;
++int vfsub_atomic_open(struct inode *dir, struct dentry *dentry,
++ struct vfsub_aopen_args *args, struct au_branch *br);
+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
+
+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
@@ -29059,12 +29198,14 @@ index 0000000..6493d90
+ lockdep_on();
+}
+
++#if 0 /* reserved */
+static inline void vfsub_mnt_drop_write_file(struct file *file)
+{
+ lockdep_off();
+ mnt_drop_write_file(file);
+ lockdep_on();
+}
++#endif
+
+/* ---------------------------------------------------------------------- */
+
@@ -29116,11 +29257,13 @@ index 0000000..6493d90
+ return flags;
+}
+
++#if 0 /* reserved */
+static inline void vfsub_file_accessed(struct file *h_file)
+{
+ file_accessed(h_file);
+ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/
+}
++#endif
+
+static inline void vfsub_touch_atime(struct vfsmount *h_mnt,
+ struct dentry *h_dentry)
@@ -29136,7 +29279,7 @@ index 0000000..6493d90
+static inline int vfsub_update_time(struct inode *h_inode, struct timespec *ts,
+ int flags)
+{
-+ return update_time(h_inode, ts, flags);
++ return generic_update_time(h_inode, ts, flags);
+ /* no vfsub_update_h_iattr() since we don't have struct path */
+}
+
@@ -29174,34 +29317,6 @@ index 0000000..6493d90
+
+/* ---------------------------------------------------------------------- */
+
-+/* dirty workaround for strict type of fmode_t */
-+union vfsub_fmu {
-+ fmode_t fm;
-+ unsigned int ui;
-+};
-+
-+static inline unsigned int vfsub_fmode_to_uint(fmode_t fm)
-+{
-+ union vfsub_fmu u = {
-+ .fm = fm
-+ };
-+
-+ BUILD_BUG_ON(sizeof(u.fm) != sizeof(u.ui));
-+
-+ return u.ui;
-+}
-+
-+static inline fmode_t vfsub_uint_to_fmode(unsigned int ui)
-+{
-+ union vfsub_fmu u = {
-+ .ui = ui
-+ };
-+
-+ return u.fm;
-+}
-+
-+/* ---------------------------------------------------------------------- */
-+
+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode);
+int vfsub_sio_rmdir(struct inode *dir, struct path *path);
+int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
@@ -29240,7 +29355,7 @@ index 0000000..6493d90
+#endif /* __AUFS_VFSUB_H__ */
diff --git a/fs/aufs/wbr_policy.c b/fs/aufs/wbr_policy.c
new file mode 100644
-index 0000000..7ce1cf1
+index 0000000..53a01fb
--- /dev/null
+++ b/fs/aufs/wbr_policy.c
@@ -0,0 +1,752 @@
@@ -29263,13 +29378,13 @@ index 0000000..7ce1cf1
+ struct iattr ia;
+ struct inode *h_isrc;
+
-+ h_isrc = h_src->d_inode;
++ h_isrc = d_inode(h_src);
+ ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID;
+ ia.ia_mode = h_isrc->i_mode;
+ ia.ia_uid = h_isrc->i_uid;
+ ia.ia_gid = h_isrc->i_gid;
+ sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID));
-+ au_cpup_attr_flags(h_path->dentry->d_inode, h_isrc->i_flags);
++ au_cpup_attr_flags(d_inode(h_path->dentry), h_isrc->i_flags);
+ /* no delegation since it is just created */
+ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL);
+
@@ -29324,7 +29439,7 @@ index 0000000..7ce1cf1
+ goto out;
+
+ err = 0;
-+ if (h_path.dentry->d_inode) {
++ if (d_is_positive(h_path.dentry)) {
+ h_path.mnt = au_br_mnt(br);
+ err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path,
+ dentry);
@@ -29349,8 +29464,8 @@ index 0000000..7ce1cf1
+ bstart = au_dbstart(dentry);
+ /* dentry is di-locked */
+ parent = dget_parent(dentry);
-+ dir = parent->d_inode;
-+ h_dir = h_parent->d_inode;
++ dir = d_inode(parent);
++ h_dir = d_inode(h_parent);
+ AuDebugOn(h_dir != au_h_iptr(dir, bdst));
+ IMustLock(h_dir);
+
@@ -29372,7 +29487,7 @@ index 0000000..7ce1cf1
+ au_fset_cpdown(*flags, WHED);
+ if (!au_ftest_cpdown(*flags, PARENT_OPQ) && bopq <= bdst)
+ au_fset_cpdown(*flags, PARENT_OPQ);
-+ h_inode = h_path.dentry->d_inode;
++ h_inode = d_inode(h_path.dentry);
+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
+ if (au_ftest_cpdown(*flags, WHED)) {
+ err = au_cpdown_dir_opq(dentry, bdst, flags);
@@ -29393,7 +29508,7 @@ index 0000000..7ce1cf1
+ goto out_opq;
+ }
+
-+ inode = dentry->d_inode;
++ inode = d_inode(dentry);
+ if (au_ibend(inode) < bdst)
+ au_set_ibend(inode, bdst);
+ au_set_h_iptr(inode, bdst, au_igrab(h_inode),
@@ -29512,7 +29627,7 @@ index 0000000..7ce1cf1
+ parent = dget_parent(dentry);
+ for (bindex = au_dbstart(parent); bindex < bstart; bindex++) {
+ h_parent = au_h_dptr(parent, bindex);
-+ if (!h_parent || !h_parent->d_inode)
++ if (!h_parent || d_is_negative(h_parent))
+ continue;
+
+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
@@ -29664,7 +29779,7 @@ index 0000000..7ce1cf1
+ for (; bindex <= bend; bindex++) {
+ if (parent) {
+ h_parent = au_h_dptr(parent, bindex);
-+ if (!h_parent || !h_parent->d_inode)
++ if (!h_parent || d_is_negative(h_parent))
+ continue;
+ }
+ br = au_sbr(sb, bindex);
@@ -29812,7 +29927,7 @@ index 0000000..7ce1cf1
+
+ for (bindex = bstart; bindex <= bend; bindex++) {
+ h_parent = au_h_dptr(parent, bindex);
-+ if (!h_parent || !h_parent->d_inode)
++ if (!h_parent || d_is_negative(h_parent))
+ continue;
+
+ br = au_sbr(sb, bindex);
@@ -29891,7 +30006,7 @@ index 0000000..7ce1cf1
+ bstart = au_dbstart(parent);
+ for (bindex = au_dbstart(dentry); bindex >= bstart; bindex--) {
+ h_parent = au_h_dptr(parent, bindex);
-+ if (!h_parent || !h_parent->d_inode)
++ if (!h_parent || d_is_negative(h_parent))
+ continue;
+
+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
@@ -29998,10 +30113,10 @@ index 0000000..7ce1cf1
+};
diff --git a/fs/aufs/whout.c b/fs/aufs/whout.c
new file mode 100644
-index 0000000..21a264f
+index 0000000..a7f160e
--- /dev/null
+++ b/fs/aufs/whout.c
-@@ -0,0 +1,1048 @@
+@@ -0,0 +1,1050 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -30064,20 +30179,23 @@ index 0000000..21a264f
+ else
+ wh_dentry = au_sio_lkup_one(wh_name, h_parent);
+ err = PTR_ERR(wh_dentry);
-+ if (IS_ERR(wh_dentry))
++ if (IS_ERR(wh_dentry)) {
++ if (err == -ENAMETOOLONG)
++ err = 0;
+ goto out;
++ }
+
+ err = 0;
-+ if (!wh_dentry->d_inode)
++ if (d_is_negative(wh_dentry))
+ goto out_wh; /* success */
+
+ err = 1;
-+ if (S_ISREG(wh_dentry->d_inode->i_mode))
++ if (d_is_reg(wh_dentry))
+ goto out_wh; /* success */
+
+ err = -EIO;
+ AuIOErr("%pd Invalid whiteout entry type 0%o.\n",
-+ wh_dentry, wh_dentry->d_inode->i_mode);
++ wh_dentry, d_inode(wh_dentry)->i_mode);
+
+out_wh:
+ dput(wh_dentry);
@@ -30093,7 +30211,7 @@ index 0000000..21a264f
+ int err;
+ struct inode *h_dir;
+
-+ h_dir = h_dentry->d_inode;
++ h_dir = d_inode(h_dentry);
+ err = au_wh_test(h_dentry, &diropq_name,
+ au_test_h_perm_sio(h_dir, MAY_EXEC));
+ return err;
@@ -30139,7 +30257,7 @@ index 0000000..21a264f
+ for (i = 0; i < 3; i++) {
+ sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++);
+ dentry = au_sio_lkup_one(&qs, h_parent);
-+ if (IS_ERR(dentry) || !dentry->d_inode)
++ if (IS_ERR(dentry) || d_is_negative(dentry))
+ goto out_name;
+ dput(dentry);
+ }
@@ -30169,7 +30287,7 @@ index 0000000..21a264f
+ struct dentry *h_parent;
+
+ h_parent = h_dentry->d_parent; /* dir inode is locked */
-+ h_dir = h_parent->d_inode;
++ h_dir = d_inode(h_parent);
+ IMustLock(h_dir);
+
+ h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name);
@@ -30208,7 +30326,7 @@ index 0000000..21a264f
+ * this may be a violation of unix fs semantics.
+ */
+ force = (h_dir->i_mode & S_ISVTX)
-+ && !uid_eq(current_fsuid(), h_path->dentry->d_inode->i_uid);
++ && !uid_eq(current_fsuid(), d_inode(h_path->dentry)->i_uid);
+ delegated = NULL;
+ err = vfsub_unlink(h_dir, h_path, &delegated, force);
+ if (unlikely(err == -EWOULDBLOCK)) {
@@ -30244,9 +30362,8 @@ index 0000000..21a264f
+ if (IS_ERR(h_path.dentry))
+ err = PTR_ERR(h_path.dentry);
+ else {
-+ if (h_path.dentry->d_inode
-+ && S_ISREG(h_path.dentry->d_inode->i_mode))
-+ err = do_unlink_wh(h_parent->d_inode, &h_path);
++ if (d_is_reg(h_path.dentry))
++ err = do_unlink_wh(d_inode(h_parent), &h_path);
+ dput(h_path.dentry);
+ }
+
@@ -30264,7 +30381,7 @@ index 0000000..21a264f
+ int err;
+ struct inode *delegated;
+
-+ if (!whpath->dentry->d_inode)
++ if (d_is_negative(whpath->dentry))
+ return;
+
+ if (isdir)
@@ -30285,7 +30402,7 @@ index 0000000..21a264f
+
+static int test_linkable(struct dentry *h_root)
+{
-+ struct inode *h_dir = h_root->d_inode;
++ struct inode *h_dir = d_inode(h_root);
+
+ if (h_dir->i_op->link)
+ return 0;
@@ -30301,13 +30418,13 @@ index 0000000..21a264f
+ int err;
+
+ err = -EEXIST;
-+ if (!path->dentry->d_inode) {
++ if (d_is_negative(path->dentry)) {
+ int mode = S_IRWXU;
+
+ if (au_test_nfs(path->dentry->d_sb))
+ mode |= S_IXUGO;
+ err = vfsub_mkdir(h_dir, path, mode);
-+ } else if (S_ISDIR(path->dentry->d_inode->i_mode))
++ } else if (d_is_dir(path->dentry))
+ err = 0;
+ else
+ pr_err("unknown %pd exists\n", path->dentry);
@@ -30344,7 +30461,7 @@ index 0000000..21a264f
+ int err;
+ struct inode *h_dir;
+
-+ h_dir = h_root->d_inode;
++ h_dir = d_inode(h_root);
+ h_path->dentry = base[AuBrWh_BASE].dentry;
+ au_wh_clean(h_dir, h_path, /*isdir*/0);
+ h_path->dentry = base[AuBrWh_PLINK].dentry;
@@ -30398,11 +30515,11 @@ index 0000000..21a264f
+ * todo: should this create be done in /sbin/mount.aufs helper?
+ */
+ err = -EEXIST;
-+ h_dir = h_root->d_inode;
-+ if (!base[AuBrWh_BASE].dentry->d_inode) {
++ h_dir = d_inode(h_root);
++ if (d_is_negative(base[AuBrWh_BASE].dentry)) {
+ h_path->dentry = base[AuBrWh_BASE].dentry;
+ err = vfsub_create(h_dir, h_path, WH_MASK, /*want_excl*/true);
-+ } else if (S_ISREG(base[AuBrWh_BASE].dentry->d_inode->i_mode))
++ } else if (d_is_reg(base[AuBrWh_BASE].dentry))
+ err = 0;
+ else
+ pr_err("unknown %pd2 exists\n", base[AuBrWh_BASE].dentry);
@@ -30490,7 +30607,7 @@ index 0000000..21a264f
+
+ err = 0;
+ if (!au_br_writable(br->br_perm)) {
-+ h_dir = h_root->d_inode;
++ h_dir = d_inode(h_root);
+ au_wh_init_ro(h_dir, base, &path);
+ } else if (!au_br_wh_linkable(br->br_perm)) {
+ err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path);
@@ -30550,7 +30667,7 @@ index 0000000..21a264f
+ goto out;
+
+ di_read_lock_parent(a->sb->s_root, AuLock_IR);
-+ dir = a->sb->s_root->d_inode;
++ dir = d_inode(a->sb->s_root);
+ hdir = au_hi(dir, bindex);
+ h_root = au_h_dptr(a->sb->s_root, bindex);
+ AuDebugOn(h_root != au_br_dentry(a->br));
@@ -30646,7 +30763,7 @@ index 0000000..21a264f
+ struct inode *h_dir, *delegated;
+
+ h_parent = wh->d_parent; /* dir inode is locked */
-+ h_dir = h_parent->d_inode;
++ h_dir = d_inode(h_parent);
+ IMustLock(h_dir);
+
+ br = au_sbr(sb, bindex);
@@ -30709,7 +30826,7 @@ index 0000000..21a264f
+ .dentry = opq_dentry,
+ .mnt = au_br_mnt(br)
+ };
-+ err = do_unlink_wh(au_h_iptr(dentry->d_inode, bindex), &tmp);
++ err = do_unlink_wh(au_h_iptr(d_inode(dentry), bindex), &tmp);
+ if (!err)
+ au_set_dbdiropq(dentry, -1);
+ }
@@ -30739,7 +30856,7 @@ index 0000000..21a264f
+ struct dentry *diropq, *h_dentry;
+
+ h_dentry = au_h_dptr(dentry, bindex);
-+ if (!au_test_h_perm_sio(h_dentry->d_inode, MAY_EXEC | MAY_WRITE))
++ if (!au_test_h_perm_sio(d_inode(h_dentry), MAY_EXEC | MAY_WRITE))
+ diropq = do_diropq(dentry, bindex, flags);
+ else {
+ int wkq_err;
@@ -30794,7 +30911,7 @@ index 0000000..21a264f
+
+ sb = dentry->d_sb;
+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex));
-+ if (!IS_ERR(wh_dentry) && !wh_dentry->d_inode) {
++ if (!IS_ERR(wh_dentry) && d_is_negative(wh_dentry)) {
+ err = link_or_create_wh(sb, bindex, wh_dentry);
+ if (!err) {
+ au_set_dbwh(dentry, bindex);
@@ -30929,11 +31046,11 @@ index 0000000..21a264f
+ struct inode *wh_inode, *h_dir;
+ struct au_branch *br;
+
-+ h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
++ h_dir = d_inode(wh_dentry->d_parent); /* dir inode is locked */
+ IMustLock(h_dir);
+
+ br = au_sbr(dir->i_sb, bindex);
-+ wh_inode = wh_dentry->d_inode;
++ wh_inode = d_inode(wh_dentry);
+ mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD);
+
+ /*
@@ -31005,7 +31122,7 @@ index 0000000..21a264f
+ err = -EIO;
+ ii_write_lock_parent(a->dir);
+ h_parent = dget_parent(a->wh_dentry);
-+ h_dir = h_parent->d_inode;
++ h_dir = d_inode(h_parent);
+ hdir = au_hi(a->dir, bindex);
+ err = vfsub_mnt_want_write(au_br_mnt(a->br));
+ if (unlikely(err))
@@ -31052,7 +31169,7 @@ index 0000000..21a264f
+}
diff --git a/fs/aufs/whout.h b/fs/aufs/whout.h
new file mode 100644
-index 0000000..14155f5
+index 0000000..b39acea
--- /dev/null
+++ b/fs/aufs/whout.h
@@ -0,0 +1,72 @@
@@ -31073,9 +31190,9 @@ index 0000000..14155f5
+
+/* whout.c */
+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name);
-+struct au_branch;
+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio);
+int au_diropq_test(struct dentry *h_dentry);
++struct au_branch;
+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
+ struct qstr *prefix);
+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br);
@@ -31420,10 +31537,10 @@ index 0000000..8f01343
+#endif /* __AUFS_WKQ_H__ */
diff --git a/fs/aufs/xattr.c b/fs/aufs/xattr.c
new file mode 100644
-index 0000000..78b34d9
+index 0000000..c1695b3
--- /dev/null
+++ b/fs/aufs/xattr.c
-@@ -0,0 +1,321 @@
+@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2014-2015 Junjiro R. Okajima
+ */
@@ -31475,7 +31592,8 @@ index 0000000..78b34d9
+static const int au_xattr_out_of_list = AuBrAttr_ICEX_OTH << 1;
+
+static int au_do_cpup_xattr(struct dentry *h_dst, struct dentry *h_src,
-+ char *name, char **buf, unsigned int ignore_flags)
++ char *name, char **buf, unsigned int ignore_flags,
++ unsigned int verbose)
+{
+ int err;
+ ssize_t ssz;
@@ -31484,21 +31602,28 @@ index 0000000..78b34d9
+ ssz = vfs_getxattr_alloc(h_src, name, buf, 0, GFP_NOFS);
+ err = ssz;
+ if (unlikely(err <= 0)) {
-+ AuTraceErr(err);
+ if (err == -ENODATA
+ || (err == -EOPNOTSUPP
-+ && (ignore_flags & au_xattr_out_of_list)))
++ && ((ignore_flags & au_xattr_out_of_list)
++ || (au_test_nfs_noacl(d_inode(h_src))
++ && (!strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS)
++ || !strcmp(name,
++ XATTR_NAME_POSIX_ACL_DEFAULT))))
++ ))
+ err = 0;
++ if (err && (verbose || au_debug_test()))
++ pr_err("%s, err %d\n", name, err);
+ goto out;
+ }
+
+ /* unlock it temporary */
-+ h_idst = h_dst->d_inode;
++ h_idst = d_inode(h_dst);
+ mutex_unlock(&h_idst->i_mutex);
+ err = vfsub_setxattr(h_dst, name, *buf, ssz, /*flags*/0);
+ mutex_lock_nested(&h_idst->i_mutex, AuLsc_I_CHILD2);
+ if (unlikely(err)) {
-+ AuDbg("%s, err %d\n", name, err);
++ if (verbose || au_debug_test())
++ pr_err("%s, err %d\n", name, err);
+ err = au_xattr_ignore(err, name, ignore_flags);
+ }
+
@@ -31506,7 +31631,8 @@ index 0000000..78b34d9
+ return err;
+}
+
-+int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags)
++int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags,
++ unsigned int verbose)
+{
+ int err, unlocked, acl_access, acl_default;
+ ssize_t ssz;
@@ -31514,9 +31640,9 @@ index 0000000..78b34d9
+ char *value, *p, *o, *e;
+
+ /* try stopping to update the source inode while we are referencing */
-+ /* there should not be the parent-child relation ship between them */
-+ h_isrc = h_src->d_inode;
-+ h_idst = h_dst->d_inode;
++ /* there should not be the parent-child relationship between them */
++ h_isrc = d_inode(h_src);
++ h_idst = d_inode(h_dst);
+ mutex_unlock(&h_idst->i_mutex);
+ mutex_lock_nested(&h_isrc->i_mutex, AuLsc_I_CHILD);
+ mutex_lock_nested(&h_idst->i_mutex, AuLsc_I_CHILD2);
@@ -31561,7 +31687,8 @@ index 0000000..78b34d9
+ acl_default |= !strncmp(p, XATTR_NAME_POSIX_ACL_DEFAULT,
+ sizeof(XATTR_NAME_POSIX_ACL_DEFAULT)
+ - 1);
-+ err = au_do_cpup_xattr(h_dst, h_src, p, &value, ignore_flags);
++ err = au_do_cpup_xattr(h_dst, h_src, p, &value, ignore_flags,
++ verbose);
+ p += strlen(p) + 1;
+ }
+ AuTraceErr(err);
@@ -31569,13 +31696,13 @@ index 0000000..78b34d9
+ if (!err && !acl_access) {
+ err = au_do_cpup_xattr(h_dst, h_src,
+ XATTR_NAME_POSIX_ACL_ACCESS, &value,
-+ ignore_flags);
++ ignore_flags, verbose);
+ AuTraceErr(err);
+ }
+ if (!err && !acl_default) {
+ err = au_do_cpup_xattr(h_dst, h_src,
+ XATTR_NAME_POSIX_ACL_DEFAULT, &value,
-+ ignore_flags);
++ ignore_flags, verbose);
+ AuTraceErr(err);
+ }
+
@@ -31747,10 +31874,10 @@ index 0000000..78b34d9
+#endif
diff --git a/fs/aufs/xino.c b/fs/aufs/xino.c
new file mode 100644
-index 0000000..c053d55
+index 0000000..8a2ddac
--- /dev/null
+++ b/fs/aufs/xino.c
-@@ -0,0 +1,1305 @@
+@@ -0,0 +1,1284 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ */
@@ -31764,7 +31891,7 @@ index 0000000..c053d55
+#include "aufs.h"
+
+/* todo: unnecessary to support mmap_sem since kernel-space? */
-+ssize_t xino_fread(au_readf_t func, struct file *file, void *kbuf, size_t size,
++ssize_t xino_fread(vfs_readf_t func, struct file *file, void *kbuf, size_t size,
+ loff_t *pos)
+{
+ ssize_t err;
@@ -31793,7 +31920,7 @@ index 0000000..c053d55
+
+/* ---------------------------------------------------------------------- */
+
-+static ssize_t do_xino_fwrite(au_writef_t func, struct file *file, void *kbuf,
++static ssize_t do_xino_fwrite(vfs_writef_t func, struct file *file, void *kbuf,
+ size_t size, loff_t *pos)
+{
+ ssize_t err;
@@ -31822,7 +31949,7 @@ index 0000000..c053d55
+
+struct do_xino_fwrite_args {
+ ssize_t *errp;
-+ au_writef_t func;
++ vfs_writef_t func;
+ struct file *file;
+ void *buf;
+ size_t size;
@@ -31835,8 +31962,8 @@ index 0000000..c053d55
+ *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos);
+}
+
-+ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
-+ loff_t *pos)
++ssize_t xino_fwrite(vfs_writef_t func, struct file *file, void *buf,
++ size_t size, loff_t *pos)
+{
+ ssize_t err;
+
@@ -31884,7 +32011,7 @@ index 0000000..c053d55
+
+ base = base_file->f_path.dentry;
+ parent = base->d_parent; /* dir inode is locked */
-+ dir = parent->d_inode;
++ dir = d_inode(parent);
+ IMustLock(dir);
+
+ file = ERR_PTR(-EINVAL);
@@ -31962,11 +32089,11 @@ index 0000000..c053d55
+ if (brid >= 0)
+ bindex = au_br_index(sb, brid);
+ if (bindex >= 0) {
-+ ldir->hdir = au_hi(sb->s_root->d_inode, bindex);
++ ldir->hdir = au_hi(d_inode(sb->s_root), bindex);
+ au_hn_imtx_lock_nested(ldir->hdir, AuLsc_I_PARENT);
+ } else {
+ ldir->parent = dget_parent(xino->f_path.dentry);
-+ ldir->mtx = &ldir->parent->d_inode->i_mutex;
++ ldir->mtx = &d_inode(ldir->parent)->i_mutex;
+ mutex_lock_nested(ldir->mtx, AuLsc_I_PARENT);
+ }
+}
@@ -32077,7 +32204,7 @@ index 0000000..c053d55
+
+ err = 0;
+ sb = args->sb;
-+ dir = sb->s_root->d_inode;
++ dir = d_inode(sb->s_root);
+ br = args->br;
+
+ si_noflush_write_lock(sb);
@@ -32154,7 +32281,7 @@ index 0000000..c053d55
+
+/* ---------------------------------------------------------------------- */
+
-+static int au_xino_do_write(au_writef_t write, struct file *file,
++static int au_xino_do_write(vfs_writef_t write, struct file *file,
+ ino_t h_ino, ino_t ino)
+{
+ loff_t pos;
@@ -32314,7 +32441,7 @@ index 0000000..c053d55
+ struct au_hinode *hi;
+ struct inode *h_inode;
+ struct au_branch *br;
-+ au_writef_t xwrite;
++ vfs_writef_t xwrite;
+
+ sb = inode->i_sb;
+ mnt_flags = au_mntflags(sb);
@@ -32469,7 +32596,7 @@ index 0000000..c053d55
+{
+ struct file *file;
+ struct dentry *h_parent, *d;
-+ struct inode *h_dir;
++ struct inode *h_dir, *inode;
+ int err;
+
+ /*
@@ -32487,12 +32614,16 @@ index 0000000..c053d55
+ }
+
+ /* keep file count */
++ err = 0;
++ inode = file_inode(file);
+ h_parent = dget_parent(file->f_path.dentry);
-+ h_dir = h_parent->d_inode;
++ h_dir = d_inode(h_parent);
+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
+ /* mnt_want_write() is unnecessary here */
+ /* no delegation since it is just created */
-+ err = vfsub_unlink(h_dir, &file->f_path, /*delegated*/NULL, /*force*/0);
++ if (inode->i_nlink)
++ err = vfsub_unlink(h_dir, &file->f_path, /*delegated*/NULL,
++ /*force*/0);
+ mutex_unlock(&h_dir->i_mutex);
+ dput(h_parent);
+ if (unlikely(err)) {
@@ -32612,7 +32743,7 @@ index 0000000..c053d55
+ unsigned long pindex;
+ loff_t pos, pend;
+ struct au_sbinfo *sbinfo;
-+ au_readf_t func;
++ vfs_readf_t func;
+ ino_t *ino;
+ unsigned long *p;
+
@@ -32730,31 +32861,6 @@ index 0000000..c053d55
+/*
+ * xino mount option handlers
+ */
-+static au_readf_t find_readf(struct file *h_file)
-+{
-+ const struct file_operations *fop = h_file->f_op;
-+
-+ if (fop->read)
-+ return fop->read;
-+ if (fop->aio_read)
-+ return do_sync_read;
-+ if (fop->read_iter)
-+ return new_sync_read;
-+ return ERR_PTR(-ENOSYS);
-+}
-+
-+static au_writef_t find_writef(struct file *h_file)
-+{
-+ const struct file_operations *fop = h_file->f_op;
-+
-+ if (fop->write)
-+ return fop->write;
-+ if (fop->aio_write)
-+ return do_sync_write;
-+ if (fop->write_iter)
-+ return new_sync_write;
-+ return ERR_PTR(-ENOSYS);
-+}
+
+/* xino bitmap */
+static void xino_clear_xib(struct super_block *sb)
@@ -32790,8 +32896,8 @@ index 0000000..c053d55
+ if (sbinfo->si_xib)
+ fput(sbinfo->si_xib);
+ sbinfo->si_xib = file;
-+ sbinfo->si_xread = find_readf(file);
-+ sbinfo->si_xwrite = find_writef(file);
++ sbinfo->si_xread = vfs_readf(file);
++ sbinfo->si_xwrite = vfs_writef(file);
+
+ err = -ENOMEM;
+ if (!sbinfo->si_xib_buf)
@@ -32852,7 +32958,7 @@ index 0000000..c053d55
+ } *fpair, *p;
+ struct au_branch *br;
+ struct inode *inode;
-+ au_writef_t writef;
++ vfs_writef_t writef;
+
+ SiMustWriteLock(sb);
+
@@ -32862,7 +32968,7 @@ index 0000000..c053d55
+ if (unlikely(!fpair))
+ goto out;
+
-+ inode = sb->s_root->d_inode;
++ inode = d_inode(sb->s_root);
+ ino = AUFS_ROOT_INO;
+ writef = au_sbi(sb)->si_xwrite;
+ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
@@ -32952,7 +33058,7 @@ index 0000000..c053d55
+ }
+
+ au_opt_set(sbinfo->si_mntflags, XINO);
-+ dir = parent->d_inode;
++ dir = d_inode(parent);
+ mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT);
+ /* mnt_want_write() is unnecessary here */
+ err = au_xino_set_xib(sb, xino->file);
@@ -33057,7 +33163,7 @@ index 0000000..c053d55
+ return err;
+}
diff --git a/fs/buffer.c b/fs/buffer.c
-index 20805db..363569f 100644
+index c7a5602..8c50a22 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -2450,7 +2450,7 @@ int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
@@ -33070,10 +33176,10 @@ index 20805db..363569f 100644
ret = __block_page_mkwrite(vma, vmf, get_block);
sb_end_pagefault(sb);
diff --git a/fs/dcache.c b/fs/dcache.c
-index e368d4f..eaed72c 100644
+index 37b5afd..bc261e2 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
-@@ -1019,7 +1019,7 @@ enum d_walk_ret {
+@@ -1164,7 +1164,7 @@ enum d_walk_ret {
*
* The @enter() and @finish() callbacks are called with d_lock held.
*/
@@ -33082,24 +33188,11 @@ index e368d4f..eaed72c 100644
enum d_walk_ret (*enter)(void *, struct dentry *),
void (*finish)(void *))
{
-diff --git a/fs/inode.c b/fs/inode.c
-index aa149e7..98d87de 100644
---- a/fs/inode.c
-+++ b/fs/inode.c
-@@ -1499,7 +1499,7 @@ static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
- * This does the actual work of updating an inodes time or version. Must have
- * had called mnt_want_write() before calling this.
- */
--static int update_time(struct inode *inode, struct timespec *time, int flags)
-+int update_time(struct inode *inode, struct timespec *time, int flags)
- {
- if (inode->i_op->update_time)
- return inode->i_op->update_time(inode, time, flags);
diff --git a/fs/proc/base.c b/fs/proc/base.c
-index 3f3d7ae..426bcc7 100644
+index 093ca14..fc1ac03 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
-@@ -1735,7 +1735,7 @@ static int proc_map_files_get_link(struct dentry *dentry, struct path *path)
+@@ -1744,7 +1744,7 @@ static int proc_map_files_get_link(struct dentry *dentry, struct path *path)
down_read(&mm->mmap_sem);
vma = find_exact_vma(mm, vm_start, vm_end);
if (vma && vma->vm_file) {
@@ -33125,10 +33218,10 @@ index d4a3574..1397181 100644
ino = inode->i_ino;
}
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
-index 246eae8..dfd0875 100644
+index 6dee68d..9afa35d 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
-@@ -276,7 +276,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
+@@ -279,7 +279,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
const char *name = NULL;
if (file) {
@@ -33140,17 +33233,17 @@ index 246eae8..dfd0875 100644
dev = inode->i_sb->s_dev;
ino = inode->i_ino;
pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
-@@ -1475,7 +1478,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid)
+@@ -1479,7 +1482,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid)
struct proc_maps_private *proc_priv = &numa_priv->proc_maps;
struct vm_area_struct *vma = v;
struct numa_maps *md = &numa_priv->md;
- struct file *file = vma->vm_file;
+ struct file *file = vma_pr_or_file(vma);
struct mm_struct *mm = vma->vm_mm;
- struct mm_walk walk = {};
- struct mempolicy *pol;
+ struct mm_walk walk = {
+ .hugetlb_entry = gather_hugetlb_stats,
diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
-index 599ec2e..de6cd6e 100644
+index 599ec2e..1740207 100644
--- a/fs/proc/task_nommu.c
+++ b/fs/proc/task_nommu.c
@@ -160,7 +160,10 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma,
@@ -33160,16 +33253,49 @@ index 599ec2e..de6cd6e 100644
- struct inode *inode = file_inode(vma->vm_file);
+ struct inode *inode;
+
-+ file = vma_pr_or_file(file);
++ file = vma_pr_or_file(vma);
+ inode = file_inode(file);
dev = inode->i_sb->s_dev;
ino = inode->i_ino;
pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT;
+diff --git a/fs/read_write.c b/fs/read_write.c
+index 819ef3f..fd0414e 100644
+--- a/fs/read_write.c
++++ b/fs/read_write.c
+@@ -494,6 +494,28 @@ ssize_t __vfs_write(struct file *file, const char __user *p, size_t count,
+ }
+ EXPORT_SYMBOL(__vfs_write);
+
++vfs_readf_t vfs_readf(struct file *file)
++{
++ const struct file_operations *fop = file->f_op;
++
++ if (fop->read)
++ return fop->read;
++ if (fop->read_iter)
++ return new_sync_read;
++ return ERR_PTR(-ENOSYS);
++}
++
++vfs_writef_t vfs_writef(struct file *file)
++{
++ const struct file_operations *fop = file->f_op;
++
++ if (fop->write)
++ return fop->write;
++ if (fop->write_iter)
++ return new_sync_write;
++ return ERR_PTR(-ENOSYS);
++}
++
+ ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos)
+ {
+ mm_segment_t old_fs;
diff --git a/fs/splice.c b/fs/splice.c
-index 75c6058..619359a 100644
+index bfe62ae..fa5eee5 100644
--- a/fs/splice.c
+++ b/fs/splice.c
-@@ -1114,8 +1114,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
+@@ -1101,8 +1101,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
/*
* Attempt to initiate a splice from pipe to file.
*/
@@ -33180,7 +33306,7 @@ index 75c6058..619359a 100644
{
ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
loff_t *, size_t, unsigned int);
-@@ -1131,9 +1131,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
+@@ -1118,9 +1118,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.
*/
@@ -33193,27 +33319,43 @@ index 75c6058..619359a 100644
{
ssize_t (*splice_read)(struct file *, loff_t *,
struct pipe_inode_info *, size_t, unsigned int);
+diff --git a/include/linux/file.h b/include/linux/file.h
+index f87d308..9a290b3 100644
+--- a/include/linux/file.h
++++ b/include/linux/file.h
+@@ -19,6 +19,7 @@ struct dentry;
+ struct path;
+ extern struct file *alloc_file(struct path *, fmode_t mode,
+ const struct file_operations *fop);
++extern struct file *get_empty_filp(void);
+
+ static inline void fput_light(struct file *file, int fput_needed)
+ {
diff --git a/include/linux/fs.h b/include/linux/fs.h
-index 42efe13..f634198 100644
+index 35ec87e..3229f97 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
-@@ -2690,6 +2690,7 @@ extern int inode_change_ok(const struct inode *, struct iattr *);
- extern int inode_newsize_ok(const struct inode *, loff_t offset);
- extern void setattr_copy(struct inode *inode, const struct iattr *attr);
+@@ -1649,6 +1649,12 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
+ struct iovec *fast_pointer,
+ struct iovec **ret_pointer);
-+extern int update_time(struct inode *, struct timespec *, int);
- extern int file_update_time(struct file *file);
-
- extern int generic_show_options(struct seq_file *m, struct dentry *root);
++typedef ssize_t (*vfs_readf_t)(struct file *, char __user *, size_t, loff_t *);
++typedef ssize_t (*vfs_writef_t)(struct file *, const char __user *, size_t,
++ loff_t *);
++vfs_readf_t vfs_readf(struct file *file);
++vfs_writef_t vfs_writef(struct file *file);
++
+ extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *);
+ extern ssize_t __vfs_write(struct file *, const char __user *, size_t, loff_t *);
+ extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *);
diff --git a/include/linux/mm.h b/include/linux/mm.h
-index dd5ea30..445d798 100644
+index 0755b9f..2ee5500 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
-@@ -1224,6 +1224,28 @@ static inline int fixup_user_fault(struct task_struct *tsk,
+@@ -1172,6 +1172,28 @@ static inline int fixup_user_fault(struct task_struct *tsk,
}
#endif
-+#ifdef CONFIG_MMU
+extern void vma_do_file_update_time(struct vm_area_struct *, const char[], int);
+extern struct file *vma_do_pr_or_file(struct vm_area_struct *, const char[],
+ int);
@@ -33226,23 +33368,24 @@ index dd5ea30..445d798 100644
+ __LINE__)
+#define vma_get_file(vma) vma_do_get_file(vma, __func__, __LINE__)
+#define vma_fput(vma) vma_do_fput(vma, __func__, __LINE__)
-+#else
++
++#ifndef CONFIG_MMU
+extern struct file *vmr_do_pr_or_file(struct vm_region *, const char[], int);
+extern void vmr_do_fput(struct vm_region *, const char[], int);
+
+#define vmr_pr_or_file(region) vmr_do_pr_or_file(region, __func__, \
+ __LINE__)
+#define vmr_fput(region) vmr_do_fput(region, __func__, __LINE__)
-+#endif /* CONFIG_MMU */
++#endif /* !CONFIG_MMU */
+
extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
extern int access_remote_vm(struct mm_struct *mm, unsigned long addr,
void *buf, int len, int write);
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
-index 6d34aa2..f13dd51 100644
+index 8d37e26..ce89d4c 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
-@@ -233,6 +233,7 @@ struct vm_region {
+@@ -241,6 +241,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 */
@@ -33250,7 +33393,7 @@ index 6d34aa2..f13dd51 100644
int vm_usage; /* region usage count (access under nommu_region_sem) */
bool vm_icache_flushed : 1; /* true if the icache has been flushed for
-@@ -301,6 +302,7 @@ struct vm_area_struct {
+@@ -305,6 +306,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). */
@@ -33274,10 +33417,10 @@ index da2751d..2e0fca6 100644
+ unsigned int flags);
#endif
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
-index 00b10002..f4a389c 100644
+index 1a0006a..ddad01a 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
-@@ -57,6 +57,7 @@ header-y += atmsvc.h
+@@ -59,6 +59,7 @@ header-y += atmsvc.h
header-y += atm_tcp.h
header-y += atm_zatm.h
header-y += audit.h
@@ -33287,7 +33430,7 @@ index 00b10002..f4a389c 100644
header-y += auxvec.h
diff --git a/include/uapi/linux/aufs_type.h b/include/uapi/linux/aufs_type.h
new file mode 100644
-index 0000000..d6abed8
+index 0000000..a06c985
--- /dev/null
+++ b/include/uapi/linux/aufs_type.h
@@ -0,0 +1,406 @@
@@ -33319,7 +33462,7 @@ index 0000000..d6abed8
+
+#include
+
-+#define AUFS_VERSION "3.19"
++#define AUFS_VERSION "4.x-rcN"
+
+/* todo? move this to linux-2.6.19/include/magic.h */
+#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
@@ -33474,10 +33617,10 @@ index 0000000..d6abed8
+ "+" AUFS_BRATTR_COO_REG \
+ "+" AUFS_BRATTR_FHSM \
+ "+" AUFS_BRATTR_UNPIN \
-+ "+" AUFS_BRATTR_ICEX_SEC \
-+ "+" AUFS_BRATTR_ICEX_SYS \
-+ "+" AUFS_BRATTR_ICEX_USR \
-+ "+" AUFS_BRATTR_ICEX_OTH \
++ "+" AUFS_BRATTR_ICEX_SEC \
++ "+" AUFS_BRATTR_ICEX_SYS \
++ "+" AUFS_BRATTR_ICEX_USR \
++ "+" AUFS_BRATTR_ICEX_OTH \
+ "+" AUFS_BRWATTR_NLWH)
+
+typedef struct {
@@ -33698,10 +33841,10 @@ index 0000000..d6abed8
+
+#endif /* __AUFS_TYPE_H__ */
diff --git a/kernel/fork.c b/kernel/fork.c
-index 4dc2dda..5984c61 100644
+index 03c1eaa..7e215ba 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
-@@ -430,7 +430,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
+@@ -456,7 +456,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
struct inode *inode = file_inode(file);
struct address_space *mapping = file->f_mapping;
@@ -33711,23 +33854,23 @@ index 4dc2dda..5984c61 100644
atomic_dec(&inode->i_writecount);
i_mmap_lock_write(mapping);
diff --git a/mm/Makefile b/mm/Makefile
-index 4bf586e..59bd276 100644
+index 98c4eae..3f0c9b9 100644
--- a/mm/Makefile
+++ b/mm/Makefile
-@@ -18,7 +18,7 @@ obj-y := filemap.o mempool.o oom_kill.o \
+@@ -21,7 +21,7 @@ obj-y := filemap.o mempool.o oom_kill.o \
mm_init.o mmu_context.o percpu.o slab_common.o \
compaction.o vmacache.o \
interval_tree.o list_lru.o workingset.o \
-- iov_iter.o debug.o $(mmu-y)
-+ iov_iter.o prfile.o debug.o $(mmu-y)
+- debug.o $(mmu-y)
++ prfile.o debug.o $(mmu-y)
obj-y += init-mm.o
diff --git a/mm/filemap.c b/mm/filemap.c
-index 673e458..a623932 100644
+index 6bf5e42..a863d0f 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
-@@ -2063,7 +2063,7 @@ int filemap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
+@@ -2062,7 +2062,7 @@ int filemap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
int ret = VM_FAULT_LOCKED;
sb_start_pagefault(inode->i_sb);
@@ -33736,46 +33879,11 @@ index 673e458..a623932 100644
lock_page(page);
if (page->mapping != inode->i_mapping) {
unlock_page(page);
-diff --git a/mm/fremap.c b/mm/fremap.c
-index 2805d71..1b011b0 100644
---- a/mm/fremap.c
-+++ b/mm/fremap.c
-@@ -224,16 +224,28 @@ get_write_lock:
- */
- if (mapping_cap_account_dirty(mapping)) {
- unsigned long addr;
-- struct file *file = get_file(vma->vm_file);
-+ struct file *file = vma->vm_file,
-+ *prfile = vma->vm_prfile;
-+
- /* mmap_region may free vma; grab the info now */
- vm_flags = vma->vm_flags;
-
-+ vma_get_file(vma);
- addr = mmap_region(file, start, size, vm_flags, pgoff);
-- fput(file);
-+ vma_fput(vma);
- if (IS_ERR_VALUE(addr)) {
- err = addr;
- } else {
- BUG_ON(addr != start);
-+ if (prfile) {
-+ struct vm_area_struct *new_vma;
-+
-+ new_vma = find_vma(mm, addr);
-+ if (!new_vma->vm_prfile)
-+ new_vma->vm_prfile = prfile;
-+ if (new_vma != vma)
-+ get_file(prfile);
-+ }
- err = 0;
- }
- goto out_freed;
diff --git a/mm/madvise.c b/mm/madvise.c
-index a271adc..29a932f 100644
+index d551475..1ebf71b 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
-@@ -324,12 +324,12 @@ static long madvise_remove(struct vm_area_struct *vma,
+@@ -320,12 +320,12 @@ static long madvise_remove(struct vm_area_struct *vma,
* vma's reference to the file) can go away as soon as we drop
* mmap_sem.
*/
@@ -33791,23 +33899,23 @@ index a271adc..29a932f 100644
return error;
}
diff --git a/mm/memory.c b/mm/memory.c
-index 2c3536c..444bb1d 100644
+index 22e037e..62096a2 100644
--- a/mm/memory.c
+++ b/mm/memory.c
-@@ -2157,7 +2157,7 @@ reuse:
-
- /* file_update_time outside page_lock */
- if (vma->vm_file)
-- file_update_time(vma->vm_file);
-+ vma_file_update_time(vma);
+@@ -2034,7 +2034,7 @@ static inline int wp_page_reuse(struct mm_struct *mm,
}
- put_page(dirty_page);
- if (page_mkwrite) {
+
+ if (!page_mkwrite)
+- file_update_time(vma->vm_file);
++ vma_file_update_time(vma);
+ }
+
+ return VM_FAULT_WRITE;
diff --git a/mm/mmap.c b/mm/mmap.c
-index 7f684d5..ffa1b91 100644
+index bb50cac..1ab5e596 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
-@@ -277,7 +277,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
+@@ -274,7 +274,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
if (vma->vm_ops && vma->vm_ops->close)
vma->vm_ops->close(vma);
if (vma->vm_file)
@@ -33816,7 +33924,7 @@ index 7f684d5..ffa1b91 100644
mpol_put(vma_policy(vma));
kmem_cache_free(vm_area_cachep, vma);
return next;
-@@ -897,7 +897,7 @@ again: remove_next = 1 + (end > next->vm_end);
+@@ -886,7 +886,7 @@ again: remove_next = 1 + (end > next->vm_end);
if (remove_next) {
if (file) {
uprobe_munmap(next, next->vm_start, next->vm_end);
@@ -33825,7 +33933,7 @@ index 7f684d5..ffa1b91 100644
}
if (next->anon_vma)
anon_vma_merge(vma, next);
-@@ -1682,8 +1682,8 @@ out:
+@@ -1671,8 +1671,8 @@ out:
return addr;
unmap_and_free_vma:
@@ -33835,7 +33943,7 @@ index 7f684d5..ffa1b91 100644
/* Undo any partial mapping done by a device driver. */
unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
-@@ -2484,7 +2484,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
+@@ -2473,7 +2473,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
goto out_free_mpol;
if (new->vm_file)
@@ -33844,7 +33952,7 @@ index 7f684d5..ffa1b91 100644
if (new->vm_ops && new->vm_ops->open)
new->vm_ops->open(new);
-@@ -2503,7 +2503,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
+@@ -2492,7 +2492,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
if (new->vm_ops && new->vm_ops->close)
new->vm_ops->close(new);
if (new->vm_file)
@@ -33853,7 +33961,28 @@ index 7f684d5..ffa1b91 100644
unlink_anon_vmas(new);
out_free_mpol:
mpol_put(vma_policy(new));
-@@ -2895,7 +2895,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
+@@ -2635,7 +2635,6 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
+ struct vm_area_struct *vma;
+ unsigned long populate = 0;
+ unsigned long ret = -EINVAL;
+- struct file *file;
+
+ pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. "
+ "See Documentation/vm/remap_file_pages.txt.\n",
+@@ -2679,10 +2678,10 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
+ munlock_vma_pages_range(vma, start, start + size);
+ }
+
+- file = get_file(vma->vm_file);
++ vma_get_file(vma);
+ ret = do_mmap_pgoff(vma->vm_file, start, size,
+ prot, flags, pgoff, &populate);
+- fput(file);
++ vma_fput(vma);
+ out:
+ up_write(&mm->mmap_sem);
+ if (populate)
+@@ -2949,7 +2948,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
if (anon_vma_clone(new_vma, vma))
goto out_free_mempol;
if (new_vma->vm_file)
@@ -33863,30 +33992,27 @@ index 7f684d5..ffa1b91 100644
new_vma->vm_ops->open(new_vma);
vma_link(mm, new_vma, prev, rb_link, rb_parent);
diff --git a/mm/msync.c b/mm/msync.c
-index 992a167..ce1915b 100644
+index bb04d53..5c24c54 100644
--- a/mm/msync.c
+++ b/mm/msync.c
-@@ -84,13 +84,13 @@ SYSCALL_DEFINE3(msync, unsigned long, start, size_t, len, int, flags)
+@@ -84,10 +84,10 @@ SYSCALL_DEFINE3(msync, unsigned long, start, size_t, len, int, flags)
start = vma->vm_end;
if ((flags & MS_SYNC) && file &&
(vma->vm_flags & VM_SHARED)) {
- get_file(file);
+ vma_get_file(vma);
up_read(&mm->mmap_sem);
- if (vma->vm_flags & VM_NONLINEAR)
- error = vfs_fsync(file, 1);
- else
- error = vfs_fsync_range(file, fstart, fend, 1);
+ error = vfs_fsync_range(file, fstart, fend, 1);
- fput(file);
+ vma_fput(vma);
if (error || start >= end)
goto out;
down_read(&mm->mmap_sem);
diff --git a/mm/nommu.c b/mm/nommu.c
-index 28bd8c4..3c0ace2 100644
+index e544508..dd6f74a 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
-@@ -659,7 +659,7 @@ static void __put_nommu_region(struct vm_region *region)
+@@ -693,7 +693,7 @@ static void __put_nommu_region(struct vm_region *region)
up_write(&nommu_region_sem);
if (region->vm_file)
@@ -33895,7 +34021,7 @@ index 28bd8c4..3c0ace2 100644
/* IO memory and memory shared directly out of the pagecache
* from ramfs/tmpfs mustn't be released here */
-@@ -824,7 +824,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma)
+@@ -858,7 +858,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma)
if (vma->vm_ops && vma->vm_ops->close)
vma->vm_ops->close(vma);
if (vma->vm_file)
@@ -33904,7 +34030,7 @@ index 28bd8c4..3c0ace2 100644
put_nommu_region(vma->vm_region);
kmem_cache_free(vm_area_cachep, vma);
}
-@@ -1375,7 +1375,7 @@ unsigned long do_mmap_pgoff(struct file *file,
+@@ -1398,7 +1398,7 @@ unsigned long do_mmap_pgoff(struct file *file,
goto error_just_free;
}
}
@@ -33913,7 +34039,7 @@ index 28bd8c4..3c0ace2 100644
kmem_cache_free(vm_region_jar, region);
region = pregion;
result = start;
-@@ -1451,10 +1451,10 @@ error_just_free:
+@@ -1474,10 +1474,10 @@ error_just_free:
up_write(&nommu_region_sem);
error:
if (region->vm_file)
@@ -33928,7 +34054,7 @@ index 28bd8c4..3c0ace2 100644
return ret;
diff --git a/mm/prfile.c b/mm/prfile.c
new file mode 100644
-index 0000000..fc708d2
+index 0000000..6aa5ab5
--- /dev/null
+++ b/mm/prfile.c
@@ -0,0 +1,86 @@
@@ -33954,11 +34080,10 @@ index 0000000..fc708d2
+#ifdef PRFILE_TRACE
+ if (pr)
+ pr_info("%s:%d: %s, %p\n", func, line, func2,
-+ f ? (char *)f->f_dentry->d_name.name : "(null)");
++ f ? (char *)f->f_path.dentry->d_name.name : "(null)");
+#endif
+}
+
-+#ifdef CONFIG_MMU
+void vma_do_file_update_time(struct vm_area_struct *vma, const char func[],
+ int line)
+{
@@ -33998,7 +34123,8 @@ index 0000000..fc708d2
+ if (f && pr)
+ fput(pr);
+}
-+#else
++
++#ifndef CONFIG_MMU
+struct file *vmr_do_pr_or_file(struct vm_region *region, const char func[],
+ int line)
+{
@@ -34017,4 +34143,4 @@ index 0000000..fc708d2
+ if (f && pr)
+ fput(pr);
+}
-+#endif /* CONFIG_MMU */
++#endif /* !CONFIG_MMU */
diff --git a/kernel/kernel/files/patches/mageia/fs-btrfs-fix-BUG_ON-in-btrfs_orphan_add-when-delete-unu.patch b/kernel/kernel/files/patches/mageia/fs-btrfs-fix-BUG_ON-in-btrfs_orphan_add-when-delete-unu.patch
deleted file mode 100644
index 31d25c9c..00000000
--- a/kernel/kernel/files/patches/mageia/fs-btrfs-fix-BUG_ON-in-btrfs_orphan_add-when-delete-unu.patch
+++ /dev/null
@@ -1,96 +0,0 @@
-From 3d84be799194147e04c0e3129ed44a948773b80a Mon Sep 17 00:00:00 2001
-From: Forrest Liu
-Date: Wed, 11 Feb 2015 14:23:47 +0800
-Subject: [PATCH] Btrfs: fix BUG_ON in btrfs_orphan_add() when delete unused
- block group
-
-Removing large amount of block group in a transaction may encounters
-BUG_ON() in btrfs_orphan_add(). That is because btrfs_orphan_reserve_metadata()
-will grab metadata reservation from transaction handle, and
-btrfs_delete_unused_bgs() didn't reserve metadata for trnasaction handle when
-delete unused block group.
-
-The problem can be reproduce by following script
-
- mntpath=/btrfs
- loopdev=/dev/loop0
- filepath=/home/forrest/image
-
- umount $mntpath
- losetup -d $loopdev
- truncate --size 1000g $filepath
- losetup $loopdev $filepath
- mkfs.btrfs -f $loopdev
- mount $loopdev $mntpath
-
- for j in `seq 1 1 1000`; do
- fallocate -l 1g $mntpath/$j
- done
- # wait cleaner thread remove unused block group
- sleep 300
-
-The call trace that results from the BUG_ON() is:
-
-[ 613.093084] ------------[ cut here ]------------
-[ 613.097928] kernel BUG at fs/btrfs/inode.c:3142!
-[ 613.105855] invalid opcode: 0000 [#1] SMP
-[ 613.112702] Modules linked in: coretemp(E) crc32_pclmul(E) ghash_clmulni_intel(E) aesni_intel(E) snd_ens1371(E) snd_ac97_codec(E) aes_x86_64(E) lrw(E) gf128mul(E) glue_helper(E) ppdev(E) ac97_bus(E) ablk_helper(E) gameport(E) cryptd(E) snd_rawmidi(E) snd_seq_device(E) snd_pcm(E) vmw_balloon(E) snd_timer(E) snd(E) soundcore(E) serio_raw(E) vmwgfx(E) ttm(E) drm_kms_helper(E) drm(E) vmw_vmci(E) parport_pc(E) shpchp(E) i2c_piix4(E) mac_hid(E) lp(E) parport(E) btrfs(E) xor(E) raid6_pq(E) hid_generic(E) usbhid(E) hid(E) psmouse(E) ahci(E) libahci(E) e1000(E) mptspi(E) mptscsih(E) mptbase(E) floppy(E) vmw_pvscsi(E) vmxnet3(E)
-[ 613.144196] CPU: 0 PID: 1480 Comm: btrfs-cleaner Tainted: G E 3.19.0-rc7-custom #2
-[ 613.148501] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 07/31/2013
-[ 613.152694] task: ffff880035cdb1a0 ti: ffff880039cf4000 task.ti: ffff880039cf4000
-[ 613.154969] RIP: 0010:[] [] btrfs_orphan_add+0x1d2/0x1e0 [btrfs]
-[ 613.157780] RSP: 0018:ffff880039cf7c48 EFLAGS: 00010286
-[ 613.159560] RAX: 00000000ffffffe4 RBX: ffff88003bd981a0 RCX: ffff88003c9e4000
-[ 613.161904] RDX: 0000000000002244 RSI: 0000000000040000 RDI: ffff88003c9e4138
-[ 613.164264] RBP: ffff880039cf7c88 R08: 000060ffc0000850 R09: 0000000000000000
-[ 613.166507] R10: ffff88003bc4b7a0 R11: ffffea0000eb6740 R12: ffff88003c9c0000
-[ 613.168681] R13: ffff88003c102160 R14: ffff88003c9c0458 R15: 0000000000000001
-[ 613.170932] FS: 0000000000000000(0000) GS:ffff88003f600000(0000) knlGS:0000000000000000
-[ 613.173316] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
-[ 613.175227] CR2: 00007f6343537000 CR3: 0000000036329000 CR4: 00000000000407f0
-[ 613.177554] Stack:
-[ 613.178712] ffff880039cf7c88 ffffffffa0182a54 ffff88003c9e4b04 ffff88003c9c7800
-[ 613.181297] ffff88003bc4b7a0 ffff88003bd981a0 ffff88003c8db200 ffff88003c2fcc60
-[ 613.183782] ffff880039cf7d18 ffffffffa012da97 ffff88003bc4b7a4 ffff88003bc4b7a0
-[ 613.186171] Call Trace:
-[ 613.187493] [] ? lookup_free_space_inode+0x44/0x100 [btrfs]
-[ 613.189801] [] btrfs_remove_block_group+0x137/0x740 [btrfs]
-[ 613.192126] [] btrfs_remove_chunk+0x672/0x780 [btrfs]
-[ 613.194267] [] btrfs_delete_unused_bgs+0x25f/0x280 [btrfs]
-[ 613.196567] [] cleaner_kthread+0x12c/0x190 [btrfs]
-[ 613.198687] [] ? check_leaf+0x350/0x350 [btrfs]
-[ 613.200758] [] kthread+0xd2/0xf0
-[ 613.202616] [] ? kthread_create_on_node+0x180/0x180
-[ 613.204738] [] ret_from_fork+0x7c/0xb0
-[ 613.206652] [] ? kthread_create_on_node+0x180/0x180
-[ 613.208741] Code: ff ff 0f 1f 80 00 00 00 00 89 45 c8 3e 80 63 80 fd 48 89 df e8 d0 23 fe ff 8b 45 c8 e9 14 ff ff ff b8 f4 ff ff ff e9 12 ff ff ff <0f> 0b 66 66 66 2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90 55 48
-[ 613.216562] RIP [] btrfs_orphan_add+0x1d2/0x1e0 [btrfs]
-[ 613.218828] RSP
-[ 613.220382] ---[ end trace 71073106deb8a457 ]---
-
-This patch replace btrfs_join_transaction() with btrfs_start_transaction() in
-btrfs_delete_unused_bgs() to revent BUG_ON() in btrfs_orphan_add()
-
-Signed-off-by: Forrest Liu
-Signed-off-by: Chris Mason
----
- fs/btrfs/extent-tree.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
-index 0f67370..28ce5c8 100644
---- a/fs/btrfs/extent-tree.c
-+++ b/fs/btrfs/extent-tree.c
-@@ -9555,7 +9555,8 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info)
- * Want to do this before we do anything else so we can recover
- * properly if we fail to join the transaction.
- */
-- trans = btrfs_join_transaction(root);
-+ /* 1 for btrfs_orphan_reserve_metadata() */
-+ trans = btrfs_start_transaction(root, 1);
- if (IS_ERR(trans)) {
- btrfs_set_block_group_rw(root, block_group);
- ret = PTR_ERR(trans);
---
-2.3.1
-
diff --git a/kernel/kernel/files/patches/mageia/fs-btrfs-unlock-i_mutex-after-attempting-to-delete-subvolume-during-send.patch b/kernel/kernel/files/patches/mageia/fs-btrfs-unlock-i_mutex-after-attempting-to-delete-subvolume-during-send.patch
deleted file mode 100644
index 92cb2cd6..00000000
--- a/kernel/kernel/files/patches/mageia/fs-btrfs-unlock-i_mutex-after-attempting-to-delete-subvolume-during-send.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 909e26dce3f7600f5e293ac0522c28790a0c8c9c Mon Sep 17 00:00:00 2001
-From: Omar Sandoval
-Date: Fri, 10 Apr 2015 14:20:40 -0700
-Subject: btrfs: unlock i_mutex after attempting to delete subvolume during send
-
-From: Omar Sandoval
-
-commit 909e26dce3f7600f5e293ac0522c28790a0c8c9c upstream.
-
-Whenever the check for a send in progress introduced in commit
-521e0546c970 (btrfs: protect snapshots from deleting during send) is
-hit, we return without unlocking inode->i_mutex. This is easy to see
-with lockdep enabled:
-
-[ +0.000059] ================================================
-[ +0.000028] [ BUG: lock held when returning to user space! ]
-[ +0.000029] 4.0.0-rc5-00096-g3c435c1 #93 Not tainted
-[ +0.000026] ------------------------------------------------
-[ +0.000029] btrfs/211 is leaving the kernel with locks still held!
-[ +0.000029] 1 lock held by btrfs/211:
-[ +0.000023] #0: (&type->i_mutex_dir_key){+.+.+.}, at: [] btrfs_ioctl_snap_destroy+0x2df/0x7a0
-
-Make sure we unlock it in the error path.
-
-Reviewed-by: Filipe Manana
-Reviewed-by: David Sterba
-Signed-off-by: Omar Sandoval
-Signed-off-by: Chris Mason
-Signed-off-by: Greg Kroah-Hartman
-
----
- fs/btrfs/ioctl.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/fs/btrfs/ioctl.c
-+++ b/fs/btrfs/ioctl.c
-@@ -2403,7 +2403,7 @@ static noinline int btrfs_ioctl_snap_des
- "Attempt to delete subvolume %llu during send",
- dest->root_key.objectid);
- err = -EPERM;
-- goto out_dput;
-+ goto out_unlock_inode;
- }
-
- d_invalidate(dentry);
-@@ -2498,6 +2498,7 @@ out_up_write:
- root_flags & ~BTRFS_ROOT_SUBVOL_DEAD);
- spin_unlock(&dest->root_item_lock);
- }
-+out_unlock_inode:
- mutex_unlock(&inode->i_mutex);
- if (!err) {
- shrink_dcache_sb(root->fs_info->sb);
diff --git a/kernel/kernel/files/patches/mageia/fs-efivarfs-Ensure-VariableName-is-NUL-terminated.patch b/kernel/kernel/files/patches/mageia/fs-efivarfs-Ensure-VariableName-is-NUL-terminated.patch
deleted file mode 100644
index 5de75876..00000000
--- a/kernel/kernel/files/patches/mageia/fs-efivarfs-Ensure-VariableName-is-NUL-terminated.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From: Ross Lagerwall
-Subject: [PATCH RESEND] efivarfs: Ensure VariableName is NUL-terminated
-Date: Thu, 2 Apr 2015 08:39:00 +0100
-
-Some buggy firmware implementations update VariableNameSize on success
-such that it does not include the final NUL character which results in
-garbage in the efivarfs name entries. Use kzalloc on the efivar_entry
-(as is done in efivars.c) to ensure that the name is always
-NUL-terminated.
-
-The buggy firmware is:
-BIOS Information
- Vendor: Intel Corp.
- Version: S1200RP.86B.02.02.0005.102320140911
- Release Date: 10/23/2014
- BIOS Revision: 4.6
-System Information
- Manufacturer: Intel Corporation
- Product Name: S1200RP_SE
-
-Signed-off-by: Ross Lagerwall
----
- fs/efivarfs/super.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c
-index ddbce42..acf9a67 100644
---- a/fs/efivarfs/super.c
-+++ b/fs/efivarfs/super.c
-@@ -121,7 +121,7 @@ static int efivarfs_callback(efi_char16_t *name16, efi_guid_t vendor,
- int len, i;
- int err = -ENOMEM;
-
-- entry = kmalloc(sizeof(*entry), GFP_KERNEL);
-+ entry = kzalloc(sizeof(*entry), GFP_KERNEL);
- if (!entry)
- return err;
-
---
-2.1.0
-
diff --git a/kernel/kernel/files/patches/mageia/fs-ext4-fix-data-corruption-caused-by-unwritten-and-del.patch b/kernel/kernel/files/patches/mageia/fs-ext4-fix-data-corruption-caused-by-unwritten-and-del.patch
deleted file mode 100644
index 5281eaec..00000000
--- a/kernel/kernel/files/patches/mageia/fs-ext4-fix-data-corruption-caused-by-unwritten-and-del.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-From d2dc317d564a46dfc683978a2e5a4f91434e9711 Mon Sep 17 00:00:00 2001
-From: Lukas Czerner
-Date: Sat, 2 May 2015 21:36:55 -0400
-Subject: [PATCH] ext4: fix data corruption caused by unwritten and delayed
- extents
-
-Currently it is possible to lose whole file system block worth of data
-when we hit the specific interaction with unwritten and delayed extents
-in status extent tree.
-
-The problem is that when we insert delayed extent into extent status
-tree the only way to get rid of it is when we write out delayed buffer.
-However there is a limitation in the extent status tree implementation
-so that when inserting unwritten extent should there be even a single
-delayed block the whole unwritten extent would be marked as delayed.
-
-At this point, there is no way to get rid of the delayed extents,
-because there are no delayed buffers to write out. So when a we write
-into said unwritten extent we will convert it to written, but it still
-remains delayed.
-
-When we try to write into that block later ext4_da_map_blocks() will set
-the buffer new and delayed and map it to invalid block which causes
-the rest of the block to be zeroed loosing already written data.
-
-For now we can fix this by simply not allowing to set delayed status on
-written extent in the extent status tree. Also add WARN_ON() to make
-sure that we notice if this happens in the future.
-
-This problem can be easily reproduced by running the following xfs_io.
-
-xfs_io -f -c "pwrite -S 0xaa 4096 2048" \
- -c "falloc 0 131072" \
- -c "pwrite -S 0xbb 65536 2048" \
- -c "fsync" /mnt/test/fff
-
-echo 3 > /proc/sys/vm/drop_caches
-xfs_io -c "pwrite -S 0xdd 67584 2048" /mnt/test/fff
-
-This can be theoretically also reproduced by at random by running fsx,
-but it's not very reliable, though on machines with bigger page size
-(like ppc) this can be seen more often (especially xfstest generic/127)
-
-Signed-off-by: Lukas Czerner
-Signed-off-by: Theodore Ts'o
-Cc: stable@vger.kernel.org
----
- fs/ext4/extents_status.c | 8 ++++++++
- fs/ext4/inode.c | 2 ++
- 2 files changed, 10 insertions(+)
-
-diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c
-index d33d5a6..26724ae 100644
---- a/fs/ext4/extents_status.c
-+++ b/fs/ext4/extents_status.c
-@@ -703,6 +703,14 @@ int ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk,
-
- BUG_ON(end < lblk);
-
-+ if ((status & EXTENT_STATUS_DELAYED) &&
-+ (status & EXTENT_STATUS_WRITTEN)) {
-+ ext4_warning(inode->i_sb, "Inserting extent [%u/%u] as "
-+ " delayed and written which can potentially "
-+ " cause data loss.\n", lblk, len);
-+ WARN_ON(1);
-+ }
-+
- newes.es_lblk = lblk;
- newes.es_len = len;
- ext4_es_store_pblock_status(&newes, pblk, status);
-diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
-index f6b35d8..4415cea 100644
---- a/fs/ext4/inode.c
-+++ b/fs/ext4/inode.c
-@@ -532,6 +532,7 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
- status = map->m_flags & EXT4_MAP_UNWRITTEN ?
- EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN;
- if (!(flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) &&
-+ !(status & EXTENT_STATUS_WRITTEN) &&
- ext4_find_delalloc_range(inode, map->m_lblk,
- map->m_lblk + map->m_len - 1))
- status |= EXTENT_STATUS_DELAYED;
-@@ -636,6 +637,7 @@ found:
- status = map->m_flags & EXT4_MAP_UNWRITTEN ?
- EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN;
- if (!(flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) &&
-+ !(status & EXTENT_STATUS_WRITTEN) &&
- ext4_find_delalloc_range(inode, map->m_lblk,
- map->m_lblk + map->m_len - 1))
- status |= EXTENT_STATUS_DELAYED;
---
-2.3.2
-
diff --git a/kernel/kernel/files/patches/mageia/fs-ext4-move-check-under-lock-scope-to-close-a-race.patch b/kernel/kernel/files/patches/mageia/fs-ext4-move-check-under-lock-scope-to-close-a-race.patch
deleted file mode 100644
index fdcda8b2..00000000
--- a/kernel/kernel/files/patches/mageia/fs-ext4-move-check-under-lock-scope-to-close-a-race.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 280227a75b56ab5d35854f3a77ef74a7ad56a203 Mon Sep 17 00:00:00 2001
-From: Davide Italiano
-Date: Sat, 2 May 2015 23:21:15 -0400
-Subject: ext4: move check under lock scope to close a race.
-
-From: Davide Italiano
-
-commit 280227a75b56ab5d35854f3a77ef74a7ad56a203 upstream.
-
-fallocate() checks that the file is extent-based and returns
-EOPNOTSUPP in case is not. Other tasks can convert from and to
-indirect and extent so it's safe to check only after grabbing
-the inode mutex.
-
-Signed-off-by: Davide Italiano
-Signed-off-by: Theodore Ts'o
-Signed-off-by: Greg Kroah-Hartman
-
----
- fs/ext4/extents.c | 15 ++++++++-------
- 1 file changed, 8 insertions(+), 7 deletions(-)
-
---- a/fs/ext4/extents.c
-+++ b/fs/ext4/extents.c
-@@ -4934,13 +4934,6 @@ long ext4_fallocate(struct file *file, i
- if (ret)
- return ret;
-
-- /*
-- * currently supporting (pre)allocate mode for extent-based
-- * files _only_
-- */
-- if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
-- return -EOPNOTSUPP;
--
- if (mode & FALLOC_FL_COLLAPSE_RANGE)
- return ext4_collapse_range(inode, offset, len);
-
-@@ -4962,6 +4955,14 @@ long ext4_fallocate(struct file *file, i
-
- mutex_lock(&inode->i_mutex);
-
-+ /*
-+ * We only support preallocation for extent-based files only
-+ */
-+ if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
-+ ret = -EOPNOTSUPP;
-+ goto out;
-+ }
-+
- if (!(mode & FALLOC_FL_KEEP_SIZE) &&
- offset + len > i_size_read(inode)) {
- new_size = offset + len;
diff --git a/kernel/kernel/files/patches/mageia/fs-mnt-Fail-collect_mounts-when-applied-to-unmounted-mo.patch b/kernel/kernel/files/patches/mageia/fs-mnt-Fail-collect_mounts-when-applied-to-unmounted-mo.patch
deleted file mode 100644
index b2f9ee94..00000000
--- a/kernel/kernel/files/patches/mageia/fs-mnt-Fail-collect_mounts-when-applied-to-unmounted-mo.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From cd4a40174b71acd021877341684d8bb1dc8ea4ae Mon Sep 17 00:00:00 2001
-From: "Eric W. Biederman"
-Date: Wed, 7 Jan 2015 14:28:26 -0600
-Subject: [PATCH] mnt: Fail collect_mounts when applied to unmounted mounts
-
-The only users of collect_mounts are in audit_tree.c
-
-In audit_trim_trees and audit_add_tree_rule the path passed into
-collect_mounts is generated from kern_path passed an audit_tree
-pathname which is guaranteed to be an absolute path. In those cases
-collect_mounts is obviously intended to work on mounted paths and
-if a race results in paths that are unmounted when collect_mounts
-it is reasonable to fail early.
-
-The paths passed into audit_tag_tree don't have the absolute path
-check. But are used to play with fsnotify and otherwise interact with
-the audit_trees, so again operating only on mounted paths appears
-reasonable.
-
-Avoid having to worry about what happens when we try and audit
-unmounted filesystems by restricting collect_mounts to mounts
-that appear in the mount tree.
-
-Signed-off-by: "Eric W. Biederman"
----
- fs/namespace.c | 7 +++++--
- 1 file changed, 5 insertions(+), 2 deletions(-)
-
-diff --git a/fs/namespace.c b/fs/namespace.c
-index 2b12b7a..acc5583 100644
---- a/fs/namespace.c
-+++ b/fs/namespace.c
-@@ -1669,8 +1669,11 @@ struct vfsmount *collect_mounts(struct path *path)
- {
- struct mount *tree;
- namespace_lock();
-- tree = copy_tree(real_mount(path->mnt), path->dentry,
-- CL_COPY_ALL | CL_PRIVATE);
-+ if (!check_mnt(real_mount(path->mnt)))
-+ tree = ERR_PTR(-EINVAL);
-+ else
-+ tree = copy_tree(real_mount(path->mnt), path->dentry,
-+ CL_COPY_ALL | CL_PRIVATE);
- namespace_unlock();
- if (IS_ERR(tree))
- return ERR_CAST(tree);
---
-2.3.2
-
diff --git a/kernel/kernel/files/patches/mageia/fs-mnt-Fix-fs_fully_visible-to-verify-the-root-director.patch b/kernel/kernel/files/patches/mageia/fs-mnt-Fix-fs_fully_visible-to-verify-the-root-director.patch
deleted file mode 100644
index 0a8a5e8f..00000000
--- a/kernel/kernel/files/patches/mageia/fs-mnt-Fix-fs_fully_visible-to-verify-the-root-director.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 7e96c1b0e0f495c5a7450dc4aa7c9a24ba4305bd Mon Sep 17 00:00:00 2001
-From: "Eric W. Biederman"
-Date: Fri, 8 May 2015 16:36:50 -0500
-Subject: [PATCH] mnt: Fix fs_fully_visible to verify the root directory is
- visible
-
-This fixes a dumb bug in fs_fully_visible that allows proc or sys to
-be mounted if there is a bind mount of part of /proc/ or /sys/ visible.
-
-Cc: stable@vger.kernel.org
-Reported-by: Eric Windisch
-Signed-off-by: "Eric W. Biederman"
----
- fs/namespace.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
-diff --git a/fs/namespace.c b/fs/namespace.c
-index 1f4f9da..1b9e111 100644
---- a/fs/namespace.c
-+++ b/fs/namespace.c
-@@ -3179,6 +3179,12 @@ bool fs_fully_visible(struct file_system_type *type)
- if (mnt->mnt.mnt_sb->s_type != type)
- continue;
-
-+ /* This mount is not fully visible if it's root directory
-+ * is not the root directory of the filesystem.
-+ */
-+ if (mnt->mnt.mnt_root != mnt->mnt.mnt_sb->s_root)
-+ continue;
-+
- /* This mount is not fully visible if there are any child mounts
- * that cover anything except for empty directories.
- */
---
-2.3.2
-
diff --git a/kernel/kernel/files/patches/mageia/fs-path_openat-fix-double-fput.patch b/kernel/kernel/files/patches/mageia/fs-path_openat-fix-double-fput.patch
deleted file mode 100644
index 6a4d81ed..00000000
--- a/kernel/kernel/files/patches/mageia/fs-path_openat-fix-double-fput.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From f15133df088ecadd141ea1907f2c96df67c729f0 Mon Sep 17 00:00:00 2001
-From: Al Viro
-Date: Fri, 8 May 2015 22:53:15 -0400
-Subject: [PATCH] path_openat(): fix double fput()
-
-path_openat() jumps to the wrong place after do_tmpfile() - it has
-already done path_cleanup() (as part of path_lookupat() called by
-do_tmpfile()), so doing that again can lead to double fput().
-
-Cc: stable@vger.kernel.org # v3.11+
-Signed-off-by: Al Viro
----
- fs/namei.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/fs/namei.c b/fs/namei.c
-index f67cf6c..fe30d3b 100644
---- a/fs/namei.c
-+++ b/fs/namei.c
-@@ -3209,7 +3209,7 @@ static struct file *path_openat(int dfd,
-
- if (unlikely(file->f_flags & __O_TMPFILE)) {
- error = do_tmpfile(dfd, pathname, nd, flags, op, file, &opened);
-- goto out;
-+ goto out2;
- }
-
- error = path_init(dfd, pathname->name, flags, nd);
-@@ -3239,6 +3239,7 @@ static struct file *path_openat(int dfd,
- }
- out:
- path_cleanup(nd);
-+out2:
- if (!(opened & FILE_OPENED)) {
- BUG_ON(!error);
- put_filp(file);
diff --git a/kernel/kernel/files/patches/mageia/fs-splice-sendfile-at-once-fails-for-big-files.patch b/kernel/kernel/files/patches/mageia/fs-splice-sendfile-at-once-fails-for-big-files.patch
deleted file mode 100644
index 369de1d1..00000000
--- a/kernel/kernel/files/patches/mageia/fs-splice-sendfile-at-once-fails-for-big-files.patch
+++ /dev/null
@@ -1,136 +0,0 @@
-From 0ff28d9f4674d781e492bcff6f32f0fe48cf0fed Mon Sep 17 00:00:00 2001
-From: Christophe Leroy
-Date: Wed, 6 May 2015 17:26:47 +0200
-Subject: [PATCH] splice: sendfile() at once fails for big files
-
-Using sendfile with below small program to get MD5 sums of some files,
-it appear that big files (over 64kbytes with 4k pages system) get a
-wrong MD5 sum while small files get the correct sum.
-This program uses sendfile() to send a file to an AF_ALG socket
-for hashing.
-
-/* md5sum2.c */
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-int main(int argc, char **argv)
-{
- int sk = socket(AF_ALG, SOCK_SEQPACKET, 0);
- struct stat st;
- struct sockaddr_alg sa = {
- .salg_family = AF_ALG,
- .salg_type = "hash",
- .salg_name = "md5",
- };
- int n;
-
- bind(sk, (struct sockaddr*)&sa, sizeof(sa));
-
- for (n = 1; n < argc; n++) {
- int size;
- int offset = 0;
- char buf[4096];
- int fd;
- int sko;
- int i;
-
- fd = open(argv[n], O_RDONLY);
- sko = accept(sk, NULL, 0);
- fstat(fd, &st);
- size = st.st_size;
- sendfile(sko, fd, &offset, size);
- size = read(sko, buf, sizeof(buf));
- for (i = 0; i < size; i++)
- printf("%2.2x", buf[i]);
- printf(" %s\n", argv[n]);
- close(fd);
- close(sko);
- }
- exit(0);
-}
-
-Test below is done using official linux patch files. First result is
-with a software based md5sum. Second result is with the program above.
-
-root@vgoip:~# ls -l patch-3.6.*
--rw-r--r-- 1 root root 64011 Aug 24 12:01 patch-3.6.2.gz
--rw-r--r-- 1 root root 94131 Aug 24 12:01 patch-3.6.3.gz
-
-root@vgoip:~# md5sum patch-3.6.*
-b3ffb9848196846f31b2ff133d2d6443 patch-3.6.2.gz
-c5e8f687878457db77cb7158c38a7e43 patch-3.6.3.gz
-
-root@vgoip:~# ./md5sum2 patch-3.6.*
-b3ffb9848196846f31b2ff133d2d6443 patch-3.6.2.gz
-5fd77b24e68bb24dcc72d6e57c64790e patch-3.6.3.gz
-
-After investivation, it appears that sendfile() sends the files by blocks
-of 64kbytes (16 times PAGE_SIZE). The problem is that at the end of each
-block, the SPLICE_F_MORE flag is missing, therefore the hashing operation
-is reset as if it was the end of the file.
-
-This patch adds SPLICE_F_MORE to the flags when more data is pending.
-
-With the patch applied, we get the correct sums:
-
-root@vgoip:~# md5sum patch-3.6.*
-b3ffb9848196846f31b2ff133d2d6443 patch-3.6.2.gz
-c5e8f687878457db77cb7158c38a7e43 patch-3.6.3.gz
-
-root@vgoip:~# ./md5sum2 patch-3.6.*
-b3ffb9848196846f31b2ff133d2d6443 patch-3.6.2.gz
-c5e8f687878457db77cb7158c38a7e43 patch-3.6.3.gz
-
-Signed-off-by: Christophe Leroy
-Signed-off-by: Jens Axboe
----
- fs/splice.c | 12 +++++++++++-
- 1 file changed, 11 insertions(+), 1 deletion(-)
-
-diff --git a/fs/splice.c b/fs/splice.c
-index 476024b..bfe62ae 100644
---- a/fs/splice.c
-+++ b/fs/splice.c
-@@ -1161,7 +1161,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
- long ret, bytes;
- umode_t i_mode;
- size_t len;
-- int i, flags;
-+ int i, flags, more;
-
- /*
- * We require the input being a regular file, as we don't want to
-@@ -1204,6 +1204,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
- * Don't block on output, we have to drain the direct pipe.
- */
- sd->flags &= ~SPLICE_F_NONBLOCK;
-+ more = sd->flags & SPLICE_F_MORE;
-
- while (len) {
- size_t read_len;
-@@ -1217,6 +1218,15 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
- sd->total_len = read_len;
-
- /*
-+ * If more data is pending, set SPLICE_F_MORE
-+ * If this is the last data and SPLICE_F_MORE was not set
-+ * initially, clears it.
-+ */
-+ if (read_len < len)
-+ sd->flags |= SPLICE_F_MORE;
-+ else if (!more)
-+ sd->flags &= ~SPLICE_F_MORE;
-+ /*
- * NOTE: nonblocking mode only applies to the input. We
- * must not do the output in nonblocking mode as then we
- * could get stuck data in the internal pipe:
---
-2.3.2
-
diff --git a/kernel/kernel/files/patches/mageia/genirq-Fix-null-pointer-reference-in-irq_set_affinit.patch b/kernel/kernel/files/patches/mageia/genirq-Fix-null-pointer-reference-in-irq_set_affinit.patch
deleted file mode 100644
index 458a93c7..00000000
--- a/kernel/kernel/files/patches/mageia/genirq-Fix-null-pointer-reference-in-irq_set_affinit.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 4fe7ffb7e17ca6ad9173b8de35f260c9c8fc2f79 Mon Sep 17 00:00:00 2001
-From: Jesse Brandeburg
-Date: Wed, 28 Jan 2015 10:57:14 -0800
-Subject: [PATCH] genirq: Fix null pointer reference in irq_set_affinity_hint()
-
-The recent set_affinity commit by me introduced some null
-pointer dereferences on driver unload, because some drivers
-call this function with a NULL argument. This fixes the issue
-by just checking for null before setting the affinity mask.
-
-Fixes: e2e64a932556 ("genirq: Set initial affinity in irq_set_affinity_hint()")
-Reported-by: Yinghai Lu
-Signed-off-by: Jesse Brandeburg
-CC: netdev@vger.kernel.org
-Link: http://lkml.kernel.org/r/20150128185739.9689.84588.stgit@jbrandeb-cp2.jf.intel.com
-Signed-off-by: Ingo Molnar
----
- kernel/irq/manage.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
-index f038e58..196a06f 100644
---- a/kernel/irq/manage.c
-+++ b/kernel/irq/manage.c
-@@ -244,7 +244,8 @@ int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m)
- desc->affinity_hint = m;
- irq_put_desc_unlock(desc, flags);
- /* set the initial affinity to prevent every interrupt being on CPU0 */
-- __irq_set_affinity(irq, m, false);
-+ if (m)
-+ __irq_set_affinity(irq, m, false);
- return 0;
- }
- EXPORT_SYMBOL_GPL(irq_set_affinity_hint);
---
-2.3.1
-
diff --git a/kernel/kernel/files/patches/mageia/genirq-Set-initial-affinity-in-irq_set_affinity_hint.patch b/kernel/kernel/files/patches/mageia/genirq-Set-initial-affinity-in-irq_set_affinity_hint.patch
deleted file mode 100644
index ca1c7fa7..00000000
--- a/kernel/kernel/files/patches/mageia/genirq-Set-initial-affinity-in-irq_set_affinity_hint.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-From e2e64a932556cdfae455497dbe94a8db151fc9fa Mon Sep 17 00:00:00 2001
-From: Jesse Brandeburg
-Date: Thu, 18 Dec 2014 17:21:41 -0800
-Subject: [PATCH] genirq: Set initial affinity in irq_set_affinity_hint()
-
-Problem:
-The default behavior of the kernel is somewhat undesirable as all
-requested interrupts end up on CPU0 after registration. A user can
-run irqbalance daemon, or can manually configure smp_affinity via the
-proc filesystem, but the default affinity of the interrupts for all
-devices is always CPU zero, this can cause performance problems or
-very heavy cpu use of only one core if not noticed and fixed by the
-user.
-
-Solution:
-Enable the setting of the initial affinity directly when the driver
-sets a hint.
-
-This enabling means that kernel drivers can include an initial
-affinity setting for the interrupt, instead of all interrupts starting
-out life on CPU0. Of course if irqbalance is still running then the
-interrupts will get moved as before.
-
-This function is currently called by drivers in block, crypto,
-infiniband, ethernet and scsi trees, but only a handful, so these will
-be the devices affected by this change.
-
-Tested on i40e, and default interrupts were spread across the CPUs
-according to the hint.
-
-drivers/block/mtip32xx/mtip32xx.c:3
-drivers/block/nvme-core.c:2
-drivers/crypto/qat/qat_dh895xcc/adf_isr.c:3
-drivers/infiniband/hw/qib/qib_iba7322.c:2
-drivers/net/ethernet/intel/i40e/i40e_main.c:3
-drivers/net/ethernet/intel/i40evf/i40evf_main.c:3
-drivers/net/ethernet/intel/ixgbe/ixgbe_main.c:3
-drivers/net/ethernet/mellanox/mlx4/en_cq.c:2
-drivers/scsi/hpsa.c:3
-drivers/scsi/lpfc/lpfc_init.c:3
-drivers/scsi/megaraid/megaraid_sas_base.c:8
-drivers/soc/ti/knav_qmss_acc.c:1
-drivers/soc/ti/knav_qmss_queue.c:2
-drivers/virtio/virtio_pci_common.c:2
-
-Signed-off-by: Jesse Brandeburg
-Cc: netdev@vger.kernel.org
-Link: http://lkml.kernel.org/r/20141219012206.4220.27491.stgit@jbrandeb-cp2.jf.intel.com
-Signed-off-by: Thomas Gleixner
----
- kernel/irq/manage.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
-index 8069237..f038e58 100644
---- a/kernel/irq/manage.c
-+++ b/kernel/irq/manage.c
-@@ -243,6 +243,8 @@ int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m)
- return -EINVAL;
- desc->affinity_hint = m;
- irq_put_desc_unlock(desc, flags);
-+ /* set the initial affinity to prevent every interrupt being on CPU0 */
-+ __irq_set_affinity(irq, m, false);
- return 0;
- }
- EXPORT_SYMBOL_GPL(irq_set_affinity_hint);
---
-2.3.1
-
diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-i915-Enable-the-HiZ-RAW-Stall-Optimization-on-Broadwell.patch b/kernel/kernel/files/patches/mageia/gpu-drm-i915-Enable-the-HiZ-RAW-Stall-Optimization-on-Broadwell.patch
deleted file mode 100644
index ae55de1c..00000000
--- a/kernel/kernel/files/patches/mageia/gpu-drm-i915-Enable-the-HiZ-RAW-Stall-Optimization-on-Broadwell.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From 2701fc43562b55f5db0139ef6a7b13c2518ed6c0 Mon Sep 17 00:00:00 2001
-From: Kenneth Graunke
-Date: Tue, 13 Jan 2015 12:46:52 -0800
-Subject: drm/i915: Enable the HiZ RAW Stall Optimization on Broadwell.
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This is an important optimization for avoiding read-after-write (RAW)
-stalls in the HiZ buffer. Certain workloads would run very slowly with
-HiZ enabled, but run much faster with the "hiz=false" driconf option.
-With this patch, they run at full speed even with HiZ.
-
-Improves performance in OglVSInstancing by 3.2x on Broadwell GT3e
-(Iris Pro 6200).
-
-Thanks to Jesse Barnes and Ben Widawsky for their help in tracking this
-down. Thanks to Chris Wilson for showing me the new workarounds system.
-
-Signed-off-by: Kenneth Graunke
-Cc: Jesse Barnes
-Reviewed-by: Ville Syrjälä
-Signed-off-by: Daniel Vetter
-
-diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
-index dabc1d8..0df15a4 100644
---- a/drivers/gpu/drm/i915/intel_ringbuffer.c
-+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
-@@ -767,6 +767,16 @@ static int bdw_init_workarounds(struct i
- HDC_FORCE_NON_COHERENT |
- (IS_BDW_GT3(dev) ? HDC_FENCE_DEST_SLM_DISABLE : 0));
-
-+ /* From the Haswell PRM, Command Reference: Registers, CACHE_MODE_0:
-+ * "The Hierarchical Z RAW Stall Optimization allows non-overlapping
-+ * polygons in the same 8x4 pixel/sample area to be processed without
-+ * stalling waiting for the earlier ones to write to Hierarchical Z
-+ * buffer."
-+ *
-+ * This optimization is off by default for Broadwell; turn it on.
-+ */
-+ WA_CLR_BIT_MASKED(CACHE_MODE_0_GEN7, HIZ_RAW_STALL_OPT_DISABLE);
-+
- /* Wa4x4STCOptimizationDisable:bdw */
- WA_SET_BIT_MASKED(CACHE_MODE_1,
- GEN8_4x4_STC_OPTIMIZATION_DISABLE);
diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-i915-Ensure-the-HiZ-RAW-Stall-Optimization-is-on-for-Cherryview.patch b/kernel/kernel/files/patches/mageia/gpu-drm-i915-Ensure-the-HiZ-RAW-Stall-Optimization-is-on-for-Cherryview.patch
deleted file mode 100644
index 598cfe20..00000000
--- a/kernel/kernel/files/patches/mageia/gpu-drm-i915-Ensure-the-HiZ-RAW-Stall-Optimization-is-on-for-Cherryview.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 973a5b06a096f1a9494ebe94c78d809459f4dc74 Mon Sep 17 00:00:00 2001
-From: Kenneth Graunke
-Date: Tue, 13 Jan 2015 12:46:53 -0800
-Subject: drm/i915: Ensure the HiZ RAW Stall Optimization is on for Cherryview.
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This is an important optimization for avoiding read-after-write (RAW)
-stalls in the HiZ buffer. Certain workloads would run very slowly with
-HiZ enabled, but run much faster with the "hiz=false" driconf option.
-With this patch, they run at full speed even with HiZ.
-
-Increases performance in OglVSInstancing by about 2.7x on Braswell.
-
-Signed-off-by: Kenneth Graunke
-Reviewed-by: Ville Syrjälä
-Signed-off-by: Daniel Vetter
-
-diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
-index 0df15a4..23020d6 100644
---- a/drivers/gpu/drm/i915/intel_ringbuffer.c
-+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
-@@ -817,6 +817,11 @@ static int chv_init_workarounds(struct i
- HDC_FORCE_NON_COHERENT |
- HDC_DONOT_FETCH_MEM_WHEN_MASKED);
-
-+ /* According to the CACHE_MODE_0 default value documentation, some
-+ * CHV platforms disable this optimization by default. Turn it on.
-+ */
-+ WA_CLR_BIT_MASKED(CACHE_MODE_0_GEN7, HIZ_RAW_STALL_OPT_DISABLE);
-+
- /* Improve HiZ throughput on CHV. */
- WA_SET_BIT_MASKED(HIZ_CHICKEN, CHV_HZ_8X8_MODE_IN_1X);
-
diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-i915-Improve-HiZ-throughput-on-Cherryview.patch b/kernel/kernel/files/patches/mageia/gpu-drm-i915-Improve-HiZ-throughput-on-Cherryview.patch
deleted file mode 100644
index 83f98e45..00000000
--- a/kernel/kernel/files/patches/mageia/gpu-drm-i915-Improve-HiZ-throughput-on-Cherryview.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From d60de81da48aa25b06a015b839906243710e7253 Mon Sep 17 00:00:00 2001
-From: Kenneth Graunke
-Date: Sat, 10 Jan 2015 18:02:22 -0800
-Subject: drm/i915: Improve HiZ throughput on Cherryview.
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Found by reading the HIZ_CHICKEN documentation.
-
-Improves performance in a HiZ microbenchmark by around 50%.
-Improves performance in OglZBuffer by around 18%.
-
-Thanks to Chris Wilson for helping me figure out where to put this.
-
-Signed-off-by: Kenneth Graunke
-Reviewed-by: Ville Syrjälä
-Signed-off-by: Daniel Vetter
-
-diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
-index 0f32fd1a..a39bb03 100644
---- a/drivers/gpu/drm/i915/i915_reg.h
-+++ b/drivers/gpu/drm/i915/i915_reg.h
-@@ -5158,6 +5158,9 @@ enum punit_power_well {
- #define COMMON_SLICE_CHICKEN2 0x7014
- # define GEN8_CSC2_SBE_VUE_CACHE_CONSERVATIVE (1<<0)
-
-+#define HIZ_CHICKEN 0x7018
-+# define CHV_HZ_8X8_MODE_IN_1X (1<<15)
-+
- #define GEN7_L3SQCREG1 0xB010
- #define VLV_B0_WA_L3SQCREG1_VALUE 0x00D30000
-
-diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
-index 12a36f0..dabc1d8 100644
---- a/drivers/gpu/drm/i915/intel_ringbuffer.c
-+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
-@@ -807,6 +807,9 @@ static int chv_init_workarounds(struct i
- HDC_FORCE_NON_COHERENT |
- HDC_DONOT_FETCH_MEM_WHEN_MASKED);
-
-+ /* Improve HiZ throughput on CHV. */
-+ WA_SET_BIT_MASKED(HIZ_CHICKEN, CHV_HZ_8X8_MODE_IN_1X);
-+
- return 0;
- }
-
diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-i915-Make-sample_c-messages-go-faster-on-Haswell.patch b/kernel/kernel/files/patches/mageia/gpu-drm-i915-Make-sample_c-messages-go-faster-on-Haswell.patch
deleted file mode 100644
index 05f60a0b..00000000
--- a/kernel/kernel/files/patches/mageia/gpu-drm-i915-Make-sample_c-messages-go-faster-on-Haswell.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-From c44c70983107257f33f2b9d1c6a5aaf3d2eb670a Mon Sep 17 00:00:00 2001
-From: Kenneth Graunke
-Date: Wed, 31 Dec 2014 16:23:00 -0800
-Subject: drm/i915: Make sample_c messages go faster on Haswell.
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Haswell significantly improved the performance of sampler_c messages,
-but the optimization appears to be off by default. Later platforms
-remove this bit, and apparently always enable the optimization.
-
-Improves performance in "Counter Strike: Global Offensive" by 18%
-at default settings on Iris Pro.
-
-This may break sampling of paletted formats (P8/A8P8/P8A8). It's
-unclear whether it affects sampling of paletted formats in general,
-or just the sample_c message (which is never used).
-
-While libva does have support for using paletted formats (primarily
-for OSDs), that support appears to have been broken for at least a
-year, so I couldn't observe a regression from this:
-
-I tried to get libva-intel to use paletted formats, and observe a
-regression...but the only thing I found that used it was mplayer's OSD
-(on screen display). Even without my patch, the colors were totally
-wrong with that, and it's according to a few distro wikis, that's been
-the case for over a year.
-
-If libva's code for paletted formats /is/ broken, they could always
-add code to disable this bit using the command validator when fixing
-it.
-
-Signed-off-by: Kenneth Graunke
-[danvet: Add wa name from Ville's review to the comment and copypaste
-the explanation why we don't care about libva (already broken) from
-Ken.]
-Reviewed-by: Ville Syrjälä
-Signed-off-by: Daniel Vetter
-
-diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
-index 1fdda42..0cb0067 100644
---- a/drivers/gpu/drm/i915/i915_reg.h
-+++ b/drivers/gpu/drm/i915/i915_reg.h
-@@ -6119,6 +6119,7 @@ enum punit_power_well {
- #define HSW_ROW_CHICKEN3_L3_GLOBAL_ATOMICS_DISABLE (1 << 6)
-
- #define HALF_SLICE_CHICKEN3 0xe184
-+#define HSW_SAMPLE_C_PERFORMANCE (1<<9)
- #define GEN8_CENTROID_PIXEL_OPT_DIS (1<<8)
- #define GEN8_SAMPLER_POWER_BYPASS_DIS (1<<1)
-
-diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
-index 4254e91..0918604 100644
---- a/drivers/gpu/drm/i915/intel_pm.c
-+++ b/drivers/gpu/drm/i915/intel_pm.c
-@@ -6710,6 +6710,10 @@ static void haswell_init_clock_gating(st
- I915_WRITE(GEN7_GT_MODE,
- _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4));
-
-+ /* WaSampleCChickenBitEnable:hsw */
-+ I915_WRITE(HALF_SLICE_CHICKEN3,
-+ _MASKED_BIT_ENABLE(HSW_SAMPLE_C_PERFORMANCE));
-+
- /* WaSwitchSolVfFArbitrationPriority:hsw */
- I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL);
-
---
-cgit v0.10.2
diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-i915-fix-vlv-crash.patch b/kernel/kernel/files/patches/mageia/gpu-drm-i915-fix-vlv-crash.patch
deleted file mode 100644
index 2d5c684f..00000000
--- a/kernel/kernel/files/patches/mageia/gpu-drm-i915-fix-vlv-crash.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-
-Revert back to legacy turbo for vlv, fixes random crashes.
-
-Reported by Timothée Giet on dev@ ml.
-
-https://bugs.freedesktop.org/show_bug.cgi?id=88012#c33
-
-
---- linux/drivers/gpu/drm/i915/i915_irq.c.orig
-+++ linux/drivers/gpu/drm/i915/i915_irq.c
-@@ -4361,12 +4361,7 @@ void intel_irq_init(struct drm_i915_priv
- INIT_WORK(&dev_priv->rps.work, gen6_pm_rps_work);
- INIT_WORK(&dev_priv->l3_parity.error_work, ivybridge_parity_work);
-
-- /* Let's track the enabled rps events */
-- if (IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv))
-- /* WaGsvRC0ResidencyMethod:vlv */
-- dev_priv->pm_rps_events = GEN6_PM_RP_UP_EI_EXPIRED;
-- else
-- dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS;
-+ dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS;
-
- setup_timer(&dev_priv->gpu_error.hangcheck_timer,
- i915_hangcheck_elapsed,
diff --git a/kernel/kernel/files/patches/mageia/iommu-vt-d-Remove-unused-variable.patch b/kernel/kernel/files/patches/mageia/iommu-vt-d-Remove-unused-variable.patch
deleted file mode 100644
index d6826897..00000000
--- a/kernel/kernel/files/patches/mageia/iommu-vt-d-Remove-unused-variable.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 509fca899d5682a6eee3d1fb70bba7c89439034b Mon Sep 17 00:00:00 2001
-From: Alex Williamson
-Date: Mon, 23 Mar 2015 19:49:56 -0600
-Subject: [PATCH] iommu/vt-d: Remove unused variable
-
-Unused after commit 71684406905f ("iommu/vt-d: Detach domain *only*
-from attached iommus"). Reported by 0-day builder.
-
-Signed-off-by: Alex Williamson
-Signed-off-by: Joerg Roedel
----
- drivers/iommu/intel-iommu.c | 1 -
- 1 file changed, 1 deletion(-)
-
-diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
-index a83c965..2d1e05b 100644
---- a/drivers/iommu/intel-iommu.c
-+++ b/drivers/iommu/intel-iommu.c
-@@ -1742,7 +1742,6 @@ static int domain_init(struct dmar_domain *domain, int guest_width)
-
- static void domain_exit(struct dmar_domain *domain)
- {
-- struct dmar_drhd_unit *drhd;
- struct page *freelist = NULL;
- int i;
-
---
-2.3.1
-
diff --git a/kernel/kernel/files/patches/mageia/md-raid5-dont-record-new-size-if-resize_stripes-fails.patch b/kernel/kernel/files/patches/mageia/md-raid5-dont-record-new-size-if-resize_stripes-fails.patch
deleted file mode 100644
index 0e1c1439..00000000
--- a/kernel/kernel/files/patches/mageia/md-raid5-dont-record-new-size-if-resize_stripes-fails.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From: NeilBrown
-Subject: [PATCH 5/7] md/raid5: don't record new size if resize_stripes fails.
-Date: Fri, 08 May 2015 18:56:11 +1000
-
-If any memory allocation in resize_stripes fails we will return
--ENOMEM, but in some cases we update conf->pool_size anyway.
-
-This means that if we try again, the allocations will be assumed
-to be larger than they are, and badness results.
-
-So only update pool_size if there is no error.
-
-This bug was introduced in 2.6.17 and the patch is suitable for
--stable.
-
-Fixes: ad01c9e3752f ("[PATCH] md: Allow stripes to be expanded in preparation for expanding an array")
-Cc: stable@vger.kernel.org (v2.6.17+)
-Signed-off-by: NeilBrown
----
- drivers/md/raid5.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
-index 85dc0e67fb88..9748e525e4c0 100644
---- a/drivers/md/raid5.c
-+++ b/drivers/md/raid5.c
-@@ -2216,7 +2216,8 @@ static int resize_stripes(struct r5conf *conf, int newsize)
-
- conf->slab_cache = sc;
- conf->active_name = 1-conf->active_name;
-- conf->pool_size = newsize;
-+ if (!err)
-+ conf->pool_size = newsize;
- return err;
- }
-
diff --git a/kernel/kernel/files/patches/mageia/media-Fix-regression-in-some-more-dib0700-based-devi.patch b/kernel/kernel/files/patches/mageia/media-Fix-regression-in-some-more-dib0700-based-devi.patch
new file mode 100644
index 00000000..590b2258
--- /dev/null
+++ b/kernel/kernel/files/patches/mageia/media-Fix-regression-in-some-more-dib0700-based-devi.patch
@@ -0,0 +1,53 @@
+From: Thomas Reitmayr
+Date: Fri, 1 May 2015 20:18:04 -0300
+Subject: [PATCH] media: Fix regression in some more dib0700 based devices
+
+Fix an oops during device initialization by correctly setting size_of_priv
+instead of leaving it 0.
+The regression was introduced by 8abe4a0a3f6d4217b16a ("[media] dib7000:
+export just one symbol") and only fixed for one type of dib0700 based
+devices in 9e334c75642b6e5bfb95 ("[media] Fix regression in some dib0700
+based devices").
+
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=92301
+
+Fixes: 8abe4a0a3f6d4217b16a ("[media] dib7000: export just one symbol")
+
+Cc: stable@vger.kernel.org # for version 3.17+
+Signed-off-by: Thomas Reitmayr
+Signed-off-by: Mauro Carvalho Chehab
+---
+ drivers/media/usb/dvb-usb/dib0700_devices.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c
+index d7d55a20e959..c170523226aa 100644
+--- a/drivers/media/usb/dvb-usb/dib0700_devices.c
++++ b/drivers/media/usb/dvb-usb/dib0700_devices.c
+@@ -3944,6 +3944,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
+
+ DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+ }},
++ .size_of_priv = sizeof(struct
++ dib0700_adapter_state),
+ }, {
+ .num_frontends = 1,
+ .fe = {{
+@@ -3956,6 +3958,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
+
+ DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
+ }},
++ .size_of_priv = sizeof(struct
++ dib0700_adapter_state),
+ }
+ },
+
+@@ -4009,6 +4013,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
+
+ DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+ }},
++ .size_of_priv = sizeof(struct
++ dib0700_adapter_state),
+ },
+ },
+
diff --git a/kernel/kernel/files/patches/mageia/mm-vmscan-wake-up-all-pfmemalloc-throttled-processes.patch b/kernel/kernel/files/patches/mageia/mm-vmscan-wake-up-all-pfmemalloc-throttled-processes.patch
deleted file mode 100644
index 5c3ffae1..00000000
--- a/kernel/kernel/files/patches/mageia/mm-vmscan-wake-up-all-pfmemalloc-throttled-processes.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From cfc511557945812280699a92f171ddd2d254aca6 Mon Sep 17 00:00:00 2001
-From: Vlastimil Babka
-Date: Wed, 11 Feb 2015 15:24:47 -0800
-Subject: [PATCH] mm, vmscan: wake up all pfmemalloc-throttled processes at
- once
-
-Kswapd in balance_pgdate() currently uses wake_up() on processes waiting
-in throttle_direct_reclaim(), which only wakes up a single process. This
-might leave processes waiting for longer than necessary, until the check
-is reached in the next loop iteration. Processes might also be left
-waiting if zone was fully balanced in single iteration. Note that the
-comment in balance_pgdat() also says "Wake them", so waking up a single
-process does not seem intentional.
-
-Thus, replace wake_up() with wake_up_all().
-
-Signed-off-by: Vlastimil Babka
-Cc: Mel Gorman
-Cc: Johannes Weiner
-Cc: Michal Hocko
-Cc: Vladimir Davydov
-Acked-by: Rik van Riel
-Signed-off-by: Andrew Morton
-Signed-off-by: Linus Torvalds
----
- mm/vmscan.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/mm/vmscan.c b/mm/vmscan.c
-index dcd90c8..f756a20 100644
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -3175,7 +3175,7 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order,
- */
- if (waitqueue_active(&pgdat->pfmemalloc_wait) &&
- pfmemalloc_watermark_ok(pgdat))
-- wake_up(&pgdat->pfmemalloc_wait);
-+ wake_up_all(&pgdat->pfmemalloc_wait);
-
- /*
- * Fragmentation may mean that the system cannot be rebalanced
---
-2.3.1
-
diff --git a/kernel/kernel/files/patches/mageia/mm-writeback-use-1-instead-of-1-to-protect-against-div-.patch b/kernel/kernel/files/patches/mageia/mm-writeback-use-1-instead-of-1-to-protect-against-div-.patch
deleted file mode 100644
index e54d0773..00000000
--- a/kernel/kernel/files/patches/mageia/mm-writeback-use-1-instead-of-1-to-protect-against-div-.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From 464d1387acb94dc43ba772b35242345e3d2ead1b Mon Sep 17 00:00:00 2001
-From: Tejun Heo