diff --git a/kernel/kernel/files/configs/kernel-6.6-x86_64-config b/kernel/kernel/files/configs/kernel-6.6-x86_64-config new file mode 100644 index 00000000..c9598576 --- /dev/null +++ b/kernel/kernel/files/configs/kernel-6.6-x86_64-config @@ -0,0 +1,11674 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/x86_64 6.6.92 Kernel Configuration +# +CONFIG_CC_VERSION_TEXT="gcc (Pisi Linux) 13.3.0" +CONFIG_CC_IS_GCC=y +CONFIG_GCC_VERSION=130300 +CONFIG_CLANG_VERSION=0 +CONFIG_AS_IS_GNU=y +CONFIG_AS_VERSION=24200 +CONFIG_LD_IS_BFD=y +CONFIG_LD_VERSION=24200 +CONFIG_LLD_VERSION=0 +CONFIG_RUST_IS_AVAILABLE=y +CONFIG_CC_CAN_LINK=y +CONFIG_CC_CAN_LINK_STATIC=y +CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y +CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT=y +CONFIG_TOOLS_SUPPORT_RELR=y +CONFIG_CC_HAS_ASM_INLINE=y +CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y +CONFIG_PAHOLE_VERSION=0 +CONFIG_IRQ_WORK=y +CONFIG_BUILDTIME_TABLE_SORT=y +CONFIG_THREAD_INFO_IN_TASK=y + +# +# General setup +# +CONFIG_INIT_ENV_ARG_LIMIT=32 +# CONFIG_COMPILE_TEST is not set +# CONFIG_WERROR is not set +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_BUILD_SALT="" +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_XZ=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_HAVE_KERNEL_LZ4=y +CONFIG_HAVE_KERNEL_ZSTD=y +# CONFIG_KERNEL_GZIP is not set +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_XZ is not set +# CONFIG_KERNEL_LZO is not set +# CONFIG_KERNEL_LZ4 is not set +CONFIG_KERNEL_ZSTD=y +CONFIG_DEFAULT_INIT="" +CONFIG_DEFAULT_HOSTNAME="" +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +CONFIG_WATCH_QUEUE=y +CONFIG_CROSS_MEMORY_ATTACH=y +# CONFIG_USELIB is not set +CONFIG_AUDIT=y +CONFIG_HAVE_ARCH_AUDITSYSCALL=y +CONFIG_AUDITSYSCALL=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_GENERIC_PENDING_IRQ=y +CONFIG_GENERIC_IRQ_MIGRATION=y +CONFIG_GENERIC_IRQ_INJECTION=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_CHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_SIM=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_GENERIC_MSI_IRQ=y +CONFIG_IRQ_MSI_IOMMU=y +CONFIG_GENERIC_IRQ_MATRIX_ALLOCATOR=y +CONFIG_GENERIC_IRQ_RESERVATION_MODE=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_SPARSE_IRQ=y +# CONFIG_GENERIC_IRQ_DEBUGFS is not set +# end of IRQ subsystem + +CONFIG_CLOCKSOURCE_WATCHDOG=y +CONFIG_ARCH_CLOCKSOURCE_INIT=y +CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_HAVE_POSIX_CPU_TIMERS_TASK_WORK=y +CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y +CONFIG_CONTEXT_TRACKING=y +CONFIG_CONTEXT_TRACKING_IDLE=y + +# +# Timers subsystem +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ_COMMON=y +# CONFIG_HZ_PERIODIC is not set +# CONFIG_NO_HZ_IDLE is not set +CONFIG_NO_HZ_FULL=y +CONFIG_CONTEXT_TRACKING_USER=y +# CONFIG_CONTEXT_TRACKING_USER_FORCE is not set +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_CLOCKSOURCE_WATCHDOG_MAX_SKEW_US=100 +# end of Timers subsystem + +CONFIG_BPF=y +CONFIG_HAVE_EBPF_JIT=y +CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y + +# +# BPF subsystem +# +CONFIG_BPF_SYSCALL=y +CONFIG_BPF_JIT=y +CONFIG_BPF_JIT_ALWAYS_ON=y +CONFIG_BPF_JIT_DEFAULT_ON=y +CONFIG_BPF_UNPRIV_DEFAULT_OFF=y +# CONFIG_BPF_PRELOAD is not set +CONFIG_BPF_LSM=y +# end of BPF subsystem + +CONFIG_PREEMPT_BUILD=y +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_COUNT=y +CONFIG_PREEMPTION=y +CONFIG_PREEMPT_DYNAMIC=y +CONFIG_SCHED_CORE=y + +# +# CPU/Task time and stats accounting +# +CONFIG_VIRT_CPU_ACCOUNTING=y +CONFIG_VIRT_CPU_ACCOUNTING_GEN=y +# CONFIG_IRQ_TIME_ACCOUNTING is not set +CONFIG_HAVE_SCHED_AVG_IRQ=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_PSI=y +# CONFIG_PSI_DEFAULT_DISABLED is not set +# end of CPU/Task time and stats accounting + +CONFIG_CPU_ISOLATION=y + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +CONFIG_PREEMPT_RCU=y +CONFIG_RCU_EXPERT=y +CONFIG_TREE_SRCU=y +CONFIG_TASKS_RCU_GENERIC=y +# CONFIG_FORCE_TASKS_RCU is not set +CONFIG_TASKS_RCU=y +# CONFIG_FORCE_TASKS_RUDE_RCU is not set +CONFIG_TASKS_RUDE_RCU=y +# CONFIG_FORCE_TASKS_TRACE_RCU is not set +CONFIG_TASKS_TRACE_RCU=y +CONFIG_RCU_STALL_COMMON=y +CONFIG_RCU_NEED_SEGCBLIST=y +CONFIG_RCU_FANOUT=64 +CONFIG_RCU_FANOUT_LEAF=16 +CONFIG_RCU_BOOST=y +CONFIG_RCU_BOOST_DELAY=97 +CONFIG_RCU_EXP_KTHREAD=y +CONFIG_RCU_NOCB_CPU=y +# CONFIG_RCU_NOCB_CPU_DEFAULT_ALL is not set +CONFIG_RCU_NOCB_CPU_CB_BOOST=y +# CONFIG_TASKS_TRACE_RCU_READ_MB is not set +# CONFIG_RCU_LAZY is not set +CONFIG_RCU_DOUBLE_CHECK_CB_TIME=y +# end of RCU Subsystem + +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_IKHEADERS=m +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 +# CONFIG_PRINTK_INDEX is not set +CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y + +# +# Scheduler features +# +CONFIG_UCLAMP_TASK=y +CONFIG_UCLAMP_BUCKETS_COUNT=5 +# end of Scheduler features + +CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y +CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH=y +CONFIG_CC_HAS_INT128=y +CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" +CONFIG_GCC10_NO_ARRAY_BOUNDS=y +CONFIG_CC_NO_ARRAY_BOUNDS=y +CONFIG_ARCH_SUPPORTS_INT128=y +# CONFIG_NUMA_BALANCING is not set +CONFIG_CGROUPS=y +CONFIG_PAGE_COUNTER=y +# CONFIG_CGROUP_FAVOR_DYNMODS is not set +CONFIG_MEMCG=y +CONFIG_MEMCG_KMEM=y +CONFIG_BLK_CGROUP=y +CONFIG_CGROUP_WRITEBACK=y +CONFIG_CGROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_CFS_BANDWIDTH=y +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_SCHED_MM_CID=y +CONFIG_UCLAMP_TASK_GROUP=y +CONFIG_CGROUP_PIDS=y +CONFIG_CGROUP_RDMA=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_HUGETLB=y +CONFIG_CPUSETS=y +CONFIG_PROC_PID_CPUSET=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_PERF=y +CONFIG_CGROUP_BPF=y +CONFIG_CGROUP_MISC=y +# CONFIG_CGROUP_DEBUG is not set +CONFIG_SOCK_CGROUP_DATA=y +CONFIG_NAMESPACES=y +CONFIG_UTS_NS=y +CONFIG_TIME_NS=y +CONFIG_IPC_NS=y +CONFIG_USER_NS=y +CONFIG_PID_NS=y +CONFIG_NET_NS=y +CONFIG_CHECKPOINT_RESTORE=y +CONFIG_SCHED_AUTOGROUP=y +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +CONFIG_RD_BZIP2=y +CONFIG_RD_LZMA=y +CONFIG_RD_XZ=y +CONFIG_RD_LZO=y +CONFIG_RD_LZ4=y +CONFIG_RD_ZSTD=y +CONFIG_BOOT_CONFIG=y +# CONFIG_BOOT_CONFIG_FORCE is not set +# CONFIG_BOOT_CONFIG_EMBED is not set +CONFIG_INITRAMFS_PRESERVE_MTIME=y +CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_LD_ORPHAN_WARN=y +CONFIG_LD_ORPHAN_WARN_LEVEL="warn" +CONFIG_SYSCTL=y +CONFIG_HAVE_UID16=y +CONFIG_SYSCTL_EXCEPTION_TRACE=y +CONFIG_HAVE_PCSPKR_PLATFORM=y +CONFIG_EXPERT=y +CONFIG_UID16=y +CONFIG_MULTIUSER=y +CONFIG_SGETMASK_SYSCALL=y +# CONFIG_SYSFS_SYSCALL is not set +CONFIG_FHANDLE=y +CONFIG_POSIX_TIMERS=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_PCSPKR_PLATFORM=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_FUTEX_PI=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_IO_URING=y +CONFIG_ADVISE_SYSCALLS=y +CONFIG_MEMBARRIER=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_SELFTEST is not set +CONFIG_KALLSYMS_ALL=y +CONFIG_KALLSYMS_ABSOLUTE_PERCPU=y +CONFIG_KALLSYMS_BASE_RELATIVE=y +CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y +CONFIG_KCMP=y +CONFIG_RSEQ=y +CONFIG_CACHESTAT_SYSCALL=y +# CONFIG_DEBUG_RSEQ is not set +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_GUEST_PERF_EVENTS=y +# CONFIG_PC104 is not set + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +# end of Kernel Performance Events And Counters + +CONFIG_SYSTEM_DATA_VERIFICATION=y +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y + +# +# Kexec and crash features +# +CONFIG_CRASH_CORE=y +CONFIG_KEXEC_CORE=y +CONFIG_KEXEC=y +# CONFIG_KEXEC_FILE is not set +CONFIG_KEXEC_JUMP=y +CONFIG_CRASH_DUMP=y +CONFIG_CRASH_HOTPLUG=y +CONFIG_CRASH_MAX_MEMORY_RANGES=8192 +# end of Kexec and crash features +# end of General setup + +CONFIG_64BIT=y +CONFIG_X86_64=y +CONFIG_X86=y +CONFIG_INSTRUCTION_DECODER=y +CONFIG_OUTPUT_FORMAT="elf64-x86-64" +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_MMU=y +CONFIG_ARCH_MMAP_RND_BITS_MIN=28 +CONFIG_ARCH_MMAP_RND_BITS_MAX=32 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16 +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ARCH_HAS_CPU_RELAX=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_AUDIT_ARCH=y +CONFIG_HAVE_INTEL_TXT=y +CONFIG_X86_64_SMP=y +CONFIG_ARCH_SUPPORTS_UPROBES=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_DYNAMIC_PHYSICAL_MASK=y +CONFIG_PGTABLE_LEVELS=4 +CONFIG_CC_HAS_SANE_STACKPROTECTOR=y + +# +# Processor type and features +# +CONFIG_SMP=y +CONFIG_X86_X2APIC=y +CONFIG_X86_MPPARSE=y +# CONFIG_GOLDFISH is not set +CONFIG_X86_CPU_RESCTRL=y +CONFIG_X86_EXTENDED_PLATFORM=y +# CONFIG_X86_NUMACHIP is not set +# CONFIG_X86_VSMP is not set +# CONFIG_X86_UV is not set +# CONFIG_X86_GOLDFISH is not set +# CONFIG_X86_INTEL_MID is not set +CONFIG_X86_INTEL_LPSS=y +CONFIG_X86_AMD_PLATFORM_DEVICE=y +CONFIG_IOSF_MBI=y +# CONFIG_IOSF_MBI_DEBUG is not set +CONFIG_X86_SUPPORTS_MEMORY_FAILURE=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y +CONFIG_HYPERVISOR_GUEST=y +CONFIG_PARAVIRT=y +CONFIG_PARAVIRT_XXL=y +# CONFIG_PARAVIRT_DEBUG is not set +CONFIG_PARAVIRT_SPINLOCKS=y +CONFIG_X86_HV_CALLBACK_VECTOR=y +CONFIG_XEN=y +CONFIG_XEN_PV=y +CONFIG_XEN_512GB=y +CONFIG_XEN_PV_SMP=y +CONFIG_XEN_PV_DOM0=y +CONFIG_XEN_PVHVM=y +CONFIG_XEN_PVHVM_SMP=y +CONFIG_XEN_PVHVM_GUEST=y +CONFIG_XEN_SAVE_RESTORE=y +CONFIG_XEN_DEBUG_FS=y +CONFIG_XEN_PVH=y +CONFIG_XEN_DOM0=y +CONFIG_XEN_PV_MSR_SAFE=y +CONFIG_KVM_GUEST=y +CONFIG_ARCH_CPUIDLE_HALTPOLL=y +CONFIG_PVH=y +CONFIG_PARAVIRT_TIME_ACCOUNTING=y +CONFIG_PARAVIRT_CLOCK=y +# CONFIG_JAILHOUSE_GUEST is not set +CONFIG_ACRN_GUEST=y +CONFIG_INTEL_TDX_GUEST=y +# CONFIG_MK8 is not set +# CONFIG_MPSC is not set +# CONFIG_MCORE2 is not set +# CONFIG_MATOM is not set +CONFIG_GENERIC_CPU=y +CONFIG_X86_INTERNODE_CACHE_SHIFT=6 +CONFIG_X86_L1_CACHE_SHIFT=6 +CONFIG_X86_TSC=y +CONFIG_X86_CMPXCHG64=y +CONFIG_X86_CMOV=y +CONFIG_X86_MINIMUM_CPU_FAMILY=64 +CONFIG_X86_DEBUGCTLMSR=y +CONFIG_IA32_FEAT_CTL=y +CONFIG_X86_VMX_FEATURE_NAMES=y +# CONFIG_PROCESSOR_SELECT is not set +CONFIG_CPU_SUP_INTEL=y +CONFIG_CPU_SUP_AMD=y +CONFIG_CPU_SUP_HYGON=y +CONFIG_CPU_SUP_CENTAUR=y +CONFIG_CPU_SUP_ZHAOXIN=y +CONFIG_HPET_TIMER=y +CONFIG_HPET_EMULATE_RTC=y +CONFIG_DMI=y +CONFIG_GART_IOMMU=y +CONFIG_BOOT_VESA_SUPPORT=y +# CONFIG_MAXSMP is not set +CONFIG_NR_CPUS_RANGE_BEGIN=2 +CONFIG_NR_CPUS_RANGE_END=512 +CONFIG_NR_CPUS_DEFAULT=64 +CONFIG_NR_CPUS=512 +CONFIG_SCHED_CLUSTER=y +CONFIG_SCHED_SMT=y +CONFIG_SCHED_MC=y +CONFIG_SCHED_MC_PRIO=y +CONFIG_X86_LOCAL_APIC=y +CONFIG_X86_IO_APIC=y +CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y +CONFIG_X86_MCE=y +# CONFIG_X86_MCELOG_LEGACY is not set +CONFIG_X86_MCE_INTEL=y +CONFIG_X86_MCE_AMD=y +CONFIG_X86_MCE_THRESHOLD=y +CONFIG_X86_MCE_INJECT=m + +# +# Performance monitoring +# +CONFIG_PERF_EVENTS_INTEL_UNCORE=m +CONFIG_PERF_EVENTS_INTEL_RAPL=m +CONFIG_PERF_EVENTS_INTEL_CSTATE=m +CONFIG_PERF_EVENTS_AMD_POWER=m +CONFIG_PERF_EVENTS_AMD_UNCORE=m +CONFIG_PERF_EVENTS_AMD_BRS=y +# end of Performance monitoring + +CONFIG_X86_16BIT=y +CONFIG_X86_ESPFIX64=y +CONFIG_X86_VSYSCALL_EMULATION=y +CONFIG_X86_IOPL_IOPERM=y +CONFIG_MICROCODE=y +# CONFIG_MICROCODE_LATE_LOADING is not set +CONFIG_X86_MSR=m +CONFIG_X86_CPUID=m +# CONFIG_X86_5LEVEL is not set +CONFIG_X86_DIRECT_GBPAGES=y +# CONFIG_X86_CPA_STATISTICS is not set +CONFIG_X86_MEM_ENCRYPT=y +# CONFIG_AMD_MEM_ENCRYPT is not set +CONFIG_NUMA=y +CONFIG_AMD_NUMA=y +CONFIG_X86_64_ACPI_NUMA=y +# CONFIG_NUMA_EMU is not set +CONFIG_NODES_SHIFT=6 +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_ARCH_MEMORY_PROBE=y +CONFIG_ARCH_PROC_KCORE_TEXT=y +CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 +# CONFIG_X86_PMEM_LEGACY is not set +CONFIG_X86_CHECK_BIOS_CORRUPTION=y +# CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK is not set +CONFIG_MTRR=y +CONFIG_MTRR_SANITIZER=y +CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=0 +CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1 +CONFIG_X86_PAT=y +CONFIG_ARCH_USES_PG_UNCACHED=y +CONFIG_X86_UMIP=y +CONFIG_CC_HAS_IBT=y +# CONFIG_X86_KERNEL_IBT is not set +CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS=y +# CONFIG_X86_INTEL_TSX_MODE_OFF is not set +# CONFIG_X86_INTEL_TSX_MODE_ON is not set +CONFIG_X86_INTEL_TSX_MODE_AUTO=y +# CONFIG_X86_SGX is not set +# CONFIG_X86_USER_SHADOW_STACK is not set +CONFIG_EFI=y +CONFIG_EFI_STUB=y +CONFIG_EFI_HANDOVER_PROTOCOL=y +CONFIG_EFI_MIXED=y +# CONFIG_EFI_FAKE_MEMMAP is not set +CONFIG_EFI_RUNTIME_MAP=y +# CONFIG_HZ_100 is not set +# CONFIG_HZ_250 is not set +# CONFIG_HZ_300 is not set +CONFIG_HZ_1000=y +CONFIG_HZ=1000 +CONFIG_SCHED_HRTICK=y +CONFIG_ARCH_SUPPORTS_KEXEC=y +CONFIG_ARCH_SUPPORTS_KEXEC_FILE=y +CONFIG_ARCH_SUPPORTS_KEXEC_PURGATORY=y +CONFIG_ARCH_SUPPORTS_KEXEC_SIG=y +CONFIG_ARCH_SUPPORTS_KEXEC_SIG_FORCE=y +CONFIG_ARCH_SUPPORTS_KEXEC_BZIMAGE_VERIFY_SIG=y +CONFIG_ARCH_SUPPORTS_KEXEC_JUMP=y +CONFIG_ARCH_SUPPORTS_CRASH_DUMP=y +CONFIG_ARCH_SUPPORTS_CRASH_HOTPLUG=y +CONFIG_PHYSICAL_START=0x200000 +CONFIG_RELOCATABLE=y +CONFIG_RANDOMIZE_BASE=y +CONFIG_X86_NEED_RELOCS=y +CONFIG_PHYSICAL_ALIGN=0x1000000 +CONFIG_DYNAMIC_MEMORY_LAYOUT=y +CONFIG_RANDOMIZE_MEMORY=y +CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING=0xa +CONFIG_HOTPLUG_CPU=y +# CONFIG_COMPAT_VDSO is not set +CONFIG_LEGACY_VSYSCALL_XONLY=y +# CONFIG_LEGACY_VSYSCALL_NONE is not set +# CONFIG_CMDLINE_BOOL is not set +CONFIG_MODIFY_LDT_SYSCALL=y +# CONFIG_STRICT_SIGALTSTACK_SIZE is not set +CONFIG_HAVE_LIVEPATCH=y +CONFIG_LIVEPATCH=y +# end of Processor type and features + +CONFIG_CC_HAS_SLS=y +CONFIG_CC_HAS_RETURN_THUNK=y +CONFIG_CC_HAS_ENTRY_PADDING=y +CONFIG_FUNCTION_PADDING_CFI=11 +CONFIG_FUNCTION_PADDING_BYTES=16 +CONFIG_CALL_PADDING=y +CONFIG_HAVE_CALL_THUNKS=y +CONFIG_CALL_THUNKS=y +CONFIG_PREFIX_SYMBOLS=y +CONFIG_CPU_MITIGATIONS=y +CONFIG_PAGE_TABLE_ISOLATION=y +CONFIG_RETPOLINE=y +CONFIG_RETHUNK=y +CONFIG_CPU_UNRET_ENTRY=y +CONFIG_CALL_DEPTH_TRACKING=y +# CONFIG_CALL_THUNKS_DEBUG is not set +CONFIG_CPU_IBPB_ENTRY=y +CONFIG_CPU_IBRS_ENTRY=y +CONFIG_CPU_SRSO=y +# CONFIG_SLS is not set +# CONFIG_GDS_FORCE_MITIGATION is not set +CONFIG_MITIGATION_RFDS=y +CONFIG_MITIGATION_ITS=y +CONFIG_MITIGATION_SPECTRE_BHI=y +CONFIG_ARCH_HAS_ADD_PAGES=y + +# +# Power management and ACPI options +# +CONFIG_ARCH_HIBERNATION_HEADER=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_SUSPEND_SKIP_SYNC is not set +CONFIG_HIBERNATE_CALLBACKS=y +CONFIG_HIBERNATION=y +CONFIG_HIBERNATION_SNAPSHOT_DEV=y +CONFIG_PM_STD_PARTITION="" +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +# CONFIG_PM_AUTOSLEEP is not set +# CONFIG_PM_USERSPACE_AUTOSLEEP is not set +CONFIG_PM_WAKELOCKS=y +CONFIG_PM_WAKELOCKS_LIMIT=100 +CONFIG_PM_WAKELOCKS_GC=y +CONFIG_PM=y +CONFIG_PM_DEBUG=y +# CONFIG_PM_ADVANCED_DEBUG is not set +# CONFIG_PM_TEST_SUSPEND is not set +CONFIG_PM_SLEEP_DEBUG=y +# CONFIG_DPM_WATCHDOG is not set +CONFIG_PM_TRACE=y +CONFIG_PM_TRACE_RTC=y +CONFIG_PM_CLK=y +CONFIG_PM_GENERIC_DOMAINS=y +# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set +CONFIG_PM_GENERIC_DOMAINS_SLEEP=y +CONFIG_ENERGY_MODEL=y +CONFIG_ARCH_SUPPORTS_ACPI=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_DEBUGGER is not set +CONFIG_ACPI_SPCR_TABLE=y +CONFIG_ACPI_FPDT=y +CONFIG_ACPI_LPIT=y +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_REV_OVERRIDE_POSSIBLE=y +# CONFIG_ACPI_EC_DEBUGFS is not set +CONFIG_ACPI_AC=y +CONFIG_ACPI_BATTERY=y +CONFIG_ACPI_BUTTON=y +CONFIG_ACPI_VIDEO=m +CONFIG_ACPI_FAN=y +CONFIG_ACPI_TAD=m +CONFIG_ACPI_DOCK=y +CONFIG_ACPI_CPU_FREQ_PSS=y +CONFIG_ACPI_PROCESSOR_CSTATE=y +CONFIG_ACPI_PROCESSOR_IDLE=y +CONFIG_ACPI_CPPC_LIB=y +CONFIG_ACPI_PROCESSOR=y +CONFIG_ACPI_IPMI=m +CONFIG_ACPI_HOTPLUG_CPU=y +CONFIG_ACPI_PROCESSOR_AGGREGATOR=m +CONFIG_ACPI_THERMAL=y +CONFIG_ACPI_PLATFORM_PROFILE=m +CONFIG_ACPI_CUSTOM_DSDT_FILE="" +CONFIG_ARCH_HAS_ACPI_TABLE_UPGRADE=y +CONFIG_ACPI_TABLE_UPGRADE=y +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_PCI_SLOT=y +CONFIG_ACPI_CONTAINER=y +CONFIG_ACPI_HOTPLUG_MEMORY=y +CONFIG_ACPI_HOTPLUG_IOAPIC=y +CONFIG_ACPI_SBS=m +CONFIG_ACPI_HED=y +# CONFIG_ACPI_CUSTOM_METHOD is not set +CONFIG_ACPI_BGRT=y +# CONFIG_ACPI_REDUCED_HARDWARE_ONLY is not set +CONFIG_ACPI_NFIT=m +# CONFIG_NFIT_SECURITY_DEBUG is not set +CONFIG_ACPI_NUMA=y +CONFIG_ACPI_HMAT=y +CONFIG_HAVE_ACPI_APEI=y +CONFIG_HAVE_ACPI_APEI_NMI=y +CONFIG_ACPI_APEI=y +CONFIG_ACPI_APEI_GHES=y +CONFIG_ACPI_APEI_PCIEAER=y +CONFIG_ACPI_APEI_MEMORY_FAILURE=y +CONFIG_ACPI_APEI_EINJ=m +# CONFIG_ACPI_APEI_ERST_DEBUG is not set +CONFIG_ACPI_DPTF=y +CONFIG_DPTF_POWER=m +CONFIG_DPTF_PCH_FIVR=m +CONFIG_ACPI_WATCHDOG=y +CONFIG_ACPI_EXTLOG=m +CONFIG_ACPI_ADXL=y +CONFIG_ACPI_CONFIGFS=m +CONFIG_ACPI_PFRUT=m +CONFIG_ACPI_PCC=y +CONFIG_ACPI_FFH=y +CONFIG_PMIC_OPREGION=y +CONFIG_BYTCRC_PMIC_OPREGION=y +CONFIG_CHTCRC_PMIC_OPREGION=y +CONFIG_XPOWER_PMIC_OPREGION=y +CONFIG_BXT_WC_PMIC_OPREGION=y +CONFIG_CHT_WC_PMIC_OPREGION=y +CONFIG_CHT_DC_TI_PMIC_OPREGION=y +CONFIG_TPS68470_PMIC_OPREGION=y +CONFIG_ACPI_VIOT=y +CONFIG_ACPI_PRMT=y +CONFIG_X86_PM_TIMER=y + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_GOV_ATTR_SET=y +CONFIG_CPU_FREQ_GOV_COMMON=y +# CONFIG_CPU_FREQ_STAT is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y + +# +# CPU frequency scaling drivers +# +CONFIG_X86_INTEL_PSTATE=y +CONFIG_X86_PCC_CPUFREQ=m +CONFIG_X86_AMD_PSTATE=y +CONFIG_X86_AMD_PSTATE_DEFAULT_MODE=3 +CONFIG_X86_AMD_PSTATE_UT=m +CONFIG_X86_ACPI_CPUFREQ=m +CONFIG_X86_ACPI_CPUFREQ_CPB=y +CONFIG_X86_POWERNOW_K8=m +CONFIG_X86_AMD_FREQ_SENSITIVITY=m +CONFIG_X86_SPEEDSTEP_CENTRINO=m +CONFIG_X86_P4_CLOCKMOD=m + +# +# shared options +# +CONFIG_X86_SPEEDSTEP_LIB=m +# end of CPU Frequency scaling + +# +# CPU Idle +# +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y +CONFIG_CPU_IDLE_GOV_TEO=y +CONFIG_CPU_IDLE_GOV_HALTPOLL=y +CONFIG_HALTPOLL_CPUIDLE=m +# end of CPU Idle + +CONFIG_INTEL_IDLE=y +# end of Power management and ACPI options + +# +# Bus options (PCI etc.) +# +CONFIG_PCI_DIRECT=y +CONFIG_PCI_MMCONFIG=y +CONFIG_PCI_XEN=y +CONFIG_MMCONF_FAM10H=y +# CONFIG_PCI_CNB20LE_QUIRK is not set +CONFIG_ISA_BUS=y +CONFIG_ISA_DMA_API=y +CONFIG_AMD_NB=y +# end of Bus options (PCI etc.) + +# +# Binary Emulations +# +CONFIG_IA32_EMULATION=y +CONFIG_X86_X32_ABI=y +CONFIG_COMPAT_32=y +CONFIG_COMPAT=y +CONFIG_COMPAT_FOR_U64_ALIGNMENT=y +# end of Binary Emulations + +CONFIG_HAVE_KVM=y +CONFIG_HAVE_KVM_PFNCACHE=y +CONFIG_HAVE_KVM_IRQCHIP=y +CONFIG_HAVE_KVM_IRQFD=y +CONFIG_HAVE_KVM_IRQ_ROUTING=y +CONFIG_HAVE_KVM_DIRTY_RING=y +CONFIG_HAVE_KVM_DIRTY_RING_TSO=y +CONFIG_HAVE_KVM_DIRTY_RING_ACQ_REL=y +CONFIG_HAVE_KVM_EVENTFD=y +CONFIG_KVM_MMIO=y +CONFIG_KVM_ASYNC_PF=y +CONFIG_HAVE_KVM_MSI=y +CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT=y +CONFIG_KVM_VFIO=y +CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT=y +CONFIG_KVM_COMPAT=y +CONFIG_HAVE_KVM_IRQ_BYPASS=y +CONFIG_HAVE_KVM_NO_POLL=y +CONFIG_KVM_XFER_TO_GUEST_WORK=y +CONFIG_HAVE_KVM_PM_NOTIFIER=y +CONFIG_KVM_GENERIC_HARDWARE_ENABLING=y +CONFIG_VIRTUALIZATION=y +CONFIG_KVM=m +CONFIG_KVM_WERROR=y +CONFIG_KVM_INTEL=m +CONFIG_KVM_AMD=m +CONFIG_KVM_AMD_SEV=y +CONFIG_KVM_SMM=y +CONFIG_KVM_XEN=y +CONFIG_KVM_PROVE_MMU=y +CONFIG_KVM_EXTERNAL_WRITE_TRACKING=y +CONFIG_AS_AVX512=y +CONFIG_AS_SHA1_NI=y +CONFIG_AS_SHA256_NI=y +CONFIG_AS_TPAUSE=y +CONFIG_AS_GFNI=y +CONFIG_AS_WRUSS=y +CONFIG_ARCH_CONFIGURES_CPU_MITIGATIONS=y + +# +# General architecture-dependent options +# +CONFIG_HOTPLUG_SMT=y +CONFIG_HOTPLUG_CORE_SYNC=y +CONFIG_HOTPLUG_CORE_SYNC_DEAD=y +CONFIG_HOTPLUG_CORE_SYNC_FULL=y +CONFIG_HOTPLUG_SPLIT_STARTUP=y +CONFIG_HOTPLUG_PARALLEL=y +CONFIG_GENERIC_ENTRY=y +CONFIG_KPROBES=y +CONFIG_JUMP_LABEL=y +# CONFIG_STATIC_KEYS_SELFTEST is not set +# CONFIG_STATIC_CALL_SELFTEST is not set +CONFIG_OPTPROBES=y +CONFIG_KPROBES_ON_FTRACE=y +CONFIG_UPROBES=y +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_ARCH_USE_BUILTIN_BSWAP=y +CONFIG_KRETPROBES=y +CONFIG_KRETPROBE_ON_RETHOOK=y +CONFIG_USER_RETURN_NOTIFIER=y +CONFIG_HAVE_IOREMAP_PROT=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_OPTPROBES=y +CONFIG_HAVE_KPROBES_ON_FTRACE=y +CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y +CONFIG_HAVE_FUNCTION_ERROR_INJECTION=y +CONFIG_HAVE_NMI=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_ARCH_HAS_FORTIFY_SOURCE=y +CONFIG_ARCH_HAS_SET_MEMORY=y +CONFIG_ARCH_HAS_SET_DIRECT_MAP=y +CONFIG_ARCH_HAS_CPU_FINALIZE_INIT=y +CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y +CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT=y +CONFIG_ARCH_WANTS_NO_INSTR=y +CONFIG_HAVE_ASM_MODVERSIONS=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_RSEQ=y +CONFIG_HAVE_RUST=y +CONFIG_HAVE_FUNCTION_ARG_ACCESS_API=y +CONFIG_HAVE_HW_BREAKPOINT=y +CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y +CONFIG_HAVE_USER_RETURN_NOTIFIER=y +CONFIG_HAVE_PERF_EVENTS_NMI=y +CONFIG_HAVE_HARDLOCKUP_DETECTOR_PERF=y +CONFIG_HAVE_PERF_REGS=y +CONFIG_HAVE_PERF_USER_STACK_DUMP=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE=y +CONFIG_MMU_GATHER_TABLE_FREE=y +CONFIG_MMU_GATHER_RCU_TABLE_FREE=y +CONFIG_MMU_GATHER_MERGE_VMAS=y +CONFIG_MMU_LAZY_TLB_REFCOUNT=y +CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y +CONFIG_ARCH_HAS_NMI_SAFE_THIS_CPU_OPS=y +CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y +CONFIG_HAVE_CMPXCHG_LOCAL=y +CONFIG_HAVE_CMPXCHG_DOUBLE=y +CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y +CONFIG_ARCH_WANT_OLD_COMPAT_IPC=y +CONFIG_HAVE_ARCH_SECCOMP=y +CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_SECCOMP=y +CONFIG_SECCOMP_FILTER=y +# CONFIG_SECCOMP_CACHE_DEBUG is not set +CONFIG_HAVE_ARCH_STACKLEAK=y +CONFIG_HAVE_STACKPROTECTOR=y +CONFIG_STACKPROTECTOR=y +CONFIG_STACKPROTECTOR_STRONG=y +CONFIG_ARCH_SUPPORTS_LTO_CLANG=y +CONFIG_ARCH_SUPPORTS_LTO_CLANG_THIN=y +CONFIG_LTO_NONE=y +CONFIG_ARCH_SUPPORTS_CFI_CLANG=y +CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES=y +CONFIG_HAVE_CONTEXT_TRACKING_USER=y +CONFIG_HAVE_CONTEXT_TRACKING_USER_OFFSTACK=y +CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y +CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_MOVE_PUD=y +CONFIG_HAVE_MOVE_PMD=y +CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y +CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD=y +CONFIG_HAVE_ARCH_HUGE_VMAP=y +CONFIG_HAVE_ARCH_HUGE_VMALLOC=y +CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y +CONFIG_ARCH_WANT_PMD_MKWRITE=y +CONFIG_HAVE_ARCH_SOFT_DIRTY=y +CONFIG_HAVE_MOD_ARCH_SPECIFIC=y +CONFIG_MODULES_USE_ELF_RELA=y +CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y +CONFIG_HAVE_SOFTIRQ_ON_OWN_STACK=y +CONFIG_SOFTIRQ_ON_OWN_STACK=y +CONFIG_ARCH_HAS_ELF_RANDOMIZE=y +CONFIG_HAVE_ARCH_MMAP_RND_BITS=y +CONFIG_HAVE_EXIT_THREAD=y +CONFIG_ARCH_MMAP_RND_BITS=28 +CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS=y +CONFIG_ARCH_MMAP_RND_COMPAT_BITS=8 +CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES=y +CONFIG_PAGE_SIZE_LESS_THAN_64KB=y +CONFIG_PAGE_SIZE_LESS_THAN_256KB=y +CONFIG_HAVE_OBJTOOL=y +CONFIG_HAVE_JUMP_LABEL_HACK=y +CONFIG_HAVE_NOINSTR_HACK=y +CONFIG_HAVE_NOINSTR_VALIDATION=y +CONFIG_HAVE_UACCESS_VALIDATION=y +CONFIG_HAVE_STACK_VALIDATION=y +CONFIG_HAVE_RELIABLE_STACKTRACE=y +CONFIG_ISA_BUS_API=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_COMPAT_OLD_SIGACTION=y +CONFIG_COMPAT_32BIT_TIME=y +CONFIG_HAVE_ARCH_VMAP_STACK=y +CONFIG_VMAP_STACK=y +CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET=y +CONFIG_RANDOMIZE_KSTACK_OFFSET=y +CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT=y +CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y +CONFIG_STRICT_KERNEL_RWX=y +CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y +CONFIG_STRICT_MODULE_RWX=y +CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y +CONFIG_ARCH_USE_MEMREMAP_PROT=y +# CONFIG_LOCK_EVENT_COUNTS is not set +CONFIG_ARCH_HAS_MEM_ENCRYPT=y +CONFIG_ARCH_HAS_CC_PLATFORM=y +CONFIG_HAVE_STATIC_CALL=y +CONFIG_HAVE_STATIC_CALL_INLINE=y +CONFIG_HAVE_PREEMPT_DYNAMIC=y +CONFIG_HAVE_PREEMPT_DYNAMIC_CALL=y +CONFIG_ARCH_WANT_LD_ORPHAN_WARN=y +CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y +CONFIG_ARCH_SUPPORTS_PAGE_TABLE_CHECK=y +CONFIG_ARCH_HAS_ELFCORE_COMPAT=y +CONFIG_ARCH_HAS_PARANOID_L1D_FLUSH=y +CONFIG_DYNAMIC_SIGFRAME=y +CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y +# end of GCOV-based kernel profiling + +CONFIG_HAVE_GCC_PLUGINS=y +CONFIG_GCC_PLUGINS=y +# CONFIG_GCC_PLUGIN_LATENT_ENTROPY is not set +CONFIG_FUNCTION_ALIGNMENT_4B=y +CONFIG_FUNCTION_ALIGNMENT_16B=y +CONFIG_FUNCTION_ALIGNMENT=16 +# end of General architecture-dependent options + +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_DEBUG is not set +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MODULE_UNLOAD_TAINT_TRACKING is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_MODULE_SIG is not set +CONFIG_MODULE_COMPRESS_NONE=y +# CONFIG_MODULE_COMPRESS_GZIP is not set +# CONFIG_MODULE_COMPRESS_XZ is not set +# CONFIG_MODULE_COMPRESS_ZSTD is not set +# CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS is not set +CONFIG_MODPROBE_PATH="/sbin/modprobe" +# CONFIG_TRIM_UNUSED_KSYMS is not set +CONFIG_MODULES_TREE_LOOKUP=y +CONFIG_BLOCK=y +CONFIG_BLOCK_LEGACY_AUTOLOAD=y +CONFIG_BLK_RQ_ALLOC_TIME=y +CONFIG_BLK_CGROUP_RWSTAT=y +CONFIG_BLK_CGROUP_PUNT_BIO=y +CONFIG_BLK_DEV_BSG_COMMON=y +CONFIG_BLK_ICQ=y +CONFIG_BLK_DEV_BSGLIB=y +CONFIG_BLK_DEV_INTEGRITY=y +CONFIG_BLK_DEV_INTEGRITY_T10=y +CONFIG_BLK_DEV_ZONED=y +CONFIG_BLK_DEV_THROTTLING=y +CONFIG_BLK_DEV_THROTTLING_LOW=y +# CONFIG_BLK_WBT is not set +CONFIG_BLK_CGROUP_IOLATENCY=y +CONFIG_BLK_CGROUP_FC_APPID=y +CONFIG_BLK_CGROUP_IOCOST=y +CONFIG_BLK_CGROUP_IOPRIO=y +CONFIG_BLK_DEBUG_FS=y +CONFIG_BLK_DEBUG_FS_ZONED=y +CONFIG_BLK_SED_OPAL=y +CONFIG_BLK_INLINE_ENCRYPTION=y +CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_AIX_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_LDM_PARTITION=y +# CONFIG_LDM_DEBUG is not set +CONFIG_SGI_PARTITION=y +# CONFIG_ULTRIX_PARTITION is not set +CONFIG_SUN_PARTITION=y +CONFIG_KARMA_PARTITION=y +CONFIG_EFI_PARTITION=y +CONFIG_SYSV68_PARTITION=y +CONFIG_CMDLINE_PARTITION=y +# end of Partition Types + +CONFIG_BLK_MQ_PCI=y +CONFIG_BLK_MQ_VIRTIO=y +CONFIG_BLK_PM=y +CONFIG_BLOCK_HOLDER_DEPRECATED=y +CONFIG_BLK_MQ_STACKING=y + +# +# IO Schedulers +# +CONFIG_MQ_IOSCHED_DEADLINE=y +CONFIG_MQ_IOSCHED_KYBER=y +CONFIG_IOSCHED_BFQ=y +CONFIG_BFQ_GROUP_IOSCHED=y +# CONFIG_BFQ_CGROUP_DEBUG is not set +# end of IO Schedulers + +CONFIG_PREEMPT_NOTIFIERS=y +CONFIG_PADATA=y +CONFIG_ASN1=y +CONFIG_UNINLINE_SPIN_UNLOCK=y +CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_RWSEM_SPIN_ON_OWNER=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y +CONFIG_QUEUED_SPINLOCKS=y +CONFIG_ARCH_USE_QUEUED_RWLOCKS=y +CONFIG_QUEUED_RWLOCKS=y +CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE=y +CONFIG_ARCH_HAS_SYNC_CORE_BEFORE_USERMODE=y +CONFIG_ARCH_HAS_SYSCALL_WRAPPER=y +CONFIG_FREEZER=y + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +CONFIG_COMPAT_BINFMT_ELF=y +CONFIG_ELFCORE=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_BINFMT_SCRIPT=y +CONFIG_BINFMT_MISC=m +CONFIG_COREDUMP=y +# end of Executable file formats + +# +# Memory Management options +# +CONFIG_ZPOOL=y +CONFIG_SWAP=y +CONFIG_ZSWAP=y +# CONFIG_ZSWAP_DEFAULT_ON is not set +# CONFIG_ZSWAP_EXCLUSIVE_LOADS_DEFAULT_ON is not set +# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_DEFLATE is not set +CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZO=y +# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_842 is not set +# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4 is not set +# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4HC is not set +# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_ZSTD is not set +CONFIG_ZSWAP_COMPRESSOR_DEFAULT="lzo" +CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y +# CONFIG_ZSWAP_ZPOOL_DEFAULT_Z3FOLD_DEPRECATED is not set +# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set +CONFIG_ZSWAP_ZPOOL_DEFAULT="zbud" +CONFIG_ZBUD=y +CONFIG_Z3FOLD_DEPRECATED=y +CONFIG_Z3FOLD=y +CONFIG_ZSMALLOC=y +CONFIG_ZSMALLOC_STAT=y +CONFIG_ZSMALLOC_CHAIN_SIZE=8 + +# +# SLAB allocator options +# +# CONFIG_SLAB_DEPRECATED is not set +CONFIG_SLUB=y +# CONFIG_SLUB_TINY is not set +# CONFIG_SLAB_MERGE_DEFAULT is not set +CONFIG_SLAB_FREELIST_RANDOM=y +# CONFIG_SLAB_FREELIST_HARDENED is not set +# CONFIG_SLUB_STATS is not set +CONFIG_SLUB_CPU_PARTIAL=y +# CONFIG_RANDOM_KMALLOC_CACHES is not set +# end of SLAB allocator options + +CONFIG_SHUFFLE_PAGE_ALLOCATOR=y +# CONFIG_COMPAT_BRK is not set +CONFIG_SPARSEMEM=y +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +CONFIG_SPARSEMEM_VMEMMAP=y +CONFIG_ARCH_WANT_OPTIMIZE_DAX_VMEMMAP=y +CONFIG_ARCH_WANT_OPTIMIZE_HUGETLB_VMEMMAP=y +CONFIG_HAVE_FAST_GUP=y +CONFIG_NUMA_KEEP_MEMINFO=y +CONFIG_MEMORY_ISOLATION=y +CONFIG_EXCLUSIVE_SYSTEM_RAM=y +CONFIG_HAVE_BOOTMEM_INFO_NODE=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_MEMORY_HOTPLUG=y +# CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE is not set +CONFIG_MEMORY_HOTREMOVE=y +CONFIG_MHP_MEMMAP_ON_MEMORY=y +CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y +CONFIG_MEMORY_BALLOON=y +CONFIG_BALLOON_COMPACTION=y +CONFIG_COMPACTION=y +CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 +CONFIG_PAGE_REPORTING=y +CONFIG_MIGRATION=y +CONFIG_DEVICE_MIGRATION=y +CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION=y +CONFIG_ARCH_ENABLE_THP_MIGRATION=y +CONFIG_CONTIG_ALLOC=y +CONFIG_PCP_BATCH_SCALE_MAX=5 +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_MMU_NOTIFIER=y +CONFIG_KSM=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=65536 +CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y +CONFIG_MEMORY_FAILURE=y +CONFIG_HWPOISON_INJECT=m +CONFIG_ARCH_WANT_GENERAL_HUGETLB=y +CONFIG_ARCH_WANTS_THP_SWAP=y +CONFIG_TRANSPARENT_HUGEPAGE=y +# CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS is not set +CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y +CONFIG_THP_SWAP=y +# CONFIG_READ_ONLY_THP_FOR_FS is not set +CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y +CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y +CONFIG_USE_PERCPU_NUMA_NODE_ID=y +CONFIG_HAVE_SETUP_PER_CPU_AREA=y +CONFIG_CMA=y +# CONFIG_CMA_DEBUG is not set +# CONFIG_CMA_DEBUGFS is not set +# CONFIG_CMA_SYSFS is not set +CONFIG_CMA_AREAS=7 +CONFIG_MEM_SOFT_DIRTY=y +CONFIG_GENERIC_EARLY_IOREMAP=y +# CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set +# CONFIG_IDLE_PAGE_TRACKING is not set +CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y +CONFIG_ARCH_HAS_CURRENT_STACK_POINTER=y +CONFIG_ARCH_HAS_PTE_DEVMAP=y +CONFIG_ARCH_HAS_ZONE_DMA_SET=y +CONFIG_ZONE_DMA=y +CONFIG_ZONE_DMA32=y +CONFIG_ZONE_DEVICE=y +CONFIG_HMM_MIRROR=y +CONFIG_GET_FREE_REGION=y +CONFIG_DEVICE_PRIVATE=y +CONFIG_VMAP_PFN=y +CONFIG_ARCH_USES_HIGH_VMA_FLAGS=y +CONFIG_ARCH_HAS_PKEYS=y +CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_PERCPU_STATS is not set +# CONFIG_GUP_TEST is not set +# CONFIG_DMAPOOL_TEST is not set +CONFIG_ARCH_HAS_PTE_SPECIAL=y +CONFIG_MAPPING_DIRTY_HELPERS=y +CONFIG_MEMFD_CREATE=y +CONFIG_SECRETMEM=y +CONFIG_ANON_VMA_NAME=y +CONFIG_USERFAULTFD=y +CONFIG_HAVE_ARCH_USERFAULTFD_WP=y +CONFIG_HAVE_ARCH_USERFAULTFD_MINOR=y +CONFIG_PTE_MARKER_UFFD_WP=y +CONFIG_LRU_GEN=y +CONFIG_LRU_GEN_ENABLED=y +# CONFIG_LRU_GEN_STATS is not set +CONFIG_ARCH_SUPPORTS_PER_VMA_LOCK=y +CONFIG_PER_VMA_LOCK=y +CONFIG_LOCK_MM_AND_FIND_VMA=y + +# +# Data Access Monitoring +# +# CONFIG_DAMON is not set +# end of Data Access Monitoring +# end of Memory Management options + +CONFIG_NET=y +CONFIG_WANT_COMPAT_NETLINK_MESSAGES=y +CONFIG_COMPAT_NETLINK_MESSAGES=y +CONFIG_NET_INGRESS=y +CONFIG_NET_EGRESS=y +CONFIG_NET_XGRESS=y +CONFIG_NET_REDIRECT=y +CONFIG_SKB_EXTENSIONS=y + +# +# Networking options +# +CONFIG_PACKET=m +CONFIG_PACKET_DIAG=m +CONFIG_UNIX=y +CONFIG_UNIX_SCM=y +CONFIG_AF_UNIX_OOB=y +CONFIG_UNIX_DIAG=m +CONFIG_TLS=m +CONFIG_TLS_DEVICE=y +# CONFIG_TLS_TOE is not set +CONFIG_XFRM=y +CONFIG_XFRM_OFFLOAD=y +CONFIG_XFRM_ALGO=m +CONFIG_XFRM_USER=m +CONFIG_XFRM_USER_COMPAT=m +CONFIG_XFRM_INTERFACE=m +CONFIG_XFRM_SUB_POLICY=y +CONFIG_XFRM_MIGRATE=y +# CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_AH=m +CONFIG_XFRM_ESP=m +CONFIG_XFRM_IPCOMP=m +CONFIG_NET_KEY=m +CONFIG_NET_KEY_MIGRATE=y +CONFIG_XFRM_ESPINTCP=y +CONFIG_SMC=m +CONFIG_SMC_DIAG=m +CONFIG_XDP_SOCKETS=y +CONFIG_XDP_SOCKETS_DIAG=m +CONFIG_NET_HANDSHAKE=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +# CONFIG_IP_FIB_TRIE_STATS is not set +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_ROUTE_CLASSID=y +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m +CONFIG_NET_IP_TUNNEL=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE_COMMON=y +CONFIG_IP_MROUTE=y +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_SYN_COOKIES=y +CONFIG_NET_IPVTI=m +CONFIG_NET_UDP_TUNNEL=m +CONFIG_NET_FOU=m +CONFIG_NET_FOU_IP_TUNNELS=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_ESP_OFFLOAD=m +CONFIG_INET_ESPINTCP=y +CONFIG_INET_IPCOMP=m +CONFIG_INET_TABLE_PERTURB_ORDER=16 +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +CONFIG_INET_UDP_DIAG=m +CONFIG_INET_RAW_DIAG=m +CONFIG_INET_DIAG_DESTROY=y +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_NV=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_CONG_ILLINOIS=m +CONFIG_TCP_CONG_DCTCP=m +CONFIG_TCP_CONG_CDG=m +CONFIG_TCP_CONG_BBR=m +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_TCP_MD5SIG=y +CONFIG_IPV6=m +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_ESP_OFFLOAD=m +CONFIG_INET6_ESPINTCP=y +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=m +CONFIG_IPV6_ILA=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_IPV6_VTI=m +CONFIG_IPV6_SIT=m +# CONFIG_IPV6_SIT_6RD is not set +CONFIG_IPV6_NDISC_NODETYPE=y +CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_GRE=m +CONFIG_IPV6_FOU=m +CONFIG_IPV6_FOU_TUNNEL=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_MROUTE=y +CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y +CONFIG_IPV6_PIMSM_V2=y +# CONFIG_IPV6_SEG6_LWTUNNEL is not set +# CONFIG_IPV6_SEG6_HMAC is not set +# CONFIG_IPV6_RPL_LWTUNNEL is not set +# CONFIG_IPV6_IOAM6_LWTUNNEL is not set +CONFIG_NETLABEL=y +# CONFIG_MPTCP is not set +CONFIG_NETWORK_SECMARK=y +CONFIG_NET_PTP_CLASSIFY=y +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +CONFIG_NETFILTER=y +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=m + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_INGRESS=y +CONFIG_NETFILTER_EGRESS=y +CONFIG_NETFILTER_SKIP_EGRESS=y +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_FAMILY_BRIDGE=y +CONFIG_NETFILTER_FAMILY_ARP=y +CONFIG_NETFILTER_BPF_LINK=y +# CONFIG_NETFILTER_NETLINK_HOOK is not set +CONFIG_NETFILTER_NETLINK_ACCT=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NETFILTER_NETLINK_OSF=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_LOG_SYSLOG=m +CONFIG_NETFILTER_CONNCOUNT=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_ZONES=y +CONFIG_NF_CONNTRACK_PROCFS=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_TIMEOUT=y +CONFIG_NF_CONNTRACK_TIMESTAMP=y +CONFIG_NF_CONNTRACK_LABELS=y +CONFIG_NF_CONNTRACK_OVS=y +CONFIG_NF_CT_PROTO_DCCP=y +CONFIG_NF_CT_PROTO_GRE=y +CONFIG_NF_CT_PROTO_SCTP=y +CONFIG_NF_CT_PROTO_UDPLITE=y +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_BROADCAST=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_NETLINK_TIMEOUT=m +CONFIG_NF_CT_NETLINK_HELPER=m +CONFIG_NETFILTER_NETLINK_GLUE_CT=y +CONFIG_NF_NAT=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NF_NAT_REDIRECT=y +CONFIG_NF_NAT_MASQUERADE=y +CONFIG_NF_NAT_OVS=y +CONFIG_NETFILTER_SYNPROXY=m +CONFIG_NF_TABLES=m +CONFIG_NF_TABLES_INET=y +CONFIG_NF_TABLES_NETDEV=y +CONFIG_NFT_NUMGEN=m +CONFIG_NFT_CT=m +CONFIG_NFT_FLOW_OFFLOAD=m +CONFIG_NFT_CONNLIMIT=m +CONFIG_NFT_LOG=m +CONFIG_NFT_LIMIT=m +CONFIG_NFT_MASQ=m +CONFIG_NFT_REDIR=m +CONFIG_NFT_NAT=m +CONFIG_NFT_TUNNEL=m +CONFIG_NFT_QUEUE=m +CONFIG_NFT_QUOTA=m +CONFIG_NFT_REJECT=m +CONFIG_NFT_REJECT_INET=m +CONFIG_NFT_COMPAT=m +CONFIG_NFT_HASH=m +CONFIG_NFT_FIB=m +CONFIG_NFT_FIB_INET=m +CONFIG_NFT_XFRM=m +CONFIG_NFT_SOCKET=m +CONFIG_NFT_OSF=m +CONFIG_NFT_TPROXY=m +CONFIG_NFT_SYNPROXY=m +CONFIG_NF_DUP_NETDEV=m +CONFIG_NFT_DUP_NETDEV=m +CONFIG_NFT_FWD_NETDEV=m +CONFIG_NFT_FIB_NETDEV=m +CONFIG_NFT_REJECT_NETDEV=m +CONFIG_NF_FLOW_TABLE_INET=m +CONFIG_NF_FLOW_TABLE=m +CONFIG_NF_FLOW_TABLE_PROCFS=y +CONFIG_NETFILTER_XTABLES=m +# CONFIG_NETFILTER_XTABLES_COMPAT is not set + +# +# Xtables combined modules +# +CONFIG_NETFILTER_XT_MARK=m +CONFIG_NETFILTER_XT_CONNMARK=m +CONFIG_NETFILTER_XT_SET=m + +# +# Xtables targets +# +CONFIG_NETFILTER_XT_TARGET_AUDIT=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_CT=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HL=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LED=m +CONFIG_NETFILTER_XT_TARGET_LOG=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_NAT=m +CONFIG_NETFILTER_XT_TARGET_NETMAP=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +CONFIG_NETFILTER_XT_TARGET_REDIRECT=m +CONFIG_NETFILTER_XT_TARGET_MASQUERADE=m +CONFIG_NETFILTER_XT_TARGET_TEE=m +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m + +# +# Xtables matches +# +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_BPF=m +CONFIG_NETFILTER_XT_MATCH_CGROUP=m +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_CPU=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ECN=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_HL=m +CONFIG_NETFILTER_XT_MATCH_IPCOMP=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_NETFILTER_XT_MATCH_L2TP=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_SOCKET=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +# end of Core Netfilter Configuration + +CONFIG_IP_SET=m +CONFIG_IP_SET_MAX=256 +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPMARK=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_IPMAC=m +CONFIG_IP_SET_HASH_MAC=m +CONFIG_IP_SET_HASH_NETPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETNET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m +CONFIG_IP_VS=m +CONFIG_IP_VS_IPV6=y +CONFIG_IP_VS_DEBUG=y +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS transport protocol load balancing support +# +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_AH_ESP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_SCTP=y + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_FO=m +CONFIG_IP_VS_OVF=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_MH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m +CONFIG_IP_VS_TWOS=m + +# +# IPVS SH scheduler +# +CONFIG_IP_VS_SH_TAB_BITS=8 + +# +# IPVS MH scheduler +# +CONFIG_IP_VS_MH_TAB_INDEX=12 + +# +# IPVS application helper +# +CONFIG_IP_VS_FTP=m +CONFIG_IP_VS_NFCT=y +CONFIG_IP_VS_PE_SIP=m + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_SOCKET_IPV4=m +CONFIG_NF_TPROXY_IPV4=m +CONFIG_NF_TABLES_IPV4=y +CONFIG_NFT_REJECT_IPV4=m +CONFIG_NFT_DUP_IPV4=m +CONFIG_NFT_FIB_IPV4=m +CONFIG_NF_TABLES_ARP=y +CONFIG_NF_DUP_IPV4=m +CONFIG_NF_LOG_ARP=m +CONFIG_NF_LOG_IPV4=m +CONFIG_NF_REJECT_IPV4=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_H323=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_SYNPROXY=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_SECURITY=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m +# end of IP: Netfilter Configuration + +# +# IPv6: Netfilter Configuration +# +CONFIG_NF_SOCKET_IPV6=m +CONFIG_NF_TPROXY_IPV6=m +CONFIG_NF_TABLES_IPV6=y +CONFIG_NFT_REJECT_IPV6=m +CONFIG_NFT_DUP_IPV6=m +CONFIG_NFT_FIB_IPV6=m +CONFIG_NF_DUP_IPV6=m +CONFIG_NF_REJECT_IPV6=m +CONFIG_NF_LOG_IPV6=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_SRH=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_TARGET_SYNPROXY=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_SECURITY=m +CONFIG_IP6_NF_NAT=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m +# end of IPv6: Netfilter Configuration + +CONFIG_NF_DEFRAG_IPV6=m +CONFIG_NF_TABLES_BRIDGE=m +CONFIG_NFT_BRIDGE_META=m +CONFIG_NFT_BRIDGE_REJECT=m +CONFIG_NF_CONNTRACK_BRIDGE=m +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_IP6=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_NFLOG=m +# CONFIG_BPFILTER is not set +CONFIG_IP_DCCP=m +CONFIG_INET_DCCP_DIAG=m + +# +# DCCP CCIDs Configuration +# +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=y +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_TFRC_LIB=y +# end of DCCP CCIDs Configuration + +# +# DCCP Kernel Hacking +# +# CONFIG_IP_DCCP_DEBUG is not set +# end of DCCP Kernel Hacking + +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_OBJCNT is not set +CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5=y +# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1 is not set +# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set +CONFIG_SCTP_COOKIE_HMAC_MD5=y +CONFIG_SCTP_COOKIE_HMAC_SHA1=y +CONFIG_INET_SCTP_DIAG=m +CONFIG_RDS=m +CONFIG_RDS_RDMA=m +CONFIG_RDS_TCP=m +# CONFIG_RDS_DEBUG is not set +CONFIG_TIPC=m +CONFIG_TIPC_MEDIA_IB=y +CONFIG_TIPC_MEDIA_UDP=y +CONFIG_TIPC_CRYPTO=y +CONFIG_TIPC_DIAG=m +CONFIG_ATM=m +CONFIG_ATM_CLIP=m +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_BR2684=m +CONFIG_ATM_BR2684_IPFILTER=y +CONFIG_L2TP=m +CONFIG_L2TP_DEBUGFS=m +# CONFIG_L2TP_V3 is not set +CONFIG_STP=m +CONFIG_GARP=m +CONFIG_MRP=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_IGMP_SNOOPING=y +CONFIG_BRIDGE_VLAN_FILTERING=y +# CONFIG_BRIDGE_MRP is not set +# CONFIG_BRIDGE_CFM is not set +CONFIG_NET_DSA=m +CONFIG_NET_DSA_TAG_NONE=m +CONFIG_NET_DSA_TAG_AR9331=m +CONFIG_NET_DSA_TAG_BRCM_COMMON=m +CONFIG_NET_DSA_TAG_BRCM=m +CONFIG_NET_DSA_TAG_BRCM_LEGACY=m +CONFIG_NET_DSA_TAG_BRCM_PREPEND=m +CONFIG_NET_DSA_TAG_HELLCREEK=m +CONFIG_NET_DSA_TAG_GSWIP=m +CONFIG_NET_DSA_TAG_DSA_COMMON=m +CONFIG_NET_DSA_TAG_DSA=m +CONFIG_NET_DSA_TAG_EDSA=m +CONFIG_NET_DSA_TAG_MTK=m +CONFIG_NET_DSA_TAG_KSZ=m +CONFIG_NET_DSA_TAG_OCELOT=m +CONFIG_NET_DSA_TAG_OCELOT_8021Q=m +CONFIG_NET_DSA_TAG_QCA=m +CONFIG_NET_DSA_TAG_RTL4_A=m +CONFIG_NET_DSA_TAG_RTL8_4=m +CONFIG_NET_DSA_TAG_RZN1_A5PSW=m +CONFIG_NET_DSA_TAG_LAN9303=m +CONFIG_NET_DSA_TAG_SJA1105=m +CONFIG_NET_DSA_TAG_TRAILER=m +CONFIG_NET_DSA_TAG_XRS700X=m +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +CONFIG_VLAN_8021Q_MVRP=y +CONFIG_LLC=m +CONFIG_LLC2=m +CONFIG_ATALK=m +CONFIG_DEV_APPLETALK=m +CONFIG_IPDDP=m +CONFIG_IPDDP_ENCAP=y +CONFIG_X25=m +CONFIG_LAPB=m +CONFIG_PHONET=m +CONFIG_6LOWPAN=m +# CONFIG_6LOWPAN_DEBUGFS is not set +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_6LOWPAN_GHC_EXT_HDR_HOP=m +CONFIG_6LOWPAN_GHC_UDP=m +CONFIG_6LOWPAN_GHC_ICMPV6=m +CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m +CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m +CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m +CONFIG_IEEE802154=m +CONFIG_IEEE802154_NL802154_EXPERIMENTAL=y +CONFIG_IEEE802154_SOCKET=m +CONFIG_IEEE802154_6LOWPAN=m +CONFIG_MAC802154=m +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFB=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_CBS=m +CONFIG_NET_SCH_ETF=m +CONFIG_NET_SCH_MQPRIO_LIB=m +CONFIG_NET_SCH_TAPRIO=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_DRR=m +CONFIG_NET_SCH_MQPRIO=m +CONFIG_NET_SCH_SKBPRIO=m +CONFIG_NET_SCH_CHOKE=m +CONFIG_NET_SCH_QFQ=m +CONFIG_NET_SCH_CODEL=m +CONFIG_NET_SCH_FQ_CODEL=y +CONFIG_NET_SCH_CAKE=m +CONFIG_NET_SCH_FQ=m +CONFIG_NET_SCH_HHF=m +CONFIG_NET_SCH_PIE=m +CONFIG_NET_SCH_FQ_PIE=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_PLUG=m +CONFIG_NET_SCH_ETS=m +CONFIG_NET_SCH_DEFAULT=y +# CONFIG_DEFAULT_FQ is not set +# CONFIG_DEFAULT_CODEL is not set +CONFIG_DEFAULT_FQ_CODEL=y +# CONFIG_DEFAULT_FQ_PIE is not set +# CONFIG_DEFAULT_SFQ is not set +# CONFIG_DEFAULT_PFIFO_FAST is not set +CONFIG_DEFAULT_NET_SCH="fq_codel" + +# +# Classification +# +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_PERF=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_FLOW=m +CONFIG_NET_CLS_CGROUP=y +CONFIG_NET_CLS_BPF=m +CONFIG_NET_CLS_FLOWER=m +CONFIG_NET_CLS_MATCHALL=m +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_EMATCH_CANID=m +CONFIG_NET_EMATCH_IPSET=m +CONFIG_NET_EMATCH_IPT=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=y +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_SAMPLE=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_ACT_CSUM=m +CONFIG_NET_ACT_MPLS=m +CONFIG_NET_ACT_VLAN=m +CONFIG_NET_ACT_BPF=m +CONFIG_NET_ACT_CONNMARK=m +CONFIG_NET_ACT_CTINFO=m +CONFIG_NET_ACT_SKBMOD=m +CONFIG_NET_ACT_IFE=m +CONFIG_NET_ACT_TUNNEL_KEY=m +CONFIG_NET_ACT_CT=m +CONFIG_NET_ACT_GATE=m +CONFIG_NET_IFE_SKBMARK=m +CONFIG_NET_IFE_SKBPRIO=m +CONFIG_NET_IFE_SKBTCINDEX=m +CONFIG_NET_TC_SKB_EXT=y +CONFIG_NET_SCH_FIFO=y +CONFIG_DCB=y +CONFIG_DNS_RESOLVER=y +CONFIG_BATMAN_ADV=m +CONFIG_BATMAN_ADV_BATMAN_V=y +CONFIG_BATMAN_ADV_BLA=y +CONFIG_BATMAN_ADV_DAT=y +CONFIG_BATMAN_ADV_NC=y +CONFIG_BATMAN_ADV_MCAST=y +# CONFIG_BATMAN_ADV_DEBUG is not set +# CONFIG_BATMAN_ADV_TRACING is not set +CONFIG_OPENVSWITCH=m +CONFIG_OPENVSWITCH_GRE=m +CONFIG_OPENVSWITCH_VXLAN=m +CONFIG_OPENVSWITCH_GENEVE=m +CONFIG_VSOCKETS=m +CONFIG_VSOCKETS_DIAG=m +CONFIG_VSOCKETS_LOOPBACK=m +CONFIG_VMWARE_VMCI_VSOCKETS=m +CONFIG_VIRTIO_VSOCKETS=m +CONFIG_VIRTIO_VSOCKETS_COMMON=m +CONFIG_HYPERV_VSOCKETS=m +CONFIG_NETLINK_DIAG=m +CONFIG_MPLS=y +CONFIG_NET_MPLS_GSO=y +CONFIG_MPLS_ROUTING=m +CONFIG_MPLS_IPTUNNEL=m +CONFIG_NET_NSH=m +CONFIG_HSR=m +CONFIG_NET_SWITCHDEV=y +CONFIG_NET_L3_MASTER_DEV=y +CONFIG_QRTR=m +CONFIG_QRTR_SMD=m +CONFIG_QRTR_TUN=m +CONFIG_QRTR_MHI=m +CONFIG_NET_NCSI=y +CONFIG_NCSI_OEM_CMD_GET_MAC=y +CONFIG_NCSI_OEM_CMD_KEEP_PHY=y +CONFIG_PCPU_DEV_REFCNT=y +CONFIG_MAX_SKB_FRAGS=17 +CONFIG_RPS=y +CONFIG_RFS_ACCEL=y +CONFIG_SOCK_RX_QUEUE_MAPPING=y +CONFIG_XPS=y +CONFIG_CGROUP_NET_PRIO=y +CONFIG_CGROUP_NET_CLASSID=y +CONFIG_NET_RX_BUSY_POLL=y +CONFIG_BQL=y +CONFIG_BPF_STREAM_PARSER=y +CONFIG_NET_FLOW_LIMIT=y + +# +# Network testing +# +CONFIG_NET_PKTGEN=m +# CONFIG_NET_DROP_MONITOR is not set +# end of Network testing +# end of Networking options + +CONFIG_HAMRADIO=y + +# +# Packet Radio protocols +# +CONFIG_AX25=m +CONFIG_AX25_DAMA_SLAVE=y +CONFIG_NETROM=m +CONFIG_ROSE=m + +# +# AX.25 network device drivers +# +CONFIG_MKISS=m +CONFIG_6PACK=m +CONFIG_BPQETHER=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_BAYCOM_PAR=m +CONFIG_YAM=m +# end of AX.25 network device drivers + +CONFIG_CAN=m +CONFIG_CAN_RAW=m +CONFIG_CAN_BCM=m +CONFIG_CAN_GW=m +CONFIG_CAN_J1939=m +CONFIG_CAN_ISOTP=m +CONFIG_BT=m +CONFIG_BT_BREDR=y +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_CMTP=m +CONFIG_BT_HIDP=m +CONFIG_BT_LE=y +CONFIG_BT_LE_L2CAP_ECRED=y +CONFIG_BT_6LOWPAN=m +CONFIG_BT_LEDS=y +CONFIG_BT_MSFTEXT=y +CONFIG_BT_AOSPEXT=y +# CONFIG_BT_DEBUGFS is not set +# CONFIG_BT_SELFTEST is not set + +# +# Bluetooth device drivers +# +CONFIG_BT_INTEL=m +CONFIG_BT_BCM=m +CONFIG_BT_RTL=m +CONFIG_BT_QCA=m +CONFIG_BT_MTK=m +CONFIG_BT_HCIBTUSB=m +# CONFIG_BT_HCIBTUSB_AUTOSUSPEND is not set +CONFIG_BT_HCIBTUSB_POLL_SYNC=y +CONFIG_BT_HCIBTUSB_BCM=y +CONFIG_BT_HCIBTUSB_MTK=y +CONFIG_BT_HCIBTUSB_RTL=y +CONFIG_BT_HCIBTSDIO=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_SERDEV=y +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_NOKIA=m +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_ATH3K=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIUART_3WIRE=y +CONFIG_BT_HCIUART_INTEL=y +CONFIG_BT_HCIUART_BCM=y +CONFIG_BT_HCIUART_RTL=y +CONFIG_BT_HCIUART_QCA=y +CONFIG_BT_HCIUART_AG6XX=y +CONFIG_BT_HCIUART_MRVL=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBCM4377=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIVHCI=m +CONFIG_BT_MRVL=m +CONFIG_BT_MRVL_SDIO=m +CONFIG_BT_ATH3K=m +CONFIG_BT_MTKSDIO=m +CONFIG_BT_MTKUART=m +CONFIG_BT_HCIRSI=m +CONFIG_BT_VIRTIO=m +CONFIG_BT_NXPUART=m +# end of Bluetooth device drivers + +CONFIG_AF_RXRPC=m +CONFIG_AF_RXRPC_IPV6=y +# CONFIG_AF_RXRPC_INJECT_LOSS is not set +# CONFIG_AF_RXRPC_INJECT_RX_DELAY is not set +# CONFIG_AF_RXRPC_DEBUG is not set +# CONFIG_RXKAD is not set +# CONFIG_RXPERF is not set +CONFIG_AF_KCM=m +CONFIG_STREAM_PARSER=y +CONFIG_MCTP=y +CONFIG_MCTP_FLOWS=y +CONFIG_FIB_RULES=y +CONFIG_WIRELESS=y +CONFIG_WIRELESS_EXT=y +CONFIG_WEXT_CORE=y +CONFIG_WEXT_PROC=y +CONFIG_WEXT_SPY=y +CONFIG_WEXT_PRIV=y +CONFIG_CFG80211=m +# CONFIG_NL80211_TESTMODE is not set +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +# CONFIG_CFG80211_CERTIFICATION_ONUS is not set +CONFIG_CFG80211_REQUIRE_SIGNED_REGDB=y +CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS=y +CONFIG_CFG80211_DEFAULT_PS=y +# CONFIG_CFG80211_DEBUGFS is not set +CONFIG_CFG80211_CRDA_SUPPORT=y +CONFIG_CFG80211_WEXT=y +CONFIG_CFG80211_WEXT_EXPORT=y +CONFIG_LIB80211=m +CONFIG_LIB80211_CRYPT_WEP=m +CONFIG_LIB80211_CRYPT_CCMP=m +CONFIG_LIB80211_CRYPT_TKIP=m +# CONFIG_LIB80211_DEBUG is not set +CONFIG_MAC80211=m +CONFIG_MAC80211_HAS_RC=y +CONFIG_MAC80211_RC_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" +CONFIG_MAC80211_MESH=y +CONFIG_MAC80211_LEDS=y +# CONFIG_MAC80211_DEBUGFS is not set +# CONFIG_MAC80211_MESSAGE_TRACING is not set +# CONFIG_MAC80211_DEBUG_MENU is not set +CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 +CONFIG_RFKILL=m +CONFIG_RFKILL_LEDS=y +CONFIG_RFKILL_INPUT=y +CONFIG_RFKILL_GPIO=m +CONFIG_NET_9P=m +CONFIG_NET_9P_FD=m +CONFIG_NET_9P_VIRTIO=m +CONFIG_NET_9P_XEN=m +CONFIG_NET_9P_RDMA=m +# CONFIG_NET_9P_DEBUG is not set +CONFIG_CAIF=m +# CONFIG_CAIF_DEBUG is not set +CONFIG_CAIF_NETDEV=m +CONFIG_CAIF_USB=m +CONFIG_CEPH_LIB=m +# CONFIG_CEPH_LIB_PRETTYDEBUG is not set +# CONFIG_CEPH_LIB_USE_DNS_RESOLVER is not set +CONFIG_NFC=m +CONFIG_NFC_DIGITAL=m +CONFIG_NFC_NCI=m +# CONFIG_NFC_NCI_SPI is not set +CONFIG_NFC_NCI_UART=m +CONFIG_NFC_HCI=m +CONFIG_NFC_SHDLC=y + +# +# Near Field Communication (NFC) devices +# +CONFIG_NFC_TRF7970A=m +CONFIG_NFC_MEI_PHY=m +CONFIG_NFC_SIM=m +CONFIG_NFC_PORT100=m +# CONFIG_NFC_VIRTUAL_NCI is not set +CONFIG_NFC_FDP=m +CONFIG_NFC_FDP_I2C=m +CONFIG_NFC_PN544=m +CONFIG_NFC_PN544_I2C=m +CONFIG_NFC_PN544_MEI=m +CONFIG_NFC_PN533=m +CONFIG_NFC_PN533_USB=m +CONFIG_NFC_PN533_I2C=m +CONFIG_NFC_PN532_UART=m +CONFIG_NFC_MICROREAD=m +CONFIG_NFC_MICROREAD_I2C=m +CONFIG_NFC_MICROREAD_MEI=m +CONFIG_NFC_MRVL=m +CONFIG_NFC_MRVL_USB=m +CONFIG_NFC_MRVL_UART=m +CONFIG_NFC_MRVL_I2C=m +CONFIG_NFC_ST21NFCA=m +CONFIG_NFC_ST21NFCA_I2C=m +CONFIG_NFC_ST_NCI=m +CONFIG_NFC_ST_NCI_I2C=m +CONFIG_NFC_ST_NCI_SPI=m +CONFIG_NFC_NXP_NCI=m +CONFIG_NFC_NXP_NCI_I2C=m +CONFIG_NFC_S3FWRN5=m +CONFIG_NFC_S3FWRN5_I2C=m +# CONFIG_NFC_S3FWRN82_UART is not set +CONFIG_NFC_ST95HF=m +# end of Near Field Communication (NFC) devices + +CONFIG_PSAMPLE=m +CONFIG_NET_IFE=m +CONFIG_LWTUNNEL=y +CONFIG_LWTUNNEL_BPF=y +CONFIG_DST_CACHE=y +CONFIG_GRO_CELLS=y +CONFIG_SOCK_VALIDATE_XMIT=y +CONFIG_NET_SELFTESTS=m +CONFIG_NET_SOCK_MSG=y +CONFIG_NET_DEVLINK=y +CONFIG_PAGE_POOL=y +CONFIG_PAGE_POOL_STATS=y +CONFIG_FAILOVER=m +CONFIG_ETHTOOL_NETLINK=y + +# +# Device Drivers +# +CONFIG_HAVE_EISA=y +# CONFIG_EISA is not set +CONFIG_HAVE_PCI=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCIEPORTBUS=y +CONFIG_HOTPLUG_PCI_PCIE=y +CONFIG_PCIEAER=y +CONFIG_PCIEAER_INJECT=m +CONFIG_PCIE_ECRC=y +CONFIG_PCIEASPM=y +CONFIG_PCIEASPM_DEFAULT=y +# CONFIG_PCIEASPM_POWERSAVE is not set +# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set +# CONFIG_PCIEASPM_PERFORMANCE is not set +CONFIG_PCIE_PME=y +CONFIG_PCIE_DPC=y +CONFIG_PCIE_PTM=y +CONFIG_PCIE_EDR=y +CONFIG_PCI_MSI=y +CONFIG_PCI_QUIRKS=y +# CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set +CONFIG_PCI_STUB=m +CONFIG_PCI_PF_STUB=m +CONFIG_XEN_PCIDEV_FRONTEND=m +CONFIG_PCI_ATS=y +CONFIG_PCI_LOCKLESS_CONFIG=y +CONFIG_PCI_IOV=y +CONFIG_PCI_PRI=y +CONFIG_PCI_PASID=y +CONFIG_PCI_P2PDMA=y +CONFIG_PCI_LABEL=y +CONFIG_PCI_HYPERV=m +# CONFIG_PCIE_BUS_TUNE_OFF is not set +CONFIG_PCIE_BUS_DEFAULT=y +# CONFIG_PCIE_BUS_SAFE is not set +# CONFIG_PCIE_BUS_PERFORMANCE is not set +# CONFIG_PCIE_BUS_PEER2PEER is not set +CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 +CONFIG_HOTPLUG_PCI=y +CONFIG_HOTPLUG_PCI_ACPI=y +CONFIG_HOTPLUG_PCI_ACPI_IBM=m +CONFIG_HOTPLUG_PCI_CPCI=y +CONFIG_HOTPLUG_PCI_CPCI_ZT5550=m +CONFIG_HOTPLUG_PCI_CPCI_GENERIC=m +CONFIG_HOTPLUG_PCI_SHPC=y + +# +# PCI controller drivers +# +CONFIG_VMD=m +CONFIG_PCI_HYPERV_INTERFACE=m + +# +# Cadence-based PCIe controllers +# +# end of Cadence-based PCIe controllers + +# +# DesignWare-based PCIe controllers +# +CONFIG_PCIE_DW=y +CONFIG_PCIE_DW_HOST=y +CONFIG_PCI_MESON=y +CONFIG_PCIE_DW_PLAT=y +CONFIG_PCIE_DW_PLAT_HOST=y +# end of DesignWare-based PCIe controllers + +# +# Mobiveil-based PCIe controllers +# +# end of Mobiveil-based PCIe controllers +# end of PCI controller drivers + +# +# PCI Endpoint +# +# CONFIG_PCI_ENDPOINT is not set +# end of PCI Endpoint + +# +# PCI switch controller drivers +# +# CONFIG_PCI_SW_SWITCHTEC is not set +# end of PCI switch controller drivers + +# CONFIG_CXL_BUS is not set +CONFIG_PCCARD=m +CONFIG_PCMCIA=m +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_CARDBUS=y + +# +# PC-card bridges +# +CONFIG_YENTA=m +CONFIG_YENTA_O2=y +CONFIG_YENTA_RICOH=y +CONFIG_YENTA_TI=y +CONFIG_YENTA_ENE_TUNE=y +CONFIG_YENTA_TOSHIBA=y +CONFIG_PD6729=m +CONFIG_I82092=m +CONFIG_PCCARD_NONSTATIC=y +CONFIG_RAPIDIO=y +CONFIG_RAPIDIO_TSI721=y +CONFIG_RAPIDIO_DISC_TIMEOUT=30 +CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS=y +CONFIG_RAPIDIO_DMA_ENGINE=y +# CONFIG_RAPIDIO_DEBUG is not set +CONFIG_RAPIDIO_ENUM_BASIC=m +CONFIG_RAPIDIO_CHMAN=m +CONFIG_RAPIDIO_MPORT_CDEV=m + +# +# RapidIO Switch drivers +# +CONFIG_RAPIDIO_CPS_XX=y +CONFIG_RAPIDIO_CPS_GEN2=y +CONFIG_RAPIDIO_RXS_GEN3=y +# end of RapidIO Switch drivers + +# +# Generic Driver Options +# +CONFIG_AUXILIARY_BUS=y +CONFIG_UEVENT_HELPER=y +CONFIG_UEVENT_HELPER_PATH="" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +# CONFIG_DEVTMPFS_SAFE is not set +# CONFIG_STANDALONE is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y + +# +# Firmware loader +# +CONFIG_FW_LOADER=y +CONFIG_FW_LOADER_DEBUG=y +CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_FW_LOADER_SYSFS=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_FW_LOADER_USER_HELPER is not set +CONFIG_FW_LOADER_COMPRESS=y +CONFIG_FW_LOADER_COMPRESS_XZ=y +CONFIG_FW_LOADER_COMPRESS_ZSTD=y +CONFIG_FW_CACHE=y +CONFIG_FW_UPLOAD=y +# end of Firmware loader + +CONFIG_WANT_DEV_COREDUMP=y +CONFIG_ALLOW_DEV_COREDUMP=y +CONFIG_DEV_COREDUMP=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set +CONFIG_HMEM_REPORTING=y +# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set +CONFIG_SYS_HYPERVISOR=y +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_CPU_VULNERABILITIES=y +CONFIG_SOC_BUS=y +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_SPI=y +CONFIG_REGMAP_SPMI=m +CONFIG_REGMAP_MMIO=y +CONFIG_REGMAP_IRQ=y +CONFIG_REGMAP_SOUNDWIRE=m +CONFIG_REGMAP_SOUNDWIRE_MBQ=m +CONFIG_REGMAP_SCCB=m +CONFIG_REGMAP_SPI_AVMM=m +CONFIG_DMA_SHARED_BUFFER=y +# CONFIG_DMA_FENCE_TRACE is not set +# CONFIG_FW_DEVLINK_SYNC_STATE_TIMEOUT is not set +# end of Generic Driver Options + +# +# Bus devices +# +CONFIG_MHI_BUS=m +# CONFIG_MHI_BUS_DEBUG is not set +CONFIG_MHI_BUS_PCI_GENERIC=m +CONFIG_MHI_BUS_EP=m +# end of Bus devices + +# +# Cache Drivers +# +# end of Cache Drivers + +CONFIG_CONNECTOR=y +CONFIG_PROC_EVENTS=y + +# +# Firmware Drivers +# + +# +# ARM System Control and Management Interface Protocol +# +# end of ARM System Control and Management Interface Protocol + +CONFIG_EDD=y +# CONFIG_EDD_OFF is not set +CONFIG_FIRMWARE_MEMMAP=y +CONFIG_DMIID=y +CONFIG_DMI_SYSFS=m +CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK=y +CONFIG_ISCSI_IBFT_FIND=y +CONFIG_ISCSI_IBFT=m +CONFIG_FW_CFG_SYSFS=m +# CONFIG_FW_CFG_SYSFS_CMDLINE is not set +CONFIG_SYSFB=y +# CONFIG_SYSFB_SIMPLEFB is not set +CONFIG_FW_CS_DSP=m +# CONFIG_GOOGLE_FIRMWARE is not set + +# +# EFI (Extensible Firmware Interface) Support +# +CONFIG_EFI_ESRT=y +CONFIG_EFI_VARS_PSTORE=y +CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE=y +CONFIG_EFI_SOFT_RESERVE=y +CONFIG_EFI_DXE_MEM_ATTRIBUTES=y +CONFIG_EFI_RUNTIME_WRAPPERS=y +CONFIG_EFI_BOOTLOADER_CONTROL=m +CONFIG_EFI_CAPSULE_LOADER=m +# CONFIG_EFI_TEST is not set +CONFIG_EFI_DEV_PATH_PARSER=y +CONFIG_APPLE_PROPERTIES=y +# CONFIG_RESET_ATTACK_MITIGATION is not set +CONFIG_EFI_RCI2_TABLE=y +# CONFIG_EFI_DISABLE_PCI_DMA is not set +CONFIG_EFI_EARLYCON=y +CONFIG_EFI_CUSTOM_SSDT_OVERLAYS=y +# CONFIG_EFI_DISABLE_RUNTIME is not set +CONFIG_EFI_COCO_SECRET=y +CONFIG_UNACCEPTED_MEMORY=y +CONFIG_EFI_EMBEDDED_FIRMWARE=y +# end of EFI (Extensible Firmware Interface) Support + +CONFIG_UEFI_CPER=y +CONFIG_UEFI_CPER_X86=y + +# +# Tegra firmware driver +# +# end of Tegra firmware driver +# end of Firmware Drivers + +CONFIG_GNSS=m +CONFIG_GNSS_SERIAL=m +CONFIG_GNSS_MTK_SERIAL=m +CONFIG_GNSS_SIRF_SERIAL=m +CONFIG_GNSS_UBX_SERIAL=m +CONFIG_GNSS_USB=m +CONFIG_MTD=m +CONFIG_MTD_TESTS=m + +# +# Partition parsers +# +CONFIG_MTD_AR7_PARTS=m +# CONFIG_MTD_CMDLINE_PARTS is not set +CONFIG_MTD_REDBOOT_PARTS=m +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# end of Partition parsers + +# +# User Modules And Translation Layers +# +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK_RO=m + +# +# Note that in some cases UBI block is preferred. See MTD_UBI_BLOCK. +# +CONFIG_FTL=m +CONFIG_NFTL=m +# CONFIG_NFTL_RW is not set +CONFIG_INFTL=m +CONFIG_RFD_FTL=m +CONFIG_SSFDC=m +CONFIG_SM_FTL=m +CONFIG_MTD_OOPS=m +CONFIG_MTD_PSTORE=m +CONFIG_MTD_SWAP=m +# CONFIG_MTD_PARTITIONED_MASTER is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_GEN_PROBE=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_CFI_UTIL=m +CONFIG_MTD_RAM=m +CONFIG_MTD_ROM=m +CONFIG_MTD_ABSENT=m +# end of RAM/ROM/Flash chip drivers + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_AMD76XROM=m +CONFIG_MTD_ICHXROM=m +CONFIG_MTD_ESB2ROM=m +CONFIG_MTD_CK804XROM=m +CONFIG_MTD_SCB2_FLASH=m +CONFIG_MTD_NETtel=m +CONFIG_MTD_L440GX=m +CONFIG_MTD_INTEL_VR_NOR=m +# CONFIG_MTD_PLATRAM is not set +# end of Mapping drivers for chip access + +# +# Self-contained MTD device drivers +# +CONFIG_MTD_PMC551=m +# CONFIG_MTD_PMC551_BUGFIX is not set +# CONFIG_MTD_PMC551_DEBUG is not set +CONFIG_MTD_DATAFLASH=m +# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set +# CONFIG_MTD_DATAFLASH_OTP is not set +# CONFIG_MTD_MCHP23K256 is not set +# CONFIG_MTD_MCHP48L640 is not set +CONFIG_MTD_SST25L=m +CONFIG_MTD_SLRAM=m +CONFIG_MTD_PHRAM=m +CONFIG_MTD_MTDRAM=m +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTDRAM_ERASE_SIZE=128 +CONFIG_MTD_BLOCK2MTD=m + +# +# Disk-On-Chip Device Drivers +# +CONFIG_MTD_DOCG3=m +CONFIG_BCH_CONST_M=14 +CONFIG_BCH_CONST_T=4 +# end of Self-contained MTD device drivers + +# +# NAND +# +CONFIG_MTD_NAND_CORE=m +CONFIG_MTD_ONENAND=m +# CONFIG_MTD_ONENAND_VERIFY_WRITE is not set +# CONFIG_MTD_ONENAND_GENERIC is not set +CONFIG_MTD_ONENAND_OTP=y +CONFIG_MTD_ONENAND_2X_PROGRAM=y +CONFIG_MTD_RAW_NAND=m + +# +# Raw/parallel NAND flash controllers +# +CONFIG_MTD_NAND_DENALI=m +CONFIG_MTD_NAND_DENALI_PCI=m +CONFIG_MTD_NAND_CAFE=m +CONFIG_MTD_NAND_MXIC=m +CONFIG_MTD_NAND_GPIO=m +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_NAND_ARASAN is not set + +# +# Misc +# +CONFIG_MTD_SM_COMMON=m +CONFIG_MTD_NAND_NANDSIM=m +CONFIG_MTD_NAND_RICOH=m +CONFIG_MTD_NAND_DISKONCHIP=m +# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 +# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set +CONFIG_MTD_SPI_NAND=m + +# +# ECC engine support +# +CONFIG_MTD_NAND_ECC=y +CONFIG_MTD_NAND_ECC_SW_HAMMING=y +# CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC is not set +CONFIG_MTD_NAND_ECC_SW_BCH=y +CONFIG_MTD_NAND_ECC_MXIC=y +# end of ECC engine support +# end of NAND + +# +# LPDDR & LPDDR2 PCM memory drivers +# +CONFIG_MTD_LPDDR=m +CONFIG_MTD_QINFO_PROBE=m +# end of LPDDR & LPDDR2 PCM memory drivers + +CONFIG_MTD_SPI_NOR=m +CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y +# CONFIG_MTD_SPI_NOR_SWP_DISABLE is not set +CONFIG_MTD_SPI_NOR_SWP_DISABLE_ON_VOLATILE=y +# CONFIG_MTD_SPI_NOR_SWP_KEEP is not set +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTD_UBI_BEB_LIMIT=20 +# CONFIG_MTD_UBI_FASTMAP is not set +# CONFIG_MTD_UBI_GLUEBI is not set +# CONFIG_MTD_UBI_BLOCK is not set +# CONFIG_MTD_HYPERBUS is not set +# CONFIG_OF is not set +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_SERIAL=m +CONFIG_PARPORT_PC_FIFO=y +CONFIG_PARPORT_PC_SUPERIO=y +CONFIG_PARPORT_PC_PCMCIA=m +CONFIG_PARPORT_1284=y +CONFIG_PARPORT_NOT_PC=y +CONFIG_PNP=y +# CONFIG_PNP_DEBUG_MESSAGES is not set + +# +# Protocols +# +CONFIG_PNPACPI=y +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_NULL_BLK is not set +CONFIG_BLK_DEV_FD=m +# CONFIG_BLK_DEV_FD_RAWCMD is not set +CONFIG_CDROM=y +CONFIG_BLK_DEV_PCIESSD_MTIP32XX=m +CONFIG_ZRAM=m +CONFIG_ZRAM_DEF_COMP_LZORLE=y +# CONFIG_ZRAM_DEF_COMP_ZSTD is not set +# CONFIG_ZRAM_DEF_COMP_LZ4 is not set +# CONFIG_ZRAM_DEF_COMP_LZO is not set +# CONFIG_ZRAM_DEF_COMP_LZ4HC is not set +# CONFIG_ZRAM_DEF_COMP_842 is not set +CONFIG_ZRAM_DEF_COMP="lzo-rle" +CONFIG_ZRAM_WRITEBACK=y +CONFIG_ZRAM_MEMORY_TRACKING=y +CONFIG_ZRAM_MULTI_COMP=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 +CONFIG_BLK_DEV_DRBD=m +# CONFIG_DRBD_FAULT_INJECTION is not set +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=16384 +CONFIG_CDROM_PKTCDVD=y +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_ATA_OVER_ETH=m +CONFIG_XEN_BLKDEV_FRONTEND=m +CONFIG_XEN_BLKDEV_BACKEND=m +CONFIG_VIRTIO_BLK=m +CONFIG_BLK_DEV_RBD=m +CONFIG_BLK_DEV_UBLK=m +CONFIG_BLKDEV_UBLK_LEGACY_OPCODES=y + +# +# NVME Support +# +CONFIG_NVME_COMMON=y +CONFIG_NVME_CORE=y +CONFIG_BLK_DEV_NVME=y +CONFIG_NVME_MULTIPATH=y +CONFIG_NVME_VERBOSE_ERRORS=y +CONFIG_NVME_FABRICS=m +CONFIG_NVME_RDMA=m +CONFIG_NVME_FC=m +CONFIG_NVME_TCP=m +CONFIG_NVME_AUTH=y +CONFIG_NVME_TARGET=m +CONFIG_NVME_TARGET_PASSTHRU=y +CONFIG_NVME_TARGET_LOOP=m +CONFIG_NVME_TARGET_RDMA=m +CONFIG_NVME_TARGET_FC=m +CONFIG_NVME_TARGET_FCLOOP=m +CONFIG_NVME_TARGET_TCP=m +CONFIG_NVME_TARGET_AUTH=y +# end of NVME Support + +# +# Misc devices +# +CONFIG_SENSORS_LIS3LV02D=m +CONFIG_AD525X_DPOT=m +CONFIG_AD525X_DPOT_I2C=m +CONFIG_AD525X_DPOT_SPI=m +CONFIG_DUMMY_IRQ=m +CONFIG_IBM_ASM=m +CONFIG_PHANTOM=m +CONFIG_TIFM_CORE=m +CONFIG_TIFM_7XX1=m +CONFIG_ICS932S401=m +CONFIG_ENCLOSURE_SERVICES=m +CONFIG_SMPRO_ERRMON=m +CONFIG_SMPRO_MISC=m +CONFIG_HP_ILO=m +CONFIG_APDS9802ALS=m +CONFIG_ISL29003=m +CONFIG_ISL29020=m +CONFIG_SENSORS_TSL2550=m +CONFIG_SENSORS_BH1770=m +CONFIG_SENSORS_APDS990X=m +CONFIG_HMC6352=m +CONFIG_DS1682=m +CONFIG_VMWARE_BALLOON=m +CONFIG_LATTICE_ECP3_CONFIG=m +CONFIG_SRAM=y +CONFIG_DW_XDATA_PCIE=m +# CONFIG_PCI_ENDPOINT_TEST is not set +# CONFIG_XILINX_SDFEC is not set +CONFIG_MISC_RTSX=m +CONFIG_TPS6594_ESM=m +CONFIG_TPS6594_PFSM=m +CONFIG_C2PORT=m +CONFIG_C2PORT_DURAMAR_2150=m + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +CONFIG_EEPROM_AT25=m +CONFIG_EEPROM_LEGACY=m +CONFIG_EEPROM_MAX6875=m +CONFIG_EEPROM_93CX6=y +CONFIG_EEPROM_93XX46=m +CONFIG_EEPROM_IDT_89HPESX=m +CONFIG_EEPROM_EE1004=m +# end of EEPROM support + +CONFIG_CB710_CORE=m +# CONFIG_CB710_DEBUG is not set +CONFIG_CB710_DEBUG_ASSUMPTIONS=y + +# +# Texas Instruments shared transport line discipline +# +CONFIG_TI_ST=m +# end of Texas Instruments shared transport line discipline + +CONFIG_SENSORS_LIS3_I2C=m +CONFIG_ALTERA_STAPL=m +CONFIG_INTEL_MEI=m +CONFIG_INTEL_MEI_ME=m +CONFIG_INTEL_MEI_TXE=m +CONFIG_INTEL_MEI_GSC=m +CONFIG_INTEL_MEI_HDCP=m +CONFIG_INTEL_MEI_PXP=m +CONFIG_INTEL_MEI_GSC_PROXY=m +CONFIG_VMWARE_VMCI=m +CONFIG_GENWQE=m +CONFIG_GENWQE_PLATFORM_ERROR_RECOVERY=1 +CONFIG_ECHO=m +CONFIG_BCM_VK=m +CONFIG_BCM_VK_TTY=y +CONFIG_MISC_ALCOR_PCI=m +CONFIG_MISC_RTSX_PCI=m +CONFIG_MISC_RTSX_USB=m +# CONFIG_UACCE is not set +CONFIG_PVPANIC=y +CONFIG_PVPANIC_MMIO=m +CONFIG_PVPANIC_PCI=m +CONFIG_GP_PCI1XXXX=m +# end of Misc devices + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +CONFIG_RAID_ATTRS=m +CONFIG_SCSI_COMMON=y +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +CONFIG_SCSI_NETLINK=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=m +CONFIG_BLK_DEV_SR=y +CONFIG_CHR_DEV_SG=y +CONFIG_BLK_DEV_BSG=y +CONFIG_CHR_DEV_SCH=m +CONFIG_SCSI_ENCLOSURE=m +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SCAN_ASYNC=y + +# +# SCSI Transports +# +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_ISCSI_ATTRS=m +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +CONFIG_SCSI_SAS_ATA=y +CONFIG_SCSI_SAS_HOST_SMP=y +CONFIG_SCSI_SRP_ATTRS=m +# end of SCSI Transports + +CONFIG_SCSI_LOWLEVEL=y +CONFIG_ISCSI_TCP=m +CONFIG_ISCSI_BOOT_SYSFS=m +CONFIG_SCSI_CXGB3_ISCSI=m +CONFIG_SCSI_CXGB4_ISCSI=m +CONFIG_SCSI_BNX2_ISCSI=m +CONFIG_SCSI_BNX2X_FCOE=m +CONFIG_BE2ISCSI=m +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_SCSI_HPSA=m +CONFIG_SCSI_3W_9XXX=m +CONFIG_SCSI_3W_SAS=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_AIC7XXX=m +CONFIG_AIC7XXX_CMDS_PER_DEVICE=253 +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC7XXX_DEBUG_ENABLE is not set +CONFIG_AIC7XXX_DEBUG_MASK=0 +CONFIG_AIC7XXX_REG_PRETTY_PRINT=y +CONFIG_SCSI_AIC79XX=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=32 +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +# CONFIG_AIC79XX_DEBUG_ENABLE is not set +CONFIG_AIC79XX_DEBUG_MASK=0 +CONFIG_AIC79XX_REG_PRETTY_PRINT=y +CONFIG_SCSI_AIC94XX=m +CONFIG_AIC94XX_DEBUG=y +CONFIG_SCSI_MVSAS=m +CONFIG_SCSI_MVSAS_DEBUG=y +# CONFIG_SCSI_MVSAS_TASKLET is not set +CONFIG_SCSI_MVUMI=m +CONFIG_SCSI_ADVANSYS=m +CONFIG_SCSI_ARCMSR=m +CONFIG_SCSI_ESAS2R=m +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_SAS=m +CONFIG_SCSI_MPT3SAS=m +CONFIG_SCSI_MPT2SAS_MAX_SGE=128 +CONFIG_SCSI_MPT3SAS_MAX_SGE=128 +CONFIG_SCSI_MPT2SAS=m +CONFIG_SCSI_MPI3MR=m +CONFIG_SCSI_SMARTPQI=m +CONFIG_SCSI_HPTIOP=m +CONFIG_SCSI_BUSLOGIC=m +CONFIG_SCSI_FLASHPOINT=y +CONFIG_SCSI_MYRB=m +CONFIG_SCSI_MYRS=m +CONFIG_VMWARE_PVSCSI=m +CONFIG_XEN_SCSI_FRONTEND=m +CONFIG_HYPERV_STORAGE=m +CONFIG_LIBFC=m +CONFIG_LIBFCOE=m +CONFIG_FCOE=m +CONFIG_FCOE_FNIC=m +CONFIG_SCSI_SNIC=m +# CONFIG_SCSI_SNIC_DEBUG_FS is not set +CONFIG_SCSI_DMX3191D=m +CONFIG_SCSI_FDOMAIN=m +CONFIG_SCSI_FDOMAIN_PCI=m +CONFIG_SCSI_ISCI=m +CONFIG_SCSI_IPS=m +CONFIG_SCSI_INITIO=m +CONFIG_SCSI_INIA100=m +CONFIG_SCSI_PPA=m +CONFIG_SCSI_IMM=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +CONFIG_SCSI_STEX=m +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +CONFIG_SCSI_IPR=m +# CONFIG_SCSI_IPR_TRACE is not set +# CONFIG_SCSI_IPR_DUMP is not set +CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_QLA_FC=m +CONFIG_TCM_QLA2XXX=m +# CONFIG_TCM_QLA2XXX_DEBUG is not set +CONFIG_SCSI_QLA_ISCSI=m +CONFIG_QEDI=m +CONFIG_QEDF=m +CONFIG_SCSI_LPFC=m +# CONFIG_SCSI_LPFC_DEBUG_FS is not set +CONFIG_SCSI_EFCT=m +CONFIG_SCSI_DC395x=m +CONFIG_SCSI_AM53C974=m +CONFIG_SCSI_WD719X=y +CONFIG_SCSI_DEBUG=m +CONFIG_SCSI_PMCRAID=m +CONFIG_SCSI_PM8001=m +CONFIG_SCSI_BFA_FC=m +CONFIG_SCSI_VIRTIO=m +CONFIG_SCSI_CHELSIO_FCOE=m +CONFIG_SCSI_LOWLEVEL_PCMCIA=y +CONFIG_PCMCIA_AHA152X=m +CONFIG_PCMCIA_FDOMAIN=m +CONFIG_PCMCIA_QLOGIC=m +CONFIG_PCMCIA_SYM53C500=m +CONFIG_SCSI_DH=y +CONFIG_SCSI_DH_RDAC=m +CONFIG_SCSI_DH_HP_SW=m +CONFIG_SCSI_DH_EMC=m +CONFIG_SCSI_DH_ALUA=m +# end of SCSI device support + +CONFIG_ATA=y +CONFIG_SATA_HOST=y +CONFIG_PATA_TIMINGS=y +CONFIG_ATA_VERBOSE_ERROR=y +CONFIG_ATA_FORCE=y +CONFIG_ATA_ACPI=y +CONFIG_SATA_ZPODD=y +CONFIG_SATA_PMP=y + +# +# Controllers with non-SFF native interface +# +CONFIG_SATA_AHCI=y +CONFIG_SATA_MOBILE_LPM_POLICY=0 +CONFIG_SATA_AHCI_PLATFORM=y +CONFIG_AHCI_DWC=m +CONFIG_SATA_INIC162X=m +CONFIG_SATA_ACARD_AHCI=m +CONFIG_SATA_SIL24=m +CONFIG_ATA_SFF=y + +# +# SFF controllers with custom DMA interface +# +CONFIG_PDC_ADMA=m +CONFIG_SATA_QSTOR=m +CONFIG_SATA_SX4=m +CONFIG_ATA_BMDMA=y + +# +# SATA SFF controllers with BMDMA +# +CONFIG_ATA_PIIX=m +CONFIG_SATA_DWC=m +# CONFIG_SATA_DWC_OLD_DMA is not set +CONFIG_SATA_MV=m +CONFIG_SATA_NV=m +CONFIG_SATA_PROMISE=m +CONFIG_SATA_SIL=m +CONFIG_SATA_SIS=m +CONFIG_SATA_SVW=m +CONFIG_SATA_ULI=m +CONFIG_SATA_VIA=m +CONFIG_SATA_VITESSE=m + +# +# PATA SFF controllers with BMDMA +# +CONFIG_PATA_ALI=m +CONFIG_PATA_AMD=m +CONFIG_PATA_ARTOP=m +CONFIG_PATA_ATIIXP=m +CONFIG_PATA_ATP867X=m +CONFIG_PATA_CMD64X=m +CONFIG_PATA_CYPRESS=m +CONFIG_PATA_EFAR=m +CONFIG_PATA_HPT366=m +CONFIG_PATA_HPT37X=m +CONFIG_PATA_HPT3X2N=m +CONFIG_PATA_HPT3X3=m +CONFIG_PATA_HPT3X3_DMA=y +CONFIG_PATA_IT8213=m +CONFIG_PATA_IT821X=m +CONFIG_PATA_JMICRON=m +CONFIG_PATA_MARVELL=m +CONFIG_PATA_NETCELL=m +CONFIG_PATA_NINJA32=m +CONFIG_PATA_NS87415=m +CONFIG_PATA_OLDPIIX=m +CONFIG_PATA_OPTIDMA=m +CONFIG_PATA_PDC2027X=m +CONFIG_PATA_PDC_OLD=m +CONFIG_PATA_RADISYS=m +CONFIG_PATA_RDC=m +CONFIG_PATA_SCH=m +CONFIG_PATA_SERVERWORKS=m +CONFIG_PATA_SIL680=m +CONFIG_PATA_SIS=m +CONFIG_PATA_TOSHIBA=m +CONFIG_PATA_TRIFLEX=m +CONFIG_PATA_VIA=m +CONFIG_PATA_WINBOND=m + +# +# PIO-only SFF controllers +# +CONFIG_PATA_CMD640_PCI=m +CONFIG_PATA_MPIIX=m +CONFIG_PATA_NS87410=m +CONFIG_PATA_OPTI=m +CONFIG_PATA_PCMCIA=m +CONFIG_PATA_RZ1000=m +# CONFIG_PATA_PARPORT is not set + +# +# Generic fallback / legacy drivers +# +CONFIG_PATA_ACPI=m +CONFIG_ATA_GENERIC=m +CONFIG_PATA_LEGACY=m +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +# CONFIG_MD_AUTODETECT is not set +CONFIG_MD_BITMAP_FILE=y +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +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_BCACHE_ASYNC_REGISTRATION=y +CONFIG_BLK_DEV_DM_BUILTIN=y +CONFIG_BLK_DEV_DM=m +# CONFIG_DM_DEBUG is not set +CONFIG_DM_BUFIO=m +# CONFIG_DM_DEBUG_BLOCK_MANAGER_LOCKING is not set +CONFIG_DM_BIO_PRISON=m +CONFIG_DM_PERSISTENT_DATA=m +CONFIG_DM_UNSTRIPED=m +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_THIN_PROVISIONING=m +CONFIG_DM_CACHE=m +CONFIG_DM_CACHE_SMQ=m +CONFIG_DM_WRITECACHE=m +CONFIG_DM_EBS=m +CONFIG_DM_ERA=m +CONFIG_DM_CLONE=m +CONFIG_DM_MIRROR=m +CONFIG_DM_LOG_USERSPACE=m +CONFIG_DM_RAID=m +CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_QL=m +CONFIG_DM_MULTIPATH_ST=m +CONFIG_DM_MULTIPATH_HST=m +CONFIG_DM_MULTIPATH_IOA=m +CONFIG_DM_DELAY=m +CONFIG_DM_DUST=m +CONFIG_DM_UEVENT=y +CONFIG_DM_FLAKEY=m +CONFIG_DM_VERITY=m +# CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG is not set +# CONFIG_DM_VERITY_FEC is not set +CONFIG_DM_SWITCH=m +CONFIG_DM_LOG_WRITES=m +CONFIG_DM_INTEGRITY=m +CONFIG_DM_ZONED=m +CONFIG_DM_AUDIT=y +CONFIG_TARGET_CORE=m +CONFIG_TCM_IBLOCK=m +CONFIG_TCM_FILEIO=m +CONFIG_TCM_PSCSI=m +CONFIG_TCM_USER2=m +CONFIG_LOOPBACK_TARGET=m +CONFIG_TCM_FC=m +CONFIG_ISCSI_TARGET=m +CONFIG_ISCSI_TARGET_CXGB4=m +CONFIG_SBP_TARGET=m +CONFIG_REMOTE_TARGET=m +CONFIG_FUSION=y +CONFIG_FUSION_SPI=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_SAS=m +CONFIG_FUSION_MAX_SGE=128 +CONFIG_FUSION_CTL=m +CONFIG_FUSION_LAN=m +CONFIG_FUSION_LOGGING=y + +# +# IEEE 1394 (FireWire) support +# +CONFIG_FIREWIRE=m +CONFIG_FIREWIRE_OHCI=m +CONFIG_FIREWIRE_SBP2=m +CONFIG_FIREWIRE_NET=m +CONFIG_FIREWIRE_NOSY=m +# end of IEEE 1394 (FireWire) support + +CONFIG_MACINTOSH_DRIVERS=y +CONFIG_MAC_EMUMOUSEBTN=y +CONFIG_NETDEVICES=y +CONFIG_MII=m +CONFIG_NET_CORE=y +CONFIG_BONDING=m +CONFIG_DUMMY=m +CONFIG_WIREGUARD=m +# CONFIG_WIREGUARD_DEBUG is not set +CONFIG_EQUALIZER=m +CONFIG_NET_FC=y +CONFIG_IFB=m +CONFIG_NET_TEAM=m +CONFIG_NET_TEAM_MODE_BROADCAST=m +CONFIG_NET_TEAM_MODE_ROUNDROBIN=m +CONFIG_NET_TEAM_MODE_RANDOM=m +CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m +CONFIG_NET_TEAM_MODE_LOADBALANCE=m +CONFIG_MACVLAN=m +CONFIG_MACVTAP=m +CONFIG_IPVLAN_L3S=y +CONFIG_IPVLAN=m +CONFIG_IPVTAP=m +CONFIG_VXLAN=m +CONFIG_GENEVE=m +CONFIG_BAREUDP=m +CONFIG_GTP=m +CONFIG_AMT=m +CONFIG_MACSEC=m +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +# CONFIG_NETCONSOLE_EXTENDED_LOG is not set +CONFIG_NETPOLL=y +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_NTB_NETDEV=m +CONFIG_RIONET=m +CONFIG_RIONET_TX_SIZE=128 +CONFIG_RIONET_RX_SIZE=128 +CONFIG_TUN=m +CONFIG_TAP=m +# CONFIG_TUN_VNET_CROSS_LE is not set +CONFIG_VETH=m +CONFIG_VIRTIO_NET=m +CONFIG_NLMON=m +CONFIG_NET_VRF=m +CONFIG_VSOCKMON=m +CONFIG_MHI_NET=m +CONFIG_SUNGEM_PHY=m +CONFIG_ARCNET=m +CONFIG_ARCNET_1201=m +CONFIG_ARCNET_1051=m +CONFIG_ARCNET_RAW=m +CONFIG_ARCNET_CAP=m +CONFIG_ARCNET_COM90xx=m +CONFIG_ARCNET_COM90xxIO=m +CONFIG_ARCNET_RIM_I=m +CONFIG_ARCNET_COM20020=m +CONFIG_ARCNET_COM20020_PCI=m +CONFIG_ARCNET_COM20020_CS=m +CONFIG_ATM_DRIVERS=y +# CONFIG_ATM_DUMMY is not set +CONFIG_ATM_TCP=m +CONFIG_ATM_LANAI=m +CONFIG_ATM_ENI=m +# CONFIG_ATM_ENI_DEBUG is not set +# CONFIG_ATM_ENI_TUNE_BURST is not set +# CONFIG_ATM_NICSTAR is not set +CONFIG_ATM_IDT77252=m +# CONFIG_ATM_IDT77252_DEBUG is not set +# CONFIG_ATM_IDT77252_RCV_ALL is not set +CONFIG_ATM_IDT77252_USE_SUNI=y +CONFIG_ATM_IA=m +# CONFIG_ATM_IA_DEBUG is not set +CONFIG_ATM_FORE200E=m +CONFIG_ATM_FORE200E_USE_TASKLET=y +CONFIG_ATM_FORE200E_TX_RETRY=16 +CONFIG_ATM_FORE200E_DEBUG=0 +CONFIG_ATM_HE=m +CONFIG_ATM_HE_USE_SUNI=y +CONFIG_ATM_SOLOS=m +# CONFIG_CAIF_DRIVERS is not set + +# +# Distributed Switch Architecture drivers +# +CONFIG_B53=m +CONFIG_B53_SPI_DRIVER=m +CONFIG_B53_MDIO_DRIVER=m +CONFIG_B53_MMAP_DRIVER=m +CONFIG_B53_SRAB_DRIVER=m +CONFIG_B53_SERDES=m +CONFIG_NET_DSA_BCM_SF2=m +# CONFIG_NET_DSA_LOOP is not set +CONFIG_NET_DSA_HIRSCHMANN_HELLCREEK=m +CONFIG_NET_DSA_LANTIQ_GSWIP=m +# CONFIG_NET_DSA_MT7530 is not set +CONFIG_NET_DSA_MV88E6060=m +CONFIG_NET_DSA_MICROCHIP_KSZ_COMMON=m +# CONFIG_NET_DSA_MICROCHIP_KSZ9477_I2C is not set +# CONFIG_NET_DSA_MICROCHIP_KSZ_SPI is not set +# CONFIG_NET_DSA_MICROCHIP_KSZ_PTP is not set +# CONFIG_NET_DSA_MICROCHIP_KSZ8863_SMI is not set +CONFIG_NET_DSA_MV88E6XXX=m +# CONFIG_NET_DSA_MV88E6XXX_PTP is not set +CONFIG_NET_DSA_MSCC_FELIX_DSA_LIB=m +CONFIG_NET_DSA_MSCC_OCELOT_EXT=m +CONFIG_NET_DSA_MSCC_SEVILLE=m +CONFIG_NET_DSA_AR9331=m +CONFIG_NET_DSA_QCA8K=m +# CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT is not set +CONFIG_NET_DSA_SJA1105=m +# CONFIG_NET_DSA_SJA1105_PTP is not set +CONFIG_NET_DSA_XRS700X=m +CONFIG_NET_DSA_XRS700X_I2C=m +CONFIG_NET_DSA_XRS700X_MDIO=m +CONFIG_NET_DSA_REALTEK=m +# CONFIG_NET_DSA_REALTEK_MDIO is not set +# CONFIG_NET_DSA_REALTEK_SMI is not set +CONFIG_NET_DSA_REALTEK_RTL8365MB=m +CONFIG_NET_DSA_REALTEK_RTL8366RB=m +# CONFIG_NET_DSA_SMSC_LAN9303_I2C is not set +# CONFIG_NET_DSA_SMSC_LAN9303_MDIO is not set +# CONFIG_NET_DSA_VITESSE_VSC73XX_SPI is not set +# CONFIG_NET_DSA_VITESSE_VSC73XX_PLATFORM is not set +# end of Distributed Switch Architecture drivers + +CONFIG_ETHERNET=y +CONFIG_MDIO=m +CONFIG_NET_VENDOR_3COM=y +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_3C589=m +CONFIG_VORTEX=m +CONFIG_TYPHOON=m +CONFIG_NET_VENDOR_ADAPTEC=y +CONFIG_ADAPTEC_STARFIRE=m +CONFIG_NET_VENDOR_AGERE=y +CONFIG_ET131X=m +CONFIG_NET_VENDOR_ALACRITECH=y +CONFIG_SLICOSS=m +CONFIG_NET_VENDOR_ALTEON=y +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_ALTERA_TSE=m +CONFIG_NET_VENDOR_AMAZON=y +CONFIG_ENA_ETHERNET=m +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_AMD_XGBE_HAVE_ECC=y +CONFIG_PDS_CORE=m +CONFIG_NET_VENDOR_AQUANTIA=y +CONFIG_AQTION=m +CONFIG_NET_VENDOR_ARC=y +CONFIG_NET_VENDOR_ASIX=y +CONFIG_SPI_AX88796C=m +CONFIG_SPI_AX88796C_COMPRESSION=y +CONFIG_NET_VENDOR_ATHEROS=y +CONFIG_ATL2=m +CONFIG_ATL1=m +CONFIG_ATL1E=m +CONFIG_ATL1C=m +CONFIG_ALX=m +CONFIG_CX_ECAT=m +CONFIG_NET_VENDOR_BROADCOM=y +CONFIG_B44=m +CONFIG_B44_PCI_AUTOSELECT=y +CONFIG_B44_PCICORE_AUTOSELECT=y +CONFIG_B44_PCI=y +CONFIG_BCMGENET=m +CONFIG_BNX2=m +CONFIG_CNIC=m +CONFIG_TIGON3=m +CONFIG_TIGON3_HWMON=y +CONFIG_BNX2X=m +CONFIG_BNX2X_SRIOV=y +CONFIG_SYSTEMPORT=m +CONFIG_BNXT=m +CONFIG_BNXT_SRIOV=y +CONFIG_BNXT_FLOWER_OFFLOAD=y +CONFIG_BNXT_DCB=y +CONFIG_BNXT_HWMON=y +CONFIG_NET_VENDOR_CADENCE=y +CONFIG_MACB=m +CONFIG_MACB_USE_HWSTAMP=y +CONFIG_MACB_PCI=m +CONFIG_NET_VENDOR_CAVIUM=y +CONFIG_THUNDER_NIC_PF=m +CONFIG_THUNDER_NIC_VF=m +CONFIG_THUNDER_NIC_BGX=m +CONFIG_THUNDER_NIC_RGX=m +CONFIG_CAVIUM_PTP=m +CONFIG_LIQUIDIO_CORE=m +CONFIG_LIQUIDIO=m +CONFIG_LIQUIDIO_VF=m +CONFIG_NET_VENDOR_CHELSIO=y +CONFIG_CHELSIO_T1=m +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_CHELSIO_LIB=m +CONFIG_CHELSIO_INLINE_CRYPTO=y +CONFIG_CHELSIO_IPSEC_INLINE=m +CONFIG_CHELSIO_TLS_DEVICE=m +CONFIG_NET_VENDOR_CISCO=y +CONFIG_ENIC=m +CONFIG_NET_VENDOR_CORTINA=y +CONFIG_NET_VENDOR_DAVICOM=y +CONFIG_DM9051=m +# CONFIG_DNET is not set +CONFIG_NET_VENDOR_DEC=y +CONFIG_NET_TULIP=y +CONFIG_DE2104X=m +CONFIG_DE2104X_DSL=0 +CONFIG_TULIP=m +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_MMIO is not set +# CONFIG_TULIP_NAPI is not set +CONFIG_WINBOND_840=m +CONFIG_DM9102=m +CONFIG_ULI526X=m +CONFIG_PCMCIA_XIRCOM=m +CONFIG_NET_VENDOR_DLINK=y +CONFIG_DL2K=m +CONFIG_SUNDANCE=m +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_NET_VENDOR_EMULEX=y +CONFIG_BE2NET=m +CONFIG_BE2NET_HWMON=y +CONFIG_BE2NET_BE2=y +CONFIG_BE2NET_BE3=y +CONFIG_BE2NET_LANCER=y +CONFIG_BE2NET_SKYHAWK=y +CONFIG_NET_VENDOR_ENGLEDER=y +# CONFIG_TSNEP is not set +CONFIG_NET_VENDOR_EZCHIP=y +CONFIG_NET_VENDOR_FUJITSU=y +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_NET_VENDOR_FUNGIBLE=y +CONFIG_FUN_CORE=m +CONFIG_FUN_ETH=m +CONFIG_NET_VENDOR_GOOGLE=y +CONFIG_GVE=m +CONFIG_NET_VENDOR_HUAWEI=y +CONFIG_HINIC=m +CONFIG_NET_VENDOR_I825XX=y +CONFIG_NET_VENDOR_INTEL=y +CONFIG_E100=m +CONFIG_E1000=m +CONFIG_E1000E=m +CONFIG_E1000E_HWTS=y +CONFIG_IGB=m +CONFIG_IGB_HWMON=y +CONFIG_IGB_DCA=y +CONFIG_IGBVF=m +CONFIG_IXGBE=m +CONFIG_IXGBE_HWMON=y +CONFIG_IXGBE_DCA=y +CONFIG_IXGBE_DCB=y +CONFIG_IXGBE_IPSEC=y +CONFIG_IXGBEVF=m +CONFIG_IXGBEVF_IPSEC=y +CONFIG_I40E=m +CONFIG_I40E_DCB=y +CONFIG_IAVF=m +CONFIG_I40EVF=m +CONFIG_ICE=m +CONFIG_ICE_SWITCHDEV=y +CONFIG_ICE_HWTS=y +CONFIG_FM10K=m +CONFIG_IGC=m +CONFIG_JME=m +CONFIG_NET_VENDOR_ADI=y +CONFIG_ADIN1110=m +CONFIG_NET_VENDOR_LITEX=y +CONFIG_NET_VENDOR_MARVELL=y +CONFIG_MVMDIO=m +CONFIG_SKGE=m +# CONFIG_SKGE_DEBUG is not set +CONFIG_SKGE_GENESIS=y +CONFIG_SKY2=m +# CONFIG_SKY2_DEBUG is not set +CONFIG_OCTEON_EP=m +CONFIG_PRESTERA=m +CONFIG_PRESTERA_PCI=m +CONFIG_NET_VENDOR_MELLANOX=y +CONFIG_MLX4_EN=m +CONFIG_MLX4_EN_DCB=y +CONFIG_MLX4_CORE=m +# CONFIG_MLX4_DEBUG is not set +CONFIG_MLX4_CORE_GEN2=y +CONFIG_MLX5_CORE=m +CONFIG_MLX5_FPGA=y +CONFIG_MLX5_CORE_EN=y +CONFIG_MLX5_EN_ARFS=y +CONFIG_MLX5_EN_RXNFC=y +CONFIG_MLX5_MPFS=y +CONFIG_MLX5_ESWITCH=y +CONFIG_MLX5_BRIDGE=y +CONFIG_MLX5_CLS_ACT=y +CONFIG_MLX5_TC_CT=y +CONFIG_MLX5_TC_SAMPLE=y +CONFIG_MLX5_CORE_EN_DCB=y +# CONFIG_MLX5_CORE_IPOIB is not set +# CONFIG_MLX5_MACSEC is not set +# CONFIG_MLX5_EN_IPSEC is not set +CONFIG_MLX5_EN_TLS=y +CONFIG_MLX5_SW_STEERING=y +CONFIG_MLX5_SF=y +CONFIG_MLX5_SF_MANAGER=y +CONFIG_MLXSW_CORE=m +CONFIG_MLXSW_CORE_HWMON=y +CONFIG_MLXSW_CORE_THERMAL=y +CONFIG_MLXSW_PCI=m +CONFIG_MLXSW_I2C=m +CONFIG_MLXSW_SPECTRUM=m +CONFIG_MLXSW_SPECTRUM_DCB=y +CONFIG_MLXSW_MINIMAL=m +CONFIG_MLXFW=m +CONFIG_NET_VENDOR_MICREL=y +CONFIG_KS8842=m +CONFIG_KS8851=m +CONFIG_KS8851_MLL=m +CONFIG_KSZ884X_PCI=m +CONFIG_NET_VENDOR_MICROCHIP=y +CONFIG_ENC28J60=m +# CONFIG_ENC28J60_WRITEVERIFY is not set +CONFIG_ENCX24J600=m +CONFIG_LAN743X=m +# CONFIG_VCAP is not set +CONFIG_NET_VENDOR_MICROSEMI=y +CONFIG_MSCC_OCELOT_SWITCH_LIB=m +CONFIG_NET_VENDOR_MICROSOFT=y +CONFIG_MICROSOFT_MANA=m +CONFIG_NET_VENDOR_MYRI=y +CONFIG_MYRI10GE=m +CONFIG_MYRI10GE_DCA=y +CONFIG_FEALNX=m +CONFIG_NET_VENDOR_NI=y +CONFIG_NI_XGE_MANAGEMENT_ENET=m +CONFIG_NET_VENDOR_NATSEMI=y +CONFIG_NATSEMI=m +CONFIG_NS83820=m +CONFIG_NET_VENDOR_NETERION=y +CONFIG_S2IO=m +CONFIG_NET_VENDOR_NETRONOME=y +CONFIG_NFP=m +CONFIG_NFP_APP_FLOWER=y +CONFIG_NFP_APP_ABM_NIC=y +CONFIG_NFP_NET_IPSEC=y +# CONFIG_NFP_DEBUG is not set +CONFIG_NET_VENDOR_8390=y +CONFIG_PCMCIA_AXNET=m +CONFIG_NE2K_PCI=m +CONFIG_PCMCIA_PCNET=m +CONFIG_NET_VENDOR_NVIDIA=y +CONFIG_FORCEDETH=m +CONFIG_NET_VENDOR_OKI=y +CONFIG_ETHOC=m +CONFIG_NET_VENDOR_PACKET_ENGINES=y +CONFIG_HAMACHI=m +CONFIG_YELLOWFIN=m +CONFIG_NET_VENDOR_PENSANDO=y +CONFIG_IONIC=m +CONFIG_NET_VENDOR_QLOGIC=y +CONFIG_QLA3XXX=m +CONFIG_QLCNIC=m +CONFIG_QLCNIC_SRIOV=y +CONFIG_QLCNIC_DCB=y +CONFIG_QLCNIC_HWMON=y +CONFIG_NETXEN_NIC=m +CONFIG_QED=m +CONFIG_QED_LL2=y +CONFIG_QED_SRIOV=y +CONFIG_QEDE=m +CONFIG_QED_RDMA=y +CONFIG_QED_ISCSI=y +CONFIG_QED_FCOE=y +CONFIG_QED_OOO=y +CONFIG_NET_VENDOR_BROCADE=y +CONFIG_BNA=m +CONFIG_NET_VENDOR_QUALCOMM=y +CONFIG_QCOM_EMAC=m +CONFIG_RMNET=m +CONFIG_NET_VENDOR_RDC=y +CONFIG_R6040=m +CONFIG_NET_VENDOR_REALTEK=y +CONFIG_ATP=m +CONFIG_8139CP=m +CONFIG_8139TOO=m +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +CONFIG_8139TOO_8129=y +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_R8169=m +CONFIG_NET_VENDOR_RENESAS=y +CONFIG_NET_VENDOR_ROCKER=y +CONFIG_ROCKER=m +CONFIG_NET_VENDOR_SAMSUNG=y +CONFIG_SXGBE_ETH=m +CONFIG_NET_VENDOR_SEEQ=y +CONFIG_NET_VENDOR_SILAN=y +CONFIG_SC92031=m +CONFIG_NET_VENDOR_SIS=y +CONFIG_SIS900=m +CONFIG_SIS190=m +CONFIG_NET_VENDOR_SOLARFLARE=y +CONFIG_SFC=m +CONFIG_SFC_MTD=y +CONFIG_SFC_MCDI_MON=y +CONFIG_SFC_SRIOV=y +CONFIG_SFC_MCDI_LOGGING=y +CONFIG_SFC_FALCON=m +CONFIG_SFC_FALCON_MTD=y +CONFIG_SFC_SIENA=m +CONFIG_SFC_SIENA_MTD=y +CONFIG_SFC_SIENA_MCDI_MON=y +CONFIG_SFC_SIENA_SRIOV=y +CONFIG_SFC_SIENA_MCDI_LOGGING=y +CONFIG_NET_VENDOR_SMSC=y +CONFIG_PCMCIA_SMC91C92=m +CONFIG_EPIC100=m +CONFIG_SMSC911X=m +CONFIG_SMSC9420=m +CONFIG_NET_VENDOR_SOCIONEXT=y +CONFIG_NET_VENDOR_STMICRO=y +CONFIG_STMMAC_ETH=m +# CONFIG_STMMAC_SELFTESTS is not set +CONFIG_STMMAC_PLATFORM=m +CONFIG_DWMAC_GENERIC=m +CONFIG_DWMAC_INTEL=m +# CONFIG_STMMAC_PCI is not set +CONFIG_NET_VENDOR_SUN=y +CONFIG_HAPPYMEAL=m +CONFIG_SUNGEM=m +CONFIG_CASSINI=m +CONFIG_NIU=m +CONFIG_NET_VENDOR_SYNOPSYS=y +CONFIG_DWC_XLGMAC=m +CONFIG_DWC_XLGMAC_PCI=m +CONFIG_NET_VENDOR_TEHUTI=y +CONFIG_TEHUTI=m +CONFIG_NET_VENDOR_TI=y +# CONFIG_TI_CPSW_PHY_SEL is not set +CONFIG_TLAN=m +CONFIG_NET_VENDOR_VERTEXCOM=y +# CONFIG_MSE102X is not set +CONFIG_NET_VENDOR_VIA=y +CONFIG_VIA_RHINE=m +# CONFIG_VIA_RHINE_MMIO is not set +CONFIG_VIA_VELOCITY=m +CONFIG_NET_VENDOR_WANGXUN=y +CONFIG_LIBWX=m +CONFIG_NGBE=m +CONFIG_TXGBE=m +CONFIG_NET_VENDOR_WIZNET=y +CONFIG_WIZNET_W5100=m +CONFIG_WIZNET_W5300=m +# CONFIG_WIZNET_BUS_DIRECT is not set +# CONFIG_WIZNET_BUS_INDIRECT is not set +CONFIG_WIZNET_BUS_ANY=y +CONFIG_WIZNET_W5100_SPI=m +CONFIG_NET_VENDOR_XILINX=y +# CONFIG_XILINX_EMACLITE is not set +CONFIG_XILINX_AXI_EMAC=m +# CONFIG_XILINX_LL_TEMAC is not set +CONFIG_NET_VENDOR_XIRCOM=y +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_FDDI=y +CONFIG_DEFXX=m +CONFIG_SKFP=m +# CONFIG_HIPPI is not set +CONFIG_NET_SB1000=m +CONFIG_PHYLINK=m +CONFIG_PHYLIB=m +CONFIG_SWPHY=y +# CONFIG_LED_TRIGGER_PHY is not set +CONFIG_FIXED_PHY=m +CONFIG_SFP=m + +# +# MII PHY device drivers +# +CONFIG_AMD_PHY=m +CONFIG_ADIN_PHY=m +CONFIG_ADIN1100_PHY=m +CONFIG_AQUANTIA_PHY=m +CONFIG_AX88796B_PHY=m +CONFIG_BROADCOM_PHY=m +CONFIG_BCM54140_PHY=m +CONFIG_BCM7XXX_PHY=m +CONFIG_BCM84881_PHY=m +CONFIG_BCM87XX_PHY=m +CONFIG_BCM_NET_PHYLIB=m +CONFIG_CICADA_PHY=m +CONFIG_CORTINA_PHY=m +CONFIG_DAVICOM_PHY=m +CONFIG_ICPLUS_PHY=m +CONFIG_LXT_PHY=m +CONFIG_INTEL_XWAY_PHY=m +CONFIG_LSI_ET1011C_PHY=m +CONFIG_MARVELL_PHY=m +CONFIG_MARVELL_10G_PHY=m +CONFIG_MARVELL_88Q2XXX_PHY=m +CONFIG_MARVELL_88X2222_PHY=m +CONFIG_MAXLINEAR_GPHY=m +CONFIG_MEDIATEK_GE_PHY=m +CONFIG_MICREL_PHY=m +CONFIG_MICROCHIP_T1S_PHY=m +CONFIG_MICROCHIP_PHY=m +CONFIG_MICROCHIP_T1_PHY=m +CONFIG_MICROSEMI_PHY=m +CONFIG_MOTORCOMM_PHY=m +CONFIG_NATIONAL_PHY=m +# CONFIG_NXP_CBTX_PHY is not set +# CONFIG_NXP_C45_TJA11XX_PHY is not set +CONFIG_NXP_TJA11XX_PHY=m +CONFIG_NCN26000_PHY=m +CONFIG_AT803X_PHY=m +CONFIG_QSEMI_PHY=m +CONFIG_REALTEK_PHY=m +CONFIG_RENESAS_PHY=m +CONFIG_ROCKCHIP_PHY=m +CONFIG_SMSC_PHY=m +CONFIG_STE10XP=m +CONFIG_TERANETICS_PHY=m +CONFIG_DP83822_PHY=m +CONFIG_DP83TC811_PHY=m +CONFIG_DP83848_PHY=m +CONFIG_DP83867_PHY=m +CONFIG_DP83869_PHY=m +CONFIG_DP83TD510_PHY=m +CONFIG_VITESSE_PHY=m +CONFIG_XILINX_GMII2RGMII=m +CONFIG_MICREL_KS8995MA=m +CONFIG_PSE_CONTROLLER=y +CONFIG_PSE_REGULATOR=m +CONFIG_CAN_DEV=m +CONFIG_CAN_VCAN=m +CONFIG_CAN_VXCAN=m +CONFIG_CAN_NETLINK=y +CONFIG_CAN_CALC_BITTIMING=y +CONFIG_CAN_RX_OFFLOAD=y +CONFIG_CAN_CAN327=m +CONFIG_CAN_JANZ_ICAN3=m +CONFIG_CAN_KVASER_PCIEFD=m +CONFIG_CAN_SLCAN=m +CONFIG_CAN_C_CAN=m +CONFIG_CAN_C_CAN_PLATFORM=m +CONFIG_CAN_C_CAN_PCI=m +CONFIG_CAN_CC770=m +CONFIG_CAN_CC770_ISA=m +CONFIG_CAN_CC770_PLATFORM=m +CONFIG_CAN_CTUCANFD=m +CONFIG_CAN_CTUCANFD_PCI=m +CONFIG_CAN_IFI_CANFD=m +CONFIG_CAN_M_CAN=m +# CONFIG_CAN_M_CAN_PCI is not set +# CONFIG_CAN_M_CAN_PLATFORM is not set +# CONFIG_CAN_M_CAN_TCAN4X5X is not set +CONFIG_CAN_PEAK_PCIEFD=m +CONFIG_CAN_SJA1000=m +CONFIG_CAN_EMS_PCI=m +CONFIG_CAN_EMS_PCMCIA=m +# CONFIG_CAN_F81601 is not set +CONFIG_CAN_KVASER_PCI=m +CONFIG_CAN_PEAK_PCI=m +CONFIG_CAN_PEAK_PCIEC=y +CONFIG_CAN_PEAK_PCMCIA=m +CONFIG_CAN_PLX_PCI=m +CONFIG_CAN_SJA1000_ISA=m +# CONFIG_CAN_SJA1000_PLATFORM is not set +CONFIG_CAN_SOFTING=m +CONFIG_CAN_SOFTING_CS=m + +# +# CAN SPI interfaces +# +# CONFIG_CAN_HI311X is not set +CONFIG_CAN_MCP251X=m +# CONFIG_CAN_MCP251XFD is not set +# end of CAN SPI interfaces + +# +# CAN USB interfaces +# +CONFIG_CAN_8DEV_USB=m +CONFIG_CAN_EMS_USB=m +CONFIG_CAN_ESD_USB=m +CONFIG_CAN_ETAS_ES58X=m +CONFIG_CAN_F81604=m +CONFIG_CAN_GS_USB=m +CONFIG_CAN_KVASER_USB=m +CONFIG_CAN_MCBA_USB=m +CONFIG_CAN_PEAK_USB=m +CONFIG_CAN_UCAN=m +# end of CAN USB interfaces + +# CONFIG_CAN_DEBUG_DEVICES is not set + +# +# MCTP Device Drivers +# +CONFIG_MCTP_SERIAL=m +CONFIG_MCTP_TRANSPORT_I2C=m +# end of MCTP Device Drivers + +CONFIG_MDIO_DEVICE=m +CONFIG_MDIO_BUS=m +CONFIG_FWNODE_MDIO=m +CONFIG_ACPI_MDIO=m +CONFIG_MDIO_DEVRES=m +CONFIG_MDIO_BITBANG=m +CONFIG_MDIO_BCM_UNIMAC=m +CONFIG_MDIO_CAVIUM=m +CONFIG_MDIO_GPIO=m +CONFIG_MDIO_I2C=m +CONFIG_MDIO_MVUSB=m +CONFIG_MDIO_MSCC_MIIM=m +CONFIG_MDIO_REGMAP=m +CONFIG_MDIO_THUNDER=m + +# +# MDIO Multiplexers +# + +# +# PCS device drivers +# +CONFIG_PCS_XPCS=m +CONFIG_PCS_LYNX=m +# end of PCS device drivers + +CONFIG_PLIP=m +CONFIG_PPP=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPPOATM=m +CONFIG_PPPOE=m +# CONFIG_PPPOE_HASH_BITS_1 is not set +# CONFIG_PPPOE_HASH_BITS_2 is not set +CONFIG_PPPOE_HASH_BITS_4=y +# CONFIG_PPPOE_HASH_BITS_8 is not set +CONFIG_PPPOE_HASH_BITS=4 +CONFIG_PPTP=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_SLIP=m +CONFIG_SLHC=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_SMART=y +CONFIG_SLIP_MODE_SLIP6=y +CONFIG_USB_NET_DRIVERS=m +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_RTL8152=m +CONFIG_USB_LAN78XX=m +CONFIG_USB_USBNET=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_AX88179_178A=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_EEM=m +CONFIG_USB_NET_CDC_NCM=m +CONFIG_USB_NET_HUAWEI_CDC_NCM=m +CONFIG_USB_NET_CDC_MBIM=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_SR9700=m +CONFIG_USB_NET_SR9800=m +CONFIG_USB_NET_SMSC75XX=m +CONFIG_USB_NET_SMSC95XX=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_NET_CDC_SUBSET_ENABLE=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_BELKIN=y +CONFIG_USB_ARMLINUX=y +CONFIG_USB_EPSON2888=y +CONFIG_USB_KC2190=y +CONFIG_USB_NET_ZAURUS=m +CONFIG_USB_NET_CX82310_ETH=m +CONFIG_USB_NET_KALMIA=m +CONFIG_USB_NET_QMI_WWAN=m +CONFIG_USB_HSO=m +CONFIG_USB_NET_INT51X1=m +CONFIG_USB_CDC_PHONET=m +CONFIG_USB_IPHETH=m +CONFIG_USB_SIERRA_NET=m +CONFIG_USB_VL600=m +CONFIG_USB_NET_CH9200=m +CONFIG_USB_NET_AQC111=m +CONFIG_USB_RTL8153_ECM=m +CONFIG_WLAN=y +CONFIG_WLAN_VENDOR_ADMTEK=y +CONFIG_ADM8211=m +CONFIG_ATH_COMMON=m +CONFIG_WLAN_VENDOR_ATH=y +CONFIG_ATH_DEBUG=y +# CONFIG_ATH_TRACEPOINTS is not set +CONFIG_ATH5K=m +CONFIG_ATH5K_DEBUG=y +# CONFIG_ATH5K_TRACER is not set +CONFIG_ATH5K_PCI=y +CONFIG_ATH9K_HW=m +CONFIG_ATH9K_COMMON=m +CONFIG_ATH9K_BTCOEX_SUPPORT=y +CONFIG_ATH9K=m +CONFIG_ATH9K_PCI=y +CONFIG_ATH9K_AHB=y +# CONFIG_ATH9K_DEBUGFS is not set +# CONFIG_ATH9K_DYNACK is not set +CONFIG_ATH9K_WOW=y +CONFIG_ATH9K_RFKILL=y +# CONFIG_ATH9K_CHANNEL_CONTEXT is not set +CONFIG_ATH9K_PCOEM=y +CONFIG_ATH9K_PCI_NO_EEPROM=m +CONFIG_ATH9K_HTC=m +# CONFIG_ATH9K_HTC_DEBUGFS is not set +CONFIG_ATH9K_HWRNG=y +CONFIG_CARL9170=m +CONFIG_CARL9170_LEDS=y +CONFIG_CARL9170_WPC=y +CONFIG_CARL9170_HWRNG=y +CONFIG_ATH6KL=m +CONFIG_ATH6KL_SDIO=m +CONFIG_ATH6KL_USB=m +# CONFIG_ATH6KL_DEBUG is not set +# CONFIG_ATH6KL_TRACING is not set +CONFIG_AR5523=m +CONFIG_WIL6210=m +CONFIG_WIL6210_ISR_COR=y +CONFIG_WIL6210_TRACING=y +# CONFIG_WIL6210_DEBUGFS is not set +CONFIG_ATH10K=m +CONFIG_ATH10K_CE=y +CONFIG_ATH10K_PCI=m +CONFIG_ATH10K_SDIO=m +CONFIG_ATH10K_USB=m +CONFIG_ATH10K_DEBUG=y +# CONFIG_ATH10K_DEBUGFS is not set +# CONFIG_ATH10K_TRACING is not set +CONFIG_WCN36XX=m +# CONFIG_WCN36XX_DEBUGFS is not set +CONFIG_ATH11K=m +CONFIG_ATH11K_PCI=m +# CONFIG_ATH11K_DEBUG is not set +# CONFIG_ATH11K_TRACING is not set +CONFIG_ATH12K=m +# CONFIG_ATH12K_DEBUG is not set +# CONFIG_ATH12K_TRACING is not set +CONFIG_WLAN_VENDOR_ATMEL=y +CONFIG_ATMEL=m +CONFIG_PCI_ATMEL=m +CONFIG_PCMCIA_ATMEL=m +CONFIG_AT76C50X_USB=m +CONFIG_WLAN_VENDOR_BROADCOM=y +CONFIG_B43=m +CONFIG_B43_BCMA=y +CONFIG_B43_SSB=y +CONFIG_B43_BUSES_BCMA_AND_SSB=y +# CONFIG_B43_BUSES_BCMA is not set +# CONFIG_B43_BUSES_SSB is not set +CONFIG_B43_PCI_AUTOSELECT=y +CONFIG_B43_PCICORE_AUTOSELECT=y +CONFIG_B43_SDIO=y +CONFIG_B43_BCMA_PIO=y +CONFIG_B43_PIO=y +CONFIG_B43_PHY_G=y +CONFIG_B43_PHY_N=y +CONFIG_B43_PHY_LP=y +CONFIG_B43_PHY_HT=y +CONFIG_B43_LEDS=y +CONFIG_B43_HWRNG=y +CONFIG_B43_DEBUG=y +CONFIG_B43LEGACY=m +CONFIG_B43LEGACY_PCI_AUTOSELECT=y +CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y +CONFIG_B43LEGACY_LEDS=y +CONFIG_B43LEGACY_HWRNG=y +CONFIG_B43LEGACY_DEBUG=y +CONFIG_B43LEGACY_DMA=y +CONFIG_B43LEGACY_PIO=y +CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y +# CONFIG_B43LEGACY_DMA_MODE is not set +# CONFIG_B43LEGACY_PIO_MODE is not set +CONFIG_BRCMUTIL=m +CONFIG_BRCMSMAC=m +CONFIG_BRCMSMAC_LEDS=y +CONFIG_BRCMFMAC=m +CONFIG_BRCMFMAC_PROTO_BCDC=y +CONFIG_BRCMFMAC_PROTO_MSGBUF=y +CONFIG_BRCMFMAC_SDIO=y +CONFIG_BRCMFMAC_USB=y +CONFIG_BRCMFMAC_PCIE=y +# CONFIG_BRCM_TRACING is not set +# CONFIG_BRCMDBG is not set +CONFIG_WLAN_VENDOR_CISCO=y +CONFIG_AIRO=m +CONFIG_AIRO_CS=m +CONFIG_WLAN_VENDOR_INTEL=y +CONFIG_IPW2100=m +CONFIG_IPW2100_MONITOR=y +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2200=m +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_RADIOTAP=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +# CONFIG_IPW2200_DEBUG is not set +CONFIG_LIBIPW=m +# CONFIG_LIBIPW_DEBUG is not set +CONFIG_IWLEGACY=m +CONFIG_IWL4965=m +CONFIG_IWL3945=m + +# +# iwl3945 / iwl4965 Debugging Options +# +# CONFIG_IWLEGACY_DEBUG is not set +# end of iwl3945 / iwl4965 Debugging Options + +CONFIG_IWLWIFI=m +CONFIG_IWLWIFI_LEDS=y +CONFIG_IWLDVM=m +CONFIG_IWLMVM=m +CONFIG_IWLWIFI_OPMODE_MODULAR=y + +# +# Debugging Options +# +CONFIG_IWLWIFI_DEBUG=y +# CONFIG_IWLWIFI_DEVICE_TRACING is not set +# end of Debugging Options + +CONFIG_WLAN_VENDOR_INTERSIL=y +CONFIG_HOSTAP=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_HOSTAP_PLX=m +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_CS=m +CONFIG_HERMES=m +CONFIG_HERMES_PRISM=y +CONFIG_HERMES_CACHE_FW_ON_INIT=y +CONFIG_PLX_HERMES=m +CONFIG_TMD_HERMES=m +CONFIG_NORTEL_HERMES=m +CONFIG_PCI_HERMES=m +CONFIG_PCMCIA_HERMES=m +CONFIG_PCMCIA_SPECTRUM=m +CONFIG_ORINOCO_USB=m +CONFIG_P54_COMMON=m +CONFIG_P54_USB=m +CONFIG_P54_PCI=m +CONFIG_P54_SPI=m +CONFIG_P54_SPI_DEFAULT_EEPROM=y +CONFIG_P54_LEDS=y +CONFIG_WLAN_VENDOR_MARVELL=y +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_USB=m +CONFIG_LIBERTAS_CS=m +CONFIG_LIBERTAS_SDIO=m +CONFIG_LIBERTAS_SPI=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_MESH=y +# CONFIG_LIBERTAS_THINFIRM is not set +CONFIG_MWIFIEX=m +CONFIG_MWIFIEX_SDIO=m +CONFIG_MWIFIEX_PCIE=m +CONFIG_MWIFIEX_USB=m +CONFIG_MWL8K=m +CONFIG_WLAN_VENDOR_MEDIATEK=y +CONFIG_MT7601U=m +CONFIG_MT76_CORE=m +CONFIG_MT76_LEDS=y +CONFIG_MT76_USB=m +CONFIG_MT76_SDIO=m +CONFIG_MT76x02_LIB=m +CONFIG_MT76x02_USB=m +CONFIG_MT76_CONNAC_LIB=m +CONFIG_MT792x_LIB=m +CONFIG_MT792x_USB=m +CONFIG_MT76x0_COMMON=m +CONFIG_MT76x0U=m +CONFIG_MT76x0E=m +CONFIG_MT76x2_COMMON=m +CONFIG_MT76x2E=m +CONFIG_MT76x2U=m +CONFIG_MT7603E=m +CONFIG_MT7615_COMMON=m +CONFIG_MT7615E=m +CONFIG_MT7663_USB_SDIO_COMMON=m +CONFIG_MT7663U=m +CONFIG_MT7663S=m +CONFIG_MT7915E=m +CONFIG_MT7921_COMMON=m +CONFIG_MT7921E=m +CONFIG_MT7921S=m +CONFIG_MT7921U=m +CONFIG_MT7996E=m +CONFIG_WLAN_VENDOR_MICROCHIP=y +CONFIG_WILC1000=m +CONFIG_WILC1000_SDIO=m +# CONFIG_WILC1000_SPI is not set +# CONFIG_WILC1000_HW_OOB_INTR is not set +CONFIG_WLAN_VENDOR_PURELIFI=y +CONFIG_PLFXLC=m +CONFIG_WLAN_VENDOR_RALINK=y +CONFIG_RT2X00=m +CONFIG_RT2400PCI=m +CONFIG_RT2500PCI=m +CONFIG_RT61PCI=m +CONFIG_RT2800PCI=m +CONFIG_RT2800PCI_RT33XX=y +CONFIG_RT2800PCI_RT35XX=y +CONFIG_RT2800PCI_RT53XX=y +CONFIG_RT2800PCI_RT3290=y +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT33XX=y +CONFIG_RT2800USB_RT35XX=y +CONFIG_RT2800USB_RT3573=y +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +CONFIG_RT2800USB_UNKNOWN=y +CONFIG_RT2800_LIB=m +CONFIG_RT2800_LIB_MMIO=m +CONFIG_RT2X00_LIB_MMIO=m +CONFIG_RT2X00_LIB_PCI=m +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_RT2X00_LIB_LEDS=y +# CONFIG_RT2X00_DEBUG is not set +CONFIG_WLAN_VENDOR_REALTEK=y +CONFIG_RTL8180=m +CONFIG_RTL8187=m +CONFIG_RTL8187_LEDS=y +CONFIG_RTL_CARDS=m +CONFIG_RTL8192CE=m +CONFIG_RTL8192SE=m +CONFIG_RTL8192DE=m +CONFIG_RTL8723AE=m +CONFIG_RTL8723BE=m +CONFIG_RTL8188EE=m +CONFIG_RTL8192EE=m +CONFIG_RTL8821AE=m +CONFIG_RTL8192CU=m +CONFIG_RTLWIFI=m +CONFIG_RTLWIFI_PCI=m +CONFIG_RTLWIFI_USB=m +CONFIG_RTLWIFI_DEBUG=y +CONFIG_RTL8192C_COMMON=m +CONFIG_RTL8723_COMMON=m +CONFIG_RTLBTCOEXIST=m +CONFIG_RTL8XXXU=m +CONFIG_RTL8XXXU_UNTESTED=y +CONFIG_RTW88=m +CONFIG_RTW88_CORE=m +CONFIG_RTW88_PCI=m +CONFIG_RTW88_SDIO=m +CONFIG_RTW88_USB=m +CONFIG_RTW88_8822B=m +CONFIG_RTW88_8822C=m +CONFIG_RTW88_8723D=m +CONFIG_RTW88_8821C=m +CONFIG_RTW88_8822BE=m +CONFIG_RTW88_8822BS=m +CONFIG_RTW88_8822BU=m +CONFIG_RTW88_8822CE=m +CONFIG_RTW88_8822CS=m +CONFIG_RTW88_8822CU=m +CONFIG_RTW88_8723DE=m +CONFIG_RTW88_8723DS=m +CONFIG_RTW88_8723DU=m +CONFIG_RTW88_8821CE=m +CONFIG_RTW88_8821CS=m +CONFIG_RTW88_8821CU=m +CONFIG_RTW88_DEBUG=y +CONFIG_RTW88_DEBUGFS=y +CONFIG_RTW89=m +CONFIG_RTW89_CORE=m +CONFIG_RTW89_PCI=m +CONFIG_RTW89_8851B=m +CONFIG_RTW89_8852A=m +CONFIG_RTW89_8852B=m +CONFIG_RTW89_8852C=m +CONFIG_RTW89_8851BE=m +CONFIG_RTW89_8852AE=m +CONFIG_RTW89_8852BE=m +CONFIG_RTW89_8852CE=m +CONFIG_RTW89_DEBUG=y +CONFIG_RTW89_DEBUGMSG=y +CONFIG_RTW89_DEBUGFS=y +CONFIG_WLAN_VENDOR_RSI=y +CONFIG_RSI_91X=m +CONFIG_RSI_DEBUGFS=y +CONFIG_RSI_SDIO=m +CONFIG_RSI_USB=m +CONFIG_RSI_COEX=y +CONFIG_WLAN_VENDOR_SILABS=y +CONFIG_WFX=m +CONFIG_WLAN_VENDOR_ST=y +CONFIG_CW1200=m +CONFIG_CW1200_WLAN_SDIO=m +CONFIG_CW1200_WLAN_SPI=m +CONFIG_WLAN_VENDOR_TI=y +CONFIG_WL1251=m +CONFIG_WL1251_SPI=m +CONFIG_WL1251_SDIO=m +CONFIG_WL12XX=m +CONFIG_WL18XX=m +CONFIG_WLCORE=m +CONFIG_WLCORE_SDIO=m +CONFIG_WLAN_VENDOR_ZYDAS=y +CONFIG_USB_ZD1201=m +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +CONFIG_WLAN_VENDOR_QUANTENNA=y +CONFIG_QTNFMAC=m +CONFIG_QTNFMAC_PCIE=m +CONFIG_PCMCIA_RAYCS=m +CONFIG_PCMCIA_WL3501=m +CONFIG_USB_NET_RNDIS_WLAN=m +CONFIG_MAC80211_HWSIM=m +CONFIG_VIRT_WIFI=m +CONFIG_WAN=y +CONFIG_HDLC=m +CONFIG_HDLC_RAW=m +CONFIG_HDLC_RAW_ETH=m +CONFIG_HDLC_CISCO=m +CONFIG_HDLC_FR=m +CONFIG_HDLC_PPP=m +CONFIG_HDLC_X25=m +CONFIG_PCI200SYN=m +CONFIG_WANXL=m +CONFIG_PC300TOO=m +CONFIG_FARSYNC=m +CONFIG_LAPBETHER=m +CONFIG_IEEE802154_DRIVERS=m +CONFIG_IEEE802154_FAKELB=m +CONFIG_IEEE802154_AT86RF230=m +CONFIG_IEEE802154_MRF24J40=m +CONFIG_IEEE802154_CC2520=m +CONFIG_IEEE802154_ATUSB=m +CONFIG_IEEE802154_ADF7242=m +CONFIG_IEEE802154_CA8210=m +# CONFIG_IEEE802154_CA8210_DEBUGFS is not set +# CONFIG_IEEE802154_MCR20A is not set +# CONFIG_IEEE802154_HWSIM is not set + +# +# Wireless WAN +# +CONFIG_WWAN=y +CONFIG_WWAN_DEBUGFS=y +# CONFIG_WWAN_HWSIM is not set +CONFIG_MHI_WWAN_CTRL=m +CONFIG_MHI_WWAN_MBIM=m +# CONFIG_RPMSG_WWAN_CTRL is not set +CONFIG_IOSM=m +CONFIG_MTK_T7XX=m +# end of Wireless WAN + +CONFIG_XEN_NETDEV_FRONTEND=m +CONFIG_XEN_NETDEV_BACKEND=m +CONFIG_VMXNET3=m +CONFIG_FUJITSU_ES=m +CONFIG_USB4_NET=m +CONFIG_HYPERV_NET=m +# CONFIG_NETDEVSIM is not set +CONFIG_NET_FAILOVER=m +CONFIG_ISDN=y +CONFIG_ISDN_CAPI=y +CONFIG_CAPI_TRACE=y +CONFIG_ISDN_CAPI_MIDDLEWARE=y +CONFIG_MISDN=m +CONFIG_MISDN_DSP=m +CONFIG_MISDN_L1OIP=m + +# +# mISDN hardware drivers +# +CONFIG_MISDN_HFCPCI=m +CONFIG_MISDN_HFCMULTI=m +CONFIG_MISDN_HFCUSB=m +CONFIG_MISDN_AVMFRITZ=m +CONFIG_MISDN_SPEEDFAX=m +CONFIG_MISDN_INFINEON=m +CONFIG_MISDN_W6692=m +CONFIG_MISDN_NETJET=m +CONFIG_MISDN_HDLC=m +CONFIG_MISDN_IPAC=m +CONFIG_MISDN_ISAR=m + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_LEDS=m +CONFIG_INPUT_FF_MEMLESS=m +CONFIG_INPUT_SPARSEKMAP=m +CONFIG_INPUT_MATRIXKMAP=m +CONFIG_INPUT_VIVALDIFMAP=m + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_EVDEV=m +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ADC=m +CONFIG_KEYBOARD_ADP5520=m +CONFIG_KEYBOARD_ADP5588=m +CONFIG_KEYBOARD_ADP5589=m +CONFIG_KEYBOARD_APPLESPI=m +CONFIG_KEYBOARD_ATKBD=m +CONFIG_KEYBOARD_QT1050=m +CONFIG_KEYBOARD_QT1070=m +CONFIG_KEYBOARD_QT2160=m +CONFIG_KEYBOARD_DLINK_DIR685=m +CONFIG_KEYBOARD_LKKBD=m +CONFIG_KEYBOARD_GPIO=m +CONFIG_KEYBOARD_GPIO_POLLED=m +CONFIG_KEYBOARD_TCA6416=m +CONFIG_KEYBOARD_TCA8418=m +CONFIG_KEYBOARD_MATRIX=m +CONFIG_KEYBOARD_LM8323=m +CONFIG_KEYBOARD_LM8333=m +CONFIG_KEYBOARD_MAX7359=m +CONFIG_KEYBOARD_MCS=m +CONFIG_KEYBOARD_MPR121=m +CONFIG_KEYBOARD_NEWTON=m +CONFIG_KEYBOARD_OPENCORES=m +CONFIG_KEYBOARD_PINEPHONE=m +CONFIG_KEYBOARD_SAMSUNG=m +CONFIG_KEYBOARD_STOWAWAY=m +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_KEYBOARD_IQS62X=m +CONFIG_KEYBOARD_TM2_TOUCHKEY=m +CONFIG_KEYBOARD_TWL4030=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_KEYBOARD_CROS_EC=m +CONFIG_KEYBOARD_CYPRESS_SF=m +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=m +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_BYD=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS=y +CONFIG_MOUSE_PS2_CYPRESS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +CONFIG_MOUSE_PS2_ELANTECH=y +CONFIG_MOUSE_PS2_ELANTECH_SMBUS=y +CONFIG_MOUSE_PS2_SENTELIC=y +CONFIG_MOUSE_PS2_TOUCHKIT=y +CONFIG_MOUSE_PS2_FOCALTECH=y +CONFIG_MOUSE_PS2_VMMOUSE=y +CONFIG_MOUSE_PS2_SMBUS=y +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_APPLETOUCH=m +CONFIG_MOUSE_BCM5974=m +CONFIG_MOUSE_CYAPA=m +CONFIG_MOUSE_ELAN_I2C=m +CONFIG_MOUSE_ELAN_I2C_I2C=y +CONFIG_MOUSE_ELAN_I2C_SMBUS=y +CONFIG_MOUSE_VSXXXAA=m +CONFIG_MOUSE_GPIO=m +CONFIG_MOUSE_SYNAPTICS_I2C=m +CONFIG_MOUSE_SYNAPTICS_USB=m +CONFIG_INPUT_JOYSTICK=y +CONFIG_JOYSTICK_ANALOG=m +CONFIG_JOYSTICK_A3D=m +CONFIG_JOYSTICK_ADC=m +CONFIG_JOYSTICK_ADI=m +CONFIG_JOYSTICK_COBRA=m +CONFIG_JOYSTICK_GF2K=m +CONFIG_JOYSTICK_GRIP=m +CONFIG_JOYSTICK_GRIP_MP=m +CONFIG_JOYSTICK_GUILLEMOT=m +CONFIG_JOYSTICK_INTERACT=m +CONFIG_JOYSTICK_SIDEWINDER=m +CONFIG_JOYSTICK_TMDC=m +CONFIG_JOYSTICK_IFORCE=m +CONFIG_JOYSTICK_IFORCE_USB=m +CONFIG_JOYSTICK_IFORCE_232=m +CONFIG_JOYSTICK_WARRIOR=m +CONFIG_JOYSTICK_MAGELLAN=m +CONFIG_JOYSTICK_SPACEORB=m +CONFIG_JOYSTICK_SPACEBALL=m +CONFIG_JOYSTICK_STINGER=m +CONFIG_JOYSTICK_TWIDJOY=m +CONFIG_JOYSTICK_ZHENHUA=m +CONFIG_JOYSTICK_DB9=m +CONFIG_JOYSTICK_GAMECON=m +CONFIG_JOYSTICK_TURBOGRAFX=m +CONFIG_JOYSTICK_AS5011=m +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +CONFIG_JOYSTICK_WALKERA0701=m +CONFIG_JOYSTICK_PSXPAD_SPI=m +CONFIG_JOYSTICK_PSXPAD_SPI_FF=y +CONFIG_JOYSTICK_PXRC=m +CONFIG_JOYSTICK_QWIIC=m +CONFIG_JOYSTICK_FSIA6B=m +CONFIG_JOYSTICK_SENSEHAT=m +CONFIG_INPUT_TABLET=y +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_HANWANG=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_PEGASUS=m +CONFIG_TABLET_SERIAL_WACOM4=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_88PM860X=m +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_AD7877=m +CONFIG_TOUCHSCREEN_AD7879=m +CONFIG_TOUCHSCREEN_AD7879_I2C=m +CONFIG_TOUCHSCREEN_AD7879_SPI=m +CONFIG_TOUCHSCREEN_ADC=m +CONFIG_TOUCHSCREEN_ATMEL_MXT=m +CONFIG_TOUCHSCREEN_ATMEL_MXT_T37=y +CONFIG_TOUCHSCREEN_AUO_PIXCIR=m +CONFIG_TOUCHSCREEN_BU21013=m +CONFIG_TOUCHSCREEN_BU21029=m +CONFIG_TOUCHSCREEN_CHIPONE_ICN8505=m +CONFIG_TOUCHSCREEN_CY8CTMA140=m +CONFIG_TOUCHSCREEN_CY8CTMG110=m +CONFIG_TOUCHSCREEN_CYTTSP_CORE=m +CONFIG_TOUCHSCREEN_CYTTSP_I2C=m +CONFIG_TOUCHSCREEN_CYTTSP_SPI=m +CONFIG_TOUCHSCREEN_CYTTSP4_CORE=m +CONFIG_TOUCHSCREEN_CYTTSP4_I2C=m +CONFIG_TOUCHSCREEN_CYTTSP4_SPI=m +CONFIG_TOUCHSCREEN_CYTTSP5=m +CONFIG_TOUCHSCREEN_DA9034=m +CONFIG_TOUCHSCREEN_DA9052=m +CONFIG_TOUCHSCREEN_DYNAPRO=m +CONFIG_TOUCHSCREEN_HAMPSHIRE=m +CONFIG_TOUCHSCREEN_EETI=m +CONFIG_TOUCHSCREEN_EGALAX_SERIAL=m +CONFIG_TOUCHSCREEN_EXC3000=m +CONFIG_TOUCHSCREEN_FUJITSU=m +CONFIG_TOUCHSCREEN_GOODIX=m +CONFIG_TOUCHSCREEN_HIDEEP=m +CONFIG_TOUCHSCREEN_HYCON_HY46XX=m +CONFIG_TOUCHSCREEN_HYNITRON_CSTXXX=m +CONFIG_TOUCHSCREEN_ILI210X=m +CONFIG_TOUCHSCREEN_ILITEK=m +CONFIG_TOUCHSCREEN_S6SY761=m +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_EKTF2127=m +CONFIG_TOUCHSCREEN_ELAN=m +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_WACOM_W8001=m +CONFIG_TOUCHSCREEN_WACOM_I2C=m +CONFIG_TOUCHSCREEN_MAX11801=m +CONFIG_TOUCHSCREEN_MCS5000=m +CONFIG_TOUCHSCREEN_MMS114=m +CONFIG_TOUCHSCREEN_MELFAS_MIP4=m +CONFIG_TOUCHSCREEN_MSG2638=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_NOVATEK_NVT_TS=m +CONFIG_TOUCHSCREEN_IMAGIS=m +CONFIG_TOUCHSCREEN_INEXIO=m +CONFIG_TOUCHSCREEN_PENMOUNT=m +CONFIG_TOUCHSCREEN_EDT_FT5X06=m +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m +CONFIG_TOUCHSCREEN_TOUCHWIN=m +CONFIG_TOUCHSCREEN_PIXCIR=m +CONFIG_TOUCHSCREEN_WDT87XX_I2C=m +CONFIG_TOUCHSCREEN_WM831X=m +CONFIG_TOUCHSCREEN_WM97XX=m +CONFIG_TOUCHSCREEN_WM9705=y +CONFIG_TOUCHSCREEN_WM9712=y +CONFIG_TOUCHSCREEN_WM9713=y +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_MC13783=m +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_IRTOUCH=y +CONFIG_TOUCHSCREEN_USB_IDEALTEK=y +CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y +CONFIG_TOUCHSCREEN_USB_GOTOP=y +CONFIG_TOUCHSCREEN_USB_JASTEC=y +CONFIG_TOUCHSCREEN_USB_ELO=y +CONFIG_TOUCHSCREEN_USB_E2I=y +CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y +CONFIG_TOUCHSCREEN_USB_ETT_TC45USB=y +CONFIG_TOUCHSCREEN_USB_NEXIO=y +CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y +CONFIG_TOUCHSCREEN_TOUCHIT213=m +CONFIG_TOUCHSCREEN_TSC_SERIO=m +CONFIG_TOUCHSCREEN_TSC200X_CORE=m +CONFIG_TOUCHSCREEN_TSC2004=m +CONFIG_TOUCHSCREEN_TSC2005=m +CONFIG_TOUCHSCREEN_TSC2007=m +CONFIG_TOUCHSCREEN_TSC2007_IIO=y +CONFIG_TOUCHSCREEN_PCAP=m +CONFIG_TOUCHSCREEN_RM_TS=m +CONFIG_TOUCHSCREEN_SILEAD=m +CONFIG_TOUCHSCREEN_SIS_I2C=m +CONFIG_TOUCHSCREEN_ST1232=m +CONFIG_TOUCHSCREEN_STMFTS=m +CONFIG_TOUCHSCREEN_SUR40=m +CONFIG_TOUCHSCREEN_SURFACE3_SPI=m +CONFIG_TOUCHSCREEN_SX8654=m +CONFIG_TOUCHSCREEN_TPS6507X=m +CONFIG_TOUCHSCREEN_ZET6223=m +CONFIG_TOUCHSCREEN_ZFORCE=m +CONFIG_TOUCHSCREEN_COLIBRI_VF50=m +CONFIG_TOUCHSCREEN_ROHM_BU21023=m +CONFIG_TOUCHSCREEN_IQS5XX=m +CONFIG_TOUCHSCREEN_IQS7211=m +CONFIG_TOUCHSCREEN_ZINITIX=m +CONFIG_TOUCHSCREEN_HIMAX_HX83112B=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_88PM860X_ONKEY=m +CONFIG_INPUT_88PM80X_ONKEY=m +CONFIG_INPUT_AD714X=m +CONFIG_INPUT_AD714X_I2C=m +CONFIG_INPUT_AD714X_SPI=m +CONFIG_INPUT_ARIZONA_HAPTICS=m +CONFIG_INPUT_BMA150=m +CONFIG_INPUT_E3X0_BUTTON=m +CONFIG_INPUT_PCSPKR=m +CONFIG_INPUT_MAX77693_HAPTIC=m +CONFIG_INPUT_MAX8925_ONKEY=m +CONFIG_INPUT_MAX8997_HAPTIC=m +CONFIG_INPUT_MC13783_PWRBUTTON=m +CONFIG_INPUT_MMA8450=m +CONFIG_INPUT_APANEL=m +CONFIG_INPUT_GPIO_BEEPER=m +CONFIG_INPUT_GPIO_DECODER=m +CONFIG_INPUT_GPIO_VIBRA=m +CONFIG_INPUT_ATLAS_BTNS=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_KXTJ9=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_YEALINK=m +CONFIG_INPUT_CM109=m +CONFIG_INPUT_REGULATOR_HAPTIC=m +CONFIG_INPUT_RETU_PWRBUTTON=m +CONFIG_INPUT_AXP20X_PEK=m +CONFIG_INPUT_TWL4030_PWRBUTTON=m +CONFIG_INPUT_TWL4030_VIBRA=m +CONFIG_INPUT_TWL6040_VIBRA=m +CONFIG_INPUT_UINPUT=m +CONFIG_INPUT_PALMAS_PWRBUTTON=m +CONFIG_INPUT_PCF8574=m +CONFIG_INPUT_PWM_BEEPER=m +CONFIG_INPUT_PWM_VIBRA=m +CONFIG_INPUT_GPIO_ROTARY_ENCODER=m +CONFIG_INPUT_DA7280_HAPTICS=m +CONFIG_INPUT_DA9052_ONKEY=m +CONFIG_INPUT_DA9055_ONKEY=m +CONFIG_INPUT_DA9063_ONKEY=m +CONFIG_INPUT_WM831X_ON=m +CONFIG_INPUT_PCAP=m +CONFIG_INPUT_ADXL34X=m +CONFIG_INPUT_ADXL34X_I2C=m +CONFIG_INPUT_ADXL34X_SPI=m +CONFIG_INPUT_IBM_PANEL=m +CONFIG_INPUT_IMS_PCU=m +CONFIG_INPUT_IQS269A=m +CONFIG_INPUT_IQS626A=m +CONFIG_INPUT_IQS7222=m +CONFIG_INPUT_CMA3000=m +CONFIG_INPUT_CMA3000_I2C=m +CONFIG_INPUT_XEN_KBDDEV_FRONTEND=m +CONFIG_INPUT_IDEAPAD_SLIDEBAR=m +CONFIG_INPUT_SOC_BUTTON_ARRAY=m +CONFIG_INPUT_DRV260X_HAPTICS=m +CONFIG_INPUT_DRV2665_HAPTICS=m +CONFIG_INPUT_DRV2667_HAPTICS=m +CONFIG_RMI4_CORE=m +CONFIG_RMI4_I2C=m +CONFIG_RMI4_SPI=m +CONFIG_RMI4_SMB=m +CONFIG_RMI4_F03=y +CONFIG_RMI4_F03_SERIO=m +CONFIG_RMI4_2D_SENSOR=y +CONFIG_RMI4_F11=y +CONFIG_RMI4_F12=y +CONFIG_RMI4_F30=y +CONFIG_RMI4_F34=y +CONFIG_RMI4_F3A=y +CONFIG_RMI4_F54=y +CONFIG_RMI4_F55=y + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=m +CONFIG_SERIO_CT82C710=m +CONFIG_SERIO_PARKBD=m +CONFIG_SERIO_PCIPS2=m +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_RAW=m +CONFIG_SERIO_ALTERA_PS2=m +CONFIG_SERIO_PS2MULT=m +CONFIG_SERIO_ARC_PS2=m +CONFIG_HYPERV_KEYBOARD=m +CONFIG_SERIO_GPIO_PS2=m +CONFIG_USERIO=m +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_FM801=m +# end of Hardware I/O ports +# end of Input device support + +# +# Character devices +# +CONFIG_TTY=y +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_CONSOLE_SLEEP=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=0 +# CONFIG_LEGACY_TIOCSTI is not set +CONFIG_LDISC_AUTOLOAD=y + +# +# Serial drivers +# +CONFIG_SERIAL_EARLYCON=y +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set +CONFIG_SERIAL_8250_PNP=y +# CONFIG_SERIAL_8250_16550A_VARIANTS is not set +CONFIG_SERIAL_8250_FINTEK=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_DMA=y +CONFIG_SERIAL_8250_PCILIB=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_EXAR=y +CONFIG_SERIAL_8250_CS=m +CONFIG_SERIAL_8250_NR_UARTS=32 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_PCI1XXXX=m +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_RSA=y +CONFIG_SERIAL_8250_DWLIB=y +CONFIG_SERIAL_8250_DW=m +CONFIG_SERIAL_8250_RT288X=y +CONFIG_SERIAL_8250_LPSS=m +CONFIG_SERIAL_8250_MID=m +CONFIG_SERIAL_8250_PERICOM=m + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_MAX3100=m +CONFIG_SERIAL_MAX310X=m +CONFIG_SERIAL_UARTLITE=m +CONFIG_SERIAL_UARTLITE_NR_UARTS=1 +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_JSM=m +# CONFIG_SERIAL_LANTIQ is not set +CONFIG_SERIAL_SCCNXP=m +CONFIG_SERIAL_SC16IS7XX_CORE=m +CONFIG_SERIAL_SC16IS7XX=m +CONFIG_SERIAL_SC16IS7XX_I2C=y +# CONFIG_SERIAL_SC16IS7XX_SPI is not set +CONFIG_SERIAL_ALTERA_JTAGUART=m +CONFIG_SERIAL_ALTERA_UART=m +CONFIG_SERIAL_ALTERA_UART_MAXPORTS=4 +CONFIG_SERIAL_ALTERA_UART_BAUDRATE=115200 +CONFIG_SERIAL_ARC=m +CONFIG_SERIAL_ARC_NR_PORTS=1 +CONFIG_SERIAL_RP2=m +CONFIG_SERIAL_RP2_NR_UARTS=32 +CONFIG_SERIAL_FSL_LPUART=m +CONFIG_SERIAL_FSL_LINFLEXUART=m +CONFIG_SERIAL_SPRD=m +# end of Serial drivers + +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_MOXA_INTELLIO=m +CONFIG_MOXA_SMARTIO=m +CONFIG_N_HDLC=m +CONFIG_IPWIRELESS=m +# CONFIG_N_GSM is not set +CONFIG_NOZOMI=m +CONFIG_NULL_TTY=y +CONFIG_HVC_DRIVER=y +CONFIG_HVC_IRQ=y +CONFIG_HVC_XEN=y +CONFIG_HVC_XEN_FRONTEND=y +CONFIG_RPMSG_TTY=m +CONFIG_SERIAL_DEV_BUS=y +CONFIG_SERIAL_DEV_CTRL_TTYPORT=y +# CONFIG_TTY_PRINTK is not set +CONFIG_PRINTER=m +CONFIG_LP_CONSOLE=y +CONFIG_PPDEV=m +CONFIG_VIRTIO_CONSOLE=m +CONFIG_IPMI_HANDLER=m +CONFIG_IPMI_DMI_DECODE=y +CONFIG_IPMI_PLAT_DATA=y +CONFIG_IPMI_PANIC_EVENT=y +CONFIG_IPMI_PANIC_STRING=y +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_SSIF=m +CONFIG_IPMI_IPMB=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPMI_POWEROFF=m +CONFIG_SSIF_IPMI_BMC=m +CONFIG_IPMB_DEVICE_INTERFACE=m +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_TIMERIOMEM=m +CONFIG_HW_RANDOM_INTEL=m +CONFIG_HW_RANDOM_AMD=m +CONFIG_HW_RANDOM_BA431=m +CONFIG_HW_RANDOM_VIA=m +CONFIG_HW_RANDOM_VIRTIO=m +CONFIG_HW_RANDOM_XIPHERA=m +CONFIG_APPLICOM=m +CONFIG_MWAVE=m +CONFIG_DEVMEM=y +CONFIG_NVRAM=m +CONFIG_DEVPORT=y +CONFIG_HPET=y +CONFIG_HPET_MMAP=y +CONFIG_HPET_MMAP_DEFAULT=y +CONFIG_HANGCHECK_TIMER=m +CONFIG_TCG_TPM=m +CONFIG_HW_RANDOM_TPM=y +CONFIG_TCG_TIS_CORE=m +CONFIG_TCG_TIS=m +CONFIG_TCG_TIS_SPI=m +CONFIG_TCG_TIS_SPI_CR50=y +CONFIG_TCG_TIS_I2C=m +CONFIG_TCG_TIS_I2C_CR50=m +CONFIG_TCG_TIS_I2C_ATMEL=m +CONFIG_TCG_TIS_I2C_INFINEON=m +CONFIG_TCG_TIS_I2C_NUVOTON=m +CONFIG_TCG_NSC=m +CONFIG_TCG_ATMEL=m +CONFIG_TCG_INFINEON=m +CONFIG_TCG_XEN=m +CONFIG_TCG_CRB=m +CONFIG_TCG_VTPM_PROXY=m +CONFIG_TCG_TIS_ST33ZP24=m +CONFIG_TCG_TIS_ST33ZP24_I2C=m +CONFIG_TCG_TIS_ST33ZP24_SPI=m +CONFIG_TELCLOCK=m +CONFIG_XILLYBUS_CLASS=m +CONFIG_XILLYBUS=m +CONFIG_XILLYBUS_PCIE=m +CONFIG_XILLYUSB=m +# end of Character devices + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_ACPI_I2C_OPREGION=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_MUX=m + +# +# Multiplexer I2C Chip support +# +CONFIG_I2C_MUX_GPIO=m +CONFIG_I2C_MUX_LTC4306=m +CONFIG_I2C_MUX_PCA9541=m +CONFIG_I2C_MUX_PCA954x=m +CONFIG_I2C_MUX_REG=m +CONFIG_I2C_MUX_MLXCPLD=m +# end of Multiplexer I2C Chip support + +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_SMBUS=m +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCA=m + +# +# I2C Hardware Bus support +# + +# +# PC SMBus host controller drivers +# +CONFIG_I2C_CCGX_UCSI=m +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_AMD_MP2=m +CONFIG_I2C_I801=m +CONFIG_I2C_ISCH=m +CONFIG_I2C_ISMT=m +CONFIG_I2C_PIIX4=m +CONFIG_I2C_CHT_WC=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_NFORCE2_S4985=m +CONFIG_I2C_NVIDIA_GPU=m +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m + +# +# ACPI drivers +# +CONFIG_I2C_SCMI=m + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +CONFIG_I2C_CBUS_GPIO=m +CONFIG_I2C_DESIGNWARE_CORE=y +CONFIG_I2C_DESIGNWARE_SLAVE=y +CONFIG_I2C_DESIGNWARE_PLATFORM=y +CONFIG_I2C_DESIGNWARE_BAYTRAIL=y +CONFIG_I2C_DESIGNWARE_PCI=m +CONFIG_I2C_EMEV2=m +CONFIG_I2C_GPIO=m +# CONFIG_I2C_GPIO_FAULT_INJECTOR is not set +CONFIG_I2C_KEMPLD=m +CONFIG_I2C_OCORES=m +CONFIG_I2C_PCA_PLATFORM=m +CONFIG_I2C_SIMTEC=m +CONFIG_I2C_XILINX=m + +# +# External I2C/SMBus adapter drivers +# +CONFIG_I2C_DIOLAN_U2C=m +CONFIG_I2C_DLN2=m +CONFIG_I2C_CP2615=m +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PCI1XXXX=m +CONFIG_I2C_ROBOTFUZZ_OSIF=m +CONFIG_I2C_TAOS_EVM=m +CONFIG_I2C_TINY_USB=m +CONFIG_I2C_VIPERBOARD=m + +# +# Other I2C/SMBus bus drivers +# +CONFIG_I2C_MLXCPLD=m +CONFIG_I2C_CROS_EC_TUNNEL=m +CONFIG_I2C_VIRTIO=m +# end of I2C Hardware Bus support + +CONFIG_I2C_STUB=m +CONFIG_I2C_SLAVE=y +CONFIG_I2C_SLAVE_EEPROM=m +# CONFIG_I2C_SLAVE_TESTUNIT is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# end of I2C support + +CONFIG_I3C=m +CONFIG_CDNS_I3C_MASTER=m +CONFIG_DW_I3C_MASTER=m +CONFIG_SVC_I3C_MASTER=m +CONFIG_MIPI_I3C_HCI=m +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y +CONFIG_SPI_MEM=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_ALTERA=m +CONFIG_SPI_ALTERA_CORE=m +CONFIG_SPI_AXI_SPI_ENGINE=m +CONFIG_SPI_BITBANG=m +CONFIG_SPI_BUTTERFLY=m +CONFIG_SPI_CADENCE=m +CONFIG_SPI_CS42L43=m +CONFIG_SPI_DESIGNWARE=m +# CONFIG_SPI_DW_DMA is not set +CONFIG_SPI_DW_PCI=m +CONFIG_SPI_DW_MMIO=m +CONFIG_SPI_DLN2=m +CONFIG_SPI_GPIO=m +CONFIG_SPI_INTEL=m +CONFIG_SPI_INTEL_PCI=m +CONFIG_SPI_INTEL_PLATFORM=m +CONFIG_SPI_LM70_LLP=m +# CONFIG_SPI_MICROCHIP_CORE is not set +# CONFIG_SPI_MICROCHIP_CORE_QSPI is not set +CONFIG_SPI_LANTIQ_SSC=m +CONFIG_SPI_OC_TINY=m +CONFIG_SPI_PCI1XXXX=m +CONFIG_SPI_PXA2XX=m +CONFIG_SPI_PXA2XX_PCI=m +CONFIG_SPI_SC18IS602=m +CONFIG_SPI_SIFIVE=m +CONFIG_SPI_MXIC=m +CONFIG_SPI_XCOMM=m +CONFIG_SPI_XILINX=m +CONFIG_SPI_ZYNQMP_GQSPI=m +CONFIG_SPI_AMD=m + +# +# SPI Multiplexer support +# +# CONFIG_SPI_MUX is not set + +# +# SPI Protocol Masters +# +CONFIG_SPI_SPIDEV=m +CONFIG_SPI_LOOPBACK_TEST=m +CONFIG_SPI_TLE62X0=m +# CONFIG_SPI_SLAVE is not set +CONFIG_SPI_DYNAMIC=y +CONFIG_SPMI=m +# CONFIG_SPMI_HISI3670 is not set +CONFIG_HSI=m +CONFIG_HSI_BOARDINFO=y + +# +# HSI controllers +# + +# +# HSI clients +# +CONFIG_HSI_CHAR=m +CONFIG_PPS=m +# CONFIG_PPS_DEBUG is not set + +# +# PPS clients support +# +CONFIG_PPS_CLIENT_KTIMER=m +CONFIG_PPS_CLIENT_LDISC=m +CONFIG_PPS_CLIENT_PARPORT=m +CONFIG_PPS_CLIENT_GPIO=m + +# +# PPS generators support +# + +# +# PTP clock support +# +CONFIG_PTP_1588_CLOCK=m +CONFIG_PTP_1588_CLOCK_OPTIONAL=m + +# +# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. +# +CONFIG_PTP_1588_CLOCK_KVM=m +CONFIG_PTP_1588_CLOCK_IDT82P33=m +CONFIG_PTP_1588_CLOCK_IDTCM=m +CONFIG_PTP_1588_CLOCK_MOCK=m +CONFIG_PTP_1588_CLOCK_VMW=m +CONFIG_PTP_1588_CLOCK_OCP=m +# end of PTP clock support + +CONFIG_PINCTRL=y +CONFIG_PINMUX=y +CONFIG_PINCONF=y +CONFIG_GENERIC_PINCONF=y +# CONFIG_DEBUG_PINCTRL is not set +CONFIG_PINCTRL_AMD=y +CONFIG_PINCTRL_CY8C95X0=m +CONFIG_PINCTRL_DA9062=m +CONFIG_PINCTRL_MCP23S08_I2C=m +CONFIG_PINCTRL_MCP23S08_SPI=m +CONFIG_PINCTRL_MCP23S08=m +CONFIG_PINCTRL_SX150X=y +CONFIG_PINCTRL_CS42L43=m +CONFIG_PINCTRL_MADERA=m +CONFIG_PINCTRL_CS47L15=y +CONFIG_PINCTRL_CS47L35=y +CONFIG_PINCTRL_CS47L85=y +CONFIG_PINCTRL_CS47L90=y +CONFIG_PINCTRL_CS47L92=y + +# +# Intel pinctrl drivers +# +CONFIG_PINCTRL_BAYTRAIL=y +CONFIG_PINCTRL_CHERRYVIEW=y +CONFIG_PINCTRL_LYNXPOINT=y +CONFIG_PINCTRL_INTEL=y +CONFIG_PINCTRL_ALDERLAKE=y +CONFIG_PINCTRL_BROXTON=y +CONFIG_PINCTRL_CANNONLAKE=y +CONFIG_PINCTRL_CEDARFORK=y +CONFIG_PINCTRL_DENVERTON=y +CONFIG_PINCTRL_ELKHARTLAKE=y +CONFIG_PINCTRL_EMMITSBURG=y +CONFIG_PINCTRL_GEMINILAKE=y +CONFIG_PINCTRL_ICELAKE=y +CONFIG_PINCTRL_JASPERLAKE=y +CONFIG_PINCTRL_LAKEFIELD=y +CONFIG_PINCTRL_LEWISBURG=y +CONFIG_PINCTRL_METEORLAKE=y +CONFIG_PINCTRL_SUNRISEPOINT=y +CONFIG_PINCTRL_TIGERLAKE=y +# end of Intel pinctrl drivers + +# +# Renesas pinctrl drivers +# +# end of Renesas pinctrl drivers + +CONFIG_GPIOLIB=y +CONFIG_GPIOLIB_FASTPATH_LIMIT=512 +CONFIG_GPIO_ACPI=y +CONFIG_GPIOLIB_IRQCHIP=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_CDEV=y +CONFIG_GPIO_CDEV_V1=y +CONFIG_GPIO_GENERIC=m +CONFIG_GPIO_REGMAP=m +CONFIG_GPIO_MAX730X=m +CONFIG_GPIO_IDIO_16=m + +# +# Memory mapped GPIO drivers +# +CONFIG_GPIO_AMDPT=m +CONFIG_GPIO_DWAPB=m +CONFIG_GPIO_EXAR=m +CONFIG_GPIO_GENERIC_PLATFORM=m +CONFIG_GPIO_ICH=m +CONFIG_GPIO_MB86S7X=m +CONFIG_GPIO_TANGIER=m +CONFIG_GPIO_AMD_FCH=m +# end of Memory mapped GPIO drivers + +# +# Port-mapped I/O GPIO drivers +# +CONFIG_GPIO_VX855=m +CONFIG_GPIO_F7188X=m +CONFIG_GPIO_IT87=m +CONFIG_GPIO_SCH=m +CONFIG_GPIO_SCH311X=m +CONFIG_GPIO_WINBOND=m +CONFIG_GPIO_WS16C48=m +# end of Port-mapped I/O GPIO drivers + +# +# I2C GPIO expanders +# +CONFIG_GPIO_FXL6408=m +CONFIG_GPIO_DS4520=m +CONFIG_GPIO_MAX7300=m +CONFIG_GPIO_MAX732X=m +CONFIG_GPIO_PCA953X=m +CONFIG_GPIO_PCA953X_IRQ=y +CONFIG_GPIO_PCA9570=m +CONFIG_GPIO_PCF857X=m +CONFIG_GPIO_TPIC2810=m +# end of I2C GPIO expanders + +# +# MFD GPIO expanders +# +CONFIG_GPIO_ADP5520=m +CONFIG_GPIO_ARIZONA=m +CONFIG_GPIO_BD9571MWV=m +CONFIG_GPIO_CRYSTAL_COVE=m +CONFIG_GPIO_DA9052=m +CONFIG_GPIO_DA9055=m +CONFIG_GPIO_DLN2=m +CONFIG_GPIO_ELKHARTLAKE=m +# CONFIG_GPIO_JANZ_TTL is not set +CONFIG_GPIO_KEMPLD=m +CONFIG_GPIO_LP3943=m +CONFIG_GPIO_MADERA=m +CONFIG_GPIO_PALMAS=y +CONFIG_GPIO_RC5T583=y +CONFIG_GPIO_TPS65086=m +CONFIG_GPIO_TPS6586X=y +CONFIG_GPIO_TPS65910=y +CONFIG_GPIO_TPS65912=m +CONFIG_GPIO_TPS68470=m +CONFIG_GPIO_TWL4030=m +CONFIG_GPIO_TWL6040=m +CONFIG_GPIO_WHISKEY_COVE=m +CONFIG_GPIO_WM831X=m +CONFIG_GPIO_WM8350=m +CONFIG_GPIO_WM8994=m +# end of MFD GPIO expanders + +# +# PCI GPIO expanders +# +CONFIG_GPIO_AMD8111=m +CONFIG_GPIO_ML_IOH=m +CONFIG_GPIO_PCI_IDIO_16=m +CONFIG_GPIO_PCIE_IDIO_24=m +CONFIG_GPIO_RDC321X=m +# end of PCI GPIO expanders + +# +# SPI GPIO expanders +# +CONFIG_GPIO_MAX3191X=m +CONFIG_GPIO_MAX7301=m +CONFIG_GPIO_MC33880=m +CONFIG_GPIO_PISOSR=m +CONFIG_GPIO_XRA1403=m +# end of SPI GPIO expanders + +# +# USB GPIO expanders +# +CONFIG_GPIO_VIPERBOARD=m +# end of USB GPIO expanders + +# +# Virtual GPIO drivers +# +CONFIG_GPIO_AGGREGATOR=m +CONFIG_GPIO_LATCH=m +CONFIG_GPIO_MOCKUP=m +CONFIG_GPIO_VIRTIO=m +CONFIG_GPIO_SIM=m +# end of Virtual GPIO drivers + +CONFIG_W1=m +CONFIG_W1_CON=y + +# +# 1-wire Bus Masters +# +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_GPIO=m +CONFIG_W1_MASTER_SGI=m +# end of 1-wire Bus Masters + +# +# 1-wire Slaves +# +CONFIG_W1_SLAVE_THERM=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_DS2405=m +CONFIG_W1_SLAVE_DS2408=m +CONFIG_W1_SLAVE_DS2408_READBACK=y +CONFIG_W1_SLAVE_DS2413=m +CONFIG_W1_SLAVE_DS2406=m +CONFIG_W1_SLAVE_DS2423=m +CONFIG_W1_SLAVE_DS2805=m +CONFIG_W1_SLAVE_DS2430=m +CONFIG_W1_SLAVE_DS2431=m +CONFIG_W1_SLAVE_DS2433=m +# CONFIG_W1_SLAVE_DS2433_CRC is not set +CONFIG_W1_SLAVE_DS2438=m +CONFIG_W1_SLAVE_DS250X=m +CONFIG_W1_SLAVE_DS2780=m +CONFIG_W1_SLAVE_DS2781=m +CONFIG_W1_SLAVE_DS28E04=m +CONFIG_W1_SLAVE_DS28E17=m +# end of 1-wire Slaves + +CONFIG_POWER_RESET=y +# CONFIG_POWER_RESET_RESTART is not set +CONFIG_POWER_RESET_TPS65086=y +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +CONFIG_GENERIC_ADC_BATTERY=m +# CONFIG_IP5XXX_POWER is not set +CONFIG_MAX8925_POWER=m +CONFIG_WM831X_BACKUP=m +CONFIG_WM831X_POWER=m +CONFIG_WM8350_POWER=m +CONFIG_TEST_POWER=m +CONFIG_BATTERY_88PM860X=m +CONFIG_CHARGER_ADP5061=m +# CONFIG_BATTERY_CW2015 is not set +CONFIG_BATTERY_DS2760=m +CONFIG_BATTERY_DS2780=m +CONFIG_BATTERY_DS2781=m +CONFIG_BATTERY_DS2782=m +# CONFIG_BATTERY_SAMSUNG_SDI is not set +CONFIG_BATTERY_SBS=m +CONFIG_CHARGER_SBS=m +CONFIG_MANAGER_SBS=m +CONFIG_BATTERY_BQ27XXX=m +CONFIG_BATTERY_BQ27XXX_I2C=m +CONFIG_BATTERY_BQ27XXX_HDQ=m +# CONFIG_BATTERY_BQ27XXX_DT_UPDATES_NVM is not set +CONFIG_BATTERY_DA9030=m +CONFIG_BATTERY_DA9052=m +CONFIG_CHARGER_DA9150=m +# CONFIG_BATTERY_DA9150 is not set +CONFIG_AXP20X_POWER=m +CONFIG_AXP288_CHARGER=m +CONFIG_AXP288_FUEL_GAUGE=m +# CONFIG_BATTERY_MAX17040 is not set +CONFIG_BATTERY_MAX17042=m +# CONFIG_BATTERY_MAX1721X is not set +CONFIG_BATTERY_TWL4030_MADC=m +CONFIG_CHARGER_88PM860X=m +CONFIG_BATTERY_RX51=m +CONFIG_CHARGER_ISP1704=m +CONFIG_CHARGER_MAX8903=m +CONFIG_CHARGER_TWL4030=m +CONFIG_CHARGER_LP8727=m +CONFIG_CHARGER_LP8788=m +CONFIG_CHARGER_GPIO=m +CONFIG_CHARGER_MANAGER=y +CONFIG_CHARGER_LT3651=m +# CONFIG_CHARGER_LTC4162L is not set +CONFIG_CHARGER_MAX14577=m +# CONFIG_CHARGER_MAX77693 is not set +# CONFIG_CHARGER_MAX77976 is not set +CONFIG_CHARGER_MAX8997=m +CONFIG_CHARGER_MAX8998=m +CONFIG_CHARGER_MP2629=m +CONFIG_CHARGER_BQ2415X=m +CONFIG_CHARGER_BQ24190=m +CONFIG_CHARGER_BQ24257=m +CONFIG_CHARGER_BQ24735=m +CONFIG_CHARGER_BQ2515X=m +CONFIG_CHARGER_BQ25890=m +CONFIG_CHARGER_BQ25980=m +# CONFIG_CHARGER_BQ256XX is not set +CONFIG_CHARGER_SMB347=m +CONFIG_CHARGER_TPS65090=m +# CONFIG_BATTERY_GAUGE_LTC2941 is not set +# CONFIG_BATTERY_GOLDFISH is not set +CONFIG_BATTERY_RT5033=m +CONFIG_CHARGER_RT9455=m +# CONFIG_CHARGER_RT9467 is not set +# CONFIG_CHARGER_RT9471 is not set +CONFIG_CHARGER_CROS_USBPD=m +CONFIG_CHARGER_CROS_PCHG=m +# CONFIG_CHARGER_BD99954 is not set +CONFIG_CHARGER_WILCO=m +CONFIG_BATTERY_SURFACE=m +CONFIG_CHARGER_SURFACE=m +# CONFIG_BATTERY_UG3105 is not set +CONFIG_HWMON=m +CONFIG_HWMON_VID=m +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Native drivers +# +CONFIG_SENSORS_ABITUGURU=m +CONFIG_SENSORS_ABITUGURU3=m +CONFIG_SENSORS_SMPRO=m +CONFIG_SENSORS_AD7314=m +CONFIG_SENSORS_AD7414=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM1177=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_ADT7X10=m +CONFIG_SENSORS_ADT7310=m +CONFIG_SENSORS_ADT7410=m +CONFIG_SENSORS_ADT7411=m +CONFIG_SENSORS_ADT7462=m +CONFIG_SENSORS_ADT7470=m +CONFIG_SENSORS_ADT7475=m +CONFIG_SENSORS_AHT10=m +CONFIG_SENSORS_AQUACOMPUTER_D5NEXT=m +CONFIG_SENSORS_AS370=m +CONFIG_SENSORS_ASC7621=m +CONFIG_SENSORS_AXI_FAN_CONTROL=m +CONFIG_SENSORS_K8TEMP=m +CONFIG_SENSORS_K10TEMP=m +CONFIG_SENSORS_FAM15H_POWER=m +CONFIG_SENSORS_APPLESMC=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_CORSAIR_CPRO=m +CONFIG_SENSORS_CORSAIR_PSU=m +CONFIG_SENSORS_DRIVETEMP=m +CONFIG_SENSORS_DS620=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_DELL_SMM=m +CONFIG_I8K=y +CONFIG_SENSORS_DA9052_ADC=m +CONFIG_SENSORS_DA9055=m +CONFIG_SENSORS_I5K_AMB=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_F71882FG=m +CONFIG_SENSORS_F75375S=m +CONFIG_SENSORS_MC13783_ADC=m +CONFIG_SENSORS_FSCHMD=m +CONFIG_SENSORS_FTSTEUTATES=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_G760A=m +CONFIG_SENSORS_G762=m +CONFIG_SENSORS_HIH6130=m +CONFIG_SENSORS_HS3001=m +CONFIG_SENSORS_IBMAEM=m +CONFIG_SENSORS_IBMPEX=m +CONFIG_SENSORS_IIO_HWMON=m +CONFIG_SENSORS_I5500=m +CONFIG_SENSORS_CORETEMP=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_JC42=m +CONFIG_SENSORS_POWR1220=m +CONFIG_SENSORS_LINEAGE=m +CONFIG_SENSORS_LTC2945=m +CONFIG_SENSORS_LTC2947=m +CONFIG_SENSORS_LTC2947_I2C=m +CONFIG_SENSORS_LTC2947_SPI=m +CONFIG_SENSORS_LTC2990=m +CONFIG_SENSORS_LTC2992=m +CONFIG_SENSORS_LTC4151=m +CONFIG_SENSORS_LTC4215=m +CONFIG_SENSORS_LTC4222=m +CONFIG_SENSORS_LTC4245=m +CONFIG_SENSORS_LTC4260=m +CONFIG_SENSORS_LTC4261=m +CONFIG_SENSORS_MAX1111=m +CONFIG_SENSORS_MAX127=m +CONFIG_SENSORS_MAX16065=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX1668=m +CONFIG_SENSORS_MAX197=m +CONFIG_SENSORS_MAX31722=m +CONFIG_SENSORS_MAX31730=m +CONFIG_SENSORS_MAX31760=m +CONFIG_MAX31827=m +CONFIG_SENSORS_MAX6620=m +CONFIG_SENSORS_MAX6621=m +CONFIG_SENSORS_MAX6639=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_MAX6697=m +CONFIG_SENSORS_MAX31790=m +CONFIG_SENSORS_MC34VR500=m +CONFIG_SENSORS_MCP3021=m +CONFIG_SENSORS_MLXREG_FAN=m +CONFIG_SENSORS_TC654=m +CONFIG_SENSORS_TPS23861=m +CONFIG_SENSORS_MENF21BMC_HWMON=m +CONFIG_SENSORS_MR75203=m +CONFIG_SENSORS_ADCXX=m +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM70=m +CONFIG_SENSORS_LM73=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_LM93=m +CONFIG_SENSORS_LM95234=m +CONFIG_SENSORS_LM95241=m +CONFIG_SENSORS_LM95245=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_NTC_THERMISTOR=m +CONFIG_SENSORS_NCT6683=m +CONFIG_SENSORS_NCT6775_CORE=m +CONFIG_SENSORS_NCT6775=m +CONFIG_SENSORS_NCT6775_I2C=m +CONFIG_SENSORS_NCT7802=m +CONFIG_SENSORS_NCT7904=m +CONFIG_SENSORS_NPCM7XX=m +CONFIG_SENSORS_NZXT_KRAKEN2=m +CONFIG_SENSORS_NZXT_SMART2=m +# CONFIG_SENSORS_OCC_P8_I2C is not set +# CONFIG_SENSORS_OXP is not set +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_PECI_CPUTEMP=m +CONFIG_SENSORS_PECI_DIMMTEMP=m +CONFIG_SENSORS_PECI=m +CONFIG_PMBUS=m +CONFIG_SENSORS_PMBUS=m +CONFIG_SENSORS_ACBEL_FSG032=m +CONFIG_SENSORS_ADM1266=m +CONFIG_SENSORS_ADM1275=m +CONFIG_SENSORS_BEL_PFE=m +CONFIG_SENSORS_BPA_RS600=m +CONFIG_SENSORS_DELTA_AHE50DC_FAN=m +CONFIG_SENSORS_FSP_3Y=m +CONFIG_SENSORS_IBM_CFFPS=m +CONFIG_SENSORS_DPS920AB=m +CONFIG_SENSORS_INSPUR_IPSPS=m +CONFIG_SENSORS_IR35221=m +CONFIG_SENSORS_IR36021=m +CONFIG_SENSORS_IR38064=m +CONFIG_SENSORS_IR38064_REGULATOR=y +CONFIG_SENSORS_IRPS5401=m +CONFIG_SENSORS_ISL68137=m +CONFIG_SENSORS_LM25066=m +CONFIG_SENSORS_LM25066_REGULATOR=y +CONFIG_SENSORS_LT7182S=m +CONFIG_SENSORS_LTC2978=m +CONFIG_SENSORS_LTC2978_REGULATOR=y +CONFIG_SENSORS_LTC3815=m +# CONFIG_SENSORS_MAX15301 is not set +CONFIG_SENSORS_MAX16064=m +CONFIG_SENSORS_MAX16601=m +CONFIG_SENSORS_MAX20730=m +CONFIG_SENSORS_MAX20751=m +CONFIG_SENSORS_MAX31785=m +CONFIG_SENSORS_MAX34440=m +CONFIG_SENSORS_MAX8688=m +CONFIG_SENSORS_MP2888=m +CONFIG_SENSORS_MP2975=m +CONFIG_SENSORS_MP2975_REGULATOR=y +CONFIG_SENSORS_MP5023=m +CONFIG_SENSORS_MPQ7932_REGULATOR=y +CONFIG_SENSORS_MPQ7932=m +CONFIG_SENSORS_PIM4328=m +CONFIG_SENSORS_PLI1209BC=m +CONFIG_SENSORS_PLI1209BC_REGULATOR=y +CONFIG_SENSORS_PM6764TR=m +CONFIG_SENSORS_PXE1610=m +CONFIG_SENSORS_Q54SJ108A2=m +CONFIG_SENSORS_STPDDC60=m +CONFIG_SENSORS_TDA38640=m +# CONFIG_SENSORS_TDA38640_REGULATOR is not set +CONFIG_SENSORS_TPS40422=m +CONFIG_SENSORS_TPS53679=m +CONFIG_SENSORS_TPS546D24=m +CONFIG_SENSORS_UCD9000=m +CONFIG_SENSORS_UCD9200=m +CONFIG_SENSORS_XDPE152=m +CONFIG_SENSORS_XDPE122=m +CONFIG_SENSORS_XDPE122_REGULATOR=y +CONFIG_SENSORS_ZL6100=m +CONFIG_SENSORS_SBTSI=m +CONFIG_SENSORS_SBRMI=m +CONFIG_SENSORS_SHT15=m +CONFIG_SENSORS_SHT21=m +CONFIG_SENSORS_SHT3x=m +CONFIG_SENSORS_SHT4x=m +CONFIG_SENSORS_SHTC1=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_DME1737=m +CONFIG_SENSORS_EMC1403=m +CONFIG_SENSORS_EMC2103=m +CONFIG_SENSORS_EMC2305=m +CONFIG_SENSORS_EMC6W201=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SCH56XX_COMMON=m +CONFIG_SENSORS_SCH5627=m +CONFIG_SENSORS_SCH5636=m +CONFIG_SENSORS_STTS751=m +CONFIG_SENSORS_ADC128D818=m +CONFIG_SENSORS_ADS7828=m +CONFIG_SENSORS_ADS7871=m +CONFIG_SENSORS_AMC6821=m +CONFIG_SENSORS_INA209=m +CONFIG_SENSORS_INA2XX=m +CONFIG_SENSORS_INA238=m +CONFIG_SENSORS_INA3221=m +CONFIG_SENSORS_TC74=m +CONFIG_SENSORS_THMC50=m +CONFIG_SENSORS_TMP102=m +CONFIG_SENSORS_TMP103=m +CONFIG_SENSORS_TMP108=m +CONFIG_SENSORS_TMP401=m +CONFIG_SENSORS_TMP421=m +CONFIG_SENSORS_TMP464=m +CONFIG_SENSORS_TMP513=m +CONFIG_SENSORS_VIA_CPUTEMP=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83773G=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83795=m +CONFIG_SENSORS_W83795_FANCTRL=y +CONFIG_SENSORS_W83L785TS=m +CONFIG_SENSORS_W83L786NG=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_WM831X=m +CONFIG_SENSORS_WM8350=m +CONFIG_SENSORS_XGENE=m +CONFIG_SENSORS_INTEL_M10_BMC_HWMON=m + +# +# ACPI drivers +# +CONFIG_SENSORS_ACPI_POWER=m +CONFIG_SENSORS_ATK0110=m +CONFIG_SENSORS_ASUS_WMI=m +CONFIG_SENSORS_ASUS_EC=m +CONFIG_SENSORS_HP_WMI=m +CONFIG_THERMAL=y +CONFIG_THERMAL_NETLINK=y +CONFIG_THERMAL_STATISTICS=y +CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 +CONFIG_THERMAL_ACPI=y +CONFIG_THERMAL_WRITABLE_TRIPS=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set +# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set +# CONFIG_THERMAL_DEFAULT_GOV_BANG_BANG is not set +CONFIG_THERMAL_GOV_FAIR_SHARE=y +CONFIG_THERMAL_GOV_STEP_WISE=y +CONFIG_THERMAL_GOV_BANG_BANG=y +CONFIG_THERMAL_GOV_USER_SPACE=y +# CONFIG_THERMAL_GOV_POWER_ALLOCATOR is not set +CONFIG_DEVFREQ_THERMAL=y +CONFIG_THERMAL_EMULATION=y + +# +# Intel thermal drivers +# +CONFIG_INTEL_POWERCLAMP=m +CONFIG_X86_THERMAL_VECTOR=y +CONFIG_INTEL_TCC=y +CONFIG_X86_PKG_TEMP_THERMAL=m +CONFIG_INTEL_SOC_DTS_IOSF_CORE=m +CONFIG_INTEL_SOC_DTS_THERMAL=m + +# +# ACPI INT340X thermal drivers +# +CONFIG_INT340X_THERMAL=m +CONFIG_ACPI_THERMAL_REL=m +CONFIG_INT3406_THERMAL=m +CONFIG_PROC_THERMAL_MMIO_RAPL=m +# end of ACPI INT340X thermal drivers + +CONFIG_INTEL_BXT_PMIC_THERMAL=m +CONFIG_INTEL_PCH_THERMAL=m +CONFIG_INTEL_TCC_COOLING=m +CONFIG_INTEL_HFI_THERMAL=y +# end of Intel thermal drivers + +CONFIG_GENERIC_ADC_THERMAL=m +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_CORE=y +CONFIG_WATCHDOG_NOWAYOUT=y +CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y +CONFIG_WATCHDOG_OPEN_TIMEOUT=0 +CONFIG_WATCHDOG_SYSFS=y +# CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT is not set + +# +# Watchdog Pretimeout Governors +# +CONFIG_WATCHDOG_PRETIMEOUT_GOV=y +CONFIG_WATCHDOG_PRETIMEOUT_GOV_SEL=m +CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP=m +CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC=y +# CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP is not set +CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC=y + +# +# Watchdog Device Drivers +# +CONFIG_SOFT_WATCHDOG=m +# CONFIG_SOFT_WATCHDOG_PRETIMEOUT is not set +CONFIG_DA9052_WATCHDOG=m +CONFIG_DA9055_WATCHDOG=m +CONFIG_DA9063_WATCHDOG=m +CONFIG_DA9062_WATCHDOG=m +CONFIG_MENF21BMC_WATCHDOG=m +CONFIG_WDAT_WDT=m +CONFIG_WM831X_WATCHDOG=m +CONFIG_WM8350_WATCHDOG=m +# CONFIG_XILINX_WATCHDOG is not set +CONFIG_ZIIRAVE_WATCHDOG=m +CONFIG_MLX_WDT=m +# CONFIG_CADENCE_WATCHDOG is not set +CONFIG_DW_WATCHDOG=m +CONFIG_TWL4030_WATCHDOG=m +CONFIG_MAX63XX_WATCHDOG=m +CONFIG_RETU_WATCHDOG=m +CONFIG_ACQUIRE_WDT=m +CONFIG_ADVANTECH_WDT=m +CONFIG_ADVANTECH_EC_WDT=m +CONFIG_ALIM1535_WDT=m +CONFIG_ALIM7101_WDT=m +CONFIG_EBC_C384_WDT=m +CONFIG_EXAR_WDT=m +CONFIG_F71808E_WDT=m +CONFIG_SP5100_TCO=m +CONFIG_SBC_FITPC2_WATCHDOG=m +CONFIG_EUROTECH_WDT=m +CONFIG_IB700_WDT=m +CONFIG_IBMASR=m +CONFIG_WAFER_WDT=m +CONFIG_I6300ESB_WDT=m +CONFIG_IE6XX_WDT=m +CONFIG_ITCO_WDT=m +CONFIG_ITCO_VENDOR_SUPPORT=y +CONFIG_IT8712F_WDT=m +CONFIG_IT87_WDT=m +CONFIG_HP_WATCHDOG=m +CONFIG_HPWDT_NMI_DECODING=y +CONFIG_KEMPLD_WDT=m +CONFIG_SC1200_WDT=m +CONFIG_PC87413_WDT=m +CONFIG_NV_TCO=m +CONFIG_60XX_WDT=m +CONFIG_CPU5_WDT=m +CONFIG_SMSC_SCH311X_WDT=m +CONFIG_SMSC37B787_WDT=m +CONFIG_TQMX86_WDT=m +CONFIG_VIA_WDT=m +CONFIG_W83627HF_WDT=m +CONFIG_W83877F_WDT=m +CONFIG_W83977F_WDT=m +CONFIG_MACHZ_WDT=m +CONFIG_SBC_EPX_C3_WATCHDOG=m +CONFIG_INTEL_MEI_WDT=m +CONFIG_NI903X_WDT=m +CONFIG_NIC7018_WDT=m +CONFIG_MEN_A21_WDT=m +CONFIG_XEN_WDT=m + +# +# PCI-based Watchdog Cards +# +CONFIG_PCIPCWATCHDOG=m +CONFIG_WDTPCI=m + +# +# USB-based Watchdog Cards +# +CONFIG_USBPCWATCHDOG=m +CONFIG_SSB_POSSIBLE=y +CONFIG_SSB=m +CONFIG_SSB_SPROM=y +CONFIG_SSB_BLOCKIO=y +CONFIG_SSB_PCIHOST_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +CONFIG_SSB_B43_PCI_BRIDGE=y +CONFIG_SSB_PCMCIAHOST_POSSIBLE=y +CONFIG_SSB_PCMCIAHOST=y +CONFIG_SSB_SDIOHOST_POSSIBLE=y +CONFIG_SSB_SDIOHOST=y +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_DRIVER_PCICORE=y +CONFIG_SSB_DRIVER_GPIO=y +CONFIG_BCMA_POSSIBLE=y +CONFIG_BCMA=m +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 + +# +# Multifunction device drivers +# +CONFIG_MFD_CORE=y +CONFIG_MFD_AS3711=y +CONFIG_MFD_SMPRO=m +CONFIG_PMIC_ADP5520=y +CONFIG_MFD_AAT2870_CORE=y +CONFIG_MFD_BCM590XX=m +CONFIG_MFD_BD9571MWV=m +CONFIG_MFD_AXP20X=m +CONFIG_MFD_AXP20X_I2C=m +CONFIG_MFD_CROS_EC_DEV=m +CONFIG_MFD_CS42L43=m +CONFIG_MFD_CS42L43_I2C=m +CONFIG_MFD_CS42L43_SDW=m +CONFIG_MFD_MADERA=m +CONFIG_MFD_MADERA_I2C=m +CONFIG_MFD_MADERA_SPI=m +CONFIG_MFD_CS47L15=y +CONFIG_MFD_CS47L35=y +CONFIG_MFD_CS47L85=y +CONFIG_MFD_CS47L90=y +CONFIG_MFD_CS47L92=y +CONFIG_PMIC_DA903X=y +CONFIG_PMIC_DA9052=y +CONFIG_MFD_DA9052_SPI=y +CONFIG_MFD_DA9052_I2C=y +CONFIG_MFD_DA9055=y +CONFIG_MFD_DA9062=m +CONFIG_MFD_DA9063=y +CONFIG_MFD_DA9150=m +CONFIG_MFD_DLN2=m +CONFIG_MFD_MC13XXX=m +CONFIG_MFD_MC13XXX_SPI=m +CONFIG_MFD_MC13XXX_I2C=m +CONFIG_MFD_MP2629=m +CONFIG_MFD_INTEL_QUARK_I2C_GPIO=m +CONFIG_LPC_ICH=m +CONFIG_LPC_SCH=m +CONFIG_INTEL_SOC_PMIC=y +CONFIG_INTEL_SOC_PMIC_BXTWC=m +CONFIG_INTEL_SOC_PMIC_CHTWC=y +CONFIG_INTEL_SOC_PMIC_CHTDC_TI=m +CONFIG_INTEL_SOC_PMIC_MRFLD=m +CONFIG_MFD_INTEL_LPSS=m +CONFIG_MFD_INTEL_LPSS_ACPI=m +CONFIG_MFD_INTEL_LPSS_PCI=m +CONFIG_MFD_INTEL_PMC_BXT=m +CONFIG_MFD_IQS62X=m +CONFIG_MFD_JANZ_CMODIO=m +CONFIG_MFD_KEMPLD=m +CONFIG_MFD_88PM800=m +CONFIG_MFD_88PM805=m +CONFIG_MFD_88PM860X=y +CONFIG_MFD_MAX14577=y +CONFIG_MFD_MAX77541=m +CONFIG_MFD_MAX77693=y +# CONFIG_MFD_MAX77843 is not set +CONFIG_MFD_MAX8907=m +CONFIG_MFD_MAX8925=y +CONFIG_MFD_MAX8997=y +CONFIG_MFD_MAX8998=y +# CONFIG_MFD_MT6360 is not set +# CONFIG_MFD_MT6370 is not set +# CONFIG_MFD_MT6397 is not set +CONFIG_MFD_MENF21BMC=m +CONFIG_MFD_OCELOT=m +CONFIG_EZX_PCAP=y +CONFIG_MFD_VIPERBOARD=m +CONFIG_MFD_RETU=m +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_SY7636A is not set +CONFIG_MFD_RDC321X=m +# CONFIG_MFD_RT4831 is not set +# CONFIG_MFD_RT5033 is not set +# CONFIG_MFD_RT5120 is not set +CONFIG_MFD_RC5T583=y +CONFIG_MFD_SI476X_CORE=m +CONFIG_MFD_SIMPLE_MFD_I2C=m +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SKY81452 is not set +CONFIG_MFD_SYSCON=y +CONFIG_MFD_LP3943=m +CONFIG_MFD_LP8788=y +CONFIG_MFD_TI_LMU=m +CONFIG_MFD_PALMAS=y +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +CONFIG_MFD_TPS65086=m +CONFIG_MFD_TPS65090=y +# CONFIG_MFD_TI_LP873X is not set +CONFIG_MFD_TPS6586X=y +CONFIG_MFD_TPS65910=y +CONFIG_MFD_TPS65912=y +CONFIG_MFD_TPS65912_I2C=y +CONFIG_MFD_TPS65912_SPI=y +CONFIG_MFD_TPS6594=m +CONFIG_MFD_TPS6594_I2C=m +CONFIG_MFD_TPS6594_SPI=m +CONFIG_TWL4030_CORE=y +CONFIG_MFD_TWL4030_AUDIO=y +CONFIG_TWL6040_CORE=y +CONFIG_MFD_WL1273_CORE=m +# CONFIG_MFD_LM3533 is not set +# CONFIG_MFD_TQMX86 is not set +CONFIG_MFD_VX855=m +CONFIG_MFD_ARIZONA=m +CONFIG_MFD_ARIZONA_I2C=m +CONFIG_MFD_ARIZONA_SPI=m +CONFIG_MFD_CS47L24=y +CONFIG_MFD_WM5102=y +CONFIG_MFD_WM5110=y +CONFIG_MFD_WM8997=y +# CONFIG_MFD_WM8998 is not set +CONFIG_MFD_WM8400=y +CONFIG_MFD_WM831X=y +CONFIG_MFD_WM831X_I2C=y +CONFIG_MFD_WM831X_SPI=y +CONFIG_MFD_WM8350=y +CONFIG_MFD_WM8350_I2C=y +CONFIG_MFD_WM8994=y +# CONFIG_MFD_ATC260X_I2C is not set +# CONFIG_RAVE_SP_CORE is not set +CONFIG_MFD_INTEL_M10_BMC_CORE=m +CONFIG_MFD_INTEL_M10_BMC_SPI=m +# end of Multifunction device drivers + +CONFIG_REGULATOR=y +# CONFIG_REGULATOR_DEBUG is not set +CONFIG_REGULATOR_FIXED_VOLTAGE=m +CONFIG_REGULATOR_VIRTUAL_CONSUMER=m +CONFIG_REGULATOR_USERSPACE_CONSUMER=m +# CONFIG_REGULATOR_88PG86X is not set +CONFIG_REGULATOR_88PM800=m +CONFIG_REGULATOR_88PM8607=m +CONFIG_REGULATOR_ACT8865=m +CONFIG_REGULATOR_AD5398=m +CONFIG_REGULATOR_AAT2870=m +# CONFIG_REGULATOR_ARIZONA_LDO1 is not set +# CONFIG_REGULATOR_ARIZONA_MICSUPP is not set +CONFIG_REGULATOR_AS3711=m +CONFIG_REGULATOR_AW37503=m +CONFIG_REGULATOR_AXP20X=m +CONFIG_REGULATOR_BCM590XX=m +CONFIG_REGULATOR_BD9571MWV=m +CONFIG_REGULATOR_DA903X=m +CONFIG_REGULATOR_DA9052=m +CONFIG_REGULATOR_DA9055=m +CONFIG_REGULATOR_DA9062=m +CONFIG_REGULATOR_DA9210=m +CONFIG_REGULATOR_DA9211=m +CONFIG_REGULATOR_FAN53555=m +CONFIG_REGULATOR_GPIO=m +CONFIG_REGULATOR_ISL9305=m +CONFIG_REGULATOR_ISL6271A=m +# CONFIG_REGULATOR_LM363X is not set +CONFIG_REGULATOR_LP3971=m +CONFIG_REGULATOR_LP3972=m +CONFIG_REGULATOR_LP872X=m +CONFIG_REGULATOR_LP8755=m +CONFIG_REGULATOR_LP8788=m +CONFIG_REGULATOR_LTC3589=m +# CONFIG_REGULATOR_LTC3676 is not set +CONFIG_REGULATOR_MAX14577=m +CONFIG_REGULATOR_MAX1586=m +CONFIG_REGULATOR_MAX77541=m +CONFIG_REGULATOR_MAX77857=m +CONFIG_REGULATOR_MAX8649=m +CONFIG_REGULATOR_MAX8660=m +# CONFIG_REGULATOR_MAX8893 is not set +CONFIG_REGULATOR_MAX8907=m +CONFIG_REGULATOR_MAX8925=m +CONFIG_REGULATOR_MAX8952=m +CONFIG_REGULATOR_MAX8997=m +CONFIG_REGULATOR_MAX8998=m +# CONFIG_REGULATOR_MAX20086 is not set +CONFIG_REGULATOR_MAX20411=m +CONFIG_REGULATOR_MAX77693=m +# CONFIG_REGULATOR_MAX77826 is not set +CONFIG_REGULATOR_MC13XXX_CORE=m +CONFIG_REGULATOR_MC13783=m +CONFIG_REGULATOR_MC13892=m +CONFIG_REGULATOR_MP8859=m +CONFIG_REGULATOR_MT6311=m +# CONFIG_REGULATOR_MT6315 is not set +CONFIG_REGULATOR_PALMAS=m +CONFIG_REGULATOR_PCA9450=m +CONFIG_REGULATOR_PCAP=m +CONFIG_REGULATOR_PV88060=m +CONFIG_REGULATOR_PV88080=m +CONFIG_REGULATOR_PV88090=m +CONFIG_REGULATOR_PWM=m +CONFIG_REGULATOR_QCOM_SPMI=m +CONFIG_REGULATOR_QCOM_USB_VBUS=m +CONFIG_REGULATOR_RAA215300=m +CONFIG_REGULATOR_RC5T583=m +# CONFIG_REGULATOR_RT4801 is not set +# CONFIG_REGULATOR_RT4803 is not set +# CONFIG_REGULATOR_RT5190A is not set +# CONFIG_REGULATOR_RT5739 is not set +# CONFIG_REGULATOR_RT5759 is not set +# CONFIG_REGULATOR_RT6160 is not set +# CONFIG_REGULATOR_RT6190 is not set +# CONFIG_REGULATOR_RT6245 is not set +# CONFIG_REGULATOR_RTQ2134 is not set +# CONFIG_REGULATOR_RTMV20 is not set +# CONFIG_REGULATOR_RTQ6752 is not set +CONFIG_REGULATOR_RTQ2208=m +# CONFIG_REGULATOR_SLG51000 is not set +CONFIG_REGULATOR_TPS51632=m +CONFIG_REGULATOR_TPS62360=m +CONFIG_REGULATOR_TPS65023=m +CONFIG_REGULATOR_TPS6507X=m +CONFIG_REGULATOR_TPS65086=m +CONFIG_REGULATOR_TPS65090=m +CONFIG_REGULATOR_TPS65132=m +CONFIG_REGULATOR_TPS6524X=m +CONFIG_REGULATOR_TPS6586X=m +CONFIG_REGULATOR_TPS65910=m +CONFIG_REGULATOR_TPS65912=m +CONFIG_REGULATOR_TPS68470=m +CONFIG_REGULATOR_TWL4030=m +CONFIG_REGULATOR_WM831X=m +CONFIG_REGULATOR_WM8350=m +CONFIG_REGULATOR_WM8400=m +CONFIG_REGULATOR_WM8994=m +CONFIG_REGULATOR_QCOM_LABIBB=m +CONFIG_RC_CORE=m +CONFIG_LIRC=y +CONFIG_RC_MAP=m +CONFIG_RC_DECODERS=y +CONFIG_IR_IMON_DECODER=m +CONFIG_IR_JVC_DECODER=m +CONFIG_IR_MCE_KBD_DECODER=m +CONFIG_IR_NEC_DECODER=m +CONFIG_IR_RC5_DECODER=m +CONFIG_IR_RC6_DECODER=m +CONFIG_IR_RCMM_DECODER=m +CONFIG_IR_SANYO_DECODER=m +CONFIG_IR_SHARP_DECODER=m +CONFIG_IR_SONY_DECODER=m +CONFIG_IR_XMP_DECODER=m +CONFIG_RC_DEVICES=y +CONFIG_IR_ENE=m +CONFIG_IR_FINTEK=m +CONFIG_IR_IGORPLUGUSB=m +CONFIG_IR_IGUANA=m +CONFIG_IR_IMON=m +CONFIG_IR_IMON_RAW=m +CONFIG_IR_ITE_CIR=m +CONFIG_IR_MCEUSB=m +CONFIG_IR_NUVOTON=m +CONFIG_IR_REDRAT3=m +CONFIG_IR_SERIAL=m +CONFIG_IR_SERIAL_TRANSMITTER=y +CONFIG_IR_STREAMZAP=m +CONFIG_IR_TOY=m +CONFIG_IR_TTUSBIR=m +CONFIG_IR_WINBOND_CIR=m +CONFIG_RC_ATI_REMOTE=m +CONFIG_RC_LOOPBACK=m +CONFIG_RC_XBOX_DVD=m +CONFIG_CEC_CORE=m +CONFIG_CEC_NOTIFIER=y +CONFIG_CEC_PIN=y + +# +# CEC support +# +CONFIG_MEDIA_CEC_RC=y +CONFIG_CEC_PIN_ERROR_INJ=y +CONFIG_MEDIA_CEC_SUPPORT=y +CONFIG_CEC_CH7322=m +CONFIG_CEC_CROS_EC=m +CONFIG_CEC_GPIO=m +# CONFIG_CEC_SECO is not set +CONFIG_USB_PULSE8_CEC=m +CONFIG_USB_RAINSHADOW_CEC=m +# end of CEC support + +CONFIG_MEDIA_SUPPORT=m +CONFIG_MEDIA_SUPPORT_FILTER=y +CONFIG_MEDIA_SUBDRV_AUTOSELECT=y + +# +# Media device types +# +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_ANALOG_TV_SUPPORT=y +CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y +CONFIG_MEDIA_RADIO_SUPPORT=y +CONFIG_MEDIA_SDR_SUPPORT=y +CONFIG_MEDIA_PLATFORM_SUPPORT=y +CONFIG_MEDIA_TEST_SUPPORT=y +# end of Media device types + +CONFIG_VIDEO_DEV=m +CONFIG_MEDIA_CONTROLLER=y +CONFIG_DVB_CORE=m + +# +# Video4Linux options +# +CONFIG_VIDEO_V4L2_I2C=y +CONFIG_VIDEO_V4L2_SUBDEV_API=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEO_TUNER=m +CONFIG_V4L2_MEM2MEM_DEV=m +CONFIG_V4L2_FLASH_LED_CLASS=m +CONFIG_V4L2_FWNODE=m +CONFIG_V4L2_ASYNC=m +CONFIG_V4L2_CCI=m +CONFIG_V4L2_CCI_I2C=m +# end of Video4Linux options + +# +# Media controller options +# +CONFIG_MEDIA_CONTROLLER_DVB=y +CONFIG_MEDIA_CONTROLLER_REQUEST_API=y +# end of Media controller options + +# +# Digital TV options +# +# CONFIG_DVB_MMAP is not set +CONFIG_DVB_NET=y +CONFIG_DVB_MAX_ADAPTERS=16 +CONFIG_DVB_DYNAMIC_MINORS=y +# CONFIG_DVB_DEMUX_SECTION_LOSS_LOG is not set +# CONFIG_DVB_ULE_DEBUG is not set +# end of Digital TV options + +# +# Media drivers +# + +# +# Drivers filtered as selected at 'Filter media drivers' +# + +# +# Media drivers +# +CONFIG_MEDIA_USB_SUPPORT=y + +# +# Webcam devices +# +CONFIG_USB_GSPCA=m +CONFIG_USB_GSPCA_BENQ=m +CONFIG_USB_GSPCA_CONEX=m +CONFIG_USB_GSPCA_CPIA1=m +CONFIG_USB_GSPCA_DTCS033=m +CONFIG_USB_GSPCA_ETOMS=m +CONFIG_USB_GSPCA_FINEPIX=m +CONFIG_USB_GSPCA_JEILINJ=m +CONFIG_USB_GSPCA_JL2005BCD=m +CONFIG_USB_GSPCA_KINECT=m +CONFIG_USB_GSPCA_KONICA=m +CONFIG_USB_GSPCA_MARS=m +CONFIG_USB_GSPCA_MR97310A=m +CONFIG_USB_GSPCA_NW80X=m +CONFIG_USB_GSPCA_OV519=m +CONFIG_USB_GSPCA_OV534=m +CONFIG_USB_GSPCA_OV534_9=m +CONFIG_USB_GSPCA_PAC207=m +CONFIG_USB_GSPCA_PAC7302=m +CONFIG_USB_GSPCA_PAC7311=m +CONFIG_USB_GSPCA_SE401=m +CONFIG_USB_GSPCA_SN9C2028=m +CONFIG_USB_GSPCA_SN9C20X=m +CONFIG_USB_GSPCA_SONIXB=m +CONFIG_USB_GSPCA_SONIXJ=m +CONFIG_USB_GSPCA_SPCA1528=m +CONFIG_USB_GSPCA_SPCA500=m +CONFIG_USB_GSPCA_SPCA501=m +CONFIG_USB_GSPCA_SPCA505=m +CONFIG_USB_GSPCA_SPCA506=m +CONFIG_USB_GSPCA_SPCA508=m +CONFIG_USB_GSPCA_SPCA561=m +CONFIG_USB_GSPCA_SQ905=m +CONFIG_USB_GSPCA_SQ905C=m +CONFIG_USB_GSPCA_SQ930X=m +CONFIG_USB_GSPCA_STK014=m +CONFIG_USB_GSPCA_STK1135=m +CONFIG_USB_GSPCA_STV0680=m +CONFIG_USB_GSPCA_SUNPLUS=m +CONFIG_USB_GSPCA_T613=m +CONFIG_USB_GSPCA_TOPRO=m +CONFIG_USB_GSPCA_TOUPTEK=m +CONFIG_USB_GSPCA_TV8532=m +CONFIG_USB_GSPCA_VC032X=m +CONFIG_USB_GSPCA_VICAM=m +CONFIG_USB_GSPCA_XIRLINK_CIT=m +CONFIG_USB_GSPCA_ZC3XX=m +CONFIG_USB_GL860=m +CONFIG_USB_M5602=m +CONFIG_USB_STV06XX=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_PWC_INPUT_EVDEV=y +CONFIG_USB_S2255=m +CONFIG_VIDEO_USBTV=m +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y + +# +# Analog TV USB devices +# +CONFIG_VIDEO_GO7007=m +CONFIG_VIDEO_GO7007_USB=m +CONFIG_VIDEO_GO7007_LOADER=m +CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m +CONFIG_VIDEO_HDPVR=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_PVRUSB2_DVB=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_STK1160=m + +# +# Analog/digital TV USB devices +# +CONFIG_VIDEO_AU0828=m +CONFIG_VIDEO_AU0828_V4L2=y +CONFIG_VIDEO_AU0828_RC=y +CONFIG_VIDEO_CX231XX=m +CONFIG_VIDEO_CX231XX_RC=y +CONFIG_VIDEO_CX231XX_ALSA=m +CONFIG_VIDEO_CX231XX_DVB=m + +# +# Digital TV USB devices +# +CONFIG_DVB_AS102=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +# CONFIG_DVB_B2C2_FLEXCOP_USB_DEBUG is not set +CONFIG_DVB_USB_V2=m +CONFIG_DVB_USB_AF9015=m +CONFIG_DVB_USB_AF9035=m +CONFIG_DVB_USB_ANYSEE=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_AZ6007=m +CONFIG_DVB_USB_CE6230=m +CONFIG_DVB_USB_DVBSKY=m +CONFIG_DVB_USB_EC168=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_LME2510=m +CONFIG_DVB_USB_MXL111SF=m +CONFIG_DVB_USB_RTL28XXU=m +CONFIG_DVB_USB_ZD1301=m +CONFIG_DVB_USB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_AZ6027=m +CONFIG_DVB_USB_CINERGY_T2=m +CONFIG_DVB_USB_CXUSB=m +CONFIG_DVB_USB_CXUSB_ANALOG=y +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_DIB3000MC=m +CONFIG_DVB_USB_DIBUSB_MB=m +# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_DTV5100=m +CONFIG_DVB_USB_DW2102=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_PCTV452E=m +CONFIG_DVB_USB_TECHNISAT_USB2=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_VP7045=m +CONFIG_SMS_USB_DRV=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m + +# +# Webcam, TV (analog/digital) USB devices +# +CONFIG_VIDEO_EM28XX=m +CONFIG_VIDEO_EM28XX_V4L2=m +CONFIG_VIDEO_EM28XX_ALSA=m +CONFIG_VIDEO_EM28XX_DVB=m +CONFIG_VIDEO_EM28XX_RC=m + +# +# Software defined radio USB devices +# +CONFIG_USB_AIRSPY=m +CONFIG_USB_HACKRF=m +CONFIG_USB_MSI2500=m +CONFIG_MEDIA_PCI_SUPPORT=y + +# +# Media capture support +# +CONFIG_VIDEO_SOLO6X10=m +CONFIG_VIDEO_TW5864=m +CONFIG_VIDEO_TW68=m +CONFIG_VIDEO_TW686X=m +CONFIG_VIDEO_ZORAN=m +CONFIG_VIDEO_ZORAN_DC30=y +CONFIG_VIDEO_ZORAN_ZR36060=y +CONFIG_VIDEO_ZORAN_BUZ=y +CONFIG_VIDEO_ZORAN_DC10=y +CONFIG_VIDEO_ZORAN_LML33=y +CONFIG_VIDEO_ZORAN_LML33R10=y +CONFIG_VIDEO_ZORAN_AVS6EYES=y + +# +# Media capture/analog TV support +# +CONFIG_VIDEO_DT3155=m +CONFIG_VIDEO_IVTV=m +CONFIG_VIDEO_IVTV_ALSA=m +CONFIG_VIDEO_FB_IVTV=m +# CONFIG_VIDEO_FB_IVTV_FORCE_PAT is not set +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_MXB=m + +# +# Media capture/analog/hybrid TV support +# +CONFIG_VIDEO_BT848=m +CONFIG_DVB_BT8XX=m +CONFIG_VIDEO_CX18=m +CONFIG_VIDEO_CX18_ALSA=m +CONFIG_VIDEO_CX23885=m +CONFIG_MEDIA_ALTERA_CI=m +CONFIG_VIDEO_CX25821=m +CONFIG_VIDEO_CX25821_ALSA=m +CONFIG_VIDEO_CX88=m +CONFIG_VIDEO_CX88_ALSA=m +CONFIG_VIDEO_CX88_BLACKBIRD=m +CONFIG_VIDEO_CX88_DVB=m +CONFIG_VIDEO_CX88_ENABLE_VP3054=y +CONFIG_VIDEO_CX88_VP3054=m +CONFIG_VIDEO_CX88_MPEG=m +CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_ALSA=m +CONFIG_VIDEO_SAA7134_RC=y +CONFIG_VIDEO_SAA7134_DVB=m +CONFIG_VIDEO_SAA7134_GO7007=m +CONFIG_VIDEO_SAA7164=m + +# +# Media digital TV PCI Adapters +# +CONFIG_DVB_B2C2_FLEXCOP_PCI=m +# CONFIG_DVB_B2C2_FLEXCOP_PCI_DEBUG is not set +CONFIG_DVB_DDBRIDGE=m +# CONFIG_DVB_DDBRIDGE_MSIENABLE is not set +CONFIG_DVB_DM1105=m +CONFIG_MANTIS_CORE=m +CONFIG_DVB_MANTIS=m +CONFIG_DVB_HOPPER=m +CONFIG_DVB_NETUP_UNIDVB=m +CONFIG_DVB_NGENE=m +CONFIG_DVB_PLUTO2=m +CONFIG_DVB_PT1=m +CONFIG_DVB_PT3=m +CONFIG_DVB_SMIPCIE=m +CONFIG_DVB_BUDGET_CORE=m +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_VIDEO_IPU3_CIO2=m +CONFIG_INTEL_VSC=m +CONFIG_IPU_BRIDGE=m +CONFIG_RADIO_ADAPTERS=m +CONFIG_RADIO_MAXIRADIO=m +CONFIG_RADIO_SAA7706H=m +CONFIG_RADIO_SHARK=m +CONFIG_RADIO_SHARK2=m +CONFIG_RADIO_SI4713=m +CONFIG_RADIO_SI476X=m +CONFIG_RADIO_TEA575X=m +CONFIG_RADIO_TEA5764=m +CONFIG_RADIO_TEF6862=m +CONFIG_RADIO_WL1273=m +CONFIG_USB_DSBR=m +CONFIG_USB_KEENE=m +CONFIG_USB_MA901=m +CONFIG_USB_MR800=m +CONFIG_USB_RAREMONO=m +CONFIG_RADIO_SI470X=m +CONFIG_USB_SI470X=m +CONFIG_I2C_SI470X=m +CONFIG_USB_SI4713=m +CONFIG_PLATFORM_SI4713=m +CONFIG_I2C_SI4713=m +CONFIG_RADIO_WL128X=m +CONFIG_MEDIA_PLATFORM_DRIVERS=y +CONFIG_V4L_PLATFORM_DRIVERS=y +# CONFIG_SDR_PLATFORM_DRIVERS is not set +CONFIG_DVB_PLATFORM_DRIVERS=y +CONFIG_V4L_MEM2MEM_DRIVERS=y +CONFIG_VIDEO_MEM2MEM_DEINTERLACE=m + +# +# Allegro DVT media platform drivers +# + +# +# Amlogic media platform drivers +# + +# +# Amphion drivers +# + +# +# Aspeed media platform drivers +# + +# +# Atmel media platform drivers +# + +# +# Cadence media platform drivers +# +CONFIG_VIDEO_CADENCE_CSI2RX=m +CONFIG_VIDEO_CADENCE_CSI2TX=m + +# +# Chips&Media media platform drivers +# + +# +# Intel media platform drivers +# + +# +# Marvell media platform drivers +# +CONFIG_VIDEO_CAFE_CCIC=m + +# +# Mediatek media platform drivers +# + +# +# Microchip Technology, Inc. media platform drivers +# + +# +# NVidia media platform drivers +# + +# +# NXP media platform drivers +# + +# +# Qualcomm media platform drivers +# + +# +# Renesas media platform drivers +# + +# +# Rockchip media platform drivers +# + +# +# Samsung media platform drivers +# + +# +# STMicroelectronics media platform drivers +# + +# +# Sunxi media platform drivers +# + +# +# Texas Instruments drivers +# + +# +# Verisilicon media platform drivers +# + +# +# VIA media platform drivers +# +CONFIG_VIDEO_VIA_CAMERA=m + +# +# Xilinx media platform drivers +# + +# +# MMC/SDIO DVB adapters +# +CONFIG_SMS_SDIO_DRV=m +CONFIG_V4L_TEST_DRIVERS=y +CONFIG_VIDEO_VIM2M=m +CONFIG_VIDEO_VICODEC=m +CONFIG_VIDEO_VIMC=m +CONFIG_VIDEO_VIVID=m +CONFIG_VIDEO_VIVID_CEC=y +CONFIG_VIDEO_VIVID_MAX_DEVS=64 +CONFIG_VIDEO_VISL=m +# CONFIG_VISL_DEBUGFS is not set +CONFIG_DVB_TEST_DRIVERS=y +CONFIG_DVB_VIDTV=m + +# +# FireWire (IEEE 1394) Adapters +# +CONFIG_DVB_FIREDTV=m +CONFIG_DVB_FIREDTV_INPUT=y +CONFIG_MEDIA_COMMON_OPTIONS=y + +# +# common driver options +# +CONFIG_CYPRESS_FIRMWARE=m +CONFIG_TTPCI_EEPROM=m +CONFIG_UVC_COMMON=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_DVB_B2C2_FLEXCOP=m +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_SMS_SIANO_MDTV=m +CONFIG_SMS_SIANO_RC=y +# CONFIG_SMS_SIANO_DEBUGFS is not set +CONFIG_VIDEO_V4L2_TPG=m +CONFIG_VIDEOBUF2_CORE=m +CONFIG_VIDEOBUF2_V4L2=m +CONFIG_VIDEOBUF2_MEMOPS=m +CONFIG_VIDEOBUF2_DMA_CONTIG=m +CONFIG_VIDEOBUF2_VMALLOC=m +CONFIG_VIDEOBUF2_DMA_SG=m +CONFIG_VIDEOBUF2_DVB=m +# end of Media drivers + +# +# Media ancillary drivers +# +CONFIG_MEDIA_ATTACH=y + +# +# IR I2C driver auto-selected by 'Autoselect ancillary drivers' +# +CONFIG_VIDEO_IR_I2C=m +CONFIG_VIDEO_CAMERA_SENSOR=y +CONFIG_VIDEO_APTINA_PLL=m +CONFIG_VIDEO_CCS_PLL=m +CONFIG_VIDEO_AR0521=m +CONFIG_VIDEO_HI556=m +CONFIG_VIDEO_HI846=m +CONFIG_VIDEO_HI847=m +CONFIG_VIDEO_IMX208=m +CONFIG_VIDEO_IMX214=m +CONFIG_VIDEO_IMX219=m +CONFIG_VIDEO_IMX258=m +CONFIG_VIDEO_IMX274=m +CONFIG_VIDEO_IMX290=m +CONFIG_VIDEO_IMX296=m +CONFIG_VIDEO_IMX319=m +CONFIG_VIDEO_IMX355=m +CONFIG_VIDEO_MAX9271_LIB=m +CONFIG_VIDEO_MT9M001=m +CONFIG_VIDEO_MT9M111=m +CONFIG_VIDEO_MT9P031=m +CONFIG_VIDEO_MT9T112=m +CONFIG_VIDEO_MT9V011=m +CONFIG_VIDEO_MT9V032=m +CONFIG_VIDEO_MT9V111=m +CONFIG_VIDEO_OG01A1B=m +CONFIG_VIDEO_OV01A10=m +CONFIG_VIDEO_OV02A10=m +CONFIG_VIDEO_OV08D10=m +CONFIG_VIDEO_OV08X40=m +CONFIG_VIDEO_OV13858=m +CONFIG_VIDEO_OV13B10=m +CONFIG_VIDEO_OV2640=m +CONFIG_VIDEO_OV2659=m +CONFIG_VIDEO_OV2680=m +CONFIG_VIDEO_OV2685=m +CONFIG_VIDEO_OV2740=m +CONFIG_VIDEO_OV4689=m +CONFIG_VIDEO_OV5647=m +CONFIG_VIDEO_OV5648=m +CONFIG_VIDEO_OV5670=m +CONFIG_VIDEO_OV5675=m +CONFIG_VIDEO_OV5693=m +CONFIG_VIDEO_OV5695=m +CONFIG_VIDEO_OV6650=m +CONFIG_VIDEO_OV7251=m +CONFIG_VIDEO_OV7640=m +CONFIG_VIDEO_OV7670=m +CONFIG_VIDEO_OV772X=m +CONFIG_VIDEO_OV7740=m +CONFIG_VIDEO_OV8856=m +CONFIG_VIDEO_OV8858=m +CONFIG_VIDEO_OV8865=m +CONFIG_VIDEO_OV9640=m +CONFIG_VIDEO_OV9650=m +CONFIG_VIDEO_OV9734=m +CONFIG_VIDEO_RDACM20=m +CONFIG_VIDEO_RDACM21=m +CONFIG_VIDEO_RJ54N1=m +CONFIG_VIDEO_S5C73M3=m +CONFIG_VIDEO_S5K5BAF=m +CONFIG_VIDEO_S5K6A3=m +CONFIG_VIDEO_CCS=m +CONFIG_VIDEO_ET8EK8=m + +# +# Lens drivers +# +CONFIG_VIDEO_AD5820=m +CONFIG_VIDEO_AK7375=m +CONFIG_VIDEO_DW9714=m +CONFIG_VIDEO_DW9719=m +CONFIG_VIDEO_DW9768=m +CONFIG_VIDEO_DW9807_VCM=m +# end of Lens drivers + +# +# Flash devices +# +CONFIG_VIDEO_ADP1653=m +CONFIG_VIDEO_LM3560=m +CONFIG_VIDEO_LM3646=m +# end of Flash devices + +# +# Audio decoders, processors and mixers +# +CONFIG_VIDEO_CS3308=m +CONFIG_VIDEO_CS5345=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_SONY_BTF_MPX=m +CONFIG_VIDEO_TDA1997X=m +CONFIG_VIDEO_TDA7432=m +CONFIG_VIDEO_TDA9840=m +CONFIG_VIDEO_TEA6415C=m +CONFIG_VIDEO_TEA6420=m +CONFIG_VIDEO_TLV320AIC23B=m +CONFIG_VIDEO_TVAUDIO=m +CONFIG_VIDEO_UDA1342=m +CONFIG_VIDEO_VP27SMPX=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_WM8775=m +# end of Audio decoders, processors and mixers + +# +# RDS decoders +# +CONFIG_VIDEO_SAA6588=m +# end of RDS decoders + +# +# Video decoders +# +CONFIG_VIDEO_ADV7180=m +CONFIG_VIDEO_ADV7183=m +CONFIG_VIDEO_ADV7604=m +CONFIG_VIDEO_ADV7604_CEC=y +CONFIG_VIDEO_ADV7842=m +CONFIG_VIDEO_ADV7842_CEC=y +CONFIG_VIDEO_BT819=m +CONFIG_VIDEO_BT856=m +CONFIG_VIDEO_BT866=m +CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_ML86V7667=m +CONFIG_VIDEO_SAA7110=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_TC358743=m +CONFIG_VIDEO_TC358743_CEC=y +CONFIG_VIDEO_TC358746=m +CONFIG_VIDEO_TVP514X=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_TVP7002=m +CONFIG_VIDEO_TW2804=m +CONFIG_VIDEO_TW9903=m +CONFIG_VIDEO_TW9906=m +CONFIG_VIDEO_TW9910=m +CONFIG_VIDEO_VPX3220=m + +# +# Video and audio decoders +# +CONFIG_VIDEO_SAA717X=m +CONFIG_VIDEO_CX25840=m +# end of Video decoders + +# +# Video encoders +# +CONFIG_VIDEO_ADV7170=m +CONFIG_VIDEO_ADV7175=m +CONFIG_VIDEO_ADV7343=m +CONFIG_VIDEO_ADV7393=m +CONFIG_VIDEO_ADV7511=m +CONFIG_VIDEO_ADV7511_CEC=y +CONFIG_VIDEO_AK881X=m +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_SAA7185=m +CONFIG_VIDEO_THS8200=m +# end of Video encoders + +# +# Video improvement chips +# +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m +# end of Video improvement chips + +# +# Audio/Video compression chips +# +CONFIG_VIDEO_SAA6752HS=m +# end of Audio/Video compression chips + +# +# SDR tuner chips +# +CONFIG_SDR_MAX2175=m +# end of SDR tuner chips + +# +# Miscellaneous helper chips +# +CONFIG_VIDEO_I2C=m +CONFIG_VIDEO_M52790=m +# CONFIG_VIDEO_ST_MIPID02 is not set +CONFIG_VIDEO_THS7303=m +# end of Miscellaneous helper chips + +# +# Video serializers and deserializers +# +# end of Video serializers and deserializers + +# +# Media SPI Adapters +# +CONFIG_CXD2880_SPI_DRV=m +CONFIG_VIDEO_GS1662=m +# end of Media SPI Adapters + +CONFIG_MEDIA_TUNER=m + +# +# Customize TV tuners +# +CONFIG_MEDIA_TUNER_E4000=m +CONFIG_MEDIA_TUNER_FC0011=m +CONFIG_MEDIA_TUNER_FC0012=m +CONFIG_MEDIA_TUNER_FC0013=m +CONFIG_MEDIA_TUNER_FC2580=m +CONFIG_MEDIA_TUNER_IT913X=m +CONFIG_MEDIA_TUNER_M88RS6000T=m +CONFIG_MEDIA_TUNER_MAX2165=m +CONFIG_MEDIA_TUNER_MC44S803=m +CONFIG_MEDIA_TUNER_MSI001=m +CONFIG_MEDIA_TUNER_MT2060=m +CONFIG_MEDIA_TUNER_MT2063=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_MT2131=m +CONFIG_MEDIA_TUNER_MT2266=m +CONFIG_MEDIA_TUNER_MXL301RF=m +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_MEDIA_TUNER_MXL5007T=m +CONFIG_MEDIA_TUNER_QM1D1B0004=m +CONFIG_MEDIA_TUNER_QM1D1C0042=m +CONFIG_MEDIA_TUNER_QT1010=m +CONFIG_MEDIA_TUNER_R820T=m +CONFIG_MEDIA_TUNER_SI2157=m +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA18212=m +CONFIG_MEDIA_TUNER_TDA18218=m +CONFIG_MEDIA_TUNER_TDA18250=m +CONFIG_MEDIA_TUNER_TDA18271=m +CONFIG_MEDIA_TUNER_TDA827X=m +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_MEDIA_TUNER_TDA9887=m +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_TUA9001=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_MEDIA_TUNER_XC4000=m +CONFIG_MEDIA_TUNER_XC5000=m +# end of Customize TV tuners + +# +# Customise DVB Frontends +# + +# +# Multistandard (satellite) frontends +# +CONFIG_DVB_M88DS3103=m +CONFIG_DVB_MXL5XX=m +CONFIG_DVB_STB0899=m +CONFIG_DVB_STB6100=m +CONFIG_DVB_STV090x=m +CONFIG_DVB_STV0910=m +CONFIG_DVB_STV6110x=m +CONFIG_DVB_STV6111=m + +# +# Multistandard (cable + terrestrial) frontends +# +CONFIG_DVB_DRXK=m +CONFIG_DVB_MN88472=m +CONFIG_DVB_MN88473=m +CONFIG_DVB_SI2165=m +CONFIG_DVB_TDA18271C2DD=m + +# +# DVB-S (satellite) frontends +# +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24116=m +CONFIG_DVB_CX24117=m +CONFIG_DVB_CX24120=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_DS3000=m +CONFIG_DVB_MB86A16=m +CONFIG_DVB_MT312=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_SI21XX=m +CONFIG_DVB_STB6000=m +CONFIG_DVB_STV0288=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_STV0900=m +CONFIG_DVB_STV6110=m +CONFIG_DVB_TDA10071=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA8261=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TS2020=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_TUNER_CX24113=m +CONFIG_DVB_TUNER_ITD1000=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_ZL10036=m +CONFIG_DVB_ZL10039=m + +# +# DVB-T (terrestrial) frontends +# +CONFIG_DVB_AF9013=m +CONFIG_DVB_AS102_FE=m +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_CXD2820R=m +CONFIG_DVB_CXD2841ER=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +CONFIG_DVB_DIB9000=m +CONFIG_DVB_DRXD=m +CONFIG_DVB_EC100=m +CONFIG_DVB_GP8PSK_FE=m +CONFIG_DVB_L64781=m +CONFIG_DVB_MT352=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_RTL2830=m +CONFIG_DVB_RTL2832=m +CONFIG_DVB_RTL2832_SDR=m +CONFIG_DVB_S5H1432=m +CONFIG_DVB_SI2168=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_STV0367=m +CONFIG_DVB_TDA10048=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_ZD1301_DEMOD=m +CONFIG_DVB_ZL10353=m +CONFIG_DVB_CXD2880=m + +# +# DVB-C (cable) frontends +# +CONFIG_DVB_STV0297=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_VES1820=m + +# +# ATSC (North American/Korean Terrestrial/Cable DTV) frontends +# +CONFIG_DVB_AU8522=m +CONFIG_DVB_AU8522_DTV=m +CONFIG_DVB_AU8522_V4L=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_LG2160=m +CONFIG_DVB_LGDT3305=m +CONFIG_DVB_LGDT3306A=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_MXL692=m +CONFIG_DVB_NXT200X=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_S5H1409=m +CONFIG_DVB_S5H1411=m + +# +# ISDB-T (terrestrial) frontends +# +CONFIG_DVB_DIB8000=m +CONFIG_DVB_MB86A20S=m +CONFIG_DVB_S921=m + +# +# ISDB-S (satellite) & ISDB-T (terrestrial) frontends +# +CONFIG_DVB_MN88443X=m +CONFIG_DVB_TC90522=m + +# +# Digital terrestrial only tuners/PLL +# +CONFIG_DVB_PLL=m +CONFIG_DVB_TUNER_DIB0070=m +CONFIG_DVB_TUNER_DIB0090=m + +# +# SEC control devices for DVB-S +# +CONFIG_DVB_A8293=m +CONFIG_DVB_AF9033=m +CONFIG_DVB_ASCOT2E=m +CONFIG_DVB_ATBM8830=m +CONFIG_DVB_HELENE=m +CONFIG_DVB_HORUS3A=m +CONFIG_DVB_ISL6405=m +CONFIG_DVB_ISL6421=m +CONFIG_DVB_ISL6423=m +CONFIG_DVB_IX2505V=m +CONFIG_DVB_LGS8GL5=m +CONFIG_DVB_LGS8GXX=m +CONFIG_DVB_LNBH25=m +CONFIG_DVB_LNBH29=m +CONFIG_DVB_LNBP21=m +CONFIG_DVB_LNBP22=m +CONFIG_DVB_M88RS2000=m +CONFIG_DVB_TDA665x=m +CONFIG_DVB_DRX39XYJ=m + +# +# Common Interface (EN50221) controller drivers +# +CONFIG_DVB_CXD2099=m +CONFIG_DVB_SP2=m +# end of Customise DVB Frontends + +# +# Tools to develop new frontends +# +CONFIG_DVB_DUMMY_FE=m +# end of Media ancillary drivers + +# +# Graphics support +# +CONFIG_APERTURE_HELPERS=y +CONFIG_SCREEN_INFO=y +CONFIG_VIDEO_CMDLINE=y +CONFIG_VIDEO_NOMODESET=y +CONFIG_AUXDISPLAY=y +CONFIG_CHARLCD=m +CONFIG_HD44780_COMMON=m +# CONFIG_HD44780 is not set +CONFIG_KS0108=m +CONFIG_KS0108_PORT=0x378 +CONFIG_KS0108_DELAY=2 +CONFIG_CFAG12864B=m +CONFIG_CFAG12864B_RATE=20 +# CONFIG_IMG_ASCII_LCD is not set +# CONFIG_HT16K33 is not set +# CONFIG_LCD2S is not set +CONFIG_PARPORT_PANEL=m +CONFIG_PANEL_PARPORT=0 +CONFIG_PANEL_PROFILE=5 +# CONFIG_PANEL_CHANGE_MESSAGE is not set +# CONFIG_CHARLCD_BL_OFF is not set +# CONFIG_CHARLCD_BL_ON is not set +CONFIG_CHARLCD_BL_FLASH=y +CONFIG_PANEL=m +CONFIG_AGP=y +CONFIG_AGP_AMD64=y +CONFIG_AGP_INTEL=y +CONFIG_AGP_SIS=y +CONFIG_AGP_VIA=y +CONFIG_INTEL_GTT=y +CONFIG_VGA_SWITCHEROO=y +CONFIG_DRM=m +CONFIG_DRM_MIPI_DBI=m +CONFIG_DRM_MIPI_DSI=y +CONFIG_DRM_KMS_HELPER=m +# CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS is not set +# CONFIG_DRM_DEBUG_MODESET_LOCK is not set +CONFIG_DRM_FBDEV_EMULATION=y +CONFIG_DRM_FBDEV_OVERALLOC=300 +# CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM is not set +CONFIG_DRM_LOAD_EDID_FIRMWARE=y +CONFIG_DRM_DISPLAY_HELPER=m +CONFIG_DRM_DISPLAY_DP_HELPER=y +CONFIG_DRM_DISPLAY_HDCP_HELPER=y +CONFIG_DRM_DISPLAY_HDMI_HELPER=y +CONFIG_DRM_DP_AUX_CHARDEV=y +CONFIG_DRM_DP_CEC=y +CONFIG_DRM_TTM=m +CONFIG_DRM_EXEC=m +CONFIG_DRM_BUDDY=m +CONFIG_DRM_VRAM_HELPER=m +CONFIG_DRM_TTM_HELPER=m +CONFIG_DRM_GEM_DMA_HELPER=m +CONFIG_DRM_GEM_SHMEM_HELPER=m +CONFIG_DRM_SUBALLOC_HELPER=m +CONFIG_DRM_SCHED=m + +# +# I2C encoder or helper chips +# +CONFIG_DRM_I2C_CH7006=m +CONFIG_DRM_I2C_SIL164=m +CONFIG_DRM_I2C_NXP_TDA998X=m +CONFIG_DRM_I2C_NXP_TDA9950=m +# end of I2C encoder or helper chips + +# +# ARM devices +# +# end of ARM devices + +CONFIG_DRM_RADEON=m +CONFIG_DRM_RADEON_USERPTR=y +CONFIG_DRM_AMDGPU=m +CONFIG_DRM_AMDGPU_SI=y +CONFIG_DRM_AMDGPU_CIK=y +CONFIG_DRM_AMDGPU_USERPTR=y +# CONFIG_DRM_AMDGPU_WERROR is not set + +# +# ACP (Audio CoProcessor) Configuration +# +CONFIG_DRM_AMD_ACP=y +# end of ACP (Audio CoProcessor) Configuration + +# +# Display Engine Configuration +# +CONFIG_DRM_AMD_DC=y +CONFIG_DRM_AMD_DC_FP=y +CONFIG_DRM_AMD_DC_SI=y +CONFIG_DRM_AMD_SECURE_DISPLAY=y +# end of Display Engine Configuration + +CONFIG_HSA_AMD=y +CONFIG_HSA_AMD_SVM=y +CONFIG_DRM_NOUVEAU=m +CONFIG_NOUVEAU_DEBUG=5 +CONFIG_NOUVEAU_DEBUG_DEFAULT=3 +# CONFIG_NOUVEAU_DEBUG_MMU is not set +# CONFIG_NOUVEAU_DEBUG_PUSH is not set +CONFIG_DRM_NOUVEAU_BACKLIGHT=y +# CONFIG_DRM_NOUVEAU_SVM is not set +CONFIG_DRM_I915=m +CONFIG_DRM_I915_FORCE_PROBE="" +CONFIG_DRM_I915_CAPTURE_ERROR=y +CONFIG_DRM_I915_COMPRESS_ERROR=y +CONFIG_DRM_I915_USERPTR=y +CONFIG_DRM_I915_GVT_KVMGT=m +CONFIG_DRM_I915_PXP=y + +# +# drm/i915 Debugging +# +# CONFIG_DRM_I915_WERROR is not set +# CONFIG_DRM_I915_DEBUG is not set +# CONFIG_DRM_I915_DEBUG_MMIO is not set +# CONFIG_DRM_I915_SW_FENCE_DEBUG_OBJECTS is not set +# CONFIG_DRM_I915_SW_FENCE_CHECK_DAG is not set +# CONFIG_DRM_I915_DEBUG_GUC is not set +# CONFIG_DRM_I915_SELFTEST is not set +# CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS is not set +# CONFIG_DRM_I915_DEBUG_VBLANK_EVADE is not set +# CONFIG_DRM_I915_DEBUG_RUNTIME_PM is not set +# end of drm/i915 Debugging + +# +# drm/i915 Profile Guided Optimisation +# +CONFIG_DRM_I915_REQUEST_TIMEOUT=20000 +CONFIG_DRM_I915_FENCE_TIMEOUT=10000 +CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND=250 +CONFIG_DRM_I915_HEARTBEAT_INTERVAL=2500 +CONFIG_DRM_I915_PREEMPT_TIMEOUT=640 +CONFIG_DRM_I915_PREEMPT_TIMEOUT_COMPUTE=7500 +CONFIG_DRM_I915_MAX_REQUEST_BUSYWAIT=8000 +CONFIG_DRM_I915_STOP_TIMEOUT=100 +CONFIG_DRM_I915_TIMESLICE_DURATION=1 +# end of drm/i915 Profile Guided Optimisation + +CONFIG_DRM_I915_GVT=y +CONFIG_DRM_VGEM=m +CONFIG_DRM_VKMS=m +CONFIG_DRM_VMWGFX=m +CONFIG_DRM_VMWGFX_MKSSTATS=y +CONFIG_DRM_GMA500=m +CONFIG_DRM_UDL=m +CONFIG_DRM_AST=m +CONFIG_DRM_MGAG200=m +CONFIG_DRM_QXL=m +CONFIG_DRM_VIRTIO_GPU=m +CONFIG_DRM_VIRTIO_GPU_KMS=y +CONFIG_DRM_PANEL=y + +# +# Display Panels +# +# CONFIG_DRM_PANEL_AUO_A030JTN01 is not set +# CONFIG_DRM_PANEL_ILITEK_ILI9341 is not set +# CONFIG_DRM_PANEL_ORISETECH_OTA5601A is not set +# CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN is not set +# CONFIG_DRM_PANEL_WIDECHIPS_WS2401 is not set +# end of Display Panels + +CONFIG_DRM_BRIDGE=y +CONFIG_DRM_PANEL_BRIDGE=y + +# +# Display Interface Bridges +# +CONFIG_DRM_ANALOGIX_ANX78XX=m +CONFIG_DRM_ANALOGIX_DP=m +# end of Display Interface Bridges + +CONFIG_DRM_LOONGSON=m +# CONFIG_DRM_ETNAVIV is not set +CONFIG_DRM_BOCHS=m +CONFIG_DRM_CIRRUS_QEMU=m +CONFIG_DRM_GM12U320=m +CONFIG_DRM_PANEL_MIPI_DBI=m +CONFIG_DRM_SIMPLEDRM=m +CONFIG_TINYDRM_HX8357D=m +CONFIG_TINYDRM_ILI9163=m +CONFIG_TINYDRM_ILI9225=m +CONFIG_TINYDRM_ILI9341=m +CONFIG_TINYDRM_ILI9486=m +CONFIG_TINYDRM_MI0283QT=m +CONFIG_TINYDRM_REPAPER=m +CONFIG_TINYDRM_ST7586=m +CONFIG_TINYDRM_ST7735R=m +CONFIG_DRM_XEN=y +CONFIG_DRM_XEN_FRONTEND=m +CONFIG_DRM_VBOXVIDEO=m +CONFIG_DRM_GUD=m +CONFIG_DRM_SSD130X=m +CONFIG_DRM_SSD130X_I2C=m +CONFIG_DRM_SSD130X_SPI=m +CONFIG_DRM_HYPERV=m +CONFIG_DRM_LEGACY=y +CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y +CONFIG_DRM_PRIVACY_SCREEN=y + +# +# Frame buffer Devices +# +CONFIG_FB=y +CONFIG_FB_SVGALIB=m +CONFIG_FB_CIRRUS=m +CONFIG_FB_PM2=m +# CONFIG_FB_PM2_FIFO_DISCONNECT is not set +CONFIG_FB_CYBER2000=m +CONFIG_FB_CYBER2000_DDC=y +CONFIG_FB_ARC=m +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +CONFIG_FB_VGA16=m +CONFIG_FB_UVESA=m +CONFIG_FB_VESA=y +CONFIG_FB_EFI=y +# CONFIG_FB_N411 is not set +# CONFIG_FB_HGA is not set +CONFIG_FB_OPENCORES=m +# CONFIG_FB_S1D13XXX is not set +CONFIG_FB_NVIDIA=m +CONFIG_FB_NVIDIA_I2C=y +# CONFIG_FB_NVIDIA_DEBUG is not set +CONFIG_FB_NVIDIA_BACKLIGHT=y +CONFIG_FB_RIVA=m +# CONFIG_FB_RIVA_I2C is not set +# CONFIG_FB_RIVA_DEBUG is not set +CONFIG_FB_RIVA_BACKLIGHT=y +CONFIG_FB_I740=m +CONFIG_FB_LE80578=m +CONFIG_FB_CARILLO_RANCH=m +CONFIG_FB_INTEL=m +# CONFIG_FB_INTEL_DEBUG is not set +CONFIG_FB_INTEL_I2C=y +CONFIG_FB_MATROX=m +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_MATROX_G=y +CONFIG_FB_MATROX_I2C=m +CONFIG_FB_MATROX_MAVEN=m +CONFIG_FB_RADEON=m +CONFIG_FB_RADEON_I2C=y +CONFIG_FB_RADEON_BACKLIGHT=y +# CONFIG_FB_RADEON_DEBUG is not set +CONFIG_FB_ATY128=m +CONFIG_FB_ATY128_BACKLIGHT=y +CONFIG_FB_ATY=m +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GENERIC_LCD=y +CONFIG_FB_ATY_GX=y +CONFIG_FB_ATY_BACKLIGHT=y +CONFIG_FB_S3=m +CONFIG_FB_S3_DDC=y +CONFIG_FB_SAVAGE=m +CONFIG_FB_SAVAGE_I2C=y +CONFIG_FB_SAVAGE_ACCEL=y +CONFIG_FB_SIS=m +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y +CONFIG_FB_VIA=m +# CONFIG_FB_VIA_DIRECT_PROCFS is not set +# CONFIG_FB_VIA_X_COMPATIBILITY is not set +CONFIG_FB_NEOMAGIC=m +CONFIG_FB_KYRO=m +CONFIG_FB_3DFX=m +# CONFIG_FB_3DFX_ACCEL is not set +CONFIG_FB_3DFX_I2C=y +CONFIG_FB_VOODOO1=m +CONFIG_FB_VT8623=m +CONFIG_FB_TRIDENT=m +CONFIG_FB_ARK=m +CONFIG_FB_PM3=m +CONFIG_FB_CARMINE=m +CONFIG_FB_CARMINE_DRAM_EVAL=y +# CONFIG_CARMINE_DRAM_CUSTOM is not set +CONFIG_FB_SMSCUFX=m +CONFIG_FB_UDL=m +CONFIG_FB_IBM_GXT4500=m +# CONFIG_FB_VIRTUAL is not set +CONFIG_XEN_FBDEV_FRONTEND=y +# CONFIG_FB_METRONOME is not set +CONFIG_FB_MB862XX=m +CONFIG_FB_MB862XX_PCI_GDC=y +CONFIG_FB_MB862XX_I2C=y +CONFIG_FB_HYPERV=m +CONFIG_FB_SIMPLE=m +# CONFIG_FB_SSD1307 is not set +CONFIG_FB_SM712=m +CONFIG_FB_CORE=y +CONFIG_FB_NOTIFY=y +# CONFIG_FIRMWARE_EDID is not set +CONFIG_FB_DEVICE=y +CONFIG_FB_DDC=m +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SYS_FILLRECT=y +CONFIG_FB_SYS_COPYAREA=y +CONFIG_FB_SYS_IMAGEBLIT=y +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_DMAMEM_HELPERS=y +CONFIG_FB_IOMEM_FOPS=y +CONFIG_FB_IOMEM_HELPERS=y +CONFIG_FB_SYSMEM_HELPERS=y +CONFIG_FB_SYSMEM_HELPERS_DEFERRED=y +CONFIG_FB_BACKLIGHT=m +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_TILEBLITTING=y +# end of Frame buffer Devices + +# +# Backlight & LCD device support +# +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LCD_L4F00242T03=m +CONFIG_LCD_LMS283GF05=m +CONFIG_LCD_LTV350QV=m +CONFIG_LCD_ILI922X=m +CONFIG_LCD_ILI9320=m +CONFIG_LCD_TDO24M=m +CONFIG_LCD_VGG2432A4=m +CONFIG_LCD_PLATFORM=m +CONFIG_LCD_AMS369FG06=m +CONFIG_LCD_LMS501KF03=m +CONFIG_LCD_HX8357=m +CONFIG_LCD_OTM3225A=m +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_KTD253=m +CONFIG_BACKLIGHT_KTZ8866=m +CONFIG_BACKLIGHT_CARILLO_RANCH=m +CONFIG_BACKLIGHT_PWM=m +CONFIG_BACKLIGHT_DA903X=m +CONFIG_BACKLIGHT_DA9052=m +CONFIG_BACKLIGHT_MAX8925=m +CONFIG_BACKLIGHT_APPLE=m +CONFIG_BACKLIGHT_QCOM_WLED=m +CONFIG_BACKLIGHT_SAHARA=m +CONFIG_BACKLIGHT_WM831X=m +CONFIG_BACKLIGHT_ADP5520=m +CONFIG_BACKLIGHT_ADP8860=m +CONFIG_BACKLIGHT_ADP8870=m +CONFIG_BACKLIGHT_88PM860X=m +CONFIG_BACKLIGHT_AAT2870=m +CONFIG_BACKLIGHT_LM3630A=m +CONFIG_BACKLIGHT_LM3639=m +CONFIG_BACKLIGHT_LP855X=m +CONFIG_BACKLIGHT_LP8788=m +CONFIG_BACKLIGHT_PANDORA=m +CONFIG_BACKLIGHT_AS3711=m +CONFIG_BACKLIGHT_GPIO=m +CONFIG_BACKLIGHT_LV5207LP=m +CONFIG_BACKLIGHT_BD6107=m +CONFIG_BACKLIGHT_ARCXCNN=m +# end of Backlight & LCD device support + +CONFIG_VGASTATE=m +CONFIG_VIDEOMODE_HELPERS=y +CONFIG_HDMI=y + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +CONFIG_DUMMY_CONSOLE=y +CONFIG_DUMMY_CONSOLE_COLUMNS=80 +CONFIG_DUMMY_CONSOLE_ROWS=25 +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION is not set +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +# CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set +# end of Console display driver support + +# CONFIG_LOGO is not set +# end of Graphics support + +CONFIG_DRM_ACCEL=y +CONFIG_DRM_ACCEL_HABANALABS=m +CONFIG_DRM_ACCEL_IVPU=m +CONFIG_DRM_ACCEL_QAIC=m +CONFIG_SOUND=m +CONFIG_SOUND_OSS_CORE=y +# CONFIG_SOUND_OSS_CORE_PRECLAIM is not set +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_PCM_ELD=y +CONFIG_SND_PCM_IEC958=y +CONFIG_SND_DMAENGINE_PCM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_SEQ_DEVICE=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_UMP=m +CONFIG_SND_UMP_LEGACY_RAWMIDI=y +CONFIG_SND_COMPRESS_OFFLOAD=m +CONFIG_SND_JACK=y +CONFIG_SND_JACK_INPUT_DEV=y +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_PCM_TIMER=y +CONFIG_SND_HRTIMER=m +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_MAX_CARDS=32 +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_PROC_FS=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +CONFIG_SND_CTL_FAST_LOOKUP=y +CONFIG_SND_DEBUG=y +# CONFIG_SND_DEBUG_VERBOSE is not set +CONFIG_SND_PCM_XRUN_DEBUG=y +# CONFIG_SND_CTL_INPUT_VALIDATION is not set +# CONFIG_SND_CTL_DEBUG is not set +# CONFIG_SND_JACK_INJECTION_DEBUG is not set +CONFIG_SND_VMASTER=y +CONFIG_SND_DMA_SGBUF=y +CONFIG_SND_CTL_LED=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SEQUENCER_OSS=m +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y +CONFIG_SND_SEQ_MIDI_EVENT=m +CONFIG_SND_SEQ_MIDI=m +CONFIG_SND_SEQ_MIDI_EMUL=m +CONFIG_SND_SEQ_VIRMIDI=m +CONFIG_SND_SEQ_UMP=y +CONFIG_SND_SEQ_UMP_CLIENT=m +CONFIG_SND_MPU401_UART=m +CONFIG_SND_OPL3_LIB=m +CONFIG_SND_OPL3_LIB_SEQ=m +CONFIG_SND_VX_LIB=m +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_DRIVERS=y +# CONFIG_SND_PCSP is not set +CONFIG_SND_DUMMY=m +CONFIG_SND_ALOOP=m +CONFIG_SND_PCMTEST=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_MTPAV=m +CONFIG_SND_MTS64=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_MPU401=m +CONFIG_SND_PORTMAN2X4=m +CONFIG_SND_AC97_POWER_SAVE=y +CONFIG_SND_AC97_POWER_SAVE_DEFAULT=0 +CONFIG_SND_SB_COMMON=m +CONFIG_SND_PCI=y +CONFIG_SND_AD1889=m +CONFIG_SND_ALS300=m +CONFIG_SND_ALS4000=m +CONFIG_SND_ALI5451=m +CONFIG_SND_ASIHPI=m +CONFIG_SND_ATIIXP=m +CONFIG_SND_ATIIXP_MODEM=m +CONFIG_SND_AU8810=m +CONFIG_SND_AU8820=m +CONFIG_SND_AU8830=m +CONFIG_SND_AW2=m +CONFIG_SND_AZT3328=m +CONFIG_SND_BT87X=m +# CONFIG_SND_BT87X_OVERCLOCK is not set +CONFIG_SND_CA0106=m +CONFIG_SND_CMIPCI=m +CONFIG_SND_OXYGEN_LIB=m +CONFIG_SND_OXYGEN=m +CONFIG_SND_CS4281=m +CONFIG_SND_CS46XX=m +CONFIG_SND_CS46XX_NEW_DSP=y +CONFIG_SND_CTXFI=m +CONFIG_SND_DARLA20=m +CONFIG_SND_GINA20=m +CONFIG_SND_LAYLA20=m +CONFIG_SND_DARLA24=m +CONFIG_SND_GINA24=m +CONFIG_SND_LAYLA24=m +CONFIG_SND_MONA=m +CONFIG_SND_MIA=m +CONFIG_SND_ECHO3G=m +CONFIG_SND_INDIGO=m +CONFIG_SND_INDIGOIO=m +CONFIG_SND_INDIGODJ=m +CONFIG_SND_INDIGOIOX=m +CONFIG_SND_INDIGODJX=m +CONFIG_SND_EMU10K1=m +CONFIG_SND_EMU10K1_SEQ=m +CONFIG_SND_EMU10K1X=m +CONFIG_SND_ENS1370=m +CONFIG_SND_ENS1371=m +CONFIG_SND_ES1938=m +CONFIG_SND_ES1968=m +CONFIG_SND_ES1968_INPUT=y +CONFIG_SND_ES1968_RADIO=y +CONFIG_SND_FM801=m +CONFIG_SND_FM801_TEA575X_BOOL=y +CONFIG_SND_HDSP=m +CONFIG_SND_HDSPM=m +CONFIG_SND_ICE1712=m +CONFIG_SND_ICE1724=m +CONFIG_SND_INTEL8X0=m +CONFIG_SND_INTEL8X0M=m +CONFIG_SND_KORG1212=m +CONFIG_SND_LOLA=m +CONFIG_SND_LX6464ES=m +CONFIG_SND_MAESTRO3=m +CONFIG_SND_MAESTRO3_INPUT=y +CONFIG_SND_MIXART=m +CONFIG_SND_NM256=m +CONFIG_SND_PCXHR=m +CONFIG_SND_RIPTIDE=m +CONFIG_SND_RME32=m +CONFIG_SND_RME96=m +CONFIG_SND_RME9652=m +CONFIG_SND_SONICVIBES=m +CONFIG_SND_TRIDENT=m +CONFIG_SND_VIA82XX=m +CONFIG_SND_VIA82XX_MODEM=m +CONFIG_SND_VIRTUOSO=m +CONFIG_SND_VX222=m +CONFIG_SND_YMFPCI=m + +# +# HD-Audio +# +CONFIG_SND_HDA=m +CONFIG_SND_HDA_GENERIC_LEDS=y +CONFIG_SND_HDA_INTEL=m +CONFIG_SND_HDA_HWDEP=y +CONFIG_SND_HDA_RECONFIG=y +CONFIG_SND_HDA_INPUT_BEEP=y +CONFIG_SND_HDA_INPUT_BEEP_MODE=1 +CONFIG_SND_HDA_PATCH_LOADER=y +CONFIG_SND_HDA_SCODEC_CS35L41=m +CONFIG_SND_HDA_CS_DSP_CONTROLS=m +CONFIG_SND_HDA_SCODEC_CS35L41_I2C=m +CONFIG_SND_HDA_SCODEC_CS35L41_SPI=m +CONFIG_SND_HDA_SCODEC_CS35L56=m +CONFIG_SND_HDA_SCODEC_CS35L56_I2C=m +CONFIG_SND_HDA_SCODEC_CS35L56_SPI=m +CONFIG_SND_HDA_SCODEC_TAS2781_I2C=m +CONFIG_SND_HDA_CODEC_REALTEK=m +CONFIG_SND_HDA_CODEC_ANALOG=m +CONFIG_SND_HDA_CODEC_SIGMATEL=m +CONFIG_SND_HDA_CODEC_VIA=m +CONFIG_SND_HDA_CODEC_HDMI=m +CONFIG_SND_HDA_CODEC_CIRRUS=m +CONFIG_SND_HDA_CODEC_CS8409=m +CONFIG_SND_HDA_CODEC_CONEXANT=m +CONFIG_SND_HDA_CODEC_CA0110=m +CONFIG_SND_HDA_CODEC_CA0132=m +CONFIG_SND_HDA_CODEC_CA0132_DSP=y +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_INTEL_HDMI_SILENT_STREAM=y +# CONFIG_SND_HDA_CTL_DEV_ID is not set +# end of HD-Audio + +CONFIG_SND_HDA_CORE=m +CONFIG_SND_HDA_DSP_LOADER=y +CONFIG_SND_HDA_COMPONENT=y +CONFIG_SND_HDA_I915=y +CONFIG_SND_HDA_EXT_CORE=m +CONFIG_SND_HDA_PREALLOC_SIZE=0 +CONFIG_SND_INTEL_NHLT=y +CONFIG_SND_INTEL_DSP_CONFIG=m +CONFIG_SND_INTEL_SOUNDWIRE_ACPI=m +CONFIG_SND_INTEL_BYT_PREFER_SOF=y +CONFIG_SND_SPI=y +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_AUDIO_MIDI_V2=y +CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER=y +CONFIG_SND_USB_UA101=m +CONFIG_SND_USB_USX2Y=m +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +CONFIG_SND_USB_US122L=m +CONFIG_SND_USB_6FIRE=m +CONFIG_SND_USB_HIFACE=m +CONFIG_SND_BCD2000=m +CONFIG_SND_USB_LINE6=m +CONFIG_SND_USB_POD=m +CONFIG_SND_USB_PODHD=m +CONFIG_SND_USB_TONEPORT=m +CONFIG_SND_USB_VARIAX=m +CONFIG_SND_FIREWIRE=y +CONFIG_SND_FIREWIRE_LIB=m +CONFIG_SND_DICE=m +CONFIG_SND_OXFW=m +CONFIG_SND_ISIGHT=m +CONFIG_SND_FIREWORKS=m +CONFIG_SND_BEBOB=m +CONFIG_SND_FIREWIRE_DIGI00X=m +CONFIG_SND_FIREWIRE_TASCAM=m +CONFIG_SND_FIREWIRE_MOTU=m +CONFIG_SND_FIREFACE=m +CONFIG_SND_PCMCIA=y +CONFIG_SND_VXPOCKET=m +CONFIG_SND_PDAUDIOCF=m +CONFIG_SND_SOC=m +CONFIG_SND_SOC_AC97_BUS=y +CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y +CONFIG_SND_SOC_COMPRESS=y +CONFIG_SND_SOC_TOPOLOGY=y +CONFIG_SND_SOC_ACPI=m +CONFIG_SND_SOC_ADI=m +CONFIG_SND_SOC_ADI_AXI_I2S=m +CONFIG_SND_SOC_ADI_AXI_SPDIF=m +CONFIG_SND_SOC_AMD_ACP=m +CONFIG_SND_SOC_AMD_CZ_DA7219MX98357_MACH=m +CONFIG_SND_SOC_AMD_CZ_RT5645_MACH=m +CONFIG_SND_SOC_AMD_ST_ES8336_MACH=m +CONFIG_SND_SOC_AMD_ACP3x=m +CONFIG_SND_SOC_AMD_RV_RT5682_MACH=m +CONFIG_SND_SOC_AMD_RENOIR=m +CONFIG_SND_SOC_AMD_RENOIR_MACH=m +CONFIG_SND_SOC_AMD_ACP5x=m +CONFIG_SND_SOC_AMD_VANGOGH_MACH=m +CONFIG_SND_SOC_AMD_ACP6x=m +CONFIG_SND_SOC_AMD_YC_MACH=m +CONFIG_SND_AMD_ACP_CONFIG=m +CONFIG_SND_SOC_AMD_ACP_COMMON=m +CONFIG_SND_SOC_AMD_ACP_PDM=m +CONFIG_SND_SOC_AMD_ACP_LEGACY_COMMON=m +CONFIG_SND_SOC_AMD_ACP_I2S=m +CONFIG_SND_SOC_AMD_ACP_PCM=m +CONFIG_SND_SOC_AMD_ACP_PCI=m +CONFIG_SND_AMD_ASOC_RENOIR=m +CONFIG_SND_AMD_ASOC_REMBRANDT=m +CONFIG_SND_SOC_AMD_MACH_COMMON=m +CONFIG_SND_SOC_AMD_LEGACY_MACH=m +CONFIG_SND_SOC_AMD_SOF_MACH=m +CONFIG_SND_SOC_AMD_RPL_ACP6x=m +CONFIG_SND_SOC_AMD_PS=m +CONFIG_SND_SOC_AMD_PS_MACH=m +# CONFIG_SND_ATMEL_SOC is not set +CONFIG_SND_BCM63XX_I2S_WHISTLER=m +CONFIG_SND_DESIGNWARE_I2S=m +CONFIG_SND_DESIGNWARE_PCM=y + +# +# SoC Audio for Freescale CPUs +# + +# +# Common SoC Audio options for Freescale CPUs: +# +# CONFIG_SND_SOC_FSL_ASRC is not set +# CONFIG_SND_SOC_FSL_SAI is not set +# CONFIG_SND_SOC_FSL_AUDMIX is not set +# CONFIG_SND_SOC_FSL_SSI is not set +# CONFIG_SND_SOC_FSL_SPDIF is not set +# CONFIG_SND_SOC_FSL_ESAI is not set +# CONFIG_SND_SOC_FSL_MICFIL is not set +# CONFIG_SND_SOC_FSL_XCVR is not set +# CONFIG_SND_SOC_FSL_RPMSG is not set +# CONFIG_SND_SOC_IMX_AUDMUX is not set +# end of SoC Audio for Freescale CPUs + +CONFIG_SND_SOC_CHV3_I2S=m +CONFIG_SND_I2S_HI6210_I2S=m +CONFIG_SND_SOC_IMG=y +CONFIG_SND_SOC_IMG_I2S_IN=m +CONFIG_SND_SOC_IMG_I2S_OUT=m +CONFIG_SND_SOC_IMG_PARALLEL_OUT=m +CONFIG_SND_SOC_IMG_SPDIF_IN=m +CONFIG_SND_SOC_IMG_SPDIF_OUT=m +CONFIG_SND_SOC_IMG_PISTACHIO_INTERNAL_DAC=m +CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y +CONFIG_SND_SOC_INTEL_SST=m +CONFIG_SND_SOC_INTEL_CATPT=m +CONFIG_SND_SST_ATOM_HIFI2_PLATFORM=m +CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_PCI=m +CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI=m +CONFIG_SND_SOC_INTEL_SKYLAKE=m +CONFIG_SND_SOC_INTEL_SKL=m +CONFIG_SND_SOC_INTEL_APL=m +CONFIG_SND_SOC_INTEL_KBL=m +CONFIG_SND_SOC_INTEL_GLK=m +CONFIG_SND_SOC_INTEL_CNL=m +CONFIG_SND_SOC_INTEL_CFL=m +CONFIG_SND_SOC_INTEL_CML_H=m +CONFIG_SND_SOC_INTEL_CML_LP=m +CONFIG_SND_SOC_INTEL_SKYLAKE_FAMILY=m +CONFIG_SND_SOC_INTEL_SKYLAKE_SSP_CLK=m +CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC=y +CONFIG_SND_SOC_INTEL_SKYLAKE_COMMON=m +CONFIG_SND_SOC_ACPI_INTEL_MATCH=m +CONFIG_SND_SOC_INTEL_AVS=m + +# +# Intel AVS Machine drivers +# + +# +# Available DSP configurations +# +CONFIG_SND_SOC_INTEL_AVS_MACH_DA7219=m +CONFIG_SND_SOC_INTEL_AVS_MACH_DMIC=m +CONFIG_SND_SOC_INTEL_AVS_MACH_ES8336=m +CONFIG_SND_SOC_INTEL_AVS_MACH_HDAUDIO=m +CONFIG_SND_SOC_INTEL_AVS_MACH_I2S_TEST=m +CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98927=m +CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98357A=m +CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98373=m +CONFIG_SND_SOC_INTEL_AVS_MACH_NAU8825=m +CONFIG_SND_SOC_INTEL_AVS_MACH_PROBE=m +CONFIG_SND_SOC_INTEL_AVS_MACH_RT274=m +CONFIG_SND_SOC_INTEL_AVS_MACH_RT286=m +CONFIG_SND_SOC_INTEL_AVS_MACH_RT298=m +CONFIG_SND_SOC_INTEL_AVS_MACH_RT5663=m +CONFIG_SND_SOC_INTEL_AVS_MACH_RT5682=m +CONFIG_SND_SOC_INTEL_AVS_MACH_SSM4567=m +# end of Intel AVS Machine drivers + +CONFIG_SND_SOC_INTEL_MACH=y +CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES=y +CONFIG_SND_SOC_INTEL_HDA_DSP_COMMON=m +CONFIG_SND_SOC_INTEL_SOF_MAXIM_COMMON=m +CONFIG_SND_SOC_INTEL_SOF_REALTEK_COMMON=m +CONFIG_SND_SOC_INTEL_SOF_CIRRUS_COMMON=m +CONFIG_SND_SOC_INTEL_HASWELL_MACH=m +CONFIG_SND_SOC_INTEL_BDW_RT5650_MACH=m +CONFIG_SND_SOC_INTEL_BDW_RT5677_MACH=m +CONFIG_SND_SOC_INTEL_BROADWELL_MACH=m +CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH=m +CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH=m +CONFIG_SND_SOC_INTEL_BYTCR_WM5102_MACH=m +CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH=m +CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH=m +CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH=m +CONFIG_SND_SOC_INTEL_CHT_BSW_NAU8824_MACH=m +CONFIG_SND_SOC_INTEL_BYT_CHT_CX2072X_MACH=m +CONFIG_SND_SOC_INTEL_BYT_CHT_DA7213_MACH=m +CONFIG_SND_SOC_INTEL_BYT_CHT_ES8316_MACH=m +CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH=m +CONFIG_SND_SOC_INTEL_SKL_RT286_MACH=m +CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH=m +CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH=m +CONFIG_SND_SOC_INTEL_DA7219_MAX98357A_GENERIC=m +CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON=m +CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH=m +CONFIG_SND_SOC_INTEL_BXT_RT298_MACH=m +CONFIG_SND_SOC_INTEL_SOF_WM8804_MACH=m +CONFIG_SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH=m +CONFIG_SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH=m +CONFIG_SND_SOC_INTEL_KBL_DA7219_MAX98357A_MACH=m +CONFIG_SND_SOC_INTEL_KBL_DA7219_MAX98927_MACH=m +CONFIG_SND_SOC_INTEL_KBL_RT5660_MACH=m +CONFIG_SND_SOC_INTEL_GLK_DA7219_MAX98357A_MACH=m +CONFIG_SND_SOC_INTEL_GLK_RT5682_MAX98357A_MACH=m +CONFIG_SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH=m +CONFIG_SND_SOC_INTEL_SOF_RT5682_MACH=m +CONFIG_SND_SOC_INTEL_SOF_CS42L42_MACH=m +CONFIG_SND_SOC_INTEL_SOF_PCM512x_MACH=m +CONFIG_SND_SOC_INTEL_SOF_ES8336_MACH=m +CONFIG_SND_SOC_INTEL_SOF_NAU8825_MACH=m +CONFIG_SND_SOC_INTEL_CML_LP_DA7219_MAX98357A_MACH=m +CONFIG_SND_SOC_INTEL_SOF_CML_RT1011_RT5682_MACH=m +CONFIG_SND_SOC_INTEL_SOF_DA7219_MAX98373_MACH=m +CONFIG_SND_SOC_INTEL_SOF_SSP_AMP_MACH=m +CONFIG_SND_SOC_INTEL_EHL_RT5660_MACH=m +CONFIG_SND_SOC_INTEL_SOUNDWIRE_SOF_MACH=m +CONFIG_SND_SOC_MTK_BTCVSD=m +CONFIG_SND_SOC_SOF_TOPLEVEL=y +CONFIG_SND_SOC_SOF_PCI_DEV=m +CONFIG_SND_SOC_SOF_PCI=m +CONFIG_SND_SOC_SOF_ACPI=m +CONFIG_SND_SOC_SOF_ACPI_DEV=m +CONFIG_SND_SOC_SOF_DEBUG_PROBES=m +CONFIG_SND_SOC_SOF_CLIENT=m +# CONFIG_SND_SOC_SOF_DEVELOPER_SUPPORT is not set +CONFIG_SND_SOC_SOF=m +CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE=y +CONFIG_SND_SOC_SOF_IPC3=y +CONFIG_SND_SOC_SOF_INTEL_IPC4=y +CONFIG_SND_SOC_SOF_AMD_TOPLEVEL=m +CONFIG_SND_SOC_SOF_AMD_COMMON=m +CONFIG_SND_SOC_SOF_AMD_RENOIR=m +CONFIG_SND_SOC_SOF_AMD_VANGOGH=m +CONFIG_SND_SOC_SOF_AMD_REMBRANDT=m +CONFIG_SND_SOC_SOF_ACP_PROBES=m +CONFIG_SND_SOC_SOF_INTEL_TOPLEVEL=y +CONFIG_SND_SOC_SOF_INTEL_HIFI_EP_IPC=m +CONFIG_SND_SOC_SOF_INTEL_ATOM_HIFI_EP=m +CONFIG_SND_SOC_SOF_INTEL_COMMON=m +CONFIG_SND_SOC_SOF_BAYTRAIL=m +CONFIG_SND_SOC_SOF_BROADWELL=m +CONFIG_SND_SOC_SOF_MERRIFIELD=m +CONFIG_SND_SOC_SOF_INTEL_SKL=m +CONFIG_SND_SOC_SOF_SKYLAKE=m +CONFIG_SND_SOC_SOF_KABYLAKE=m +CONFIG_SND_SOC_SOF_INTEL_APL=m +CONFIG_SND_SOC_SOF_APOLLOLAKE=m +CONFIG_SND_SOC_SOF_GEMINILAKE=m +CONFIG_SND_SOC_SOF_INTEL_CNL=m +CONFIG_SND_SOC_SOF_CANNONLAKE=m +CONFIG_SND_SOC_SOF_COFFEELAKE=m +CONFIG_SND_SOC_SOF_COMETLAKE=m +CONFIG_SND_SOC_SOF_INTEL_ICL=m +CONFIG_SND_SOC_SOF_ICELAKE=m +CONFIG_SND_SOC_SOF_JASPERLAKE=m +CONFIG_SND_SOC_SOF_INTEL_TGL=m +CONFIG_SND_SOC_SOF_TIGERLAKE=m +CONFIG_SND_SOC_SOF_ELKHARTLAKE=m +CONFIG_SND_SOC_SOF_ALDERLAKE=m +CONFIG_SND_SOC_SOF_INTEL_MTL=m +CONFIG_SND_SOC_SOF_METEORLAKE=m +CONFIG_SND_SOC_SOF_INTEL_LNL=m +CONFIG_SND_SOC_SOF_LUNARLAKE=m +CONFIG_SND_SOC_SOF_HDA_COMMON=m +CONFIG_SND_SOC_SOF_HDA_MLINK=m +CONFIG_SND_SOC_SOF_HDA_LINK=y +CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC=y +CONFIG_SND_SOC_SOF_HDA_LINK_BASELINE=m +CONFIG_SND_SOC_SOF_HDA=m +CONFIG_SND_SOC_SOF_HDA_PROBES=m +CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE=m +CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE=m +CONFIG_SND_SOC_SOF_XTENSA=m + +# +# STMicroelectronics STM32 SOC audio support +# +# end of STMicroelectronics STM32 SOC audio support + +CONFIG_SND_SOC_XILINX_I2S=m +# CONFIG_SND_SOC_XILINX_AUDIO_FORMATTER is not set +# CONFIG_SND_SOC_XILINX_SPDIF is not set +# CONFIG_SND_SOC_XTFPGA_I2S is not set +CONFIG_SND_SOC_I2C_AND_SPI=m + +# +# CODEC drivers +# +CONFIG_SND_SOC_ARIZONA=m +CONFIG_SND_SOC_WM_ADSP=m +CONFIG_SND_SOC_AC97_CODEC=m +CONFIG_SND_SOC_ADAU_UTILS=m +CONFIG_SND_SOC_ADAU1372=m +CONFIG_SND_SOC_ADAU1372_I2C=m +CONFIG_SND_SOC_ADAU1372_SPI=m +CONFIG_SND_SOC_ADAU1701=m +CONFIG_SND_SOC_ADAU17X1=m +CONFIG_SND_SOC_ADAU1761=m +CONFIG_SND_SOC_ADAU1761_I2C=m +CONFIG_SND_SOC_ADAU1761_SPI=m +CONFIG_SND_SOC_ADAU7002=m +CONFIG_SND_SOC_ADAU7118=m +CONFIG_SND_SOC_ADAU7118_HW=m +CONFIG_SND_SOC_ADAU7118_I2C=m +CONFIG_SND_SOC_AK4104=m +CONFIG_SND_SOC_AK4118=m +CONFIG_SND_SOC_AK4375=m +CONFIG_SND_SOC_AK4458=m +CONFIG_SND_SOC_AK4554=m +CONFIG_SND_SOC_AK4613=m +CONFIG_SND_SOC_AK4642=m +CONFIG_SND_SOC_AK5386=m +CONFIG_SND_SOC_AK5558=m +CONFIG_SND_SOC_ALC5623=m +CONFIG_SND_SOC_AUDIO_IIO_AUX=m +CONFIG_SND_SOC_AW8738=m +CONFIG_SND_SOC_AW88395_LIB=m +CONFIG_SND_SOC_AW88395=m +CONFIG_SND_SOC_AW88261=m +CONFIG_SND_SOC_BD28623=m +CONFIG_SND_SOC_BT_SCO=m +CONFIG_SND_SOC_CHV3_CODEC=m +CONFIG_SND_SOC_CROS_EC_CODEC=m +CONFIG_SND_SOC_CS35L32=m +CONFIG_SND_SOC_CS35L33=m +CONFIG_SND_SOC_CS35L34=m +CONFIG_SND_SOC_CS35L35=m +CONFIG_SND_SOC_CS35L36=m +CONFIG_SND_SOC_CS35L41_LIB=m +CONFIG_SND_SOC_CS35L41=m +CONFIG_SND_SOC_CS35L41_SPI=m +CONFIG_SND_SOC_CS35L41_I2C=m +CONFIG_SND_SOC_CS35L45=m +CONFIG_SND_SOC_CS35L45_SPI=m +CONFIG_SND_SOC_CS35L45_I2C=m +CONFIG_SND_SOC_CS35L56=m +CONFIG_SND_SOC_CS35L56_SHARED=m +CONFIG_SND_SOC_CS35L56_I2C=m +CONFIG_SND_SOC_CS35L56_SPI=m +CONFIG_SND_SOC_CS35L56_SDW=m +CONFIG_SND_SOC_CS42L42_CORE=m +CONFIG_SND_SOC_CS42L42=m +CONFIG_SND_SOC_CS42L42_SDW=m +CONFIG_SND_SOC_CS42L43=m +CONFIG_SND_SOC_CS42L43_SDW=m +CONFIG_SND_SOC_CS42L51=m +CONFIG_SND_SOC_CS42L51_I2C=m +CONFIG_SND_SOC_CS42L52=m +CONFIG_SND_SOC_CS42L56=m +CONFIG_SND_SOC_CS42L73=m +CONFIG_SND_SOC_CS42L83=m +CONFIG_SND_SOC_CS4234=m +CONFIG_SND_SOC_CS4265=m +CONFIG_SND_SOC_CS4270=m +CONFIG_SND_SOC_CS4271=m +CONFIG_SND_SOC_CS4271_I2C=m +CONFIG_SND_SOC_CS4271_SPI=m +CONFIG_SND_SOC_CS42XX8=m +CONFIG_SND_SOC_CS42XX8_I2C=m +CONFIG_SND_SOC_CS43130=m +CONFIG_SND_SOC_CS4341=m +CONFIG_SND_SOC_CS4349=m +CONFIG_SND_SOC_CS53L30=m +CONFIG_SND_SOC_CX2072X=m +CONFIG_SND_SOC_DA7213=m +CONFIG_SND_SOC_DA7219=m +CONFIG_SND_SOC_DMIC=m +CONFIG_SND_SOC_HDMI_CODEC=m +CONFIG_SND_SOC_ES7134=m +CONFIG_SND_SOC_ES7241=m +CONFIG_SND_SOC_ES8316=m +CONFIG_SND_SOC_ES8326=m +CONFIG_SND_SOC_ES8328=m +CONFIG_SND_SOC_ES8328_I2C=m +CONFIG_SND_SOC_ES8328_SPI=m +# CONFIG_SND_SOC_GTM601 is not set +CONFIG_SND_SOC_HDAC_HDMI=m +CONFIG_SND_SOC_HDAC_HDA=m +CONFIG_SND_SOC_HDA=m +CONFIG_SND_SOC_ICS43432=m +CONFIG_SND_SOC_IDT821034=m +# CONFIG_SND_SOC_INNO_RK3036 is not set +CONFIG_SND_SOC_MAX98088=m +CONFIG_SND_SOC_MAX98090=m +CONFIG_SND_SOC_MAX98357A=m +# CONFIG_SND_SOC_MAX98504 is not set +CONFIG_SND_SOC_MAX9867=m +CONFIG_SND_SOC_MAX98927=m +CONFIG_SND_SOC_MAX98520=m +CONFIG_SND_SOC_MAX98363=m +CONFIG_SND_SOC_MAX98373=m +CONFIG_SND_SOC_MAX98373_I2C=m +CONFIG_SND_SOC_MAX98373_SDW=m +CONFIG_SND_SOC_MAX98388=m +CONFIG_SND_SOC_MAX98390=m +CONFIG_SND_SOC_MAX98396=m +# CONFIG_SND_SOC_MAX9860 is not set +# CONFIG_SND_SOC_MSM8916_WCD_ANALOG is not set +# CONFIG_SND_SOC_MSM8916_WCD_DIGITAL is not set +# CONFIG_SND_SOC_PCM1681 is not set +CONFIG_SND_SOC_PCM1789=m +CONFIG_SND_SOC_PCM1789_I2C=m +# CONFIG_SND_SOC_PCM179X_I2C is not set +# CONFIG_SND_SOC_PCM179X_SPI is not set +CONFIG_SND_SOC_PCM186X=m +CONFIG_SND_SOC_PCM186X_I2C=m +CONFIG_SND_SOC_PCM186X_SPI=m +CONFIG_SND_SOC_PCM3060=m +CONFIG_SND_SOC_PCM3060_I2C=m +CONFIG_SND_SOC_PCM3060_SPI=m +# CONFIG_SND_SOC_PCM3168A_I2C is not set +# CONFIG_SND_SOC_PCM3168A_SPI is not set +# CONFIG_SND_SOC_PCM5102A is not set +CONFIG_SND_SOC_PCM512x=m +CONFIG_SND_SOC_PCM512x_I2C=m +# CONFIG_SND_SOC_PCM512x_SPI is not set +# CONFIG_SND_SOC_PEB2466 is not set +# CONFIG_SND_SOC_RK3328 is not set +CONFIG_SND_SOC_RL6231=m +CONFIG_SND_SOC_RL6347A=m +CONFIG_SND_SOC_RT274=m +CONFIG_SND_SOC_RT286=m +CONFIG_SND_SOC_RT298=m +CONFIG_SND_SOC_RT1011=m +CONFIG_SND_SOC_RT1015=m +CONFIG_SND_SOC_RT1015P=m +CONFIG_SND_SOC_RT1017_SDCA_SDW=m +CONFIG_SND_SOC_RT1019=m +CONFIG_SND_SOC_RT1308=m +CONFIG_SND_SOC_RT1308_SDW=m +CONFIG_SND_SOC_RT1316_SDW=m +CONFIG_SND_SOC_RT1318_SDW=m +CONFIG_SND_SOC_RT5514=m +CONFIG_SND_SOC_RT5514_SPI=m +CONFIG_SND_SOC_RT5616=m +CONFIG_SND_SOC_RT5631=m +CONFIG_SND_SOC_RT5640=m +CONFIG_SND_SOC_RT5645=m +CONFIG_SND_SOC_RT5651=m +CONFIG_SND_SOC_RT5659=m +CONFIG_SND_SOC_RT5660=m +CONFIG_SND_SOC_RT5663=m +CONFIG_SND_SOC_RT5670=m +CONFIG_SND_SOC_RT5677=m +CONFIG_SND_SOC_RT5677_SPI=m +CONFIG_SND_SOC_RT5682=m +CONFIG_SND_SOC_RT5682_I2C=m +CONFIG_SND_SOC_RT5682_SDW=m +CONFIG_SND_SOC_RT5682S=m +CONFIG_SND_SOC_RT700=m +CONFIG_SND_SOC_RT700_SDW=m +CONFIG_SND_SOC_RT711=m +CONFIG_SND_SOC_RT711_SDW=m +CONFIG_SND_SOC_RT711_SDCA_SDW=m +CONFIG_SND_SOC_RT712_SDCA_SDW=m +CONFIG_SND_SOC_RT712_SDCA_DMIC_SDW=m +CONFIG_SND_SOC_RT722_SDCA_SDW=m +CONFIG_SND_SOC_RT715=m +CONFIG_SND_SOC_RT715_SDW=m +CONFIG_SND_SOC_RT715_SDCA_SDW=m +CONFIG_SND_SOC_RT9120=m +# CONFIG_SND_SOC_SDW_MOCKUP is not set +# CONFIG_SND_SOC_SGTL5000 is not set +CONFIG_SND_SOC_SI476X=m +CONFIG_SND_SOC_SIGMADSP=m +CONFIG_SND_SOC_SIGMADSP_I2C=m +CONFIG_SND_SOC_SIGMADSP_REGMAP=m +CONFIG_SND_SOC_SIMPLE_AMPLIFIER=m +CONFIG_SND_SOC_SIMPLE_MUX=m +CONFIG_SND_SOC_SMA1303=m +CONFIG_SND_SOC_SPDIF=m +CONFIG_SND_SOC_SRC4XXX_I2C=m +CONFIG_SND_SOC_SRC4XXX=m +# CONFIG_SND_SOC_SSM2305 is not set +# CONFIG_SND_SOC_SSM2518 is not set +# CONFIG_SND_SOC_SSM2602_SPI is not set +# CONFIG_SND_SOC_SSM2602_I2C is not set +CONFIG_SND_SOC_SSM4567=m +# CONFIG_SND_SOC_STA32X is not set +# CONFIG_SND_SOC_STA350 is not set +# CONFIG_SND_SOC_STI_SAS is not set +# CONFIG_SND_SOC_TAS2552 is not set +CONFIG_SND_SOC_TAS2562=m +CONFIG_SND_SOC_TAS2764=m +CONFIG_SND_SOC_TAS2770=m +CONFIG_SND_SOC_TAS2780=m +CONFIG_SND_SOC_TAS2781_COMLIB=m +CONFIG_SND_SOC_TAS2781_FMWLIB=m +CONFIG_SND_SOC_TAS2781_I2C=m +# CONFIG_SND_SOC_TAS5086 is not set +# CONFIG_SND_SOC_TAS571X is not set +# CONFIG_SND_SOC_TAS5720 is not set +CONFIG_SND_SOC_TAS5805M=m +CONFIG_SND_SOC_TAS6424=m +CONFIG_SND_SOC_TDA7419=m +# CONFIG_SND_SOC_TFA9879 is not set +# CONFIG_SND_SOC_TFA989X is not set +# CONFIG_SND_SOC_TLV320ADC3XXX is not set +CONFIG_SND_SOC_TLV320AIC23=m +CONFIG_SND_SOC_TLV320AIC23_I2C=m +CONFIG_SND_SOC_TLV320AIC23_SPI=m +# CONFIG_SND_SOC_TLV320AIC31XX is not set +CONFIG_SND_SOC_TLV320AIC32X4=m +CONFIG_SND_SOC_TLV320AIC32X4_I2C=m +CONFIG_SND_SOC_TLV320AIC32X4_SPI=m +# CONFIG_SND_SOC_TLV320AIC3X_I2C is not set +# CONFIG_SND_SOC_TLV320AIC3X_SPI is not set +CONFIG_SND_SOC_TLV320ADCX140=m +CONFIG_SND_SOC_TS3A227E=m +CONFIG_SND_SOC_TSCS42XX=m +# CONFIG_SND_SOC_TSCS454 is not set +# CONFIG_SND_SOC_UDA1334 is not set +# CONFIG_SND_SOC_WCD938X_SDW is not set +CONFIG_SND_SOC_WM5102=m +# CONFIG_SND_SOC_WM8510 is not set +# CONFIG_SND_SOC_WM8523 is not set +CONFIG_SND_SOC_WM8524=m +# CONFIG_SND_SOC_WM8580 is not set +# CONFIG_SND_SOC_WM8711 is not set +# CONFIG_SND_SOC_WM8728 is not set +CONFIG_SND_SOC_WM8731=m +CONFIG_SND_SOC_WM8731_I2C=m +CONFIG_SND_SOC_WM8731_SPI=m +# CONFIG_SND_SOC_WM8737 is not set +# CONFIG_SND_SOC_WM8741 is not set +# CONFIG_SND_SOC_WM8750 is not set +# CONFIG_SND_SOC_WM8753 is not set +# CONFIG_SND_SOC_WM8770 is not set +# CONFIG_SND_SOC_WM8776 is not set +CONFIG_SND_SOC_WM8782=m +CONFIG_SND_SOC_WM8804=m +CONFIG_SND_SOC_WM8804_I2C=m +# CONFIG_SND_SOC_WM8804_SPI is not set +# CONFIG_SND_SOC_WM8903 is not set +# CONFIG_SND_SOC_WM8904 is not set +CONFIG_SND_SOC_WM8940=m +# CONFIG_SND_SOC_WM8960 is not set +CONFIG_SND_SOC_WM8961=m +# CONFIG_SND_SOC_WM8962 is not set +# CONFIG_SND_SOC_WM8974 is not set +# CONFIG_SND_SOC_WM8978 is not set +# CONFIG_SND_SOC_WM8985 is not set +CONFIG_SND_SOC_WSA881X=m +CONFIG_SND_SOC_WSA883X=m +CONFIG_SND_SOC_WSA884X=m +CONFIG_SND_SOC_ZL38060=m +CONFIG_SND_SOC_MAX9759=m +# CONFIG_SND_SOC_MT6351 is not set +# CONFIG_SND_SOC_MT6358 is not set +# CONFIG_SND_SOC_MT6660 is not set +CONFIG_SND_SOC_NAU8315=m +CONFIG_SND_SOC_NAU8540=m +CONFIG_SND_SOC_NAU8810=m +CONFIG_SND_SOC_NAU8821=m +CONFIG_SND_SOC_NAU8822=m +CONFIG_SND_SOC_NAU8824=m +CONFIG_SND_SOC_NAU8825=m +CONFIG_SND_SOC_TPA6130A2=m +# CONFIG_SND_SOC_LPASS_WSA_MACRO is not set +# CONFIG_SND_SOC_LPASS_VA_MACRO is not set +# CONFIG_SND_SOC_LPASS_RX_MACRO is not set +# CONFIG_SND_SOC_LPASS_TX_MACRO is not set +# end of CODEC drivers + +CONFIG_SND_SIMPLE_CARD_UTILS=m +CONFIG_SND_SIMPLE_CARD=m +CONFIG_SND_X86=y +CONFIG_HDMI_LPE_AUDIO=m +CONFIG_SND_SYNTH_EMUX=m +CONFIG_SND_XEN_FRONTEND=m +CONFIG_SND_VIRTIO=m +CONFIG_AC97_BUS=m +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +CONFIG_HID_BATTERY_STRENGTH=y +CONFIG_HIDRAW=y +CONFIG_UHID=m +CONFIG_HID_GENERIC=y + +# +# Special HID drivers +# +CONFIG_HID_A4TECH=m +CONFIG_HID_ACCUTOUCH=m +CONFIG_HID_ACRUX=m +CONFIG_HID_ACRUX_FF=y +CONFIG_HID_APPLE=m +CONFIG_HID_APPLEIR=m +CONFIG_HID_ASUS=m +CONFIG_HID_AUREAL=m +CONFIG_HID_BELKIN=m +CONFIG_HID_BETOP_FF=m +CONFIG_HID_BIGBEN_FF=m +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +CONFIG_HID_CORSAIR=m +CONFIG_HID_COUGAR=m +CONFIG_HID_MACALLY=m +CONFIG_HID_PRODIKEYS=m +CONFIG_HID_CMEDIA=m +CONFIG_HID_CP2112=m +CONFIG_HID_CREATIVE_SB0540=m +CONFIG_HID_CYPRESS=m +CONFIG_HID_DRAGONRISE=m +CONFIG_DRAGONRISE_FF=y +CONFIG_HID_EMS_FF=m +CONFIG_HID_ELAN=m +CONFIG_HID_ELECOM=m +CONFIG_HID_ELO=m +CONFIG_HID_EVISION=m +CONFIG_HID_EZKEY=m +CONFIG_HID_FT260=m +CONFIG_HID_GEMBIRD=m +CONFIG_HID_GFRM=m +CONFIG_HID_GLORIOUS=m +CONFIG_HID_HOLTEK=m +CONFIG_HOLTEK_FF=y +CONFIG_HID_VIVALDI_COMMON=m +CONFIG_HID_GOOGLE_HAMMER=m +CONFIG_HID_GOOGLE_STADIA_FF=m +CONFIG_HID_VIVALDI=m +CONFIG_HID_GT683R=m +CONFIG_HID_KEYTOUCH=m +CONFIG_HID_KYE=m +CONFIG_HID_UCLOGIC=m +CONFIG_HID_WALTOP=m +CONFIG_HID_VIEWSONIC=m +CONFIG_HID_VRC2=m +CONFIG_HID_XIAOMI=m +CONFIG_HID_GYRATION=m +CONFIG_HID_ICADE=m +CONFIG_HID_ITE=m +CONFIG_HID_JABRA=m +CONFIG_HID_TWINHAN=m +CONFIG_HID_KENSINGTON=m +CONFIG_HID_LCPOWER=m +CONFIG_HID_LED=m +CONFIG_HID_LENOVO=m +CONFIG_HID_LETSKETCH=m +CONFIG_HID_LOGITECH=m +CONFIG_HID_LOGITECH_DJ=m +CONFIG_HID_LOGITECH_HIDPP=m +CONFIG_LOGITECH_FF=y +CONFIG_LOGIRUMBLEPAD2_FF=y +CONFIG_LOGIG940_FF=y +CONFIG_LOGIWHEELS_FF=y +CONFIG_HID_MAGICMOUSE=m +CONFIG_HID_MALTRON=m +CONFIG_HID_MAYFLASH=m +CONFIG_HID_MEGAWORLD_FF=m +CONFIG_HID_REDRAGON=m +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MONTEREY=m +CONFIG_HID_MULTITOUCH=m +CONFIG_HID_NINTENDO=m +CONFIG_NINTENDO_FF=y +CONFIG_HID_NTI=m +CONFIG_HID_NTRIG=m +CONFIG_HID_NVIDIA_SHIELD=m +CONFIG_NVIDIA_SHIELD_FF=y +CONFIG_HID_ORTEK=m +CONFIG_HID_PANTHERLORD=m +CONFIG_PANTHERLORD_FF=y +CONFIG_HID_PENMOUNT=m +CONFIG_HID_PETALYNX=m +CONFIG_HID_PICOLCD=m +CONFIG_HID_PICOLCD_FB=y +CONFIG_HID_PICOLCD_BACKLIGHT=y +CONFIG_HID_PICOLCD_LCD=y +CONFIG_HID_PICOLCD_LEDS=y +CONFIG_HID_PICOLCD_CIR=y +CONFIG_HID_PLANTRONICS=m +CONFIG_HID_PLAYSTATION=m +CONFIG_PLAYSTATION_FF=y +CONFIG_HID_PXRC=m +CONFIG_HID_RAZER=m +CONFIG_HID_PRIMAX=m +CONFIG_HID_RETRODE=m +CONFIG_HID_ROCCAT=m +CONFIG_HID_SAITEK=m +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SEMITEK=m +CONFIG_HID_SIGMAMICRO=m +CONFIG_HID_SONY=m +CONFIG_SONY_FF=y +CONFIG_HID_SPEEDLINK=m +CONFIG_HID_STEAM=m +CONFIG_STEAM_FF=y +CONFIG_HID_STEELSERIES=m +CONFIG_HID_SUNPLUS=m +CONFIG_HID_RMI=m +CONFIG_HID_GREENASIA=m +CONFIG_GREENASIA_FF=y +CONFIG_HID_HYPERV_MOUSE=m +CONFIG_HID_SMARTJOYPLUS=m +CONFIG_SMARTJOYPLUS_FF=y +CONFIG_HID_TIVO=m +CONFIG_HID_TOPSEED=m +CONFIG_HID_TOPRE=m +CONFIG_HID_THINGM=m +CONFIG_HID_THRUSTMASTER=m +CONFIG_THRUSTMASTER_FF=y +CONFIG_HID_UDRAW_PS3=m +CONFIG_HID_U2FZERO=m +CONFIG_HID_UNIVERSAL_PIDFF=m +CONFIG_HID_WACOM=m +CONFIG_HID_WIIMOTE=m +CONFIG_HID_XINMO=m +CONFIG_HID_ZEROPLUS=m +CONFIG_ZEROPLUS_FF=y +CONFIG_HID_ZYDACRON=m +CONFIG_HID_SENSOR_HUB=m +CONFIG_HID_SENSOR_CUSTOM_SENSOR=m +CONFIG_HID_ALPS=m +CONFIG_HID_MCP2200=m +CONFIG_HID_MCP2221=m +# end of Special HID drivers + +# +# HID-BPF support +# +# CONFIG_HID_BPF is not set +# end of HID-BPF support + +# +# USB HID support +# +CONFIG_USB_HID=y +CONFIG_HID_PID=y +CONFIG_USB_HIDDEV=y +# end of USB HID support + +CONFIG_I2C_HID=y +CONFIG_I2C_HID_ACPI=m +CONFIG_I2C_HID_OF=m +CONFIG_I2C_HID_CORE=m + +# +# Intel ISH HID support +# +CONFIG_INTEL_ISH_HID=m +CONFIG_INTEL_ISH_FIRMWARE_DOWNLOADER=m +# end of Intel ISH HID support + +# +# AMD SFH HID Support +# +CONFIG_AMD_SFH_HID=m +# end of AMD SFH HID Support + +# +# Surface System Aggregator Module HID support +# +CONFIG_SURFACE_HID=m +CONFIG_SURFACE_KBD=m +# end of Surface System Aggregator Module HID support + +CONFIG_SURFACE_HID_CORE=m +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_COMMON=y +CONFIG_USB_LED_TRIG=y +CONFIG_USB_ULPI_BUS=m +CONFIG_USB_CONN_GPIO=m +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB=y +CONFIG_USB_PCI=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +CONFIG_USB_DEFAULT_PERSIST=y +# CONFIG_USB_FEW_INIT_RETRIES is not set +CONFIG_USB_DYNAMIC_MINORS=y +CONFIG_USB_OTG=y +# CONFIG_USB_OTG_PRODUCTLIST is not set +# CONFIG_USB_OTG_DISABLE_EXTERNAL_HUB is not set +CONFIG_USB_OTG_FSM=m +CONFIG_USB_LEDS_TRIGGER_USBPORT=y +CONFIG_USB_AUTOSUSPEND_DELAY=2 +CONFIG_USB_MON=m + +# +# USB Host Controller Drivers +# +CONFIG_USB_C67X00_HCD=m +CONFIG_USB_XHCI_HCD=y +# CONFIG_USB_XHCI_DBGCAP is not set +CONFIG_USB_XHCI_PCI=m +CONFIG_USB_XHCI_PCI_RENESAS=m +CONFIG_USB_XHCI_PLATFORM=m +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EHCI_PCI=y +CONFIG_USB_EHCI_FSL=m +CONFIG_USB_EHCI_HCD_PLATFORM=m +CONFIG_USB_OXU210HP_HCD=m +CONFIG_USB_ISP116X_HCD=m +CONFIG_USB_MAX3421_HCD=m +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PCI=y +CONFIG_USB_OHCI_HCD_PLATFORM=m +CONFIG_USB_UHCI_HCD=y +CONFIG_USB_SL811_HCD=m +CONFIG_USB_SL811_HCD_ISO=y +CONFIG_USB_SL811_CS=m +CONFIG_USB_R8A66597_HCD=m +CONFIG_USB_HCD_BCMA=m +CONFIG_USB_HCD_SSB=m +# CONFIG_USB_HCD_TEST_MODE is not set +CONFIG_USB_XEN_HCD=m + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +CONFIG_USB_WDM=m +CONFIG_USB_TMC=m + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_REALTEK=m +CONFIG_REALTEK_AUTOPM=y +CONFIG_USB_STORAGE_DATAFAB=m +CONFIG_USB_STORAGE_FREECOM=m +CONFIG_USB_STORAGE_ISD200=m +CONFIG_USB_STORAGE_USBAT=m +CONFIG_USB_STORAGE_SDDR09=m +CONFIG_USB_STORAGE_SDDR55=m +CONFIG_USB_STORAGE_JUMPSHOT=m +CONFIG_USB_STORAGE_ALAUDA=m +CONFIG_USB_STORAGE_ONETOUCH=m +CONFIG_USB_STORAGE_KARMA=m +CONFIG_USB_STORAGE_CYPRESS_ATACB=m +CONFIG_USB_STORAGE_ENE_UB6250=m +CONFIG_USB_UAS=m + +# +# USB Imaging devices +# +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +CONFIG_USBIP_CORE=m +CONFIG_USBIP_VHCI_HCD=m +CONFIG_USBIP_VHCI_HC_PORTS=8 +CONFIG_USBIP_VHCI_NR_HCS=1 +CONFIG_USBIP_HOST=m +# CONFIG_USBIP_DEBUG is not set + +# +# USB dual-mode controller drivers +# +CONFIG_USB_CDNS_SUPPORT=m +# CONFIG_USB_CDNS3 is not set +CONFIG_USB_CDNSP_PCI=m +# CONFIG_USB_CDNSP_HOST is not set +CONFIG_USB_MUSB_HDRC=m +CONFIG_USB_MUSB_HOST=y + +# +# Platform Glue Layer +# + +# +# MUSB DMA mode +# +CONFIG_MUSB_PIO_ONLY=y +CONFIG_USB_DWC3=m +# CONFIG_USB_DWC3_ULPI is not set +CONFIG_USB_DWC3_HOST=y + +# +# Platform Glue Driver Support +# +CONFIG_USB_DWC3_PCI=m +CONFIG_USB_DWC3_HAPS=m +CONFIG_USB_DWC2=m +CONFIG_USB_DWC2_HOST=y + +# +# Gadget/Dual-role mode requires USB Gadget support to be enabled +# +CONFIG_USB_DWC2_PCI=m +# CONFIG_USB_DWC2_DEBUG is not set +# CONFIG_USB_DWC2_TRACK_MISSED_SOFS is not set +CONFIG_USB_CHIPIDEA=m +CONFIG_USB_CHIPIDEA_HOST=y +CONFIG_USB_CHIPIDEA_PCI=m +CONFIG_USB_CHIPIDEA_MSM=m +CONFIG_USB_CHIPIDEA_GENERIC=m +CONFIG_USB_ISP1760=m +CONFIG_USB_ISP1760_HCD=y +CONFIG_USB_ISP1760_HOST_ROLE=y + +# +# USB port drivers +# +CONFIG_USB_SERIAL=y +CONFIG_USB_SERIAL_CONSOLE=y +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_SIMPLE=m +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_CP210X=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_F81232=m +CONFIG_USB_SERIAL_F8153X=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_IPW=m +CONFIG_USB_SERIAL_IUU=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_METRO=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7715_PARPORT=y +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_MXUPORT=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_USB_SERIAL_QCAUX=m +CONFIG_USB_SERIAL_QUALCOMM=m +CONFIG_USB_SERIAL_SPCP8X5=m +CONFIG_USB_SERIAL_SAFE=m +CONFIG_USB_SERIAL_SAFE_PADDED=y +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_SYMBOL=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_WWAN=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTICON=m +CONFIG_USB_SERIAL_XSENS_MT=m +CONFIG_USB_SERIAL_WISHBONE=m +CONFIG_USB_SERIAL_SSU100=m +CONFIG_USB_SERIAL_QT2=m +CONFIG_USB_SERIAL_UPD78F0730=m +CONFIG_USB_SERIAL_XR=m +CONFIG_USB_SERIAL_DEBUG=m + +# +# USB Miscellaneous drivers +# +CONFIG_USB_USS720=m +CONFIG_USB_EMI62=m +CONFIG_USB_EMI26=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_SEVSEG=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LCD=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_APPLEDISPLAY=m +CONFIG_APPLE_MFI_FASTCHARGE=m +CONFIG_USB_SISUSBVGA=m +CONFIG_USB_LD=m +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_TEST=m +CONFIG_USB_EHSET_TEST_FIXTURE=m +CONFIG_USB_ISIGHTFW=m +CONFIG_USB_YUREX=m +CONFIG_USB_EZUSB_FX2=m +CONFIG_USB_HUB_USB251XB=m +CONFIG_USB_HSIC_USB3503=m +CONFIG_USB_HSIC_USB4604=m +CONFIG_USB_LINK_LAYER_TEST=m +CONFIG_USB_CHAOSKEY=m +CONFIG_USB_ATM=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_CXACRU=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_XUSBATM=m + +# +# USB Physical Layer drivers +# +CONFIG_USB_PHY=y +CONFIG_NOP_USB_XCEIV=m +CONFIG_USB_GPIO_VBUS=m +CONFIG_TAHVO_USB=m +# CONFIG_TAHVO_USB_HOST_BY_DEFAULT is not set +CONFIG_USB_ISP1301=m +# end of USB Physical Layer drivers + +# CONFIG_USB_GADGET is not set +CONFIG_TYPEC=m +CONFIG_TYPEC_TCPM=m +CONFIG_TYPEC_TCPCI=m +CONFIG_TYPEC_RT1711H=m +CONFIG_TYPEC_TCPCI_MAXIM=m +CONFIG_TYPEC_FUSB302=m +CONFIG_TYPEC_WCOVE=m +CONFIG_TYPEC_UCSI=m +CONFIG_UCSI_CCG=m +CONFIG_UCSI_ACPI=m +CONFIG_UCSI_STM32G0=m +CONFIG_TYPEC_TPS6598X=m +CONFIG_TYPEC_ANX7411=m +CONFIG_TYPEC_RT1719=m +CONFIG_TYPEC_HD3SS3220=m +CONFIG_TYPEC_STUSB160X=m +CONFIG_TYPEC_WUSB3801=m + +# +# USB Type-C Multiplexer/DeMultiplexer Switch support +# +CONFIG_TYPEC_MUX_FSA4480=m +CONFIG_TYPEC_MUX_GPIO_SBU=m +CONFIG_TYPEC_MUX_PI3USB30532=m +CONFIG_TYPEC_MUX_INTEL_PMC=m +CONFIG_TYPEC_MUX_NB7VPQ904M=m +# end of USB Type-C Multiplexer/DeMultiplexer Switch support + +# +# USB Type-C Alternate Mode drivers +# +CONFIG_TYPEC_DP_ALTMODE=m +CONFIG_TYPEC_NVIDIA_ALTMODE=m +# end of USB Type-C Alternate Mode drivers + +CONFIG_USB_ROLE_SWITCH=m +CONFIG_USB_ROLES_INTEL_XHCI=m +CONFIG_MMC=m +CONFIG_MMC_BLOCK=m +CONFIG_MMC_BLOCK_MINORS=8 +CONFIG_SDIO_UART=m +CONFIG_MMC_TEST=m +CONFIG_MMC_CRYPTO=y + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_SDHCI=m +CONFIG_MMC_SDHCI_IO_ACCESSORS=y +CONFIG_MMC_SDHCI_PCI=m +CONFIG_MMC_RICOH_MMC=y +CONFIG_MMC_SDHCI_ACPI=m +CONFIG_MMC_SDHCI_PLTFM=m +CONFIG_MMC_SDHCI_F_SDH30=m +CONFIG_MMC_WBSD=m +CONFIG_MMC_ALCOR=m +CONFIG_MMC_TIFM_SD=m +CONFIG_MMC_SPI=m +CONFIG_MMC_SDRICOH_CS=m +CONFIG_MMC_CB710=m +CONFIG_MMC_VIA_SDMMC=m +CONFIG_MMC_VUB300=m +CONFIG_MMC_USHC=m +CONFIG_MMC_USDHI6ROL0=m +CONFIG_MMC_REALTEK_PCI=m +CONFIG_MMC_REALTEK_USB=m +CONFIG_MMC_CQHCI=m +CONFIG_MMC_HSQ=m +CONFIG_MMC_TOSHIBA_PCI=m +CONFIG_MMC_MTK=m +CONFIG_MMC_SDHCI_XENON=m +CONFIG_SCSI_UFSHCD=m +CONFIG_SCSI_UFS_BSG=y +CONFIG_SCSI_UFS_CRYPTO=y +CONFIG_SCSI_UFS_HWMON=y +CONFIG_SCSI_UFSHCD_PCI=m +CONFIG_SCSI_UFS_DWC_TC_PCI=m +CONFIG_SCSI_UFSHCD_PLATFORM=m +CONFIG_SCSI_UFS_CDNS_PLATFORM=m +CONFIG_MEMSTICK=m +# CONFIG_MEMSTICK_DEBUG is not set + +# +# MemoryStick drivers +# +# CONFIG_MEMSTICK_UNSAFE_RESUME is not set +CONFIG_MSPRO_BLOCK=m +CONFIG_MS_BLOCK=m + +# +# MemoryStick Host Controller Drivers +# +CONFIG_MEMSTICK_TIFM_MS=m +CONFIG_MEMSTICK_JMICRON_38X=m +CONFIG_MEMSTICK_R592=m +CONFIG_MEMSTICK_REALTEK_PCI=m +CONFIG_MEMSTICK_REALTEK_USB=m +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_CLASS_FLASH=m +CONFIG_LEDS_CLASS_MULTICOLOR=m +CONFIG_LEDS_BRIGHTNESS_HW_CHANGED=y + +# +# LED drivers +# +CONFIG_LEDS_88PM860X=m +CONFIG_LEDS_APU=m +CONFIG_LEDS_AW200XX=m +CONFIG_LEDS_CHT_WCOVE=m +CONFIG_LEDS_LM3530=m +CONFIG_LEDS_LM3532=m +CONFIG_LEDS_LM3642=m +CONFIG_LEDS_PCA9532=m +CONFIG_LEDS_PCA9532_GPIO=y +CONFIG_LEDS_GPIO=m +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_LP3952 is not set +# CONFIG_LEDS_LP50XX is not set +# CONFIG_LEDS_LP8788 is not set +# CONFIG_LEDS_PCA955X is not set +CONFIG_LEDS_PCA963X=m +CONFIG_LEDS_PCA995X=m +CONFIG_LEDS_WM831X_STATUS=m +CONFIG_LEDS_WM8350=m +CONFIG_LEDS_DA903X=m +CONFIG_LEDS_DA9052=m +CONFIG_LEDS_DAC124S085=m +CONFIG_LEDS_PWM=m +CONFIG_LEDS_REGULATOR=m +# CONFIG_LEDS_BD2606MVV is not set +# CONFIG_LEDS_BD2802 is not set +CONFIG_LEDS_INTEL_SS4200=m +CONFIG_LEDS_LT3593=m +CONFIG_LEDS_ADP5520=m +CONFIG_LEDS_MC13783=m +CONFIG_LEDS_TCA6507=m +CONFIG_LEDS_TLC591XX=m +CONFIG_LEDS_MAX8997=m +CONFIG_LEDS_LM355x=m +CONFIG_LEDS_MENF21BMC=m +CONFIG_LEDS_IS31FL319X=m + +# +# LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) +# +CONFIG_LEDS_BLINKM=m +CONFIG_LEDS_MLXCPLD=m +CONFIG_LEDS_MLXREG=m +CONFIG_LEDS_USER=m +CONFIG_LEDS_NIC78BX=m +CONFIG_LEDS_TI_LMU_COMMON=m +CONFIG_LEDS_LM36274=m + +# +# Flash and Torch LED drivers +# +# CONFIG_LEDS_AS3645A is not set +# CONFIG_LEDS_LM3601X is not set +CONFIG_LEDS_RT8515=m +# CONFIG_LEDS_SGM3140 is not set + +# +# RGB LED drivers +# +CONFIG_LEDS_PWM_MULTICOLOR=m + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=m +CONFIG_LEDS_TRIGGER_ONESHOT=m +CONFIG_LEDS_TRIGGER_DISK=y +# CONFIG_LEDS_TRIGGER_MTD is not set +CONFIG_LEDS_TRIGGER_HEARTBEAT=m +CONFIG_LEDS_TRIGGER_BACKLIGHT=m +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_LEDS_TRIGGER_ACTIVITY=m +CONFIG_LEDS_TRIGGER_DEFAULT_ON=m + +# +# iptables trigger is under Netfilter config (LED target) +# +CONFIG_LEDS_TRIGGER_TRANSIENT=m +CONFIG_LEDS_TRIGGER_CAMERA=m +CONFIG_LEDS_TRIGGER_PANIC=y +CONFIG_LEDS_TRIGGER_NETDEV=m +CONFIG_LEDS_TRIGGER_PATTERN=m +CONFIG_LEDS_TRIGGER_AUDIO=m +CONFIG_LEDS_TRIGGER_TTY=m + +# +# Simple LED drivers +# +CONFIG_ACCESSIBILITY=y +CONFIG_A11Y_BRAILLE_CONSOLE=y + +# +# Speakup console speech +# +CONFIG_SPEAKUP=m +CONFIG_SPEAKUP_SYNTH_ACNTSA=m +CONFIG_SPEAKUP_SYNTH_APOLLO=m +CONFIG_SPEAKUP_SYNTH_AUDPTR=m +CONFIG_SPEAKUP_SYNTH_BNS=m +CONFIG_SPEAKUP_SYNTH_DECTLK=m +CONFIG_SPEAKUP_SYNTH_DECEXT=m +CONFIG_SPEAKUP_SYNTH_LTLK=m +CONFIG_SPEAKUP_SYNTH_SOFT=m +CONFIG_SPEAKUP_SYNTH_SPKOUT=m +CONFIG_SPEAKUP_SYNTH_TXPRT=m +CONFIG_SPEAKUP_SYNTH_DUMMY=m +# end of Speakup console speech + +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_USER_MAD=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_USER_MEM=y +CONFIG_INFINIBAND_ON_DEMAND_PAGING=y +CONFIG_INFINIBAND_ADDR_TRANS=y +CONFIG_INFINIBAND_ADDR_TRANS_CONFIGFS=y +CONFIG_INFINIBAND_VIRT_DMA=y +CONFIG_INFINIBAND_BNXT_RE=m +CONFIG_INFINIBAND_CXGB4=m +CONFIG_INFINIBAND_EFA=m +CONFIG_INFINIBAND_ERDMA=m +CONFIG_INFINIBAND_HFI1=m +# CONFIG_HFI1_DEBUG_SDMA_ORDER is not set +# CONFIG_SDMA_VERBOSITY is not set +CONFIG_INFINIBAND_IRDMA=m +CONFIG_MANA_INFINIBAND=m +CONFIG_MLX4_INFINIBAND=m +CONFIG_MLX5_INFINIBAND=m +CONFIG_INFINIBAND_MTHCA=m +# CONFIG_INFINIBAND_MTHCA_DEBUG is not set +CONFIG_INFINIBAND_OCRDMA=m +CONFIG_INFINIBAND_QEDR=m +CONFIG_INFINIBAND_QIB=m +CONFIG_INFINIBAND_QIB_DCA=y +CONFIG_INFINIBAND_USNIC=m +CONFIG_INFINIBAND_VMWARE_PVRDMA=m +CONFIG_INFINIBAND_RDMAVT=m +CONFIG_RDMA_RXE=m +CONFIG_RDMA_SIW=m +CONFIG_INFINIBAND_IPOIB=m +# CONFIG_INFINIBAND_IPOIB_CM is not set +# CONFIG_INFINIBAND_IPOIB_DEBUG is not set +CONFIG_INFINIBAND_SRP=m +CONFIG_INFINIBAND_SRPT=m +CONFIG_INFINIBAND_ISER=m +CONFIG_INFINIBAND_ISERT=m +# CONFIG_INFINIBAND_RTRS_CLIENT is not set +# CONFIG_INFINIBAND_RTRS_SERVER is not set +CONFIG_INFINIBAND_OPA_VNIC=m +CONFIG_EDAC_ATOMIC_SCRUB=y +CONFIG_EDAC_SUPPORT=y +CONFIG_EDAC=y +CONFIG_EDAC_LEGACY_SYSFS=y +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_DECODE_MCE=y +# CONFIG_EDAC_GHES is not set +CONFIG_EDAC_AMD64=m +CONFIG_EDAC_E752X=m +CONFIG_EDAC_I82975X=m +CONFIG_EDAC_I3000=m +CONFIG_EDAC_I3200=m +CONFIG_EDAC_IE31200=m +CONFIG_EDAC_X38=m +CONFIG_EDAC_I5400=m +CONFIG_EDAC_I7CORE=m +CONFIG_EDAC_I5100=m +CONFIG_EDAC_I7300=m +CONFIG_EDAC_SBRIDGE=m +CONFIG_EDAC_SKX=m +CONFIG_EDAC_I10NM=m +CONFIG_EDAC_PND2=m +CONFIG_EDAC_IGEN6=m +CONFIG_RTC_LIB=y +CONFIG_RTC_MC146818_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_SYSTOHC=y +CONFIG_RTC_SYSTOHC_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set +CONFIG_RTC_NVMEM=y + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +CONFIG_RTC_DRV_88PM860X=m +CONFIG_RTC_DRV_88PM80X=m +CONFIG_RTC_DRV_ABB5ZES3=m +CONFIG_RTC_DRV_ABEOZ9=m +CONFIG_RTC_DRV_ABX80X=m +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1307_CENTURY=y +CONFIG_RTC_DRV_DS1374=m +CONFIG_RTC_DRV_DS1374_WDT=y +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_LP8788=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_MAX8907=m +CONFIG_RTC_DRV_MAX8925=m +CONFIG_RTC_DRV_MAX8998=m +CONFIG_RTC_DRV_MAX8997=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_ISL12022=m +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_DRV_PCF8523=m +CONFIG_RTC_DRV_PCF85063=m +CONFIG_RTC_DRV_PCF85363=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m +CONFIG_RTC_DRV_M41T80=m +CONFIG_RTC_DRV_M41T80_WDT=y +CONFIG_RTC_DRV_BQ32K=m +CONFIG_RTC_DRV_PALMAS=m +CONFIG_RTC_DRV_TPS6586X=m +CONFIG_RTC_DRV_TPS65910=m +CONFIG_RTC_DRV_RC5T583=m +CONFIG_RTC_DRV_S35390A=m +CONFIG_RTC_DRV_FM3130=m +CONFIG_RTC_DRV_RX8010=m +CONFIG_RTC_DRV_RX8581=m +CONFIG_RTC_DRV_RX8025=m +CONFIG_RTC_DRV_EM3027=m +CONFIG_RTC_DRV_RV3028=m +CONFIG_RTC_DRV_RV3032=m +CONFIG_RTC_DRV_RV8803=m +CONFIG_RTC_DRV_SD3078=m + +# +# SPI RTC drivers +# +CONFIG_RTC_DRV_M41T93=m +CONFIG_RTC_DRV_M41T94=m +CONFIG_RTC_DRV_DS1302=m +CONFIG_RTC_DRV_DS1305=m +CONFIG_RTC_DRV_DS1343=m +CONFIG_RTC_DRV_DS1347=m +CONFIG_RTC_DRV_DS1390=m +CONFIG_RTC_DRV_MAX6916=m +CONFIG_RTC_DRV_R9701=m +CONFIG_RTC_DRV_RX4581=m +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_MAX6902=m +CONFIG_RTC_DRV_PCF2123=m +CONFIG_RTC_DRV_MCP795=m +CONFIG_RTC_I2C_AND_SPI=y + +# +# SPI and I2C RTC drivers +# +CONFIG_RTC_DRV_DS3232=m +CONFIG_RTC_DRV_DS3232_HWMON=y +CONFIG_RTC_DRV_PCF2127=m +CONFIG_RTC_DRV_RV3029C2=m +CONFIG_RTC_DRV_RV3029_HWMON=y +CONFIG_RTC_DRV_RX6110=m + +# +# Platform RTC drivers +# +CONFIG_RTC_DRV_CMOS=y +CONFIG_RTC_DRV_DS1286=m +CONFIG_RTC_DRV_DS1511=m +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1685_FAMILY=m +CONFIG_RTC_DRV_DS1685=y +# CONFIG_RTC_DRV_DS1689 is not set +# CONFIG_RTC_DRV_DS17285 is not set +# CONFIG_RTC_DRV_DS17485 is not set +# CONFIG_RTC_DRV_DS17885 is not set +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_DS2404=m +CONFIG_RTC_DRV_DA9052=m +CONFIG_RTC_DRV_DA9055=m +CONFIG_RTC_DRV_DA9063=m +CONFIG_RTC_DRV_STK17TA8=m +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_M48T35=m +CONFIG_RTC_DRV_M48T59=m +CONFIG_RTC_DRV_MSM6242=m +CONFIG_RTC_DRV_RP5C01=m +CONFIG_RTC_DRV_WM831X=m +CONFIG_RTC_DRV_WM8350=m +CONFIG_RTC_DRV_CROS_EC=m + +# +# on-CPU RTC drivers +# +# CONFIG_RTC_DRV_FTRTC010 is not set +CONFIG_RTC_DRV_PCAP=m +CONFIG_RTC_DRV_MC13XXX=m + +# +# HID Sensor RTC drivers +# +CONFIG_RTC_DRV_HID_SENSOR_TIME=m +# CONFIG_RTC_DRV_GOLDFISH is not set +CONFIG_RTC_DRV_WILCO_EC=m +CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +CONFIG_DMA_ENGINE=y +CONFIG_DMA_VIRTUAL_CHANNELS=y +CONFIG_DMA_ACPI=y +CONFIG_ALTERA_MSGDMA=m +CONFIG_INTEL_IDMA64=m +CONFIG_INTEL_IDXD_BUS=m +CONFIG_INTEL_IDXD=m +# CONFIG_INTEL_IDXD_COMPAT is not set +CONFIG_INTEL_IDXD_SVM=y +CONFIG_INTEL_IDXD_PERFMON=y +CONFIG_INTEL_IOATDMA=m +CONFIG_PLX_DMA=m +CONFIG_XILINX_DMA=m +# CONFIG_XILINX_XDMA is not set +CONFIG_AMD_PTDMA=m +CONFIG_QCOM_HIDMA_MGMT=m +CONFIG_QCOM_HIDMA=m +CONFIG_DW_DMAC_CORE=m +CONFIG_DW_DMAC=m +CONFIG_DW_DMAC_PCI=m +CONFIG_DW_EDMA=m +CONFIG_DW_EDMA_PCIE=m +CONFIG_HSU_DMA=m +CONFIG_SF_PDMA=m +CONFIG_INTEL_LDMA=y + +# +# DMA Clients +# +# CONFIG_ASYNC_TX_DMA is not set +CONFIG_DMATEST=m +CONFIG_DMA_ENGINE_RAID=y + +# +# DMABUF options +# +CONFIG_SYNC_FILE=y +# CONFIG_SW_SYNC is not set +CONFIG_UDMABUF=y +# CONFIG_DMABUF_MOVE_NOTIFY is not set +# CONFIG_DMABUF_DEBUG is not set +# CONFIG_DMABUF_SELFTESTS is not set +CONFIG_DMABUF_HEAPS=y +# CONFIG_DMABUF_SYSFS_STATS is not set +CONFIG_DMABUF_HEAPS_SYSTEM=y +CONFIG_DMABUF_HEAPS_CMA=y +# end of DMABUF options + +CONFIG_DCA=m +CONFIG_UIO=m +CONFIG_UIO_CIF=m +CONFIG_UIO_PDRV_GENIRQ=m +CONFIG_UIO_DMEM_GENIRQ=m +CONFIG_UIO_AEC=m +CONFIG_UIO_SERCOS3=m +CONFIG_UIO_PCI_GENERIC=m +CONFIG_UIO_NETX=m +CONFIG_UIO_PRUSS=m +CONFIG_UIO_MF624=m +CONFIG_UIO_HV_GENERIC=m +CONFIG_VFIO=m +CONFIG_VFIO_DEVICE_CDEV=y +CONFIG_VFIO_GROUP=y +CONFIG_VFIO_CONTAINER=y +CONFIG_VFIO_IOMMU_TYPE1=m +# CONFIG_VFIO_NOIOMMU is not set +CONFIG_VFIO_VIRQFD=y + +# +# VFIO support for PCI devices +# +CONFIG_VFIO_PCI_CORE=m +CONFIG_VFIO_PCI_MMAP=y +CONFIG_VFIO_PCI_INTX=y +CONFIG_VFIO_PCI=m +CONFIG_VFIO_PCI_VGA=y +CONFIG_VFIO_PCI_IGD=y +CONFIG_MLX5_VFIO_PCI=m +CONFIG_PDS_VFIO_PCI=m +# end of VFIO support for PCI devices + +CONFIG_VFIO_MDEV=m +CONFIG_IRQ_BYPASS_MANAGER=m +CONFIG_VIRT_DRIVERS=y +CONFIG_VMGENID=y +CONFIG_VBOXGUEST=m +CONFIG_NITRO_ENCLAVES=m +CONFIG_ACRN_HSM=m +CONFIG_EFI_SECRET=m +CONFIG_TDX_GUEST_DRIVER=m +CONFIG_VIRTIO_ANCHOR=y +CONFIG_VIRTIO=m +CONFIG_VIRTIO_PCI_LIB=m +CONFIG_VIRTIO_PCI_LIB_LEGACY=m +CONFIG_VIRTIO_MENU=y +CONFIG_VIRTIO_PCI=m +CONFIG_VIRTIO_PCI_LEGACY=y +CONFIG_VIRTIO_VDPA=m +CONFIG_VIRTIO_PMEM=m +CONFIG_VIRTIO_BALLOON=m +CONFIG_VIRTIO_MEM=m +CONFIG_VIRTIO_INPUT=m +CONFIG_VIRTIO_MMIO=m +CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y +CONFIG_VIRTIO_DMA_SHARED_BUFFER=m +CONFIG_VDPA=m +CONFIG_VDPA_SIM=m +CONFIG_VDPA_SIM_NET=m +CONFIG_VDPA_SIM_BLOCK=m +CONFIG_VDPA_USER=m +CONFIG_IFCVF=m +CONFIG_MLX5_VDPA=y +CONFIG_MLX5_VDPA_NET=m +# CONFIG_MLX5_VDPA_STEERING_DEBUG is not set +CONFIG_VP_VDPA=m +CONFIG_ALIBABA_ENI_VDPA=m +CONFIG_SNET_VDPA=m +CONFIG_PDS_VDPA=m +CONFIG_VHOST_IOTLB=m +CONFIG_VHOST_RING=m +CONFIG_VHOST_TASK=y +CONFIG_VHOST=m +CONFIG_VHOST_MENU=y +CONFIG_VHOST_NET=m +CONFIG_VHOST_SCSI=m +CONFIG_VHOST_VSOCK=m +CONFIG_VHOST_VDPA=m +# CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set + +# +# Microsoft Hyper-V guest support +# +CONFIG_HYPERV=m +# CONFIG_HYPERV_VTL_MODE is not set +CONFIG_HYPERV_TIMER=y +CONFIG_HYPERV_UTILS=m +CONFIG_HYPERV_BALLOON=m +# end of Microsoft Hyper-V guest support + +# +# Xen driver support +# +CONFIG_XEN_BALLOON=y +CONFIG_XEN_BALLOON_MEMORY_HOTPLUG=y +CONFIG_XEN_MEMORY_HOTPLUG_LIMIT=512 +CONFIG_XEN_SCRUB_PAGES_DEFAULT=y +CONFIG_XEN_DEV_EVTCHN=m +CONFIG_XEN_BACKEND=y +CONFIG_XENFS=m +CONFIG_XEN_COMPAT_XENFS=y +CONFIG_XEN_SYS_HYPERVISOR=y +CONFIG_XEN_XENBUS_FRONTEND=y +CONFIG_XEN_GNTDEV=m +CONFIG_XEN_GNTDEV_DMABUF=y +CONFIG_XEN_GRANT_DEV_ALLOC=m +CONFIG_XEN_GRANT_DMA_ALLOC=y +CONFIG_SWIOTLB_XEN=y +CONFIG_XEN_PCI_STUB=y +CONFIG_XEN_PCIDEV_BACKEND=m +CONFIG_XEN_PVCALLS_FRONTEND=m +# CONFIG_XEN_PVCALLS_BACKEND is not set +CONFIG_XEN_SCSI_BACKEND=m +CONFIG_XEN_PRIVCMD=m +CONFIG_XEN_PRIVCMD_IRQFD=y +CONFIG_XEN_ACPI_PROCESSOR=m +# CONFIG_XEN_MCE_LOG is not set +CONFIG_XEN_HAVE_PVMMU=y +CONFIG_XEN_EFI=y +CONFIG_XEN_AUTO_XLATE=y +CONFIG_XEN_ACPI=y +CONFIG_XEN_SYMS=y +CONFIG_XEN_HAVE_VPMU=y +CONFIG_XEN_FRONT_PGDIR_SHBUF=m +CONFIG_XEN_UNPOPULATED_ALLOC=y +CONFIG_XEN_GRANT_DMA_OPS=y +CONFIG_XEN_VIRTIO=y +# CONFIG_XEN_VIRTIO_FORCE_GRANT is not set +# end of Xen driver support + +# CONFIG_GREYBUS is not set +CONFIG_COMEDI=m +# CONFIG_COMEDI_DEBUG is not set +CONFIG_COMEDI_DEFAULT_BUF_SIZE_KB=2048 +CONFIG_COMEDI_DEFAULT_BUF_MAXSIZE_KB=20480 +CONFIG_COMEDI_MISC_DRIVERS=y +CONFIG_COMEDI_BOND=m +CONFIG_COMEDI_TEST=m +CONFIG_COMEDI_PARPORT=m +# CONFIG_COMEDI_ISA_DRIVERS is not set +CONFIG_COMEDI_PCI_DRIVERS=m +CONFIG_COMEDI_8255_PCI=m +CONFIG_COMEDI_ADDI_WATCHDOG=m +CONFIG_COMEDI_ADDI_APCI_1032=m +CONFIG_COMEDI_ADDI_APCI_1500=m +CONFIG_COMEDI_ADDI_APCI_1516=m +CONFIG_COMEDI_ADDI_APCI_1564=m +CONFIG_COMEDI_ADDI_APCI_16XX=m +CONFIG_COMEDI_ADDI_APCI_2032=m +CONFIG_COMEDI_ADDI_APCI_2200=m +CONFIG_COMEDI_ADDI_APCI_3120=m +CONFIG_COMEDI_ADDI_APCI_3501=m +CONFIG_COMEDI_ADDI_APCI_3XXX=m +CONFIG_COMEDI_ADL_PCI6208=m +CONFIG_COMEDI_ADL_PCI7X3X=m +CONFIG_COMEDI_ADL_PCI8164=m +# CONFIG_COMEDI_ADL_PCI9111 is not set +# CONFIG_COMEDI_ADL_PCI9118 is not set +# CONFIG_COMEDI_ADV_PCI1710 is not set +CONFIG_COMEDI_ADV_PCI1720=m +CONFIG_COMEDI_ADV_PCI1723=m +CONFIG_COMEDI_ADV_PCI1724=m +CONFIG_COMEDI_ADV_PCI1760=m +# CONFIG_COMEDI_ADV_PCI_DIO is not set +# CONFIG_COMEDI_AMPLC_DIO200_PCI is not set +CONFIG_COMEDI_AMPLC_PC236_PCI=m +CONFIG_COMEDI_AMPLC_PC263_PCI=m +# CONFIG_COMEDI_AMPLC_PCI224 is not set +# CONFIG_COMEDI_AMPLC_PCI230 is not set +CONFIG_COMEDI_CONTEC_PCI_DIO=m +# CONFIG_COMEDI_DAS08_PCI is not set +CONFIG_COMEDI_DT3000=m +CONFIG_COMEDI_DYNA_PCI10XX=m +CONFIG_COMEDI_GSC_HPDI=m +CONFIG_COMEDI_MF6X4=m +CONFIG_COMEDI_ICP_MULTI=m +CONFIG_COMEDI_DAQBOARD2000=m +CONFIG_COMEDI_JR3_PCI=m +CONFIG_COMEDI_KE_COUNTER=m +CONFIG_COMEDI_CB_PCIDAS64=m +# CONFIG_COMEDI_CB_PCIDAS is not set +CONFIG_COMEDI_CB_PCIDDA=m +# CONFIG_COMEDI_CB_PCIMDAS is not set +CONFIG_COMEDI_CB_PCIMDDA=m +# CONFIG_COMEDI_ME4000 is not set +CONFIG_COMEDI_ME_DAQ=m +CONFIG_COMEDI_NI_6527=m +CONFIG_COMEDI_NI_65XX=m +CONFIG_COMEDI_NI_660X=m +CONFIG_COMEDI_NI_670X=m +# CONFIG_COMEDI_NI_LABPC_PCI is not set +CONFIG_COMEDI_NI_PCIDIO=m +CONFIG_COMEDI_NI_PCIMIO=m +# CONFIG_COMEDI_RTD520 is not set +CONFIG_COMEDI_S626=m +CONFIG_COMEDI_MITE=m +CONFIG_COMEDI_NI_TIOCMD=m +CONFIG_COMEDI_PCMCIA_DRIVERS=m +# CONFIG_COMEDI_CB_DAS16_CS is not set +# CONFIG_COMEDI_DAS08_CS is not set +CONFIG_COMEDI_NI_DAQ_700_CS=m +CONFIG_COMEDI_NI_DAQ_DIO24_CS=m +# CONFIG_COMEDI_NI_LABPC_CS is not set +CONFIG_COMEDI_NI_MIO_CS=m +CONFIG_COMEDI_QUATECH_DAQP_CS=m +CONFIG_COMEDI_USB_DRIVERS=m +CONFIG_COMEDI_DT9812=m +CONFIG_COMEDI_NI_USB6501=m +CONFIG_COMEDI_USBDUX=m +CONFIG_COMEDI_USBDUXFAST=m +CONFIG_COMEDI_USBDUXSIGMA=m +CONFIG_COMEDI_VMK80XX=m +CONFIG_COMEDI_8255=m +CONFIG_COMEDI_8255_SA=m +CONFIG_COMEDI_KCOMEDILIB=m +CONFIG_COMEDI_AMPLC_PC236=m +CONFIG_COMEDI_NI_TIO=m +CONFIG_COMEDI_NI_ROUTING=m +# CONFIG_COMEDI_TESTS is not set +CONFIG_STAGING=y +CONFIG_PRISM2_USB=m +CONFIG_RTL8192U=m +CONFIG_RTLLIB=m +CONFIG_RTLLIB_CRYPTO_CCMP=m +CONFIG_RTLLIB_CRYPTO_TKIP=m +CONFIG_RTLLIB_CRYPTO_WEP=m +CONFIG_RTL8192E=m +CONFIG_RTL8723BS=m +CONFIG_R8712U=m +CONFIG_RTL8812AU=m +CONFIG_RTS5208=m +CONFIG_VT6655=m +CONFIG_VT6656=m + +# +# IIO staging drivers +# + +# +# Accelerometers +# +CONFIG_ADIS16203=m +CONFIG_ADIS16240=m +# end of Accelerometers + +# +# Analog to digital converters +# +CONFIG_AD7816=m +# end of Analog to digital converters + +# +# Analog digital bi-direction converters +# +CONFIG_ADT7316=m +CONFIG_ADT7316_SPI=m +CONFIG_ADT7316_I2C=m +# end of Analog digital bi-direction converters + +# +# Direct Digital Synthesis +# +CONFIG_AD9832=m +CONFIG_AD9834=m +# end of Direct Digital Synthesis + +# +# Network Analyzer, Impedance Converters +# +CONFIG_AD5933=m +# end of Network Analyzer, Impedance Converters + +# +# Resolver to digital converters +# +CONFIG_AD2S1210=m +# end of Resolver to digital converters +# end of IIO staging drivers + +# CONFIG_FB_SM750 is not set +CONFIG_STAGING_MEDIA=y +# CONFIG_INTEL_ATOMISP is not set +CONFIG_DVB_AV7110_IR=y +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +CONFIG_DVB_BUDGET_PATCH=m +CONFIG_DVB_SP8870=m +CONFIG_VIDEO_IPU3_IMGU=m +# CONFIG_STAGING_MEDIA_DEPRECATED is not set +CONFIG_LTE_GDM724X=m +# CONFIG_FB_TFT is not set +# CONFIG_MOST_COMPONENTS is not set +CONFIG_KS7010=m +# CONFIG_PI433 is not set +CONFIG_FIELDBUS_DEV=m +CONFIG_QLGE=m +CONFIG_VME_BUS=y + +# +# VME Bridge Drivers +# +CONFIG_VME_TSI148=m +# CONFIG_VME_FAKE is not set + +# +# VME Device Drivers +# +CONFIG_VME_USER=m +CONFIG_CHROME_PLATFORMS=y +CONFIG_CHROMEOS_ACPI=m +CONFIG_CHROMEOS_LAPTOP=m +CONFIG_CHROMEOS_PSTORE=m +CONFIG_CHROMEOS_TBMC=m +CONFIG_CROS_EC=m +CONFIG_CROS_EC_I2C=m +CONFIG_CROS_EC_ISHTP=m +CONFIG_CROS_EC_SPI=m +CONFIG_CROS_EC_UART=m +CONFIG_CROS_EC_LPC=m +CONFIG_CROS_EC_PROTO=y +CONFIG_CROS_KBD_LED_BACKLIGHT=m +CONFIG_CROS_EC_CHARDEV=m +CONFIG_CROS_EC_LIGHTBAR=m +CONFIG_CROS_EC_DEBUGFS=m +CONFIG_CROS_EC_SENSORHUB=m +CONFIG_CROS_EC_SYSFS=m +CONFIG_CROS_EC_TYPEC=m +CONFIG_CROS_HPS_I2C=m +CONFIG_CROS_USBPD_LOGGER=m +CONFIG_CROS_USBPD_NOTIFY=m +CONFIG_CHROMEOS_PRIVACY_SCREEN=m +CONFIG_CROS_TYPEC_SWITCH=m +CONFIG_WILCO_EC=m +CONFIG_WILCO_EC_DEBUGFS=m +CONFIG_WILCO_EC_EVENTS=m +CONFIG_WILCO_EC_TELEMETRY=m +CONFIG_MELLANOX_PLATFORM=y +CONFIG_MLXREG_HOTPLUG=m +CONFIG_MLXREG_IO=m +CONFIG_MLXREG_LC=m +CONFIG_NVSW_SN2201=m +CONFIG_SURFACE_PLATFORMS=y +CONFIG_SURFACE3_WMI=m +CONFIG_SURFACE_3_POWER_OPREGION=m +CONFIG_SURFACE_ACPI_NOTIFY=m +CONFIG_SURFACE_AGGREGATOR_CDEV=m +CONFIG_SURFACE_AGGREGATOR_HUB=m +CONFIG_SURFACE_AGGREGATOR_REGISTRY=m +CONFIG_SURFACE_AGGREGATOR_TABLET_SWITCH=m +CONFIG_SURFACE_DTX=m +CONFIG_SURFACE_GPE=m +CONFIG_SURFACE_HOTPLUG=m +CONFIG_SURFACE_PLATFORM_PROFILE=m +CONFIG_SURFACE_PRO3_BUTTON=m +CONFIG_SURFACE_AGGREGATOR=m +CONFIG_SURFACE_AGGREGATOR_BUS=y +# CONFIG_SURFACE_AGGREGATOR_ERROR_INJECTION is not set +CONFIG_X86_PLATFORM_DEVICES=y +CONFIG_ACPI_WMI=m +CONFIG_WMI_BMOF=m +CONFIG_HUAWEI_WMI=m +CONFIG_MXM_WMI=m +CONFIG_NVIDIA_WMI_EC_BACKLIGHT=m +CONFIG_XIAOMI_WMI=m +CONFIG_GIGABYTE_WMI=m +CONFIG_YOGABOOK=m +CONFIG_ACERHDF=m +CONFIG_ACER_WIRELESS=m +CONFIG_ACER_WMI=m +CONFIG_AMD_PMF=m +# CONFIG_AMD_PMF_DEBUG is not set +CONFIG_AMD_PMC=m +CONFIG_AMD_HSMP=m +CONFIG_ADV_SWBUTTON=m +CONFIG_APPLE_GMUX=m +CONFIG_ASUS_LAPTOP=m +CONFIG_ASUS_WIRELESS=m +CONFIG_ASUS_WMI=m +CONFIG_ASUS_NB_WMI=m +CONFIG_ASUS_TF103C_DOCK=m +# CONFIG_MERAKI_MX100 is not set +CONFIG_EEEPC_LAPTOP=m +CONFIG_EEEPC_WMI=m +CONFIG_X86_PLATFORM_DRIVERS_DELL=y +CONFIG_ALIENWARE_WMI=m +CONFIG_DCDBAS=m +CONFIG_DELL_LAPTOP=m +# CONFIG_DELL_RBU is not set +CONFIG_DELL_RBTN=m +CONFIG_DELL_SMBIOS=m +CONFIG_DELL_SMBIOS_WMI=y +CONFIG_DELL_SMBIOS_SMM=y +CONFIG_DELL_SMO8800=m +CONFIG_DELL_WMI=m +CONFIG_DELL_WMI_PRIVACY=y +CONFIG_DELL_WMI_AIO=m +CONFIG_DELL_WMI_DESCRIPTOR=m +CONFIG_DELL_WMI_DDV=m +CONFIG_DELL_WMI_LED=m +CONFIG_DELL_WMI_SYSMAN=m +CONFIG_AMILO_RFKILL=m +CONFIG_FUJITSU_LAPTOP=m +CONFIG_FUJITSU_TABLET=m +CONFIG_GPD_POCKET_FAN=m +CONFIG_X86_PLATFORM_DRIVERS_HP=y +CONFIG_HP_ACCEL=m +CONFIG_HP_WMI=m +CONFIG_HP_BIOSCFG=m +CONFIG_WIRELESS_HOTKEY=m +CONFIG_IBM_RTL=m +CONFIG_IDEAPAD_LAPTOP=m +CONFIG_LENOVO_YMC=m +CONFIG_SENSORS_HDAPS=m +CONFIG_THINKPAD_ACPI=m +CONFIG_THINKPAD_ACPI_ALSA_SUPPORT=y +# CONFIG_THINKPAD_ACPI_DEBUGFACILITIES is not set +# CONFIG_THINKPAD_ACPI_DEBUG is not set +# CONFIG_THINKPAD_ACPI_UNSAFE_LEDS is not set +CONFIG_THINKPAD_ACPI_VIDEO=y +CONFIG_THINKPAD_ACPI_HOTKEY_POLL=y +CONFIG_THINKPAD_LMI=m +CONFIG_INTEL_ATOMISP2_PDX86=y +# CONFIG_INTEL_ATOMISP2_LED is not set +CONFIG_INTEL_ATOMISP2_PM=m +# CONFIG_INTEL_IFS is not set +CONFIG_INTEL_SAR_INT1092=m +CONFIG_INTEL_SKL_INT3472=m +CONFIG_INTEL_PMC_CORE=y +CONFIG_INTEL_PMT_CLASS=m +CONFIG_INTEL_PMT_TELEMETRY=m +CONFIG_INTEL_PMT_CRASHLOG=m + +# +# Intel Speed Select Technology interface support +# +CONFIG_INTEL_SPEED_SELECT_TPMI=m +CONFIG_INTEL_SPEED_SELECT_INTERFACE=m +# end of Intel Speed Select Technology interface support + +# CONFIG_INTEL_TELEMETRY is not set +CONFIG_INTEL_WMI=y +# CONFIG_INTEL_WMI_SBL_FW_UPDATE is not set +CONFIG_INTEL_WMI_THUNDERBOLT=m + +# +# Intel Uncore Frequency Control +# +CONFIG_INTEL_UNCORE_FREQ_CONTROL_TPMI=m +CONFIG_INTEL_UNCORE_FREQ_CONTROL=m +# end of Intel Uncore Frequency Control + +CONFIG_INTEL_HID_EVENT=m +CONFIG_INTEL_VBTN=m +CONFIG_INTEL_INT0002_VGPIO=m +CONFIG_INTEL_OAKTRAIL=m +CONFIG_INTEL_BXTWC_PMIC_TMU=m +CONFIG_INTEL_BYTCRC_PWRSRC=m +CONFIG_INTEL_CHTDC_TI_PWRBTN=m +CONFIG_INTEL_CHTWC_INT33FE=m +CONFIG_INTEL_ISHTP_ECLITE=m +CONFIG_INTEL_MRFLD_PWRBTN=m +CONFIG_INTEL_PUNIT_IPC=m +CONFIG_INTEL_RST=m +CONFIG_INTEL_SDSI=m +CONFIG_INTEL_SMARTCONNECT=m +CONFIG_INTEL_TPMI=m +CONFIG_INTEL_TURBO_MAX_3=y +CONFIG_INTEL_VSEC=m +CONFIG_MSI_EC=m +CONFIG_MSI_LAPTOP=m +CONFIG_MSI_WMI=m +CONFIG_PCENGINES_APU2=m +CONFIG_BARCO_P50_GPIO=m +CONFIG_SAMSUNG_LAPTOP=m +CONFIG_SAMSUNG_Q10=m +CONFIG_ACPI_TOSHIBA=m +CONFIG_TOSHIBA_BT_RFKILL=m +CONFIG_TOSHIBA_HAPS=m +CONFIG_TOSHIBA_WMI=m +CONFIG_ACPI_CMPC=m +CONFIG_COMPAL_LAPTOP=m +CONFIG_LG_LAPTOP=m +CONFIG_PANASONIC_LAPTOP=m +CONFIG_SHUTTLE_WMI=m +CONFIG_SONY_LAPTOP=m +CONFIG_SONYPI_COMPAT=y +CONFIG_SYSTEM76_ACPI=m +CONFIG_TOPSTAR_LAPTOP=m +CONFIG_SERIAL_MULTI_INSTANTIATE=m +CONFIG_MLX_PLATFORM=m +CONFIG_TOUCHSCREEN_DMI=y +CONFIG_X86_ANDROID_TABLETS=m +CONFIG_FW_ATTR_CLASS=m +CONFIG_INTEL_IPS=m +CONFIG_INTEL_SCU_IPC=y +CONFIG_INTEL_SCU=y +CONFIG_INTEL_SCU_PCI=y +CONFIG_INTEL_SCU_PLATFORM=m +CONFIG_INTEL_SCU_IPC_UTIL=m +# CONFIG_SIEMENS_SIMATIC_IPC is not set +# CONFIG_WINMATE_FM07_KEYS is not set +CONFIG_SEL3350_PLATFORM=m +CONFIG_P2SB=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_COMMON_CLK=y +CONFIG_COMMON_CLK_WM831X=m +CONFIG_LMK04832=m +CONFIG_COMMON_CLK_MAX9485=m +CONFIG_COMMON_CLK_SI5341=m +CONFIG_COMMON_CLK_SI5351=m +CONFIG_COMMON_CLK_SI544=m +CONFIG_COMMON_CLK_CDCE706=m +CONFIG_COMMON_CLK_TPS68470=m +CONFIG_COMMON_CLK_CS2000_CP=m +CONFIG_CLK_TWL6040=m +CONFIG_COMMON_CLK_PALMAS=m +CONFIG_COMMON_CLK_PWM=m +CONFIG_XILINX_VCU=m +# CONFIG_HWSPINLOCK is not set + +# +# Clock Source drivers +# +CONFIG_CLKEVT_I8253=y +CONFIG_I8253_LOCK=y +CONFIG_CLKBLD_I8253=y +# end of Clock Source drivers + +CONFIG_MAILBOX=y +CONFIG_PCC=y +CONFIG_ALTERA_MBOX=m +CONFIG_IOMMU_IOVA=y +CONFIG_IOMMU_API=y +CONFIG_IOMMU_SUPPORT=y + +# +# Generic IOMMU Pagetable Support +# +CONFIG_IOMMU_IO_PGTABLE=y +# end of Generic IOMMU Pagetable Support + +# CONFIG_IOMMU_DEBUGFS is not set +# CONFIG_IOMMU_DEFAULT_DMA_STRICT is not set +CONFIG_IOMMU_DEFAULT_DMA_LAZY=y +# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set +CONFIG_IOMMU_DMA=y +CONFIG_IOMMU_SVA=y +CONFIG_AMD_IOMMU=y +CONFIG_AMD_IOMMU_V2=m +CONFIG_DMAR_TABLE=y +CONFIG_INTEL_IOMMU=y +CONFIG_INTEL_IOMMU_SVM=y +# CONFIG_INTEL_IOMMU_DEFAULT_ON is not set +CONFIG_INTEL_IOMMU_FLOPPY_WA=y +# CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON is not set +CONFIG_INTEL_IOMMU_PERF_EVENTS=y +CONFIG_IOMMUFD=m +CONFIG_IRQ_REMAP=y +CONFIG_HYPERV_IOMMU=y +CONFIG_VIRTIO_IOMMU=m + +# +# Remoteproc drivers +# +# CONFIG_REMOTEPROC is not set +# end of Remoteproc drivers + +# +# Rpmsg drivers +# +CONFIG_RPMSG=m +# CONFIG_RPMSG_CHAR is not set +# CONFIG_RPMSG_CTRL is not set +CONFIG_RPMSG_NS=m +CONFIG_RPMSG_QCOM_GLINK=m +CONFIG_RPMSG_QCOM_GLINK_RPM=m +CONFIG_RPMSG_VIRTIO=m +# end of Rpmsg drivers + +CONFIG_SOUNDWIRE=y + +# +# SoundWire Devices +# +CONFIG_SOUNDWIRE_AMD=m +CONFIG_SOUNDWIRE_CADENCE=m +CONFIG_SOUNDWIRE_INTEL=m +CONFIG_SOUNDWIRE_QCOM=m +CONFIG_SOUNDWIRE_GENERIC_ALLOCATION=m + +# +# SOC (System On Chip) specific Drivers +# + +# +# Amlogic SoC drivers +# +# end of Amlogic SoC drivers + +# +# Broadcom SoC drivers +# +# end of Broadcom SoC drivers + +# +# NXP/Freescale QorIQ SoC drivers +# +# end of NXP/Freescale QorIQ SoC drivers + +# +# fujitsu SoC drivers +# +# end of fujitsu SoC drivers + +# +# i.MX SoC drivers +# +# end of i.MX SoC drivers + +# +# Enable LiteX SoC Builder specific drivers +# +# end of Enable LiteX SoC Builder specific drivers + +CONFIG_WPCM450_SOC=m + +# +# Qualcomm SoC drivers +# +CONFIG_QCOM_QMI_HELPERS=m +# end of Qualcomm SoC drivers + +# CONFIG_SOC_TI is not set + +# +# Xilinx SoC drivers +# +# end of Xilinx SoC drivers +# end of SOC (System On Chip) specific Drivers + +CONFIG_PM_DEVFREQ=y + +# +# DEVFREQ Governors +# +CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y +CONFIG_DEVFREQ_GOV_PERFORMANCE=y +CONFIG_DEVFREQ_GOV_POWERSAVE=y +CONFIG_DEVFREQ_GOV_USERSPACE=y +CONFIG_DEVFREQ_GOV_PASSIVE=m + +# +# DEVFREQ Drivers +# +# CONFIG_PM_DEVFREQ_EVENT is not set +CONFIG_EXTCON=y + +# +# Extcon Device Drivers +# +CONFIG_EXTCON_ADC_JACK=m +CONFIG_EXTCON_AXP288=m +CONFIG_EXTCON_FSA9480=m +CONFIG_EXTCON_GPIO=m +CONFIG_EXTCON_INTEL_INT3496=m +CONFIG_EXTCON_INTEL_CHT_WC=m +CONFIG_EXTCON_INTEL_MRFLD=m +CONFIG_EXTCON_MAX14577=m +CONFIG_EXTCON_MAX3355=m +CONFIG_EXTCON_MAX77693=m +CONFIG_EXTCON_MAX8997=m +CONFIG_EXTCON_PALMAS=m +CONFIG_EXTCON_PTN5150=m +CONFIG_EXTCON_RT8973A=m +CONFIG_EXTCON_SM5502=m +CONFIG_EXTCON_USB_GPIO=m +CONFIG_EXTCON_USBC_CROS_EC=m +CONFIG_EXTCON_USBC_TUSB320=m +CONFIG_MEMORY=y +CONFIG_IIO=m +CONFIG_IIO_BUFFER=y +CONFIG_IIO_BUFFER_CB=m +CONFIG_IIO_BUFFER_DMA=m +CONFIG_IIO_BUFFER_DMAENGINE=m +CONFIG_IIO_BUFFER_HW_CONSUMER=m +CONFIG_IIO_KFIFO_BUF=m +CONFIG_IIO_TRIGGERED_BUFFER=m +CONFIG_IIO_CONFIGFS=m +CONFIG_IIO_TRIGGER=y +CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 +CONFIG_IIO_SW_DEVICE=m +CONFIG_IIO_SW_TRIGGER=m +CONFIG_IIO_TRIGGERED_EVENT=m +CONFIG_IIO_BACKEND=m + +# +# Accelerometers +# +CONFIG_ADIS16201=m +CONFIG_ADIS16209=m +# CONFIG_ADXL313_I2C is not set +# CONFIG_ADXL313_SPI is not set +# CONFIG_ADXL355_I2C is not set +# CONFIG_ADXL355_SPI is not set +# CONFIG_ADXL367_SPI is not set +# CONFIG_ADXL367_I2C is not set +# CONFIG_ADXL372_SPI is not set +# CONFIG_ADXL372_I2C is not set +CONFIG_BMA220=m +# CONFIG_BMA400 is not set +CONFIG_BMC150_ACCEL=m +CONFIG_BMC150_ACCEL_I2C=m +CONFIG_BMC150_ACCEL_SPI=m +# CONFIG_BMI088_ACCEL is not set +# CONFIG_DA280 is not set +# CONFIG_DA311 is not set +# CONFIG_DMARD06 is not set +# CONFIG_DMARD09 is not set +# CONFIG_DMARD10 is not set +# CONFIG_FXLS8962AF_I2C is not set +# CONFIG_FXLS8962AF_SPI is not set +CONFIG_HID_SENSOR_ACCEL_3D=m +# CONFIG_IIO_CROS_EC_ACCEL_LEGACY is not set +CONFIG_IIO_ST_ACCEL_3AXIS=m +CONFIG_IIO_ST_ACCEL_I2C_3AXIS=m +CONFIG_IIO_ST_ACCEL_SPI_3AXIS=m +# CONFIG_IIO_KX022A_SPI is not set +# CONFIG_IIO_KX022A_I2C is not set +CONFIG_KXSD9=m +CONFIG_KXSD9_SPI=m +CONFIG_KXSD9_I2C=m +CONFIG_KXCJK1013=m +# CONFIG_MC3230 is not set +CONFIG_MMA7455=m +CONFIG_MMA7455_I2C=m +CONFIG_MMA7455_SPI=m +CONFIG_MMA7660=m +CONFIG_MMA8452=m +# CONFIG_MMA9551 is not set +# CONFIG_MMA9553 is not set +# CONFIG_MSA311 is not set +CONFIG_MXC4005=m +CONFIG_MXC6255=m +CONFIG_SCA3000=m +# CONFIG_SCA3300 is not set +CONFIG_STK8312=m +CONFIG_STK8BA50=m +# end of Accelerometers + +# +# Analog to digital converters +# +CONFIG_AD_SIGMA_DELTA=m +CONFIG_AD4130=m +CONFIG_AD7091R5=m +CONFIG_AD7124=m +CONFIG_AD7192=m +CONFIG_AD7266=m +CONFIG_AD7280=m +CONFIG_AD7291=m +CONFIG_AD7292=m +CONFIG_AD7298=m +CONFIG_AD7476=m +CONFIG_AD7606=m +CONFIG_AD7606_IFACE_PARALLEL=m +CONFIG_AD7606_IFACE_SPI=m +CONFIG_AD7766=m +CONFIG_AD7768_1=m +CONFIG_AD7780=m +CONFIG_AD7791=m +CONFIG_AD7793=m +CONFIG_AD7887=m +CONFIG_AD7923=m +CONFIG_AD7949=m +CONFIG_AD799X=m +CONFIG_AD9467=m +CONFIG_ADI_AXI_ADC=m +# CONFIG_AXP20X_ADC is not set +CONFIG_AXP288_ADC=m +# CONFIG_CC10001_ADC is not set +CONFIG_DA9150_GPADC=m +CONFIG_DLN2_ADC=m +# CONFIG_ENVELOPE_DETECTOR is not set +CONFIG_HI8435=m +# CONFIG_HX711 is not set +CONFIG_INA2XX_ADC=m +CONFIG_INTEL_MRFLD_ADC=m +CONFIG_LP8788_ADC=m +CONFIG_LTC2471=m +# CONFIG_LTC2485 is not set +# CONFIG_LTC2496 is not set +# CONFIG_LTC2497 is not set +CONFIG_MAX1027=m +# CONFIG_MAX11100 is not set +# CONFIG_MAX1118 is not set +# CONFIG_MAX11205 is not set +CONFIG_MAX11410=m +# CONFIG_MAX1241 is not set +CONFIG_MAX1363=m +CONFIG_MAX77541_ADC=m +# CONFIG_MAX9611 is not set +CONFIG_MCP320X=m +CONFIG_MCP3422=m +# CONFIG_MCP3911 is not set +CONFIG_MP2629_ADC=m +CONFIG_NAU7802=m +CONFIG_PALMAS_GPADC=m +CONFIG_QCOM_SPMI_IADC=m +# CONFIG_QCOM_SPMI_VADC is not set +# CONFIG_QCOM_SPMI_ADC5 is not set +# CONFIG_RICHTEK_RTQ6056 is not set +# CONFIG_SD_ADC_MODULATOR is not set +CONFIG_TI_ADC081C=m +CONFIG_TI_ADC0832=m +CONFIG_TI_ADC084S021=m +# CONFIG_TI_ADC12138 is not set +CONFIG_TI_ADC108S102=m +CONFIG_TI_ADC128S052=m +# CONFIG_TI_ADC161S626 is not set +CONFIG_TI_ADS1015=m +CONFIG_TI_ADS7924=m +CONFIG_TI_ADS1100=m +# CONFIG_TI_ADS7950 is not set +# CONFIG_TI_ADS8344 is not set +# CONFIG_TI_ADS8688 is not set +# CONFIG_TI_ADS124S08 is not set +# CONFIG_TI_ADS131E08 is not set +CONFIG_TI_LMP92064=m +# CONFIG_TI_TLC4541 is not set +# CONFIG_TI_TSC2046 is not set +CONFIG_TWL4030_MADC=m +CONFIG_TWL6030_GPADC=m +# CONFIG_VF610_ADC is not set +CONFIG_VIPERBOARD_ADC=m +CONFIG_XILINX_XADC=m +# end of Analog to digital converters + +# +# Analog to digital and digital to analog converters +# +CONFIG_AD74115=m +CONFIG_AD74413R=m +# end of Analog to digital and digital to analog converters + +# +# Analog Front Ends +# +CONFIG_IIO_RESCALE=m +# end of Analog Front Ends + +# +# Amplifiers +# +CONFIG_AD8366=m +# CONFIG_ADA4250 is not set +# CONFIG_HMC425 is not set +# end of Amplifiers + +# +# Capacitance to digital converters +# +CONFIG_AD7150=m +CONFIG_AD7746=m +# end of Capacitance to digital converters + +# +# Chemical Sensors +# +CONFIG_ATLAS_PH_SENSOR=m +# CONFIG_ATLAS_EZO_SENSOR is not set +# CONFIG_BME680 is not set +CONFIG_CCS811=m +CONFIG_IAQCORE=m +# CONFIG_PMS7003 is not set +CONFIG_SCD30_CORE=m +CONFIG_SCD30_I2C=m +CONFIG_SCD30_SERIAL=m +# CONFIG_SCD4X is not set +# CONFIG_SENSIRION_SGP30 is not set +# CONFIG_SENSIRION_SGP40 is not set +# CONFIG_SPS30_I2C is not set +# CONFIG_SPS30_SERIAL is not set +# CONFIG_SENSEAIR_SUNRISE_CO2 is not set +CONFIG_VZ89X=m +# end of Chemical Sensors + +CONFIG_IIO_CROS_EC_SENSORS_CORE=m +CONFIG_IIO_CROS_EC_SENSORS=m +CONFIG_IIO_CROS_EC_SENSORS_LID_ANGLE=m + +# +# Hid Sensor IIO Common +# +CONFIG_HID_SENSOR_IIO_COMMON=m +CONFIG_HID_SENSOR_IIO_TRIGGER=m +# end of Hid Sensor IIO Common + +CONFIG_IIO_INV_SENSORS_TIMESTAMP=m +CONFIG_IIO_MS_SENSORS_I2C=m + +# +# IIO SCMI Sensors +# +# end of IIO SCMI Sensors + +# +# SSP Sensor Common +# +# CONFIG_IIO_SSP_SENSORHUB is not set +# end of SSP Sensor Common + +CONFIG_IIO_ST_SENSORS_I2C=m +CONFIG_IIO_ST_SENSORS_SPI=m +CONFIG_IIO_ST_SENSORS_CORE=m + +# +# Digital to analog converters +# +# CONFIG_AD3552R is not set +CONFIG_AD5064=m +CONFIG_AD5360=m +CONFIG_AD5380=m +CONFIG_AD5421=m +CONFIG_AD5446=m +CONFIG_AD5449=m +CONFIG_AD5592R_BASE=m +CONFIG_AD5592R=m +CONFIG_AD5593R=m +CONFIG_AD5504=m +CONFIG_AD5624R_SPI=m +CONFIG_LTC2688=m +CONFIG_AD5686=m +CONFIG_AD5686_SPI=m +CONFIG_AD5696_I2C=m +CONFIG_AD5755=m +CONFIG_AD5758=m +CONFIG_AD5761=m +CONFIG_AD5764=m +CONFIG_AD5766=m +# CONFIG_AD5770R is not set +CONFIG_AD5791=m +# CONFIG_AD7293 is not set +CONFIG_AD7303=m +# CONFIG_AD8801 is not set +# CONFIG_CIO_DAC is not set +# CONFIG_DPOT_DAC is not set +# CONFIG_DS4424 is not set +CONFIG_LTC1660=m +# CONFIG_LTC2632 is not set +CONFIG_M62332=m +CONFIG_MAX517=m +CONFIG_MAX5522=m +# CONFIG_MAX5821 is not set +CONFIG_MCP4725=m +CONFIG_MCP4728=m +CONFIG_MCP4922=m +# CONFIG_TI_DAC082S085 is not set +# CONFIG_TI_DAC5571 is not set +# CONFIG_TI_DAC7311 is not set +# CONFIG_TI_DAC7612 is not set +# CONFIG_VF610_DAC is not set +# end of Digital to analog converters + +# +# IIO dummy driver +# +# CONFIG_IIO_SIMPLE_DUMMY is not set +# end of IIO dummy driver + +# +# Filters +# +# CONFIG_ADMV8818 is not set +# end of Filters + +# +# Frequency Synthesizers DDS/PLL +# + +# +# Clock Generator/Distribution +# +CONFIG_AD9523=m +# end of Clock Generator/Distribution + +# +# Phase-Locked Loop (PLL) frequency synthesizers +# +CONFIG_ADF4350=m +CONFIG_ADF4371=m +CONFIG_ADF4377=m +# CONFIG_ADMV1013 is not set +# CONFIG_ADMV1014 is not set +# CONFIG_ADMV4420 is not set +# CONFIG_ADRF6780 is not set +# end of Phase-Locked Loop (PLL) frequency synthesizers +# end of Frequency Synthesizers DDS/PLL + +# +# Digital gyroscope sensors +# +CONFIG_ADIS16080=m +CONFIG_ADIS16130=m +CONFIG_ADIS16136=m +CONFIG_ADIS16260=m +CONFIG_ADXRS290=m +CONFIG_ADXRS450=m +CONFIG_BMG160=m +CONFIG_BMG160_I2C=m +CONFIG_BMG160_SPI=m +# CONFIG_FXAS21002C is not set +CONFIG_HID_SENSOR_GYRO_3D=m +# CONFIG_MPU3050_I2C is not set +CONFIG_IIO_ST_GYRO_3AXIS=m +CONFIG_IIO_ST_GYRO_I2C_3AXIS=m +CONFIG_IIO_ST_GYRO_SPI_3AXIS=m +CONFIG_ITG3200=m +# end of Digital gyroscope sensors + +# +# Health Sensors +# + +# +# Heart Rate Monitors +# +CONFIG_AFE4403=m +CONFIG_AFE4404=m +CONFIG_MAX30100=m +CONFIG_MAX30102=m +# end of Heart Rate Monitors +# end of Health Sensors + +# +# Humidity sensors +# +CONFIG_AM2315=m +CONFIG_DHT11=m +CONFIG_HDC100X=m +CONFIG_HDC2010=m +CONFIG_HID_SENSOR_HUMIDITY=m +CONFIG_HTS221=m +CONFIG_HTS221_I2C=m +CONFIG_HTS221_SPI=m +CONFIG_HTU21=m +CONFIG_SI7005=m +CONFIG_SI7020=m +# end of Humidity sensors + +# +# Inertial measurement units +# +CONFIG_ADIS16400=m +CONFIG_ADIS16460=m +# CONFIG_ADIS16475 is not set +CONFIG_ADIS16480=m +CONFIG_BMI160=m +CONFIG_BMI160_I2C=m +CONFIG_BMI160_SPI=m +# CONFIG_BOSCH_BNO055_SERIAL is not set +# CONFIG_BOSCH_BNO055_I2C is not set +CONFIG_FXOS8700=m +CONFIG_FXOS8700_I2C=m +CONFIG_FXOS8700_SPI=m +# CONFIG_KMX61 is not set +CONFIG_INV_ICM42600=m +CONFIG_INV_ICM42600_I2C=m +CONFIG_INV_ICM42600_SPI=m +CONFIG_INV_MPU6050_IIO=m +CONFIG_INV_MPU6050_I2C=m +CONFIG_INV_MPU6050_SPI=m +# CONFIG_IIO_ST_LSM6DSX is not set +# CONFIG_IIO_ST_LSM9DS0 is not set +# end of Inertial measurement units + +CONFIG_IIO_ADIS_LIB=m +CONFIG_IIO_ADIS_LIB_BUFFER=y + +# +# Light sensors +# +CONFIG_ACPI_ALS=m +CONFIG_ADJD_S311=m +# CONFIG_ADUX1020 is not set +# CONFIG_AL3010 is not set +CONFIG_AL3320A=m +CONFIG_APDS9300=m +CONFIG_APDS9960=m +# CONFIG_AS73211 is not set +CONFIG_BH1750=m +CONFIG_BH1780=m +CONFIG_CM32181=m +# CONFIG_CM3232 is not set +# CONFIG_CM3323 is not set +# CONFIG_CM3605 is not set +CONFIG_CM36651=m +CONFIG_IIO_CROS_EC_LIGHT_PROX=m +# CONFIG_GP2AP002 is not set +CONFIG_GP2AP020A00F=m +CONFIG_IQS621_ALS=m +CONFIG_SENSORS_ISL29018=m +CONFIG_SENSORS_ISL29028=m +CONFIG_ISL29125=m +CONFIG_HID_SENSOR_ALS=m +CONFIG_HID_SENSOR_PROX=m +# CONFIG_JSA1212 is not set +# CONFIG_ROHM_BU27008 is not set +# CONFIG_ROHM_BU27034 is not set +CONFIG_RPR0521=m +CONFIG_LTR501=m +# CONFIG_LTRF216A is not set +# CONFIG_LV0104CS is not set +CONFIG_MAX44000=m +# CONFIG_MAX44009 is not set +# CONFIG_NOA1305 is not set +CONFIG_OPT3001=m +CONFIG_OPT4001=m +CONFIG_PA12203001=m +# CONFIG_SI1133 is not set +# CONFIG_SI1145 is not set +CONFIG_STK3310=m +CONFIG_ST_UVIS25=m +CONFIG_ST_UVIS25_I2C=m +CONFIG_ST_UVIS25_SPI=m +CONFIG_TCS3414=m +CONFIG_TCS3472=m +CONFIG_SENSORS_TSL2563=m +CONFIG_TSL2583=m +# CONFIG_TSL2591 is not set +# CONFIG_TSL2772 is not set +CONFIG_TSL4531=m +CONFIG_US5182D=m +CONFIG_VCNL4000=m +# CONFIG_VCNL4035 is not set +# CONFIG_VEML6030 is not set +CONFIG_VEML6070=m +# CONFIG_VL6180 is not set +# CONFIG_ZOPT2201 is not set +# end of Light sensors + +# +# Magnetometer sensors +# +# CONFIG_AK8974 is not set +CONFIG_AK8975=m +CONFIG_AK09911=m +CONFIG_BMC150_MAGN=m +CONFIG_BMC150_MAGN_I2C=m +CONFIG_BMC150_MAGN_SPI=m +CONFIG_MAG3110=m +CONFIG_HID_SENSOR_MAGNETOMETER_3D=m +CONFIG_MMC35240=m +CONFIG_IIO_ST_MAGN_3AXIS=m +CONFIG_IIO_ST_MAGN_I2C_3AXIS=m +CONFIG_IIO_ST_MAGN_SPI_3AXIS=m +CONFIG_SENSORS_HMC5843=m +CONFIG_SENSORS_HMC5843_I2C=m +CONFIG_SENSORS_HMC5843_SPI=m +# CONFIG_SENSORS_RM3100_I2C is not set +# CONFIG_SENSORS_RM3100_SPI is not set +CONFIG_TI_TMAG5273=m +# CONFIG_YAMAHA_YAS530 is not set +# end of Magnetometer sensors + +# +# Multiplexers +# +CONFIG_IIO_MUX=m +# end of Multiplexers + +# +# Inclinometer sensors +# +CONFIG_HID_SENSOR_INCLINOMETER_3D=m +CONFIG_HID_SENSOR_DEVICE_ROTATION=m +# end of Inclinometer sensors + +# +# Triggers - standalone +# +CONFIG_IIO_HRTIMER_TRIGGER=m +CONFIG_IIO_INTERRUPT_TRIGGER=m +# CONFIG_IIO_TIGHTLOOP_TRIGGER is not set +CONFIG_IIO_SYSFS_TRIGGER=m +# end of Triggers - standalone + +# +# Linear and angular position sensors +# +CONFIG_IQS624_POS=m +CONFIG_HID_SENSOR_CUSTOM_INTEL_HINGE=m +# end of Linear and angular position sensors + +# +# Digital potentiometers +# +CONFIG_AD5110=m +CONFIG_AD5272=m +CONFIG_DS1803=m +CONFIG_MAX5432=m +CONFIG_MAX5481=m +CONFIG_MAX5487=m +CONFIG_MCP4018=m +CONFIG_MCP4131=m +CONFIG_MCP4531=m +CONFIG_MCP41010=m +CONFIG_TPL0102=m +CONFIG_X9250=m +# end of Digital potentiometers + +# +# Digital potentiostats +# +# CONFIG_LMP91000 is not set +# end of Digital potentiostats + +# +# Pressure sensors +# +# CONFIG_ABP060MG is not set +# CONFIG_BMP280 is not set +CONFIG_IIO_CROS_EC_BARO=m +# CONFIG_DLHL60D is not set +# CONFIG_DPS310 is not set +CONFIG_HID_SENSOR_PRESS=m +CONFIG_HP03=m +# CONFIG_ICP10100 is not set +CONFIG_MPL115=m +CONFIG_MPL115_I2C=m +CONFIG_MPL115_SPI=m +# CONFIG_MPL3115 is not set +CONFIG_MPRLS0025PA=m +# CONFIG_MS5611 is not set +CONFIG_MS5637=m +CONFIG_IIO_ST_PRESS=m +CONFIG_IIO_ST_PRESS_I2C=m +CONFIG_IIO_ST_PRESS_SPI=m +CONFIG_T5403=m +CONFIG_HP206C=m +# CONFIG_ZPA2326 is not set +# end of Pressure sensors + +# +# Lightning sensors +# +CONFIG_AS3935=m +# end of Lightning sensors + +# +# Proximity and distance sensors +# +CONFIG_CROS_EC_MKBP_PROXIMITY=m +CONFIG_IRSD200=m +# CONFIG_ISL29501 is not set +CONFIG_LIDAR_LITE_V2=m +# CONFIG_MB1232 is not set +# CONFIG_PING is not set +# CONFIG_RFD77402 is not set +# CONFIG_SRF04 is not set +# CONFIG_SX9310 is not set +# CONFIG_SX9324 is not set +# CONFIG_SX9360 is not set +# CONFIG_SX9500 is not set +# CONFIG_SRF08 is not set +# CONFIG_VCNL3020 is not set +# CONFIG_VL53L0X_I2C is not set +# end of Proximity and distance sensors + +# +# Resolver to digital converters +# +CONFIG_AD2S90=m +CONFIG_AD2S1200=m +# end of Resolver to digital converters + +# +# Temperature sensors +# +CONFIG_IQS620AT_TEMP=m +# CONFIG_LTC2983 is not set +# CONFIG_MAXIM_THERMOCOUPLE is not set +CONFIG_HID_SENSOR_TEMP=m +CONFIG_MLX90614=m +CONFIG_MLX90632=m +CONFIG_TMP006=m +# CONFIG_TMP007 is not set +# CONFIG_TMP117 is not set +CONFIG_TSYS01=m +CONFIG_TSYS02D=m +CONFIG_MAX30208=m +# CONFIG_MAX31856 is not set +# CONFIG_MAX31865 is not set +# end of Temperature sensors + +CONFIG_NTB=m +# CONFIG_NTB_MSI is not set +CONFIG_NTB_AMD=m +CONFIG_NTB_IDT=m +CONFIG_NTB_INTEL=m +CONFIG_NTB_EPF=m +# CONFIG_NTB_SWITCHTEC is not set +CONFIG_NTB_PINGPONG=m +CONFIG_NTB_TOOL=m +CONFIG_NTB_PERF=m +CONFIG_NTB_TRANSPORT=m +CONFIG_PWM=y +CONFIG_PWM_SYSFS=y +# CONFIG_PWM_DEBUG is not set +CONFIG_PWM_CLK=y +CONFIG_PWM_CRC=y +CONFIG_PWM_CROS_EC=m +CONFIG_PWM_DWC=m +CONFIG_PWM_IQS620A=m +CONFIG_PWM_LP3943=m +CONFIG_PWM_LPSS=m +CONFIG_PWM_LPSS_PCI=m +CONFIG_PWM_LPSS_PLATFORM=m +CONFIG_PWM_PCA9685=m +CONFIG_PWM_TWL=m +CONFIG_PWM_TWL_LED=m + +# +# IRQ chip support +# +CONFIG_MADERA_IRQ=m +# end of IRQ chip support + +# CONFIG_IPACK_BUS is not set +CONFIG_RESET_CONTROLLER=y +# CONFIG_RESET_SIMPLE is not set +CONFIG_RESET_TI_SYSCON=m +# CONFIG_RESET_TI_TPS380X is not set + +# +# PHY Subsystem +# +CONFIG_GENERIC_PHY=y +CONFIG_GENERIC_PHY_MIPI_DPHY=y +CONFIG_USB_LGM_PHY=m +CONFIG_PHY_CAN_TRANSCEIVER=m + +# +# PHY drivers for Broadcom platforms +# +CONFIG_BCM_KONA_USB2_PHY=m +# end of PHY drivers for Broadcom platforms + +CONFIG_PHY_PXA_28NM_HSIC=m +CONFIG_PHY_PXA_28NM_USB2=m +CONFIG_PHY_CPCAP_USB=m +CONFIG_PHY_QCOM_USB_HS=m +CONFIG_PHY_QCOM_USB_HSIC=m +CONFIG_PHY_SAMSUNG_USB2=m +CONFIG_PHY_TUSB1210=m +CONFIG_PHY_INTEL_LGM_EMMC=m +# end of PHY Subsystem + +CONFIG_POWERCAP=y +CONFIG_INTEL_RAPL_CORE=m +CONFIG_INTEL_RAPL=m +CONFIG_INTEL_RAPL_TPMI=m +CONFIG_IDLE_INJECT=y +# CONFIG_MCB is not set + +# +# Performance monitor support +# +# end of Performance monitor support + +CONFIG_RAS=y +# CONFIG_RAS_CEC is not set +CONFIG_USB4=m +# CONFIG_USB4_DEBUGFS_WRITE is not set +# CONFIG_USB4_DMA_TEST is not set + +# +# Android +# +CONFIG_ANDROID_BINDER_IPC=y +CONFIG_ANDROID_BINDERFS=y +CONFIG_ANDROID_BINDER_DEVICES="binder,hwbinder,vndbinder" +# CONFIG_ANDROID_BINDER_IPC_SELFTEST is not set +# end of Android + +CONFIG_LIBNVDIMM=m +CONFIG_BLK_DEV_PMEM=m +CONFIG_ND_CLAIM=y +CONFIG_ND_BTT=m +CONFIG_BTT=y +CONFIG_ND_PFN=m +CONFIG_NVDIMM_PFN=y +CONFIG_NVDIMM_DAX=y +CONFIG_NVDIMM_KEYS=y +# CONFIG_NVDIMM_SECURITY_TEST is not set +CONFIG_DAX=y +CONFIG_DEV_DAX=m +CONFIG_DEV_DAX_PMEM=m +CONFIG_DEV_DAX_HMEM=m +CONFIG_DEV_DAX_HMEM_DEVICES=y +CONFIG_DEV_DAX_KMEM=m +CONFIG_NVMEM=y +CONFIG_NVMEM_SYSFS=y + +# +# Layout Types +# +# CONFIG_NVMEM_LAYOUT_SL28_VPD is not set +# CONFIG_NVMEM_LAYOUT_ONIE_TLV is not set +# end of Layout Types + +# CONFIG_NVMEM_RMEM is not set +CONFIG_NVMEM_SPMI_SDAM=m + +# +# HW tracing support +# +CONFIG_STM=m +CONFIG_STM_PROTO_BASIC=m +CONFIG_STM_PROTO_SYS_T=m +CONFIG_STM_DUMMY=m +CONFIG_STM_SOURCE_CONSOLE=m +CONFIG_STM_SOURCE_HEARTBEAT=m +# CONFIG_STM_SOURCE_FTRACE is not set +CONFIG_INTEL_TH=m +CONFIG_INTEL_TH_PCI=m +CONFIG_INTEL_TH_ACPI=m +CONFIG_INTEL_TH_GTH=m +CONFIG_INTEL_TH_STH=m +CONFIG_INTEL_TH_MSU=m +CONFIG_INTEL_TH_PTI=m +# CONFIG_INTEL_TH_DEBUG is not set +# end of HW tracing support + +CONFIG_FPGA=m +# CONFIG_ALTERA_PR_IP_CORE is not set +# CONFIG_FPGA_MGR_ALTERA_PS_SPI is not set +# CONFIG_FPGA_MGR_ALTERA_CVP is not set +# CONFIG_FPGA_MGR_XILINX_SPI is not set +# CONFIG_FPGA_MGR_MACHXO2_SPI is not set +# CONFIG_FPGA_BRIDGE is not set +# CONFIG_FPGA_DFL is not set +CONFIG_FPGA_M10_BMC_SEC_UPDATE=m +# CONFIG_FPGA_MGR_MICROCHIP_SPI is not set +# CONFIG_FPGA_MGR_LATTICE_SYSCONFIG_SPI is not set +CONFIG_TEE=m +CONFIG_AMDTEE=m +CONFIG_MULTIPLEXER=m + +# +# Multiplexer drivers +# +CONFIG_MUX_ADG792A=m +CONFIG_MUX_ADGS1408=m +CONFIG_MUX_GPIO=m +# end of Multiplexer drivers + +CONFIG_PM_OPP=y +# CONFIG_SIOX is not set +# CONFIG_SLIMBUS is not set +# CONFIG_INTERCONNECT is not set +CONFIG_COUNTER=y +CONFIG_INTEL_QEP=m +CONFIG_INTERRUPT_CNT=m +CONFIG_MOST=m +CONFIG_MOST_USB_HDM=m +CONFIG_MOST_CDEV=m +CONFIG_MOST_SND=m +CONFIG_PECI=m +CONFIG_PECI_CPU=m +CONFIG_HTE=y +# end of Device Drivers + +# +# File systems +# +CONFIG_DCACHE_WORD_ACCESS=y +# CONFIG_VALIDATE_FS_PARSER is not set +CONFIG_FS_IOMAP=y +CONFIG_BUFFER_HEAD=y +CONFIG_LEGACY_DIRECT_IO=y +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT3_FS=m +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +# CONFIG_EXT4_DEBUG is not set +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_PROC_INFO=y +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +# CONFIG_JFS_DEBUG is not set +CONFIG_JFS_STATISTICS=y +CONFIG_XFS_FS=m +CONFIG_XFS_SUPPORT_V4=y +CONFIG_XFS_SUPPORT_ASCII_CI=y +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_RT=y +# CONFIG_XFS_ONLINE_SCRUB is not set +# CONFIG_XFS_WARN is not set +# CONFIG_XFS_DEBUG is not set +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_DLM=y +CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m +CONFIG_OCFS2_FS_STATS=y +CONFIG_OCFS2_DEBUG_MASKLOG=y +# CONFIG_OCFS2_DEBUG_FS is not set +CONFIG_BTRFS_FS=y +CONFIG_BTRFS_FS_POSIX_ACL=y +# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set +# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set +# CONFIG_BTRFS_DEBUG is not set +# CONFIG_BTRFS_ASSERT is not set +# CONFIG_BTRFS_FS_REF_VERIFY 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=y +# CONFIG_F2FS_CHECK_FS is not set +# CONFIG_F2FS_FAULT_INJECTION is not set +CONFIG_F2FS_FS_COMPRESSION=y +CONFIG_F2FS_FS_LZO=y +CONFIG_F2FS_FS_LZORLE=y +CONFIG_F2FS_FS_LZ4=y +CONFIG_F2FS_FS_LZ4HC=y +CONFIG_F2FS_FS_ZSTD=y +# CONFIG_F2FS_IOSTAT is not set +# CONFIG_F2FS_UNFAIR_RWSEM is not set +CONFIG_ZONEFS_FS=m +CONFIG_FS_DAX=y +CONFIG_FS_DAX_PMD=y +CONFIG_FS_POSIX_ACL=y +CONFIG_EXPORTFS=y +CONFIG_EXPORTFS_BLOCK_OPS=y +CONFIG_FILE_LOCKING=y +CONFIG_FS_ENCRYPTION=y +CONFIG_FS_ENCRYPTION_ALGS=y +CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y +# CONFIG_FS_VERITY is not set +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_FANOTIFY=y +CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y +CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +# CONFIG_QUOTA_DEBUG is not set +CONFIG_QUOTA_TREE=y +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=y +CONFIG_QUOTACTL=y +CONFIG_AUTOFS_FS=y +CONFIG_FUSE_FS=m +CONFIG_CUSE=m +CONFIG_VIRTIO_FS=m +CONFIG_FUSE_DAX=y +CONFIG_OVERLAY_FS=m +# CONFIG_OVERLAY_FS_REDIRECT_DIR is not set +CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y +# CONFIG_OVERLAY_FS_INDEX is not set +# CONFIG_OVERLAY_FS_XINO_AUTO is not set +# CONFIG_OVERLAY_FS_METACOPY is not set +# CONFIG_OVERLAY_FS_DEBUG is not set + +# +# Caches +# +CONFIG_NETFS_SUPPORT=y +CONFIG_NETFS_STATS=y +CONFIG_FSCACHE=y +CONFIG_FSCACHE_STATS=y +CONFIG_FSCACHE_DEBUG=y +CONFIG_CACHEFILES=m +CONFIG_CACHEFILES_DEBUG=y +# CONFIG_CACHEFILES_ERROR_INJECTION is not set +# CONFIG_CACHEFILES_ONDEMAND is not set +# end of Caches + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +# end of CD-ROM/DVD Filesystems + +# +# DOS/FAT/EXFAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +CONFIG_FAT_DEFAULT_UTF8=y +CONFIG_EXFAT_FS=m +CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8" +CONFIG_NTFS_FS=m +# CONFIG_NTFS_DEBUG is not set +# CONFIG_NTFS_RW is not set +CONFIG_NTFS3_FS=m +# CONFIG_NTFS3_64BIT_CLUSTER is not set +CONFIG_NTFS3_LZX_XPRESS=y +# CONFIG_NTFS3_FS_POSIX_ACL is not set +# end of DOS/FAT/EXFAT/NT Filesystems + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_VMCORE=y +# CONFIG_PROC_VMCORE_DEVICE_DUMP is not set +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_PROC_CHILDREN=y +CONFIG_PROC_PID_ARCH_STATUS=y +CONFIG_PROC_CPU_RESCTRL=y +CONFIG_KERNFS=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMPFS_XATTR=y +CONFIG_TMPFS_INODE64=y +# CONFIG_TMPFS_QUOTA is not set +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP=y +# CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP_DEFAULT_ON is not set +CONFIG_ARCH_HAS_GIGANTIC_PAGE=y +CONFIG_CONFIGFS_FS=y +CONFIG_EFIVAR_FS=y +# end of Pseudo filesystems + +CONFIG_MISC_FILESYSTEMS=y +CONFIG_ORANGEFS_FS=m +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_AFFS_FS=m +CONFIG_ECRYPT_FS=m +# CONFIG_ECRYPT_FS_MESSAGING is not set +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +CONFIG_BEFS_FS=m +# CONFIG_BEFS_DEBUG is not set +CONFIG_BFS_FS=m +CONFIG_EFS_FS=m +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_SUMMARY=y +CONFIG_JFFS2_FS_XATTR=y +CONFIG_JFFS2_FS_POSIX_ACL=y +CONFIG_JFFS2_FS_SECURITY=y +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +CONFIG_UBIFS_FS=m +# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_ZLIB=y +CONFIG_UBIFS_FS_ZSTD=y +# CONFIG_UBIFS_ATIME_SUPPORT is not set +CONFIG_UBIFS_FS_XATTR=y +CONFIG_UBIFS_FS_SECURITY=y +CONFIG_UBIFS_FS_AUTHENTICATION=y +CONFIG_CRAMFS=y +CONFIG_CRAMFS_BLOCKDEV=y +CONFIG_SQUASHFS=m +# CONFIG_SQUASHFS_FILE_CACHE is not set +CONFIG_SQUASHFS_FILE_DIRECT=y +CONFIG_SQUASHFS_DECOMP_MULTI=y +# CONFIG_SQUASHFS_CHOICE_DECOMP_BY_MOUNT is not set +# CONFIG_SQUASHFS_COMPILE_DECOMP_SINGLE is not set +CONFIG_SQUASHFS_COMPILE_DECOMP_MULTI=y +# CONFIG_SQUASHFS_COMPILE_DECOMP_MULTI_PERCPU is not set +CONFIG_SQUASHFS_MOUNT_DECOMP_THREADS=y +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_ZLIB=y +CONFIG_SQUASHFS_LZ4=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_SQUASHFS_ZSTD=y +# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +CONFIG_VXFS_FS=m +CONFIG_MINIX_FS=m +CONFIG_OMFS_FS=m +CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +CONFIG_QNX6FS_FS=m +# CONFIG_QNX6FS_DEBUG is not set +CONFIG_ROMFS_FS=m +# CONFIG_ROMFS_BACKED_BY_BLOCK is not set +# CONFIG_ROMFS_BACKED_BY_MTD is not set +CONFIG_ROMFS_BACKED_BY_BOTH=y +CONFIG_ROMFS_ON_BLOCK=y +CONFIG_ROMFS_ON_MTD=y +CONFIG_PSTORE=y +CONFIG_PSTORE_DEFAULT_KMSG_BYTES=10240 +CONFIG_PSTORE_COMPRESS=y +# CONFIG_PSTORE_CONSOLE is not set +# CONFIG_PSTORE_PMSG is not set +# CONFIG_PSTORE_FTRACE is not set +CONFIG_PSTORE_RAM=m +CONFIG_PSTORE_ZONE=m +CONFIG_PSTORE_BLK=m +CONFIG_PSTORE_BLK_BLKDEV="" +CONFIG_PSTORE_BLK_KMSG_SIZE=64 +CONFIG_PSTORE_BLK_MAX_REASON=2 +CONFIG_SYSV_FS=m +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_UFS_DEBUG is not set +CONFIG_EROFS_FS=m +# CONFIG_EROFS_FS_DEBUG is not set +CONFIG_EROFS_FS_XATTR=y +CONFIG_EROFS_FS_POSIX_ACL=y +CONFIG_EROFS_FS_SECURITY=y +CONFIG_EROFS_FS_ZIP=y +CONFIG_EROFS_FS_ZIP_LZMA=y +CONFIG_EROFS_FS_ZIP_DEFLATE=y +CONFIG_EROFS_FS_PCPU_KTHREAD=y +# CONFIG_EROFS_FS_PCPU_KTHREAD_HIPRI is not set +CONFIG_VBOXSF_FS=m +CONFIG_AUFS_FS=y +CONFIG_AUFS_BRANCH_MAX_127=y +# CONFIG_AUFS_BRANCH_MAX_511 is not set +# CONFIG_AUFS_BRANCH_MAX_1023 is not set +# CONFIG_AUFS_BRANCH_MAX_32767 is not set +CONFIG_AUFS_SBILIST=y +CONFIG_AUFS_HNOTIFY=y +CONFIG_AUFS_HFSNOTIFY=y +CONFIG_AUFS_EXPORT=y +CONFIG_AUFS_INO_T_64=y +CONFIG_AUFS_XATTR=y +CONFIG_AUFS_FHSM=y +CONFIG_AUFS_RDU=y +# CONFIG_AUFS_DIRREN is not set +CONFIG_AUFS_SHWH=y +CONFIG_AUFS_BR_RAMFS=y +CONFIG_AUFS_BR_FUSE=y +CONFIG_AUFS_POLL=y +CONFIG_AUFS_BR_HFSPLUS=y +CONFIG_AUFS_BDEV_LOOP=y +CONFIG_AUFS_DEBUG=y +CONFIG_AUFS_MAGIC_SYSRQ=y +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=m +CONFIG_NFS_V2=m +CONFIG_NFS_V3=m +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=m +CONFIG_NFS_SWAP=y +CONFIG_NFS_V4_1=y +CONFIG_NFS_V4_2=y +CONFIG_PNFS_FILE_LAYOUT=m +CONFIG_PNFS_BLOCK=m +CONFIG_PNFS_FLEXFILE_LAYOUT=m +CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org" +# CONFIG_NFS_V4_1_MIGRATION is not set +CONFIG_NFS_V4_SECURITY_LABEL=y +CONFIG_NFS_FSCACHE=y +# CONFIG_NFS_USE_LEGACY_DNS is not set +CONFIG_NFS_USE_KERNEL_DNS=y +CONFIG_NFS_DEBUG=y +CONFIG_NFS_DISABLE_UDP_SUPPORT=y +# CONFIG_NFS_V4_2_READ_PLUS is not set +CONFIG_NFSD=m +# CONFIG_NFSD_V2 is not set +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFSD_PNFS=y +CONFIG_NFSD_BLOCKLAYOUT=y +CONFIG_NFSD_SCSILAYOUT=y +CONFIG_NFSD_FLEXFILELAYOUT=y +CONFIG_NFSD_V4_2_INTER_SSC=y +# CONFIG_NFSD_V4_SECURITY_LABEL is not set +CONFIG_GRACE_PERIOD=m +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_COMMON=y +CONFIG_NFS_V4_2_SSC_HELPER=y +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +CONFIG_SUNRPC_BACKCHANNEL=y +CONFIG_SUNRPC_SWAP=y +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA1=y +# CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_CAMELLIA is not set +CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA2=y +CONFIG_SUNRPC_DEBUG=y +CONFIG_SUNRPC_XPRT_RDMA=m +CONFIG_CEPH_FS=m +CONFIG_CEPH_FSCACHE=y +CONFIG_CEPH_FS_POSIX_ACL=y +CONFIG_CEPH_FS_SECURITY_LABEL=y +CONFIG_CIFS=m +CONFIG_CIFS_STATS2=y +CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +CONFIG_CIFS_DEBUG=y +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_DEBUG_DUMP_KEYS is not set +CONFIG_CIFS_DFS_UPCALL=y +CONFIG_CIFS_SWN_UPCALL=y +# CONFIG_CIFS_SMB_DIRECT is not set +CONFIG_CIFS_FSCACHE=y +CONFIG_SMB_SERVER=m +CONFIG_SMB_SERVER_SMBDIRECT=y +CONFIG_SMB_SERVER_CHECK_CAP_NET_ADMIN=y +CONFIG_SMB_SERVER_KERBEROS5=y +CONFIG_SMBFS=m +CONFIG_CODA_FS=m +CONFIG_AFS_FS=m +# CONFIG_AFS_DEBUG is not set +CONFIG_AFS_FSCACHE=y +# CONFIG_AFS_DEBUG_CURSOR is not set +CONFIG_9P_FS=m +CONFIG_9P_FSCACHE=y +CONFIG_9P_FS_POSIX_ACL=y +# CONFIG_9P_FS_SECURITY is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_MAC_ROMAN=m +CONFIG_NLS_MAC_CELTIC=m +CONFIG_NLS_MAC_CENTEURO=m +CONFIG_NLS_MAC_CROATIAN=m +CONFIG_NLS_MAC_CYRILLIC=m +CONFIG_NLS_MAC_GAELIC=m +CONFIG_NLS_MAC_GREEK=m +CONFIG_NLS_MAC_ICELAND=m +CONFIG_NLS_MAC_INUIT=m +CONFIG_NLS_MAC_ROMANIAN=m +CONFIG_NLS_MAC_TURKISH=m +CONFIG_NLS_UTF8=m +CONFIG_NLS_UCS2_UTILS=m +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set +# CONFIG_UNICODE is not set +CONFIG_IO_WQ=y +# end of File systems + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_KEYS_REQUEST_CACHE is not set +# CONFIG_PERSISTENT_KEYRINGS is not set +CONFIG_TRUSTED_KEYS=m +CONFIG_TRUSTED_KEYS_TPM=y +CONFIG_TRUSTED_KEYS_TEE=y +CONFIG_ENCRYPTED_KEYS=y +# CONFIG_USER_DECRYPTED_DATA is not set +CONFIG_KEY_DH_OPERATIONS=y +# CONFIG_KEY_NOTIFICATIONS is not set +# CONFIG_SECURITY_DMESG_RESTRICT is not set +CONFIG_PROC_MEM_ALWAYS_FORCE=y +# CONFIG_PROC_MEM_FORCE_PTRACE is not set +# CONFIG_PROC_MEM_NO_FORCE is not set +CONFIG_SECURITY=y +CONFIG_SECURITYFS=y +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_INFINIBAND is not set +CONFIG_SECURITY_NETWORK_XFRM=y +CONFIG_SECURITY_PATH=y +CONFIG_INTEL_TXT=y +CONFIG_HARDENED_USERCOPY=y +CONFIG_FORTIFY_SOURCE=y +# CONFIG_STATIC_USERMODEHELPER is not set +# CONFIG_SECURITY_SELINUX is not set +# CONFIG_SECURITY_SMACK is not set +# CONFIG_SECURITY_TOMOYO is not set +CONFIG_SECURITY_APPARMOR=y +# CONFIG_SECURITY_APPARMOR_DEBUG is not set +CONFIG_SECURITY_APPARMOR_INTROSPECT_POLICY=y +CONFIG_SECURITY_APPARMOR_HASH=y +CONFIG_SECURITY_APPARMOR_HASH_DEFAULT=y +CONFIG_SECURITY_APPARMOR_EXPORT_BINARY=y +CONFIG_SECURITY_APPARMOR_PARANOID_LOAD=y +# CONFIG_SECURITY_LOADPIN is not set +# CONFIG_SECURITY_YAMA is not set +# CONFIG_SECURITY_SAFESETID is not set +# CONFIG_SECURITY_LOCKDOWN_LSM is not set +CONFIG_SECURITY_LANDLOCK=y +CONFIG_INTEGRITY=y +# CONFIG_INTEGRITY_SIGNATURE is not set +CONFIG_INTEGRITY_AUDIT=y +# CONFIG_IMA is not set +# CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT is not set +# CONFIG_EVM is not set +CONFIG_DEFAULT_SECURITY_APPARMOR=y +# CONFIG_DEFAULT_SECURITY_DAC is not set +CONFIG_LSM="" + +# +# Kernel hardening options +# + +# +# Memory initialization +# +CONFIG_CC_HAS_AUTO_VAR_INIT_PATTERN=y +CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO_BARE=y +CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO=y +CONFIG_INIT_STACK_NONE=y +# CONFIG_INIT_STACK_ALL_PATTERN is not set +# CONFIG_INIT_STACK_ALL_ZERO is not set +# CONFIG_GCC_PLUGIN_STACKLEAK is not set +# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set +# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set +CONFIG_CC_HAS_ZERO_CALL_USED_REGS=y +# CONFIG_ZERO_CALL_USED_REGS is not set +# end of Memory initialization + +# +# Hardening of kernel data structures +# +# CONFIG_LIST_HARDENED is not set +# CONFIG_BUG_ON_DATA_CORRUPTION is not set +# end of Hardening of kernel data structures + +CONFIG_RANDSTRUCT_NONE=y +# CONFIG_RANDSTRUCT_FULL is not set +# CONFIG_RANDSTRUCT_PERFORMANCE is not set +# end of Kernel hardening options +# end of Security options + +CONFIG_XOR_BLOCKS=y +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_ASYNC_PQ=m +CONFIG_ASYNC_RAID6_RECOV=m +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_SIG=y +CONFIG_CRYPTO_SIG2=y +CONFIG_CRYPTO_SKCIPHER=y +CONFIG_CRYPTO_SKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=y +CONFIG_CRYPTO_AKCIPHER2=y +CONFIG_CRYPTO_AKCIPHER=y +CONFIG_CRYPTO_KPP2=y +CONFIG_CRYPTO_KPP=y +CONFIG_CRYPTO_ACOMP2=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_USER=m +CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_NULL2=y +CONFIG_CRYPTO_PCRYPT=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_SIMD=m +CONFIG_CRYPTO_ENGINE=m +# end of Crypto core or helper + +# +# Public-key cryptography +# +CONFIG_CRYPTO_RSA=y +CONFIG_CRYPTO_DH=y +CONFIG_CRYPTO_DH_RFC7919_GROUPS=y +CONFIG_CRYPTO_ECC=m +CONFIG_CRYPTO_ECDH=m +CONFIG_CRYPTO_ECDSA=m +CONFIG_CRYPTO_ECRDSA=m +CONFIG_CRYPTO_SM2=m +CONFIG_CRYPTO_CURVE25519=m +# end of Public-key cryptography + +# +# Block ciphers +# +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_AES_TI=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARIA=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_BLOWFISH_COMMON=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST_COMMON=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_SM4=m +CONFIG_CRYPTO_SM4_GENERIC=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +# end of Block ciphers + +# +# Length-preserving ciphers and modes +# +CONFIG_CRYPTO_ADIANTUM=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_CHACHA20=m +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CFB=m +CONFIG_CRYPTO_CTR=y +CONFIG_CRYPTO_CTS=y +CONFIG_CRYPTO_ECB=y +CONFIG_CRYPTO_HCTR2=m +CONFIG_CRYPTO_KEYWRAP=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_OFB=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XCTR=m +CONFIG_CRYPTO_XTS=y +CONFIG_CRYPTO_NHPOLY1305=m +# end of Length-preserving ciphers and modes + +# +# AEAD (authenticated encryption with associated data) ciphers +# +CONFIG_CRYPTO_AEGIS128=m +CONFIG_CRYPTO_CHACHA20POLY1305=m +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_GENIV=y +CONFIG_CRYPTO_SEQIV=y +CONFIG_CRYPTO_ECHAINIV=m +CONFIG_CRYPTO_ESSIV=m +# end of AEAD (authenticated encryption with associated data) ciphers + +# +# Hashes, digests, and MACs +# +CONFIG_CRYPTO_BLAKE2B=y +CONFIG_CRYPTO_CMAC=m +CONFIG_CRYPTO_GHASH=m +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_POLYVAL=m +CONFIG_CRYPTO_POLY1305=m +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_SHA3=y +CONFIG_CRYPTO_SM3=m +CONFIG_CRYPTO_SM3_GENERIC=m +CONFIG_CRYPTO_STREEBOG=m +CONFIG_CRYPTO_VMAC=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_XXHASH=y +# end of Hashes, digests, and MACs + +# +# CRCs (cyclic redundancy checks) +# +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_CRC32=m +CONFIG_CRYPTO_CRCT10DIF=y +CONFIG_CRYPTO_CRC64_ROCKSOFT=y +# end of CRCs (cyclic redundancy checks) + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_LZO=y +CONFIG_CRYPTO_842=y +CONFIG_CRYPTO_LZ4=y +CONFIG_CRYPTO_LZ4HC=m +CONFIG_CRYPTO_ZSTD=y +# end of Compression + +# +# Random number generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_DRBG_HMAC=y +CONFIG_CRYPTO_DRBG_HASH=y +CONFIG_CRYPTO_DRBG_CTR=y +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_JITTERENTROPY=y +# CONFIG_CRYPTO_JITTERENTROPY_TESTINTERFACE is not set +CONFIG_CRYPTO_KDF800108_CTR=y +# end of Random number generation + +# +# Userspace interface +# +CONFIG_CRYPTO_USER_API=m +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m +CONFIG_CRYPTO_USER_API_RNG=m +# CONFIG_CRYPTO_USER_API_RNG_CAVP is not set +CONFIG_CRYPTO_USER_API_AEAD=m +CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE=y +# CONFIG_CRYPTO_STATS is not set +# end of Userspace interface + +CONFIG_CRYPTO_HASH_INFO=y + +# +# Accelerated Cryptographic Algorithms for CPU (x86) +# +CONFIG_CRYPTO_CURVE25519_X86=m +CONFIG_CRYPTO_AES_NI_INTEL=m +CONFIG_CRYPTO_BLOWFISH_X86_64=m +CONFIG_CRYPTO_CAMELLIA_X86_64=m +CONFIG_CRYPTO_CAMELLIA_AESNI_AVX_X86_64=m +CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64=m +CONFIG_CRYPTO_CAST5_AVX_X86_64=m +CONFIG_CRYPTO_CAST6_AVX_X86_64=m +CONFIG_CRYPTO_DES3_EDE_X86_64=m +CONFIG_CRYPTO_SERPENT_SSE2_X86_64=m +CONFIG_CRYPTO_SERPENT_AVX_X86_64=m +CONFIG_CRYPTO_SERPENT_AVX2_X86_64=m +CONFIG_CRYPTO_SM4_AESNI_AVX_X86_64=m +CONFIG_CRYPTO_SM4_AESNI_AVX2_X86_64=m +CONFIG_CRYPTO_TWOFISH_X86_64=m +CONFIG_CRYPTO_TWOFISH_X86_64_3WAY=m +CONFIG_CRYPTO_TWOFISH_AVX_X86_64=m +CONFIG_CRYPTO_ARIA_AESNI_AVX_X86_64=m +CONFIG_CRYPTO_ARIA_AESNI_AVX2_X86_64=m +CONFIG_CRYPTO_ARIA_GFNI_AVX512_X86_64=m +CONFIG_CRYPTO_CHACHA20_X86_64=m +CONFIG_CRYPTO_AEGIS128_AESNI_SSE2=m +CONFIG_CRYPTO_NHPOLY1305_SSE2=m +CONFIG_CRYPTO_NHPOLY1305_AVX2=m +CONFIG_CRYPTO_BLAKE2S_X86=y +CONFIG_CRYPTO_POLYVAL_CLMUL_NI=m +CONFIG_CRYPTO_POLY1305_X86_64=m +CONFIG_CRYPTO_SHA1_SSSE3=m +CONFIG_CRYPTO_SHA256_SSSE3=m +CONFIG_CRYPTO_SHA512_SSSE3=m +CONFIG_CRYPTO_SM3_AVX_X86_64=m +CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL=m +CONFIG_CRYPTO_CRC32C_INTEL=m +CONFIG_CRYPTO_CRC32_PCLMUL=m +CONFIG_CRYPTO_CRCT10DIF_PCLMUL=y +# end of Accelerated Cryptographic Algorithms for CPU (x86) + +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_DEV_PADLOCK=m +CONFIG_CRYPTO_DEV_PADLOCK_AES=m +CONFIG_CRYPTO_DEV_PADLOCK_SHA=m +CONFIG_CRYPTO_DEV_ATMEL_I2C=m +CONFIG_CRYPTO_DEV_ATMEL_ECC=m +CONFIG_CRYPTO_DEV_ATMEL_SHA204A=m +CONFIG_CRYPTO_DEV_CCP=y +CONFIG_CRYPTO_DEV_CCP_DD=m +CONFIG_CRYPTO_DEV_SP_CCP=y +CONFIG_CRYPTO_DEV_CCP_CRYPTO=m +CONFIG_CRYPTO_DEV_SP_PSP=y +# CONFIG_CRYPTO_DEV_CCP_DEBUGFS is not set +CONFIG_CRYPTO_DEV_NITROX=m +CONFIG_CRYPTO_DEV_NITROX_CNN55XX=m +CONFIG_CRYPTO_DEV_QAT=m +CONFIG_CRYPTO_DEV_QAT_DH895xCC=m +CONFIG_CRYPTO_DEV_QAT_C3XXX=m +CONFIG_CRYPTO_DEV_QAT_C62X=m +CONFIG_CRYPTO_DEV_QAT_4XXX=m +CONFIG_CRYPTO_DEV_QAT_DH895xCCVF=m +CONFIG_CRYPTO_DEV_QAT_C3XXXVF=m +CONFIG_CRYPTO_DEV_QAT_C62XVF=m +CONFIG_CRYPTO_DEV_CHELSIO=m +CONFIG_CRYPTO_DEV_VIRTIO=m +CONFIG_CRYPTO_DEV_SAFEXCEL=m +CONFIG_CRYPTO_DEV_AMLOGIC_GXL=m +# CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG is not set +CONFIG_ASYMMETRIC_KEY_TYPE=y +CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y +CONFIG_X509_CERTIFICATE_PARSER=y +CONFIG_PKCS8_PRIVATE_KEY_PARSER=m +CONFIG_PKCS7_MESSAGE_PARSER=y +# CONFIG_PKCS7_TEST_KEY is not set +CONFIG_SIGNED_PE_FILE_VERIFICATION=y +# CONFIG_FIPS_SIGNATURE_SELFTEST is not set + +# +# Certificates for signature checking +# +CONFIG_SYSTEM_TRUSTED_KEYRING=y +CONFIG_SYSTEM_TRUSTED_KEYS="" +# CONFIG_SYSTEM_EXTRA_CERTIFICATE is not set +# CONFIG_SECONDARY_TRUSTED_KEYRING is not set +# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set +# end of Certificates for signature checking + +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_RAID6_PQ=y +CONFIG_RAID6_PQ_BENCHMARK=y +CONFIG_LINEAR_RANGES=y +CONFIG_PACKING=y +CONFIG_BITREVERSE=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_NET_UTILS=y +CONFIG_CORDIC=m +# CONFIG_PRIME_NUMBERS is not set +CONFIG_RATIONAL=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_IOMAP=y +CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y +CONFIG_ARCH_HAS_FAST_MULTIPLIER=y +CONFIG_ARCH_USE_SYM_ANNOTATIONS=y + +# +# Crypto library routines +# +CONFIG_CRYPTO_LIB_UTILS=y +CONFIG_CRYPTO_LIB_AES=y +CONFIG_CRYPTO_LIB_ARC4=m +CONFIG_CRYPTO_LIB_GF128MUL=m +CONFIG_CRYPTO_ARCH_HAVE_LIB_BLAKE2S=y +CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y +CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=m +CONFIG_CRYPTO_LIB_CHACHA_GENERIC=m +CONFIG_CRYPTO_LIB_CHACHA=m +CONFIG_CRYPTO_ARCH_HAVE_LIB_CURVE25519=m +CONFIG_CRYPTO_LIB_CURVE25519_GENERIC=m +CONFIG_CRYPTO_LIB_CURVE25519=m +CONFIG_CRYPTO_LIB_DES=m +CONFIG_CRYPTO_LIB_POLY1305_RSIZE=11 +CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305=m +CONFIG_CRYPTO_LIB_POLY1305_GENERIC=m +CONFIG_CRYPTO_LIB_POLY1305=m +CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m +CONFIG_CRYPTO_LIB_SHA1=y +CONFIG_CRYPTO_LIB_SHA256=y +# end of Crypto library routines + +CONFIG_CRC_CCITT=m +CONFIG_CRC16=y +CONFIG_CRC_T10DIF=y +CONFIG_CRC64_ROCKSOFT=y +CONFIG_CRC_ITU_T=m +CONFIG_CRC32=y +# CONFIG_CRC32_SELFTEST is not set +CONFIG_CRC32_SLICEBY8=y +# CONFIG_CRC32_SLICEBY4 is not set +# CONFIG_CRC32_SARWATE is not set +# CONFIG_CRC32_BIT is not set +CONFIG_CRC64=y +CONFIG_CRC4=m +CONFIG_CRC7=m +CONFIG_LIBCRC32C=y +CONFIG_CRC8=y +CONFIG_XXHASH=y +# CONFIG_RANDOM32_SELFTEST is not set +CONFIG_842_COMPRESS=y +CONFIG_842_DECOMPRESS=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_LZ4_COMPRESS=y +CONFIG_LZ4HC_COMPRESS=m +CONFIG_LZ4_DECOMPRESS=y +CONFIG_ZSTD_COMMON=y +CONFIG_ZSTD_COMPRESS=y +CONFIG_ZSTD_DECOMPRESS=y +CONFIG_XZ_DEC=y +CONFIG_XZ_DEC_X86=y +# CONFIG_XZ_DEC_POWERPC is not set +# CONFIG_XZ_DEC_IA64 is not set +# CONFIG_XZ_DEC_ARM is not set +# CONFIG_XZ_DEC_ARMTHUMB is not set +# CONFIG_XZ_DEC_SPARC is not set +CONFIG_XZ_DEC_MICROLZMA=y +CONFIG_XZ_DEC_BCJ=y +# CONFIG_XZ_DEC_TEST is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_DECOMPRESS_BZIP2=y +CONFIG_DECOMPRESS_LZMA=y +CONFIG_DECOMPRESS_XZ=y +CONFIG_DECOMPRESS_LZO=y +CONFIG_DECOMPRESS_LZ4=y +CONFIG_DECOMPRESS_ZSTD=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_ENC8=y +CONFIG_REED_SOLOMON_DEC8=y +CONFIG_REED_SOLOMON_DEC16=y +CONFIG_BCH=m +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_BTREE=y +CONFIG_INTERVAL_TREE=y +CONFIG_INTERVAL_TREE_SPAN_ITER=y +CONFIG_XARRAY_MULTI=y +CONFIG_ASSOCIATIVE_ARRAY=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HAS_DMA=y +CONFIG_DMA_OPS=y +CONFIG_NEED_SG_DMA_FLAGS=y +CONFIG_NEED_SG_DMA_LENGTH=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_ARCH_DMA_ADDR_T_64BIT=y +CONFIG_ARCH_HAS_FORCE_DMA_UNENCRYPTED=y +CONFIG_SWIOTLB=y +# CONFIG_SWIOTLB_DYNAMIC is not set +CONFIG_DMA_CMA=y +# CONFIG_DMA_NUMA_CMA is not set + +# +# Default contiguous memory area size: +# +CONFIG_CMA_SIZE_MBYTES=0 +CONFIG_CMA_SIZE_SEL_MBYTES=y +# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set +# CONFIG_CMA_SIZE_SEL_MIN is not set +# CONFIG_CMA_SIZE_SEL_MAX is not set +CONFIG_CMA_ALIGNMENT=8 +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_DMA_MAP_BENCHMARK is not set +CONFIG_SGL_ALLOC=y +CONFIG_IOMMU_HELPER=y +CONFIG_CHECK_SIGNATURE=y +CONFIG_CPU_RMAP=y +CONFIG_DQL=y +CONFIG_GLOB=y +# CONFIG_GLOB_SELFTEST is not set +CONFIG_NLATTR=y +CONFIG_LRU_CACHE=m +CONFIG_CLZ_TAB=y +CONFIG_IRQ_POLL=y +CONFIG_MPILIB=y +CONFIG_DIMLIB=y +CONFIG_OID_REGISTRY=y +CONFIG_UCS2_STRING=y +CONFIG_HAVE_GENERIC_VDSO=y +CONFIG_GENERIC_GETTIMEOFDAY=y +CONFIG_GENERIC_VDSO_TIME_NS=y +CONFIG_FONT_SUPPORT=y +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_6x10 is not set +CONFIG_FONT_10x18=y +# CONFIG_FONT_SUN8x16 is not set +CONFIG_FONT_SUN12x22=y +CONFIG_FONT_TER16x32=y +# CONFIG_FONT_6x8 is not set +CONFIG_SG_POOL=y +CONFIG_ARCH_HAS_PMEM_API=y +CONFIG_MEMREGION=y +CONFIG_ARCH_HAS_CPU_CACHE_INVALIDATE_MEMREGION=y +CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE=y +CONFIG_ARCH_HAS_COPY_MC=y +CONFIG_ARCH_STACKWALK=y +CONFIG_STACKDEPOT=y +CONFIG_SBITMAP=y +CONFIG_PARMAN=m +CONFIG_OBJAGG=m +# end of Library routines + +CONFIG_PLDMFW=y +CONFIG_ASN1_ENCODER=m +CONFIG_POLYNOMIAL=m + +# +# Kernel hacking +# + +# +# printk and dmesg options +# +CONFIG_PRINTK_TIME=y +# CONFIG_PRINTK_CALLER is not set +# CONFIG_STACKTRACE_BUILD_ID is not set +CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 +CONFIG_CONSOLE_LOGLEVEL_QUIET=4 +CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 +CONFIG_BOOT_PRINTK_DELAY=y +CONFIG_DYNAMIC_DEBUG=y +CONFIG_DYNAMIC_DEBUG_CORE=y +CONFIG_SYMBOLIC_ERRNAME=y +CONFIG_DEBUG_BUGVERBOSE=y +# end of printk and dmesg options + +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_MISC=y + +# +# Compile-time checks and compiler options +# +CONFIG_AS_HAS_NON_CONST_LEB128=y +CONFIG_DEBUG_INFO_NONE=y +# CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT is not set +# CONFIG_DEBUG_INFO_DWARF4 is not set +# CONFIG_DEBUG_INFO_DWARF5 is not set +CONFIG_FRAME_WARN=2048 +CONFIG_STRIP_ASM_SYMS=y +# CONFIG_READABLE_ASM is not set +# CONFIG_HEADERS_INSTALL is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_SECTION_MISMATCH_WARN_ONLY=y +# CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B is not set +CONFIG_OBJTOOL=y +# CONFIG_VMLINUX_MAP is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# end of Compile-time checks and compiler options + +# +# Generic Kernel Debugging Instruments +# +CONFIG_MAGIC_SYSRQ=y +CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 +CONFIG_MAGIC_SYSRQ_SERIAL=y +CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE="" +CONFIG_DEBUG_FS=y +CONFIG_DEBUG_FS_ALLOW_ALL=y +# CONFIG_DEBUG_FS_DISALLOW_MOUNT is not set +# CONFIG_DEBUG_FS_ALLOW_NONE is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y +# CONFIG_UBSAN is not set +CONFIG_HAVE_ARCH_KCSAN=y +CONFIG_HAVE_KCSAN_COMPILER=y +# CONFIG_KCSAN is not set +# end of Generic Kernel Debugging Instruments + +# +# Networking Debugging +# +# CONFIG_NET_DEV_REFCNT_TRACKER is not set +# CONFIG_NET_NS_REFCNT_TRACKER is not set +# CONFIG_DEBUG_NET is not set +# end of Networking Debugging + +# +# Memory Debugging +# +# CONFIG_PAGE_EXTENSION is not set +# CONFIG_DEBUG_PAGEALLOC is not set +CONFIG_SLUB_DEBUG=y +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_PAGE_OWNER is not set +# CONFIG_PAGE_TABLE_CHECK is not set +# CONFIG_PAGE_POISONING is not set +# CONFIG_DEBUG_PAGE_REF is not set +# CONFIG_DEBUG_RODATA_TEST is not set +CONFIG_ARCH_HAS_DEBUG_WX=y +CONFIG_DEBUG_WX=y +CONFIG_GENERIC_PTDUMP=y +CONFIG_PTDUMP_CORE=y +# CONFIG_PTDUMP_DEBUGFS is not set +CONFIG_HAVE_DEBUG_KMEMLEAK=y +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_PER_VMA_LOCK_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SHRINKER_DEBUG is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_SCHED_STACK_END_CHECK is not set +CONFIG_ARCH_HAS_DEBUG_VM_PGTABLE=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_VM_PGTABLE is not set +CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y +# CONFIG_DEBUG_VIRTUAL is not set +CONFIG_DEBUG_MEMORY_INIT=y +CONFIG_MEMORY_NOTIFIER_ERROR_INJECT=m +# CONFIG_DEBUG_PER_CPU_MAPS is not set +CONFIG_ARCH_SUPPORTS_KMAP_LOCAL_FORCE_MAP=y +# CONFIG_DEBUG_KMAP_LOCAL_FORCE_MAP is not set +CONFIG_HAVE_ARCH_KASAN=y +CONFIG_HAVE_ARCH_KASAN_VMALLOC=y +CONFIG_CC_HAS_KASAN_GENERIC=y +CONFIG_CC_HAS_WORKING_NOSANITIZE_ADDRESS=y +# CONFIG_KASAN is not set +CONFIG_HAVE_ARCH_KFENCE=y +CONFIG_KFENCE=y +CONFIG_KFENCE_SAMPLE_INTERVAL=0 +CONFIG_KFENCE_NUM_OBJECTS=255 +# CONFIG_KFENCE_DEFERRABLE is not set +# CONFIG_KFENCE_STATIC_KEYS is not set +CONFIG_KFENCE_STRESS_TEST_FAULTS=0 +CONFIG_HAVE_ARCH_KMSAN=y +# end of Memory Debugging + +# CONFIG_DEBUG_SHIRQ is not set + +# +# Debug Oops, Lockups and Hangs +# +# CONFIG_PANIC_ON_OOPS is not set +CONFIG_PANIC_ON_OOPS_VALUE=0 +CONFIG_PANIC_TIMEOUT=0 +CONFIG_LOCKUP_DETECTOR=y +CONFIG_SOFTLOCKUP_DETECTOR=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_HAVE_HARDLOCKUP_DETECTOR_BUDDY=y +CONFIG_HARDLOCKUP_DETECTOR=y +# CONFIG_HARDLOCKUP_DETECTOR_PREFER_BUDDY is not set +CONFIG_HARDLOCKUP_DETECTOR_PERF=y +# CONFIG_HARDLOCKUP_DETECTOR_BUDDY is not set +# CONFIG_HARDLOCKUP_DETECTOR_ARCH is not set +CONFIG_HARDLOCKUP_DETECTOR_COUNTS_HRTIMER=y +CONFIG_HARDLOCKUP_CHECK_TIMESTAMP=y +# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set +CONFIG_DETECT_HUNG_TASK=y +CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +# CONFIG_WQ_WATCHDOG is not set +# CONFIG_WQ_CPU_INTENSIVE_REPORT is not set +# CONFIG_TEST_LOCKUP is not set +# end of Debug Oops, Lockups and Hangs + +# +# Scheduler Debugging +# +CONFIG_SCHED_DEBUG=y +CONFIG_SCHED_INFO=y +CONFIG_SCHEDSTATS=y +# end of Scheduler Debugging + +# CONFIG_DEBUG_TIMEKEEPING is not set +# CONFIG_DEBUG_PREEMPT is not set + +# +# Lock Debugging (spinlocks, mutexes, etc...) +# +CONFIG_LOCK_DEBUGGING_SUPPORT=y +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set +# CONFIG_DEBUG_RWSEMS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_LOCK_TORTURE_TEST is not set +# CONFIG_WW_MUTEX_SELFTEST is not set +# CONFIG_SCF_TORTURE_TEST is not set +# CONFIG_CSD_LOCK_WAIT_DEBUG is not set +# end of Lock Debugging (spinlocks, mutexes, etc...) + +CONFIG_NMI_CHECK_CPU=y +# CONFIG_DEBUG_IRQFLAGS is not set +CONFIG_STACKTRACE=y +# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set +# CONFIG_DEBUG_KOBJECT is not set + +# +# Debug kernel data structures +# +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_PLIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_MAPLE_TREE is not set +# end of Debug kernel data structures + +# +# RCU Debugging +# +# CONFIG_RCU_SCALE_TEST is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_REF_SCALE_TEST is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=60 +CONFIG_RCU_EXP_CPU_STALL_TIMEOUT=0 +# CONFIG_RCU_CPU_STALL_CPUTIME is not set +# CONFIG_RCU_TRACE is not set +# CONFIG_RCU_EQS_DEBUG is not set +# end of RCU Debugging + +# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set +# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set +CONFIG_LATENCYTOP=y +# CONFIG_DEBUG_CGROUP_REF is not set +CONFIG_USER_STACKTRACE_SUPPORT=y +CONFIG_NOP_TRACER=y +CONFIG_HAVE_RETHOOK=y +CONFIG_RETHOOK=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_RETVAL=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS=y +CONFIG_HAVE_DYNAMIC_FTRACE_NO_PATCHABLE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_FENTRY=y +CONFIG_HAVE_OBJTOOL_MCOUNT=y +CONFIG_HAVE_OBJTOOL_NOP_MCOUNT=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_HAVE_BUILDTIME_MCOUNT_SORT=y +CONFIG_BUILDTIME_MCOUNT_SORT=y +CONFIG_TRACER_MAX_TRACE=y +CONFIG_TRACE_CLOCK=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_TRACING=y +CONFIG_GENERIC_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +CONFIG_BOOTTIME_TRACING=y +CONFIG_FUNCTION_TRACER=y +# CONFIG_FUNCTION_GRAPH_TRACER is not set +CONFIG_DYNAMIC_FTRACE=y +CONFIG_DYNAMIC_FTRACE_WITH_REGS=y +CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y +CONFIG_DYNAMIC_FTRACE_WITH_ARGS=y +# CONFIG_FPROBE is not set +CONFIG_FUNCTION_PROFILER=y +CONFIG_STACK_TRACER=y +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +CONFIG_SCHED_TRACER=y +# CONFIG_HWLAT_TRACER is not set +# CONFIG_OSNOISE_TRACER is not set +# CONFIG_TIMERLAT_TRACER is not set +CONFIG_MMIOTRACE=y +CONFIG_FTRACE_SYSCALLS=y +CONFIG_TRACER_SNAPSHOT=y +# CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_KPROBE_EVENTS=y +# CONFIG_KPROBE_EVENTS_ON_NOTRACE is not set +CONFIG_UPROBE_EVENTS=y +CONFIG_BPF_EVENTS=y +CONFIG_DYNAMIC_EVENTS=y +CONFIG_PROBE_EVENTS=y +# CONFIG_BPF_KPROBE_OVERRIDE is not set +CONFIG_FTRACE_MCOUNT_RECORD=y +CONFIG_FTRACE_MCOUNT_USE_CC=y +# CONFIG_SYNTH_EVENTS is not set +# CONFIG_USER_EVENTS is not set +# CONFIG_HIST_TRIGGERS is not set +# CONFIG_TRACE_EVENT_INJECT is not set +# CONFIG_TRACEPOINT_BENCHMARK is not set +CONFIG_RING_BUFFER_BENCHMARK=m +# CONFIG_TRACE_EVAL_MAP_FILE is not set +# CONFIG_FTRACE_RECORD_RECURSION is not set +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_FTRACE_SORT_STARTUP_TEST is not set +# CONFIG_RING_BUFFER_STARTUP_TEST is not set +# CONFIG_RING_BUFFER_VALIDATE_TIME_DELTAS is not set +# CONFIG_MMIOTRACE_TEST is not set +# CONFIG_PREEMPTIRQ_DELAY_TEST is not set +# CONFIG_KPROBE_EVENT_GEN_TEST is not set +# CONFIG_RV is not set +# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_SAMPLE_FTRACE_DIRECT=y +CONFIG_HAVE_SAMPLE_FTRACE_DIRECT_MULTI=y +CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y +CONFIG_STRICT_DEVMEM=y +CONFIG_IO_STRICT_DEVMEM=y + +# +# x86 Debugging +# +# CONFIG_X86_VERBOSE_BOOTUP is not set +CONFIG_EARLY_PRINTK=y +# CONFIG_EARLY_PRINTK_DBGP is not set +# CONFIG_EARLY_PRINTK_USB_XDBC is not set +# CONFIG_EFI_PGT_DUMP is not set +# CONFIG_DEBUG_TLBFLUSH is not set +# CONFIG_IOMMU_DEBUG is not set +CONFIG_HAVE_MMIOTRACE_SUPPORT=y +# CONFIG_X86_DECODER_SELFTEST is not set +CONFIG_IO_DELAY_0X80=y +# CONFIG_IO_DELAY_0XED is not set +# CONFIG_IO_DELAY_UDELAY is not set +# CONFIG_IO_DELAY_NONE is not set +# CONFIG_DEBUG_BOOT_PARAMS is not set +# CONFIG_CPA_DEBUG is not set +# CONFIG_DEBUG_ENTRY is not set +# CONFIG_DEBUG_NMI_SELFTEST is not set +CONFIG_X86_DEBUG_FPU=y +CONFIG_PUNIT_ATOM_DEBUG=m +CONFIG_UNWINDER_ORC=y +# CONFIG_UNWINDER_FRAME_POINTER is not set +# end of x86 Debugging + +# +# Kernel Testing and Coverage +# +# CONFIG_KUNIT is not set +CONFIG_NOTIFIER_ERROR_INJECTION=m +CONFIG_PM_NOTIFIER_ERROR_INJECT=m +# CONFIG_NETDEV_NOTIFIER_ERROR_INJECT is not set +CONFIG_FUNCTION_ERROR_INJECTION=y +# CONFIG_FAULT_INJECTION is not set +CONFIG_ARCH_HAS_KCOV=y +CONFIG_CC_HAS_SANCOV_TRACE_PC=y +# CONFIG_KCOV is not set +CONFIG_RUNTIME_TESTING_MENU=y +# CONFIG_TEST_DHRY is not set +# CONFIG_LKDTM is not set +# CONFIG_TEST_MIN_HEAP is not set +# CONFIG_TEST_DIV64 is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_TEST_REF_TRACKER is not set +CONFIG_RBTREE_TEST=m +# CONFIG_REED_SOLOMON_TEST is not set +CONFIG_INTERVAL_TREE_TEST=m +# CONFIG_PERCPU_TEST is not set +# CONFIG_ATOMIC64_SELFTEST is not set +# CONFIG_ASYNC_RAID6_TEST is not set +# CONFIG_TEST_HEXDUMP is not set +# CONFIG_STRING_SELFTEST is not set +# CONFIG_TEST_STRING_HELPERS is not set +# CONFIG_TEST_KSTRTOX is not set +# CONFIG_TEST_PRINTF is not set +# CONFIG_TEST_SCANF is not set +# CONFIG_TEST_BITMAP is not set +# CONFIG_TEST_UUID is not set +CONFIG_TEST_XARRAY=m +# CONFIG_TEST_MAPLE_TREE is not set +# CONFIG_TEST_RHASHTABLE is not set +# CONFIG_TEST_IDA is not set +# CONFIG_TEST_PARMAN is not set +# CONFIG_TEST_LKM is not set +# CONFIG_TEST_BITOPS is not set +# CONFIG_TEST_VMALLOC is not set +# CONFIG_TEST_USER_COPY is not set +# CONFIG_TEST_BPF is not set +# CONFIG_TEST_BLACKHOLE_DEV is not set +# CONFIG_FIND_BIT_BENCHMARK is not set +# CONFIG_TEST_FIRMWARE is not set +# CONFIG_TEST_SYSCTL is not set +# CONFIG_TEST_UDELAY is not set +# CONFIG_TEST_STATIC_KEYS is not set +# CONFIG_TEST_DYNAMIC_DEBUG is not set +# CONFIG_TEST_KMOD is not set +# CONFIG_TEST_MEMCAT_P is not set +# CONFIG_TEST_LIVEPATCH is not set +# CONFIG_TEST_OBJAGG is not set +# CONFIG_TEST_MEMINIT is not set +# CONFIG_TEST_HMM is not set +# CONFIG_TEST_FREE_PAGES is not set +# CONFIG_TEST_FPU is not set +# CONFIG_TEST_CLOCKSOURCE_WATCHDOG is not set +CONFIG_ARCH_USE_MEMTEST=y +CONFIG_MEMTEST=y +# CONFIG_HYPERV_TESTING is not set +# end of Kernel Testing and Coverage + +# +# Rust hacking +# +# end of Rust hacking +# end of Kernel hacking diff --git a/kernel/kernel/files/configs/kernel-x86_64-config b/kernel/kernel/files/configs/kernel-x86_64-config index c9598576..d21a55e4 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 6.6.92 Kernel Configuration +# Linux/x86_64 6.12.40 Kernel Configuration # CONFIG_CC_VERSION_TEXT="gcc (Pisi Linux) 13.3.0" CONFIG_CC_IS_GCC=y @@ -11,7 +11,8 @@ CONFIG_AS_VERSION=24200 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=24200 CONFIG_LLD_VERSION=0 -CONFIG_RUST_IS_AVAILABLE=y +CONFIG_RUSTC_VERSION=0 +CONFIG_RUSTC_LLVM_VERSION=0 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y @@ -19,6 +20,7 @@ CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT=y CONFIG_TOOLS_SUPPORT_RELR=y CONFIG_CC_HAS_ASM_INLINE=y CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y +CONFIG_LD_CAN_USE_KEEP_IN_OVERLAY=y CONFIG_PAHOLE_VERSION=0 CONFIG_IRQ_WORK=y CONFIG_BUILDTIME_TABLE_SORT=y @@ -86,10 +88,10 @@ CONFIG_SPARSE_IRQ=y CONFIG_CLOCKSOURCE_WATCHDOG=y CONFIG_ARCH_CLOCKSOURCE_INIT=y -CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE=y CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST_IDLE=y CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y CONFIG_GENERIC_CMOS_UPDATE=y CONFIG_HAVE_POSIX_CPU_TIMERS_TASK_WORK=y @@ -124,7 +126,9 @@ CONFIG_BPF_JIT=y CONFIG_BPF_JIT_ALWAYS_ON=y CONFIG_BPF_JIT_DEFAULT_ON=y CONFIG_BPF_UNPRIV_DEFAULT_OFF=y -# CONFIG_BPF_PRELOAD is not set +CONFIG_USERMODE_DRIVER=y +CONFIG_BPF_PRELOAD=y +CONFIG_BPF_PRELOAD_UMD=m CONFIG_BPF_LSM=y # end of BPF subsystem @@ -132,6 +136,7 @@ CONFIG_PREEMPT_BUILD=y # CONFIG_PREEMPT_NONE is not set # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y +# CONFIG_PREEMPT_RT is not set CONFIG_PREEMPT_COUNT=y CONFIG_PREEMPTION=y CONFIG_PREEMPT_DYNAMIC=y @@ -165,6 +170,7 @@ CONFIG_RCU_EXPERT=y CONFIG_TREE_SRCU=y CONFIG_TASKS_RCU_GENERIC=y # CONFIG_FORCE_TASKS_RCU is not set +CONFIG_NEED_TASKS_RCU=y CONFIG_TASKS_RCU=y # CONFIG_FORCE_TASKS_RUDE_RCU is not set CONFIG_TASKS_RUDE_RCU=y @@ -206,16 +212,20 @@ CONFIG_CC_HAS_INT128=y CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" CONFIG_GCC10_NO_ARRAY_BOUNDS=y CONFIG_CC_NO_ARRAY_BOUNDS=y +CONFIG_GCC_NO_STRINGOP_OVERFLOW=y +CONFIG_CC_NO_STRINGOP_OVERFLOW=y CONFIG_ARCH_SUPPORTS_INT128=y # CONFIG_NUMA_BALANCING is not set +CONFIG_SLAB_OBJ_EXT=y CONFIG_CGROUPS=y CONFIG_PAGE_COUNTER=y # CONFIG_CGROUP_FAVOR_DYNMODS is not set CONFIG_MEMCG=y -CONFIG_MEMCG_KMEM=y +# CONFIG_MEMCG_V1 is not set CONFIG_BLK_CGROUP=y CONFIG_CGROUP_WRITEBACK=y CONFIG_CGROUP_SCHED=y +CONFIG_GROUP_SCHED_WEIGHT=y CONFIG_FAIR_GROUP_SCHED=y CONFIG_CFS_BANDWIDTH=y # CONFIG_RT_GROUP_SCHED is not set @@ -226,6 +236,7 @@ CONFIG_CGROUP_RDMA=y CONFIG_CGROUP_FREEZER=y CONFIG_CGROUP_HUGETLB=y CONFIG_CPUSETS=y +# CONFIG_CPUSETS_V1 is not set CONFIG_PROC_PID_CPUSET=y CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_CPUACCT=y @@ -276,7 +287,7 @@ CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_PCSPKR_PLATFORM=y -CONFIG_BASE_FULL=y +# CONFIG_BASE_SMALL is not set CONFIG_FUTEX=y CONFIG_FUTEX_PI=y CONFIG_EPOLL=y @@ -288,19 +299,18 @@ CONFIG_AIO=y CONFIG_IO_URING=y CONFIG_ADVISE_SYSCALLS=y CONFIG_MEMBARRIER=y +CONFIG_KCMP=y +CONFIG_RSEQ=y +# CONFIG_DEBUG_RSEQ is not set +CONFIG_CACHESTAT_SYSCALL=y +# CONFIG_PC104 is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_SELFTEST is not set CONFIG_KALLSYMS_ALL=y CONFIG_KALLSYMS_ABSOLUTE_PERCPU=y -CONFIG_KALLSYMS_BASE_RELATIVE=y CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y -CONFIG_KCMP=y -CONFIG_RSEQ=y -CONFIG_CACHESTAT_SYSCALL=y -# CONFIG_DEBUG_RSEQ is not set CONFIG_HAVE_PERF_EVENTS=y CONFIG_GUEST_PERF_EVENTS=y -# CONFIG_PC104 is not set # # Kernel Performance Events And Counters @@ -316,7 +326,8 @@ CONFIG_TRACEPOINTS=y # # Kexec and crash features # -CONFIG_CRASH_CORE=y +CONFIG_CRASH_RESERVE=y +CONFIG_VMCORE_INFO=y CONFIG_KEXEC_CORE=y CONFIG_KEXEC=y # CONFIG_KEXEC_FILE is not set @@ -361,9 +372,10 @@ CONFIG_CC_HAS_SANE_STACKPROTECTOR=y # CONFIG_SMP=y CONFIG_X86_X2APIC=y +CONFIG_X86_POSTED_MSI=y CONFIG_X86_MPPARSE=y -# CONFIG_GOLDFISH is not set CONFIG_X86_CPU_RESCTRL=y +# CONFIG_X86_FRED is not set CONFIG_X86_EXTENDED_PLATFORM=y # CONFIG_X86_NUMACHIP is not set # CONFIG_X86_VSMP is not set @@ -411,6 +423,7 @@ CONFIG_GENERIC_CPU=y CONFIG_X86_INTERNODE_CACHE_SHIFT=6 CONFIG_X86_L1_CACHE_SHIFT=6 CONFIG_X86_TSC=y +CONFIG_X86_HAVE_PAE=y CONFIG_X86_CMPXCHG64=y CONFIG_X86_CMOV=y CONFIG_X86_MINIMUM_CPU_FAMILY=64 @@ -438,6 +451,7 @@ CONFIG_SCHED_SMT=y CONFIG_SCHED_MC=y CONFIG_SCHED_MC_PRIO=y CONFIG_X86_LOCAL_APIC=y +CONFIG_ACPI_MADT_WAKEUP=y CONFIG_X86_IO_APIC=y CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y CONFIG_X86_MCE=y @@ -470,18 +484,18 @@ CONFIG_X86_CPUID=m CONFIG_X86_DIRECT_GBPAGES=y # CONFIG_X86_CPA_STATISTICS is not set CONFIG_X86_MEM_ENCRYPT=y -# CONFIG_AMD_MEM_ENCRYPT is not set +CONFIG_AMD_MEM_ENCRYPT=y CONFIG_NUMA=y CONFIG_AMD_NUMA=y CONFIG_X86_64_ACPI_NUMA=y -# CONFIG_NUMA_EMU is not set CONFIG_NODES_SHIFT=6 CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_ARCH_MEMORY_PROBE=y CONFIG_ARCH_PROC_KCORE_TEXT=y CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 -# CONFIG_X86_PMEM_LEGACY is not set +CONFIG_X86_PMEM_LEGACY_DEVICE=y +CONFIG_X86_PMEM_LEGACY=y CONFIG_X86_CHECK_BIOS_CORRUPTION=y # CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK is not set CONFIG_MTRR=y @@ -489,21 +503,21 @@ CONFIG_MTRR_SANITIZER=y CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=0 CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1 CONFIG_X86_PAT=y -CONFIG_ARCH_USES_PG_UNCACHED=y CONFIG_X86_UMIP=y CONFIG_CC_HAS_IBT=y +CONFIG_X86_CET=y # CONFIG_X86_KERNEL_IBT is not set CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS=y +CONFIG_ARCH_PKEY_BITS=4 # CONFIG_X86_INTEL_TSX_MODE_OFF is not set # CONFIG_X86_INTEL_TSX_MODE_ON is not set CONFIG_X86_INTEL_TSX_MODE_AUTO=y # CONFIG_X86_SGX is not set -# CONFIG_X86_USER_SHADOW_STACK is not set +CONFIG_X86_USER_SHADOW_STACK=y CONFIG_EFI=y CONFIG_EFI_STUB=y CONFIG_EFI_HANDOVER_PROTOCOL=y CONFIG_EFI_MIXED=y -# CONFIG_EFI_FAKE_MEMMAP is not set CONFIG_EFI_RUNTIME_MAP=y # CONFIG_HZ_100 is not set # CONFIG_HZ_250 is not set @@ -519,7 +533,9 @@ CONFIG_ARCH_SUPPORTS_KEXEC_SIG_FORCE=y CONFIG_ARCH_SUPPORTS_KEXEC_BZIMAGE_VERIFY_SIG=y CONFIG_ARCH_SUPPORTS_KEXEC_JUMP=y CONFIG_ARCH_SUPPORTS_CRASH_DUMP=y +CONFIG_ARCH_DEFAULT_CRASH_DUMP=y CONFIG_ARCH_SUPPORTS_CRASH_HOTPLUG=y +CONFIG_ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION=y CONFIG_PHYSICAL_START=0x200000 CONFIG_RELOCATABLE=y CONFIG_RANDOMIZE_BASE=y @@ -539,6 +555,9 @@ CONFIG_HAVE_LIVEPATCH=y CONFIG_LIVEPATCH=y # end of Processor type and features +CONFIG_CC_HAS_NAMED_AS=y +CONFIG_CC_HAS_NAMED_AS_FIXED_SANITIZERS=y +CONFIG_USE_X86_SEG_SUPPORT=y CONFIG_CC_HAS_SLS=y CONFIG_CC_HAS_RETURN_THUNK=y CONFIG_CC_HAS_ENTRY_PADDING=y @@ -549,20 +568,30 @@ CONFIG_HAVE_CALL_THUNKS=y CONFIG_CALL_THUNKS=y CONFIG_PREFIX_SYMBOLS=y CONFIG_CPU_MITIGATIONS=y -CONFIG_PAGE_TABLE_ISOLATION=y -CONFIG_RETPOLINE=y -CONFIG_RETHUNK=y -CONFIG_CPU_UNRET_ENTRY=y -CONFIG_CALL_DEPTH_TRACKING=y +CONFIG_MITIGATION_PAGE_TABLE_ISOLATION=y +CONFIG_MITIGATION_RETPOLINE=y +CONFIG_MITIGATION_RETHUNK=y +CONFIG_MITIGATION_UNRET_ENTRY=y +CONFIG_MITIGATION_CALL_DEPTH_TRACKING=y # CONFIG_CALL_THUNKS_DEBUG is not set -CONFIG_CPU_IBPB_ENTRY=y -CONFIG_CPU_IBRS_ENTRY=y -CONFIG_CPU_SRSO=y -# CONFIG_SLS is not set -# CONFIG_GDS_FORCE_MITIGATION is not set +CONFIG_MITIGATION_IBPB_ENTRY=y +CONFIG_MITIGATION_IBRS_ENTRY=y +CONFIG_MITIGATION_SRSO=y +# CONFIG_MITIGATION_SLS is not set +CONFIG_MITIGATION_GDS=y CONFIG_MITIGATION_RFDS=y -CONFIG_MITIGATION_ITS=y CONFIG_MITIGATION_SPECTRE_BHI=y +CONFIG_MITIGATION_MDS=y +CONFIG_MITIGATION_TAA=y +CONFIG_MITIGATION_MMIO_STALE_DATA=y +CONFIG_MITIGATION_L1TF=y +CONFIG_MITIGATION_RETBLEED=y +CONFIG_MITIGATION_SPECTRE_V1=y +CONFIG_MITIGATION_SPECTRE_V2=y +CONFIG_MITIGATION_SRBDS=y +CONFIG_MITIGATION_SSB=y +CONFIG_MITIGATION_ITS=y +CONFIG_MITIGATION_TSA=y CONFIG_ARCH_HAS_ADD_PAGES=y # @@ -575,6 +604,9 @@ CONFIG_SUSPEND_FREEZER=y CONFIG_HIBERNATE_CALLBACKS=y CONFIG_HIBERNATION=y CONFIG_HIBERNATION_SNAPSHOT_DEV=y +CONFIG_HIBERNATION_COMP_LZO=y +# CONFIG_HIBERNATION_COMP_LZ4 is not set +CONFIG_HIBERNATION_DEF_COMP="lzo" CONFIG_PM_STD_PARTITION="" CONFIG_PM_SLEEP=y CONFIG_PM_SLEEP_SMP=y @@ -595,12 +627,14 @@ CONFIG_PM_CLK=y CONFIG_PM_GENERIC_DOMAINS=y # CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set CONFIG_PM_GENERIC_DOMAINS_SLEEP=y +CONFIG_PM_GENERIC_DOMAINS_OF=y CONFIG_ENERGY_MODEL=y CONFIG_ARCH_SUPPORTS_ACPI=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_THERMAL_LIB=y # CONFIG_ACPI_DEBUGGER is not set CONFIG_ACPI_SPCR_TABLE=y CONFIG_ACPI_FPDT=y @@ -635,9 +669,9 @@ CONFIG_ACPI_HOTPLUG_MEMORY=y CONFIG_ACPI_HOTPLUG_IOAPIC=y CONFIG_ACPI_SBS=m CONFIG_ACPI_HED=y -# CONFIG_ACPI_CUSTOM_METHOD is not set CONFIG_ACPI_BGRT=y # CONFIG_ACPI_REDUCED_HARDWARE_ONLY is not set +CONFIG_ACPI_NHLT=y CONFIG_ACPI_NFIT=m # CONFIG_NFIT_SECURITY_DEBUG is not set CONFIG_ACPI_NUMA=y @@ -678,7 +712,7 @@ CONFIG_X86_PM_TIMER=y CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_GOV_ATTR_SET=y CONFIG_CPU_FREQ_GOV_COMMON=y -# CONFIG_CPU_FREQ_STAT is not set +CONFIG_CPU_FREQ_STAT=y # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set @@ -693,6 +727,8 @@ CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y # # CPU frequency scaling drivers # +# CONFIG_CPUFREQ_DT is not set +# CONFIG_CPUFREQ_DT_PLATDEV is not set CONFIG_X86_INTEL_PSTATE=y CONFIG_X86_PCC_CPUFREQ=m CONFIG_X86_AMD_PSTATE=y @@ -742,50 +778,65 @@ CONFIG_AMD_NB=y # Binary Emulations # CONFIG_IA32_EMULATION=y +# CONFIG_IA32_EMULATION_DEFAULT_DISABLED is not set CONFIG_X86_X32_ABI=y CONFIG_COMPAT_32=y CONFIG_COMPAT=y CONFIG_COMPAT_FOR_U64_ALIGNMENT=y # end of Binary Emulations -CONFIG_HAVE_KVM=y +CONFIG_KVM_COMMON=y CONFIG_HAVE_KVM_PFNCACHE=y CONFIG_HAVE_KVM_IRQCHIP=y -CONFIG_HAVE_KVM_IRQFD=y CONFIG_HAVE_KVM_IRQ_ROUTING=y CONFIG_HAVE_KVM_DIRTY_RING=y CONFIG_HAVE_KVM_DIRTY_RING_TSO=y CONFIG_HAVE_KVM_DIRTY_RING_ACQ_REL=y -CONFIG_HAVE_KVM_EVENTFD=y CONFIG_KVM_MMIO=y CONFIG_KVM_ASYNC_PF=y CONFIG_HAVE_KVM_MSI=y +CONFIG_HAVE_KVM_READONLY_MEM=y CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT=y CONFIG_KVM_VFIO=y CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT=y +CONFIG_KVM_GENERIC_PRE_FAULT_MEMORY=y CONFIG_KVM_COMPAT=y -CONFIG_HAVE_KVM_IRQ_BYPASS=y +CONFIG_HAVE_KVM_IRQ_BYPASS=m CONFIG_HAVE_KVM_NO_POLL=y CONFIG_KVM_XFER_TO_GUEST_WORK=y CONFIG_HAVE_KVM_PM_NOTIFIER=y CONFIG_KVM_GENERIC_HARDWARE_ENABLING=y +CONFIG_KVM_GENERIC_MMU_NOTIFIER=y +CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES=y +CONFIG_KVM_PRIVATE_MEM=y +CONFIG_KVM_GENERIC_PRIVATE_MEM=y +CONFIG_HAVE_KVM_ARCH_GMEM_PREPARE=y +CONFIG_HAVE_KVM_ARCH_GMEM_INVALIDATE=y CONFIG_VIRTUALIZATION=y +CONFIG_KVM_X86=m CONFIG_KVM=m CONFIG_KVM_WERROR=y +CONFIG_KVM_SW_PROTECTED_VM=y CONFIG_KVM_INTEL=m +# CONFIG_KVM_INTEL_PROVE_VE is not set CONFIG_KVM_AMD=m CONFIG_KVM_AMD_SEV=y CONFIG_KVM_SMM=y +CONFIG_KVM_HYPERV=y CONFIG_KVM_XEN=y CONFIG_KVM_PROVE_MMU=y CONFIG_KVM_EXTERNAL_WRITE_TRACKING=y +CONFIG_KVM_MAX_NR_VCPUS=1024 CONFIG_AS_AVX512=y CONFIG_AS_SHA1_NI=y CONFIG_AS_SHA256_NI=y CONFIG_AS_TPAUSE=y CONFIG_AS_GFNI=y +CONFIG_AS_VAES=y +CONFIG_AS_VPCLMULQDQ=y CONFIG_AS_WRUSS=y CONFIG_ARCH_CONFIGURES_CPU_MITIGATIONS=y +CONFIG_ARCH_HAS_DMA_OPS=y # # General architecture-dependent options @@ -826,6 +877,7 @@ CONFIG_ARCH_HAS_FORTIFY_SOURCE=y CONFIG_ARCH_HAS_SET_MEMORY=y CONFIG_ARCH_HAS_SET_DIRECT_MAP=y CONFIG_ARCH_HAS_CPU_FINALIZE_INIT=y +CONFIG_ARCH_HAS_CPU_PASID=y CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT=y CONFIG_ARCH_WANTS_NO_INSTR=y @@ -848,6 +900,7 @@ CONFIG_MMU_GATHER_RCU_TABLE_FREE=y CONFIG_MMU_GATHER_MERGE_VMAS=y CONFIG_MMU_LAZY_TLB_REFCOUNT=y CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y +CONFIG_ARCH_HAVE_EXTRA_ELF_NOTES=y CONFIG_ARCH_HAS_NMI_SAFE_THIS_CPU_OPS=y CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y CONFIG_HAVE_CMPXCHG_LOCAL=y @@ -893,8 +946,11 @@ CONFIG_ARCH_MMAP_RND_BITS=28 CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS=y CONFIG_ARCH_MMAP_RND_COMPAT_BITS=8 CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES=y +CONFIG_HAVE_PAGE_SIZE_4KB=y +CONFIG_PAGE_SIZE_4KB=y CONFIG_PAGE_SIZE_LESS_THAN_64KB=y CONFIG_PAGE_SIZE_LESS_THAN_256KB=y +CONFIG_PAGE_SHIFT=12 CONFIG_HAVE_OBJTOOL=y CONFIG_HAVE_JUMP_LABEL_HACK=y CONFIG_HAVE_NOINSTR_HACK=y @@ -906,6 +962,7 @@ CONFIG_ISA_BUS_API=y CONFIG_OLD_SIGSUSPEND3=y CONFIG_COMPAT_OLD_SIGACTION=y CONFIG_COMPAT_32BIT_TIME=y +CONFIG_ARCH_SUPPORTS_RT=y CONFIG_HAVE_ARCH_VMAP_STACK=y CONFIG_VMAP_STACK=y CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET=y @@ -930,7 +987,9 @@ CONFIG_ARCH_SUPPORTS_PAGE_TABLE_CHECK=y CONFIG_ARCH_HAS_ELFCORE_COMPAT=y CONFIG_ARCH_HAS_PARANOID_L1D_FLUSH=y CONFIG_DYNAMIC_SIGFRAME=y +CONFIG_ARCH_HAS_HW_PTE_YOUNG=y CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG=y +CONFIG_ARCH_HAS_KERNEL_FPU_SUPPORT=y # # GCOV-based kernel profiling @@ -948,7 +1007,6 @@ CONFIG_FUNCTION_ALIGNMENT=16 # end of General architecture-dependent options CONFIG_RT_MUTEXES=y -CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_DEBUG is not set CONFIG_MODULE_FORCE_LOAD=y @@ -958,10 +1016,7 @@ CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set # CONFIG_MODULE_SIG is not set -CONFIG_MODULE_COMPRESS_NONE=y -# CONFIG_MODULE_COMPRESS_GZIP is not set -# CONFIG_MODULE_COMPRESS_XZ is not set -# CONFIG_MODULE_COMPRESS_ZSTD is not set +# CONFIG_MODULE_COMPRESS is not set # CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS is not set CONFIG_MODPROBE_PATH="/sbin/modprobe" # CONFIG_TRIM_UNUSED_KSYMS is not set @@ -975,17 +1030,16 @@ CONFIG_BLK_DEV_BSG_COMMON=y CONFIG_BLK_ICQ=y CONFIG_BLK_DEV_BSGLIB=y CONFIG_BLK_DEV_INTEGRITY=y -CONFIG_BLK_DEV_INTEGRITY_T10=y +CONFIG_BLK_DEV_WRITE_MOUNTED=y CONFIG_BLK_DEV_ZONED=y CONFIG_BLK_DEV_THROTTLING=y -CONFIG_BLK_DEV_THROTTLING_LOW=y -# CONFIG_BLK_WBT is not set +CONFIG_BLK_WBT=y +CONFIG_BLK_WBT_MQ=y CONFIG_BLK_CGROUP_IOLATENCY=y CONFIG_BLK_CGROUP_FC_APPID=y CONFIG_BLK_CGROUP_IOCOST=y CONFIG_BLK_CGROUP_IOPRIO=y CONFIG_BLK_DEBUG_FS=y -CONFIG_BLK_DEBUG_FS_ZONED=y CONFIG_BLK_SED_OPAL=y CONFIG_BLK_INLINE_ENCRYPTION=y CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y @@ -1068,7 +1122,7 @@ CONFIG_ZPOOL=y CONFIG_SWAP=y CONFIG_ZSWAP=y # CONFIG_ZSWAP_DEFAULT_ON is not set -# CONFIG_ZSWAP_EXCLUSIVE_LOADS_DEFAULT_ON is not set +CONFIG_ZSWAP_SHRINKER_DEFAULT_ON=y # CONFIG_ZSWAP_COMPRESSOR_DEFAULT_DEFLATE is not set CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZO=y # CONFIG_ZSWAP_COMPRESSOR_DEFAULT_842 is not set @@ -1088,18 +1142,18 @@ CONFIG_ZSMALLOC_STAT=y CONFIG_ZSMALLOC_CHAIN_SIZE=8 # -# SLAB allocator options +# Slab allocator options # -# CONFIG_SLAB_DEPRECATED is not set CONFIG_SLUB=y # CONFIG_SLUB_TINY is not set # CONFIG_SLAB_MERGE_DEFAULT is not set CONFIG_SLAB_FREELIST_RANDOM=y # CONFIG_SLAB_FREELIST_HARDENED is not set +# CONFIG_SLAB_BUCKETS is not set # CONFIG_SLUB_STATS is not set CONFIG_SLUB_CPU_PARTIAL=y # CONFIG_RANDOM_KMALLOC_CACHES is not set -# end of SLAB allocator options +# end of Slab allocator options CONFIG_SHUFFLE_PAGE_ALLOCATOR=y # CONFIG_COMPAT_BRK is not set @@ -1109,7 +1163,7 @@ CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y CONFIG_SPARSEMEM_VMEMMAP=y CONFIG_ARCH_WANT_OPTIMIZE_DAX_VMEMMAP=y CONFIG_ARCH_WANT_OPTIMIZE_HUGETLB_VMEMMAP=y -CONFIG_HAVE_FAST_GUP=y +CONFIG_HAVE_GUP_FAST=y CONFIG_NUMA_KEEP_MEMINFO=y CONFIG_MEMORY_ISOLATION=y CONFIG_EXCLUSIVE_SYSTEM_RAM=y @@ -1121,8 +1175,9 @@ CONFIG_MEMORY_HOTPLUG=y CONFIG_MEMORY_HOTREMOVE=y CONFIG_MHP_MEMMAP_ON_MEMORY=y CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y -CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_SPLIT_PTE_PTLOCKS=y CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y +CONFIG_SPLIT_PMD_PTLOCKS=y CONFIG_MEMORY_BALLOON=y CONFIG_BALLOON_COMPACTION=y CONFIG_COMPACTION=y @@ -1146,21 +1201,26 @@ CONFIG_ARCH_WANTS_THP_SWAP=y CONFIG_TRANSPARENT_HUGEPAGE=y # CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS is not set CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y +# CONFIG_TRANSPARENT_HUGEPAGE_NEVER is not set CONFIG_THP_SWAP=y # CONFIG_READ_ONLY_THP_FOR_FS is not set +CONFIG_PGTABLE_HAS_HUGE_LEAVES=y +CONFIG_ARCH_SUPPORTS_HUGE_PFNMAP=y +CONFIG_ARCH_SUPPORTS_PMD_PFNMAP=y +CONFIG_ARCH_SUPPORTS_PUD_PFNMAP=y CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y CONFIG_USE_PERCPU_NUMA_NODE_ID=y CONFIG_HAVE_SETUP_PER_CPU_AREA=y CONFIG_CMA=y -# CONFIG_CMA_DEBUG is not set # CONFIG_CMA_DEBUGFS is not set -# CONFIG_CMA_SYSFS is not set +CONFIG_CMA_SYSFS=y CONFIG_CMA_AREAS=7 CONFIG_MEM_SOFT_DIRTY=y CONFIG_GENERIC_EARLY_IOREMAP=y # CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set -# CONFIG_IDLE_PAGE_TRACKING is not set +CONFIG_PAGE_IDLE_FLAG=y +CONFIG_IDLE_PAGE_TRACKING=y CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y CONFIG_ARCH_HAS_CURRENT_STACK_POINTER=y CONFIG_ARCH_HAS_PTE_DEVMAP=y @@ -1174,6 +1234,7 @@ CONFIG_DEVICE_PRIVATE=y CONFIG_VMAP_PFN=y CONFIG_ARCH_USES_HIGH_VMA_FLAGS=y CONFIG_ARCH_HAS_PKEYS=y +CONFIG_ARCH_USES_PG_ARCH_2=y CONFIG_VM_EVENT_COUNTERS=y # CONFIG_PERCPU_STATS is not set # CONFIG_GUP_TEST is not set @@ -1183,16 +1244,21 @@ CONFIG_MAPPING_DIRTY_HELPERS=y CONFIG_MEMFD_CREATE=y CONFIG_SECRETMEM=y CONFIG_ANON_VMA_NAME=y -CONFIG_USERFAULTFD=y CONFIG_HAVE_ARCH_USERFAULTFD_WP=y CONFIG_HAVE_ARCH_USERFAULTFD_MINOR=y +CONFIG_USERFAULTFD=y CONFIG_PTE_MARKER_UFFD_WP=y CONFIG_LRU_GEN=y CONFIG_LRU_GEN_ENABLED=y # CONFIG_LRU_GEN_STATS is not set +CONFIG_LRU_GEN_WALKS_MMU=y CONFIG_ARCH_SUPPORTS_PER_VMA_LOCK=y CONFIG_PER_VMA_LOCK=y CONFIG_LOCK_MM_AND_FIND_VMA=y +CONFIG_IOMMU_MM_DATA=y +CONFIG_EXECMEM=y +CONFIG_NUMA_MEMBLKS=y +# CONFIG_NUMA_EMU is not set # # Data Access Monitoring @@ -1208,7 +1274,9 @@ CONFIG_NET_INGRESS=y CONFIG_NET_EGRESS=y CONFIG_NET_XGRESS=y CONFIG_NET_REDIRECT=y +CONFIG_SKB_DECRYPTED=y CONFIG_SKB_EXTENSIONS=y +CONFIG_NET_DEVMEM=y # # Networking options @@ -1216,7 +1284,6 @@ CONFIG_SKB_EXTENSIONS=y CONFIG_PACKET=m CONFIG_PACKET_DIAG=m CONFIG_UNIX=y -CONFIG_UNIX_SCM=y CONFIG_AF_UNIX_OOB=y CONFIG_UNIX_DIAG=m CONFIG_TLS=m @@ -1239,13 +1306,14 @@ CONFIG_NET_KEY_MIGRATE=y CONFIG_XFRM_ESPINTCP=y CONFIG_SMC=m CONFIG_SMC_DIAG=m +# CONFIG_SMC_LO is not set CONFIG_XDP_SOCKETS=y CONFIG_XDP_SOCKETS_DIAG=m CONFIG_NET_HANDSHAKE=y CONFIG_INET=y CONFIG_IP_MULTICAST=y CONFIG_IP_ADVANCED_ROUTER=y -# CONFIG_IP_FIB_TRIE_STATS is not set +CONFIG_IP_FIB_TRIE_STATS=y CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_MULTIPATH=y CONFIG_IP_ROUTE_VERBOSE=y @@ -1295,10 +1363,12 @@ CONFIG_TCP_CONG_YEAH=m CONFIG_TCP_CONG_ILLINOIS=m CONFIG_TCP_CONG_DCTCP=m CONFIG_TCP_CONG_CDG=m -CONFIG_TCP_CONG_BBR=m +CONFIG_TCP_CONG_BBR=y CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_BBR is not set # CONFIG_DEFAULT_RENO is not set CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_TCP_SIGPOOL=y CONFIG_TCP_MD5SIG=y CONFIG_IPV6=m CONFIG_IPV6_ROUTER_PREF=y @@ -1315,7 +1385,7 @@ CONFIG_INET6_XFRM_TUNNEL=m CONFIG_INET6_TUNNEL=m CONFIG_IPV6_VTI=m CONFIG_IPV6_SIT=m -# CONFIG_IPV6_SIT_6RD is not set +CONFIG_IPV6_SIT_6RD=y CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m CONFIG_IPV6_GRE=m @@ -1326,15 +1396,16 @@ CONFIG_IPV6_SUBTREES=y CONFIG_IPV6_MROUTE=y CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y CONFIG_IPV6_PIMSM_V2=y -# CONFIG_IPV6_SEG6_LWTUNNEL is not set -# CONFIG_IPV6_SEG6_HMAC is not set -# CONFIG_IPV6_RPL_LWTUNNEL is not set -# CONFIG_IPV6_IOAM6_LWTUNNEL is not set +CONFIG_IPV6_SEG6_LWTUNNEL=y +CONFIG_IPV6_SEG6_HMAC=y +CONFIG_IPV6_RPL_LWTUNNEL=y +CONFIG_IPV6_IOAM6_LWTUNNEL=y CONFIG_NETLABEL=y -# CONFIG_MPTCP is not set +CONFIG_MPTCP=y +CONFIG_INET_MPTCP_DIAG=y CONFIG_NETWORK_SECMARK=y CONFIG_NET_PTP_CLASSIFY=y -# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +CONFIG_NETWORK_PHY_TIMESTAMPING=y CONFIG_NETFILTER=y CONFIG_NETFILTER_ADVANCED=y CONFIG_BRIDGE_NETFILTER=m @@ -1349,7 +1420,7 @@ CONFIG_NETFILTER_NETLINK=m CONFIG_NETFILTER_FAMILY_BRIDGE=y CONFIG_NETFILTER_FAMILY_ARP=y CONFIG_NETFILTER_BPF_LINK=y -# CONFIG_NETFILTER_NETLINK_HOOK is not set +CONFIG_NETFILTER_NETLINK_HOOK=m CONFIG_NETFILTER_NETLINK_ACCT=m CONFIG_NETFILTER_NETLINK_QUEUE=m CONFIG_NETFILTER_NETLINK_LOG=m @@ -1593,6 +1664,7 @@ CONFIG_IP_VS_PE_SIP=m # IP: Netfilter Configuration # CONFIG_NF_DEFRAG_IPV4=m +CONFIG_IP_NF_IPTABLES_LEGACY=m CONFIG_NF_SOCKET_IPV4=m CONFIG_NF_TPROXY_IPV4=m CONFIG_NF_TABLES_IPV4=y @@ -1625,6 +1697,7 @@ CONFIG_IP_NF_TARGET_TTL=m CONFIG_IP_NF_RAW=m CONFIG_IP_NF_SECURITY=m CONFIG_IP_NF_ARPTABLES=m +CONFIG_NFT_COMPAT_ARP=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m # end of IP: Netfilter Configuration @@ -1632,6 +1705,7 @@ CONFIG_IP_NF_ARP_MANGLE=m # # IPv6: Netfilter Configuration # +CONFIG_IP6_NF_IPTABLES_LEGACY=m CONFIG_NF_SOCKET_IPV6=m CONFIG_NF_TPROXY_IPV6=m CONFIG_NF_TABLES_IPV6=y @@ -1669,6 +1743,7 @@ CONFIG_NF_TABLES_BRIDGE=m CONFIG_NFT_BRIDGE_META=m CONFIG_NFT_BRIDGE_REJECT=m CONFIG_NF_CONNTRACK_BRIDGE=m +CONFIG_BRIDGE_NF_EBTABLES_LEGACY=m CONFIG_BRIDGE_NF_EBTABLES=m CONFIG_BRIDGE_EBT_BROUTE=m CONFIG_BRIDGE_EBT_T_FILTER=m @@ -1690,7 +1765,6 @@ CONFIG_BRIDGE_EBT_REDIRECT=m CONFIG_BRIDGE_EBT_SNAT=m CONFIG_BRIDGE_EBT_LOG=m CONFIG_BRIDGE_EBT_NFLOG=m -# CONFIG_BPFILTER is not set CONFIG_IP_DCCP=m CONFIG_INET_DCCP_DIAG=m @@ -1767,6 +1841,7 @@ CONFIG_NET_DSA_TAG_RZN1_A5PSW=m CONFIG_NET_DSA_TAG_LAN9303=m CONFIG_NET_DSA_TAG_SJA1105=m CONFIG_NET_DSA_TAG_TRAILER=m +CONFIG_NET_DSA_TAG_VSC73XX_8021Q=m CONFIG_NET_DSA_TAG_XRS700X=m CONFIG_VLAN_8021Q=m CONFIG_VLAN_8021Q_GVRP=y @@ -1774,9 +1849,6 @@ CONFIG_VLAN_8021Q_MVRP=y CONFIG_LLC=m CONFIG_LLC2=m CONFIG_ATALK=m -CONFIG_DEV_APPLETALK=m -CONFIG_IPDDP=m -CONFIG_IPDDP_ENCAP=y CONFIG_X25=m CONFIG_LAPB=m CONFIG_PHONET=m @@ -1876,7 +1948,6 @@ CONFIG_NET_ACT_GACT=m CONFIG_GACT_PROB=y CONFIG_NET_ACT_MIRRED=m CONFIG_NET_ACT_SAMPLE=m -CONFIG_NET_ACT_IPT=m CONFIG_NET_ACT_NAT=m CONFIG_NET_ACT_PEDIT=m CONFIG_NET_ACT_SIMP=m @@ -1906,7 +1977,7 @@ CONFIG_BATMAN_ADV_DAT=y CONFIG_BATMAN_ADV_NC=y CONFIG_BATMAN_ADV_MCAST=y # CONFIG_BATMAN_ADV_DEBUG is not set -# CONFIG_BATMAN_ADV_TRACING is not set +CONFIG_BATMAN_ADV_TRACING=y CONFIG_OPENVSWITCH=m CONFIG_OPENVSWITCH_GRE=m CONFIG_OPENVSWITCH_VXLAN=m @@ -1990,7 +2061,6 @@ CONFIG_BT_RFCOMM_TTY=y CONFIG_BT_BNEP=m CONFIG_BT_BNEP_MC_FILTER=y CONFIG_BT_BNEP_PROTO_FILTER=y -CONFIG_BT_CMTP=m CONFIG_BT_HIDP=m CONFIG_BT_LE=y CONFIG_BT_LE_L2CAP_ECRED=y @@ -2030,6 +2100,7 @@ CONFIG_BT_HCIUART_RTL=y CONFIG_BT_HCIUART_QCA=y CONFIG_BT_HCIUART_AG6XX=y CONFIG_BT_HCIUART_MRVL=y +CONFIG_BT_HCIUART_AML=y CONFIG_BT_HCIBCM203X=m CONFIG_BT_HCIBCM4377=m CONFIG_BT_HCIBPA10X=m @@ -2046,6 +2117,7 @@ CONFIG_BT_MTKUART=m CONFIG_BT_HCIRSI=m CONFIG_BT_VIRTIO=m CONFIG_BT_NXPUART=m +CONFIG_BT_INTEL_PCIE=m # end of Bluetooth device drivers CONFIG_AF_RXRPC=m @@ -2089,7 +2161,6 @@ CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" CONFIG_MAC80211_MESH=y CONFIG_MAC80211_LEDS=y -# CONFIG_MAC80211_DEBUGFS is not set # CONFIG_MAC80211_MESSAGE_TRACING is not set # CONFIG_MAC80211_DEBUG_MENU is not set CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 @@ -2162,6 +2233,7 @@ CONFIG_LWTUNNEL_BPF=y CONFIG_DST_CACHE=y CONFIG_GRO_CELLS=y CONFIG_SOCK_VALIDATE_XMIT=y +CONFIG_NET_IEEE8021Q_HELPERS=y CONFIG_NET_SELFTESTS=m CONFIG_NET_SOCK_MSG=y CONFIG_NET_DEVLINK=y @@ -2173,9 +2245,8 @@ CONFIG_ETHTOOL_NETLINK=y # # Device Drivers # -CONFIG_HAVE_EISA=y -# CONFIG_EISA is not set CONFIG_HAVE_PCI=y +CONFIG_GENERIC_PCI_IOMAP=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y CONFIG_PCIEPORTBUS=y @@ -2202,11 +2273,13 @@ CONFIG_XEN_PCIDEV_FRONTEND=m CONFIG_PCI_ATS=y CONFIG_PCI_LOCKLESS_CONFIG=y CONFIG_PCI_IOV=y +CONFIG_PCI_NPEM=y CONFIG_PCI_PRI=y CONFIG_PCI_PASID=y CONFIG_PCI_P2PDMA=y CONFIG_PCI_LABEL=y CONFIG_PCI_HYPERV=m +# CONFIG_PCI_DYNAMIC_OF_NODES is not set # CONFIG_PCIE_BUS_TUNE_OFF is not set CONFIG_PCIE_BUS_DEFAULT=y # CONFIG_PCIE_BUS_SAFE is not set @@ -2225,12 +2298,16 @@ CONFIG_HOTPLUG_PCI_SHPC=y # # PCI controller drivers # +# CONFIG_PCI_FTPCI100 is not set +# CONFIG_PCI_HOST_GENERIC is not set CONFIG_VMD=m CONFIG_PCI_HYPERV_INTERFACE=m +# CONFIG_PCIE_XILINX is not set # # Cadence-based PCIe controllers # +# CONFIG_PCIE_CADENCE_PLAT_HOST is not set # end of Cadence-based PCIe controllers # @@ -2239,6 +2316,7 @@ CONFIG_PCI_HYPERV_INTERFACE=m CONFIG_PCIE_DW=y CONFIG_PCIE_DW_HOST=y CONFIG_PCI_MESON=y +# CONFIG_PCIE_INTEL_GW is not set CONFIG_PCIE_DW_PLAT=y CONFIG_PCIE_DW_PLAT_HOST=y # end of DesignWare-based PCIe controllers @@ -2247,6 +2325,12 @@ CONFIG_PCIE_DW_PLAT_HOST=y # Mobiveil-based PCIe controllers # # end of Mobiveil-based PCIe controllers + +# +# PLDA-based PCIe controllers +# +# CONFIG_PCIE_MICROCHIP_HOST is not set +# end of PLDA-based PCIe controllers # end of PCI controller drivers # @@ -2305,7 +2389,7 @@ CONFIG_UEVENT_HELPER=y CONFIG_UEVENT_HELPER_PATH="" CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y -# CONFIG_DEVTMPFS_SAFE is not set +CONFIG_DEVTMPFS_SAFE=y # CONFIG_STANDALONE is not set CONFIG_PREVENT_FIRMWARE_BUILD=y @@ -2317,7 +2401,8 @@ CONFIG_FW_LOADER_DEBUG=y CONFIG_FW_LOADER_PAGED_BUF=y CONFIG_FW_LOADER_SYSFS=y CONFIG_EXTRA_FIRMWARE="" -# CONFIG_FW_LOADER_USER_HELPER is not set +CONFIG_FW_LOADER_USER_HELPER=y +# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set CONFIG_FW_LOADER_COMPRESS=y CONFIG_FW_LOADER_COMPRESS_XZ=y CONFIG_FW_LOADER_COMPRESS_ZSTD=y @@ -2334,6 +2419,7 @@ CONFIG_DEV_COREDUMP=y CONFIG_HMEM_REPORTING=y # CONFIG_TEST_ASYNC_DRIVER_PROBE is not set CONFIG_SYS_HYPERVISOR=y +CONFIG_GENERIC_CPU_DEVICES=y CONFIG_GENERIC_CPU_AUTOPROBE=y CONFIG_GENERIC_CPU_VULNERABILITIES=y CONFIG_SOC_BUS=y @@ -2341,6 +2427,7 @@ CONFIG_REGMAP=y CONFIG_REGMAP_I2C=y CONFIG_REGMAP_SPI=y CONFIG_REGMAP_SPMI=m +CONFIG_REGMAP_W1=m CONFIG_REGMAP_MMIO=y CONFIG_REGMAP_IRQ=y CONFIG_REGMAP_SOUNDWIRE=m @@ -2355,6 +2442,7 @@ CONFIG_DMA_SHARED_BUFFER=y # # Bus devices # +# CONFIG_MOXTET is not set CONFIG_MHI_BUS=m # CONFIG_MHI_BUS_DEBUG is not set CONFIG_MHI_BUS_PCI_GENERIC=m @@ -2421,6 +2509,11 @@ CONFIG_EFI_EMBEDDED_FIRMWARE=y CONFIG_UEFI_CPER=y CONFIG_UEFI_CPER_X86=y +# +# Qualcomm firmware drivers +# +# end of Qualcomm firmware drivers + # # Tegra firmware driver # @@ -2439,8 +2532,8 @@ CONFIG_MTD_TESTS=m # # Partition parsers # -CONFIG_MTD_AR7_PARTS=m # CONFIG_MTD_CMDLINE_PARTS is not set +CONFIG_MTD_OF_PARTS=m CONFIG_MTD_REDBOOT_PARTS=m CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 # CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set @@ -2493,8 +2586,9 @@ CONFIG_MTD_ABSENT=m # # Mapping drivers for chip access # -# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_COMPLEX_MAPPINGS=y # CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_SBC_GXX=m CONFIG_MTD_AMD76XROM=m CONFIG_MTD_ICHXROM=m CONFIG_MTD_ESB2ROM=m @@ -2502,7 +2596,9 @@ CONFIG_MTD_CK804XROM=m CONFIG_MTD_SCB2_FLASH=m CONFIG_MTD_NETtel=m CONFIG_MTD_L440GX=m -CONFIG_MTD_INTEL_VR_NOR=m +CONFIG_MTD_PCI=m +CONFIG_MTD_PCMCIA=m +# CONFIG_MTD_PCMCIA_ANONYMOUS is not set # CONFIG_MTD_PLATRAM is not set # end of Mapping drivers for chip access @@ -2549,11 +2645,14 @@ CONFIG_MTD_RAW_NAND=m # CONFIG_MTD_NAND_DENALI=m CONFIG_MTD_NAND_DENALI_PCI=m +# CONFIG_MTD_NAND_DENALI_DT is not set CONFIG_MTD_NAND_CAFE=m CONFIG_MTD_NAND_MXIC=m CONFIG_MTD_NAND_GPIO=m # CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_NAND_CADENCE is not set # CONFIG_MTD_NAND_ARASAN is not set +# CONFIG_MTD_NAND_INTEL_LGM is not set # # Misc @@ -2593,11 +2692,24 @@ CONFIG_MTD_SPI_NOR_SWP_DISABLE_ON_VOLATILE=y CONFIG_MTD_UBI=m CONFIG_MTD_UBI_WL_THRESHOLD=4096 CONFIG_MTD_UBI_BEB_LIMIT=20 -# CONFIG_MTD_UBI_FASTMAP is not set -# CONFIG_MTD_UBI_GLUEBI is not set -# CONFIG_MTD_UBI_BLOCK is not set -# CONFIG_MTD_HYPERBUS is not set -# CONFIG_OF is not set +CONFIG_MTD_UBI_FASTMAP=y +CONFIG_MTD_UBI_GLUEBI=m +CONFIG_MTD_UBI_BLOCK=y +CONFIG_MTD_UBI_NVMEM=m +CONFIG_MTD_HYPERBUS=m +CONFIG_DTC=y +CONFIG_OF=y +# CONFIG_OF_UNITTEST is not set +CONFIG_OF_FLATTREE=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_KOBJ=y +CONFIG_OF_DYNAMIC=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_IRQ=y +CONFIG_OF_RESERVED_MEM=y +CONFIG_OF_RESOLVE=y +CONFIG_OF_OVERLAY=y +CONFIG_OF_NUMA=y CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y CONFIG_PARPORT=m CONFIG_PARPORT_PC=m @@ -2621,14 +2733,22 @@ CONFIG_BLK_DEV_FD=m CONFIG_CDROM=y CONFIG_BLK_DEV_PCIESSD_MTIP32XX=m CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_DEF_COMP_LZORLE=y -# CONFIG_ZRAM_DEF_COMP_ZSTD is not set -# CONFIG_ZRAM_DEF_COMP_LZ4 is not set # CONFIG_ZRAM_DEF_COMP_LZO is not set +# CONFIG_ZRAM_DEF_COMP_LZ4 is not set # CONFIG_ZRAM_DEF_COMP_LZ4HC is not set +# CONFIG_ZRAM_DEF_COMP_ZSTD is not set +# CONFIG_ZRAM_DEF_COMP_DEFLATE is not set # CONFIG_ZRAM_DEF_COMP_842 is not set CONFIG_ZRAM_DEF_COMP="lzo-rle" CONFIG_ZRAM_WRITEBACK=y +CONFIG_ZRAM_TRACK_ENTRY_ACTIME=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_ZRAM_MULTI_COMP=y CONFIG_BLK_DEV_LOOP=y @@ -2649,11 +2769,15 @@ CONFIG_VIRTIO_BLK=m CONFIG_BLK_DEV_RBD=m CONFIG_BLK_DEV_UBLK=m CONFIG_BLKDEV_UBLK_LEGACY_OPCODES=y +CONFIG_BLK_DEV_RNBD=y +CONFIG_BLK_DEV_RNBD_CLIENT=m +CONFIG_BLK_DEV_RNBD_SERVER=m # # NVME Support # -CONFIG_NVME_COMMON=y +CONFIG_NVME_KEYRING=y +CONFIG_NVME_AUTH=y CONFIG_NVME_CORE=y CONFIG_BLK_DEV_NVME=y CONFIG_NVME_MULTIPATH=y @@ -2662,14 +2786,17 @@ CONFIG_NVME_FABRICS=m CONFIG_NVME_RDMA=m CONFIG_NVME_FC=m CONFIG_NVME_TCP=m -CONFIG_NVME_AUTH=y +CONFIG_NVME_TCP_TLS=y +CONFIG_NVME_HOST_AUTH=y CONFIG_NVME_TARGET=m +# CONFIG_NVME_TARGET_DEBUGFS is not set CONFIG_NVME_TARGET_PASSTHRU=y CONFIG_NVME_TARGET_LOOP=m CONFIG_NVME_TARGET_RDMA=m CONFIG_NVME_TARGET_FC=m CONFIG_NVME_TARGET_FCLOOP=m CONFIG_NVME_TARGET_TCP=m +CONFIG_NVME_TARGET_TCP_TLS=y CONFIG_NVME_TARGET_AUTH=y # end of NVME Support @@ -2683,12 +2810,14 @@ CONFIG_AD525X_DPOT_SPI=m CONFIG_DUMMY_IRQ=m CONFIG_IBM_ASM=m CONFIG_PHANTOM=m +# CONFIG_RPMB is not set CONFIG_TIFM_CORE=m CONFIG_TIFM_7XX1=m CONFIG_ICS932S401=m CONFIG_ENCLOSURE_SERVICES=m CONFIG_SMPRO_ERRMON=m CONFIG_SMPRO_MISC=m +# CONFIG_HI6421V600_IRQ is not set CONFIG_HP_ILO=m CONFIG_APDS9802ALS=m CONFIG_ISL29003=m @@ -2705,8 +2834,12 @@ CONFIG_DW_XDATA_PCIE=m # CONFIG_PCI_ENDPOINT_TEST is not set # CONFIG_XILINX_SDFEC is not set CONFIG_MISC_RTSX=m +# CONFIG_HISI_HIKEY_USB is not set +# CONFIG_OPEN_DICE is not set +# CONFIG_VCPU_STALL_DETECTOR is not set CONFIG_TPS6594_ESM=m CONFIG_TPS6594_PFSM=m +# CONFIG_NSM is not set CONFIG_C2PORT=m CONFIG_C2PORT_DURAMAR_2150=m @@ -2715,7 +2848,6 @@ CONFIG_C2PORT_DURAMAR_2150=m # # CONFIG_EEPROM_AT24 is not set CONFIG_EEPROM_AT25=m -CONFIG_EEPROM_LEGACY=m CONFIG_EEPROM_MAX6875=m CONFIG_EEPROM_93CX6=y CONFIG_EEPROM_93XX46=m @@ -2730,7 +2862,7 @@ CONFIG_CB710_DEBUG_ASSUMPTIONS=y # # Texas Instruments shared transport line discipline # -CONFIG_TI_ST=m +# CONFIG_TI_ST is not set # end of Texas Instruments shared transport line discipline CONFIG_SENSORS_LIS3_I2C=m @@ -2739,6 +2871,7 @@ CONFIG_INTEL_MEI=m CONFIG_INTEL_MEI_ME=m CONFIG_INTEL_MEI_TXE=m CONFIG_INTEL_MEI_GSC=m +# CONFIG_INTEL_MEI_VSC_HW is not set CONFIG_INTEL_MEI_HDCP=m CONFIG_INTEL_MEI_PXP=m CONFIG_INTEL_MEI_GSC_PROXY=m @@ -2756,6 +2889,7 @@ CONFIG_PVPANIC=y CONFIG_PVPANIC_MMIO=m CONFIG_PVPANIC_PCI=m CONFIG_GP_PCI1XXXX=m +CONFIG_KEBA_CP500=m # end of Misc devices # @@ -2865,7 +2999,6 @@ CONFIG_SCSI_INITIO=m CONFIG_SCSI_INIA100=m CONFIG_SCSI_PPA=m CONFIG_SCSI_IMM=m -# CONFIG_SCSI_IZIP_EPP16 is not set # CONFIG_SCSI_IZIP_SLOW_CTR is not set CONFIG_SCSI_STEX=m CONFIG_SCSI_SYM53C8XX_2=m @@ -2923,6 +3056,7 @@ CONFIG_SATA_AHCI=y CONFIG_SATA_MOBILE_LPM_POLICY=0 CONFIG_SATA_AHCI_PLATFORM=y CONFIG_AHCI_DWC=m +CONFIG_AHCI_CEVA=m CONFIG_SATA_INIC162X=m CONFIG_SATA_ACARD_AHCI=m CONFIG_SATA_SIL24=m @@ -2939,7 +3073,7 @@ CONFIG_ATA_BMDMA=y # # SATA SFF controllers with BMDMA # -CONFIG_ATA_PIIX=m +CONFIG_ATA_PIIX=y CONFIG_SATA_DWC=m # CONFIG_SATA_DWC_OLD_DMA is not set CONFIG_SATA_MV=m @@ -2998,6 +3132,8 @@ CONFIG_PATA_MPIIX=m CONFIG_PATA_NS87410=m CONFIG_PATA_OPTI=m CONFIG_PATA_PCMCIA=m +CONFIG_PATA_PLATFORM=m +CONFIG_PATA_OF_PLATFORM=m CONFIG_PATA_RZ1000=m # CONFIG_PATA_PARPORT is not set @@ -3009,19 +3145,16 @@ CONFIG_ATA_GENERIC=m CONFIG_PATA_LEGACY=m CONFIG_MD=y CONFIG_BLK_DEV_MD=y -# CONFIG_MD_AUTODETECT is not set +CONFIG_MD_AUTODETECT=y CONFIG_MD_BITMAP_FILE=y CONFIG_MD_LINEAR=m CONFIG_MD_RAID0=m CONFIG_MD_RAID1=m 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_BCACHE_ASYNC_REGISTRATION=y CONFIG_BLK_DEV_DM_BUILTIN=y CONFIG_BLK_DEV_DM=m @@ -3061,6 +3194,7 @@ CONFIG_DM_LOG_WRITES=m CONFIG_DM_INTEGRITY=m CONFIG_DM_ZONED=m CONFIG_DM_AUDIT=y +# CONFIG_DM_VDO is not set CONFIG_TARGET_CORE=m CONFIG_TCM_IBLOCK=m CONFIG_TCM_FILEIO=m @@ -3118,6 +3252,7 @@ CONFIG_VXLAN=m CONFIG_GENEVE=m CONFIG_BAREUDP=m CONFIG_GTP=m +# CONFIG_PFCP is not set CONFIG_AMT=m CONFIG_MACSEC=m CONFIG_NETCONSOLE=m @@ -3135,6 +3270,7 @@ CONFIG_TAP=m CONFIG_VETH=m CONFIG_VIRTIO_NET=m CONFIG_NLMON=m +CONFIG_NETKIT=y CONFIG_NET_VRF=m CONFIG_VSOCKMON=m CONFIG_MHI_NET=m @@ -3194,13 +3330,13 @@ CONFIG_NET_DSA_MICROCHIP_KSZ_COMMON=m # CONFIG_NET_DSA_MICROCHIP_KSZ_PTP is not set # CONFIG_NET_DSA_MICROCHIP_KSZ8863_SMI is not set CONFIG_NET_DSA_MV88E6XXX=m -# CONFIG_NET_DSA_MV88E6XXX_PTP is not set +CONFIG_NET_DSA_MV88E6XXX_PTP=y CONFIG_NET_DSA_MSCC_FELIX_DSA_LIB=m CONFIG_NET_DSA_MSCC_OCELOT_EXT=m CONFIG_NET_DSA_MSCC_SEVILLE=m CONFIG_NET_DSA_AR9331=m CONFIG_NET_DSA_QCA8K=m -# CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT is not set +CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT=y CONFIG_NET_DSA_SJA1105=m # CONFIG_NET_DSA_SJA1105_PTP is not set CONFIG_NET_DSA_XRS700X=m @@ -3209,8 +3345,6 @@ CONFIG_NET_DSA_XRS700X_MDIO=m CONFIG_NET_DSA_REALTEK=m # CONFIG_NET_DSA_REALTEK_MDIO is not set # CONFIG_NET_DSA_REALTEK_SMI is not set -CONFIG_NET_DSA_REALTEK_RTL8365MB=m -CONFIG_NET_DSA_REALTEK_RTL8366RB=m # CONFIG_NET_DSA_SMSC_LAN9303_I2C is not set # CONFIG_NET_DSA_SMSC_LAN9303_MDIO is not set # CONFIG_NET_DSA_VITESSE_VSC73XX_SPI is not set @@ -3303,6 +3437,7 @@ CONFIG_CHELSIO_TLS_DEVICE=m CONFIG_NET_VENDOR_CISCO=y CONFIG_ENIC=m CONFIG_NET_VENDOR_CORTINA=y +CONFIG_GEMINI_ETHERNET=m CONFIG_NET_VENDOR_DAVICOM=y CONFIG_DM9051=m # CONFIG_DNET is not set @@ -3332,6 +3467,7 @@ CONFIG_BE2NET_SKYHAWK=y CONFIG_NET_VENDOR_ENGLEDER=y # CONFIG_TSNEP is not set CONFIG_NET_VENDOR_EZCHIP=y +CONFIG_EZCHIP_NPS_MANAGEMENT_ENET=m CONFIG_NET_VENDOR_FUJITSU=y CONFIG_PCMCIA_FMVJ18X=m CONFIG_NET_VENDOR_FUNGIBLE=y @@ -3343,6 +3479,8 @@ CONFIG_NET_VENDOR_HUAWEI=y CONFIG_HINIC=m CONFIG_NET_VENDOR_I825XX=y CONFIG_NET_VENDOR_INTEL=y +CONFIG_LIBETH=m +CONFIG_LIBIE=m CONFIG_E100=m CONFIG_E1000=m CONFIG_E1000E=m @@ -3363,14 +3501,18 @@ CONFIG_I40E_DCB=y CONFIG_IAVF=m CONFIG_I40EVF=m CONFIG_ICE=m +CONFIG_ICE_HWMON=y CONFIG_ICE_SWITCHDEV=y CONFIG_ICE_HWTS=y CONFIG_FM10K=m CONFIG_IGC=m +CONFIG_IGC_LEDS=y +# CONFIG_IDPF is not set CONFIG_JME=m CONFIG_NET_VENDOR_ADI=y CONFIG_ADIN1110=m CONFIG_NET_VENDOR_LITEX=y +CONFIG_LITEX_LITEETH=m CONFIG_NET_VENDOR_MARVELL=y CONFIG_MVMDIO=m CONFIG_SKGE=m @@ -3379,6 +3521,7 @@ CONFIG_SKGE_GENESIS=y CONFIG_SKY2=m # CONFIG_SKY2_DEBUG is not set CONFIG_OCTEON_EP=m +CONFIG_OCTEON_EP_VF=m CONFIG_PRESTERA=m CONFIG_PRESTERA_PCI=m CONFIG_NET_VENDOR_MELLANOX=y @@ -3399,13 +3542,15 @@ CONFIG_MLX5_CLS_ACT=y CONFIG_MLX5_TC_CT=y CONFIG_MLX5_TC_SAMPLE=y CONFIG_MLX5_CORE_EN_DCB=y -# CONFIG_MLX5_CORE_IPOIB is not set -# CONFIG_MLX5_MACSEC is not set -# CONFIG_MLX5_EN_IPSEC is not set +CONFIG_MLX5_CORE_IPOIB=y +CONFIG_MLX5_MACSEC=y +CONFIG_MLX5_EN_IPSEC=y CONFIG_MLX5_EN_TLS=y CONFIG_MLX5_SW_STEERING=y +CONFIG_MLX5_HW_STEERING=y CONFIG_MLX5_SF=y CONFIG_MLX5_SF_MANAGER=y +CONFIG_MLX5_DPLL=m CONFIG_MLXSW_CORE=m CONFIG_MLXSW_CORE_HWMON=y CONFIG_MLXSW_CORE_THERMAL=y @@ -3415,6 +3560,8 @@ CONFIG_MLXSW_SPECTRUM=m CONFIG_MLXSW_SPECTRUM_DCB=y CONFIG_MLXSW_MINIMAL=m CONFIG_MLXFW=m +CONFIG_NET_VENDOR_META=y +CONFIG_FBNIC=m CONFIG_NET_VENDOR_MICREL=y CONFIG_KS8842=m CONFIG_KS8851=m @@ -3425,9 +3572,14 @@ CONFIG_ENC28J60=m # CONFIG_ENC28J60_WRITEVERIFY is not set CONFIG_ENCX24J600=m CONFIG_LAN743X=m -# CONFIG_VCAP is not set +# CONFIG_LAN865X is not set +CONFIG_LAN966X_SWITCH=m +CONFIG_LAN966X_DCB=y +CONFIG_VCAP=y +CONFIG_FDMA=y CONFIG_NET_VENDOR_MICROSEMI=y CONFIG_MSCC_OCELOT_SWITCH_LIB=m +CONFIG_MSCC_OCELOT_SWITCH=m CONFIG_NET_VENDOR_MICROSOFT=y CONFIG_MICROSOFT_MANA=m CONFIG_NET_VENDOR_MYRI=y @@ -3455,6 +3607,7 @@ CONFIG_NET_VENDOR_NVIDIA=y CONFIG_FORCEDETH=m CONFIG_NET_VENDOR_OKI=y CONFIG_ETHOC=m +CONFIG_OA_TC6=m CONFIG_NET_VENDOR_PACKET_ENGINES=y CONFIG_HAMACHI=m CONFIG_YELLOWFIN=m @@ -3478,6 +3631,9 @@ CONFIG_QED_OOO=y CONFIG_NET_VENDOR_BROCADE=y CONFIG_BNA=m CONFIG_NET_VENDOR_QUALCOMM=y +CONFIG_QCA7000=m +CONFIG_QCA7000_SPI=m +CONFIG_QCA7000_UART=m CONFIG_QCOM_EMAC=m CONFIG_RMNET=m CONFIG_NET_VENDOR_RDC=y @@ -3491,6 +3647,8 @@ CONFIG_8139TOO=m CONFIG_8139TOO_8129=y # CONFIG_8139_OLD_RX_RESET is not set CONFIG_R8169=m +CONFIG_R8169_LEDS=y +# CONFIG_RTASE is not set CONFIG_NET_VENDOR_RENESAS=y CONFIG_NET_VENDOR_ROCKER=y CONFIG_ROCKER=m @@ -3525,7 +3683,9 @@ CONFIG_NET_VENDOR_STMICRO=y CONFIG_STMMAC_ETH=m # CONFIG_STMMAC_SELFTESTS is not set CONFIG_STMMAC_PLATFORM=m +CONFIG_DWMAC_DWC_QOS_ETH=m CONFIG_DWMAC_GENERIC=m +CONFIG_DWMAC_INTEL_PLAT=m CONFIG_DWMAC_INTEL=m # CONFIG_STMMAC_PCI is not set CONFIG_NET_VENDOR_SUN=y @@ -3538,6 +3698,7 @@ CONFIG_DWC_XLGMAC=m CONFIG_DWC_XLGMAC_PCI=m CONFIG_NET_VENDOR_TEHUTI=y CONFIG_TEHUTI=m +CONFIG_TEHUTI_TN40=m CONFIG_NET_VENDOR_TI=y # CONFIG_TI_CPSW_PHY_SEL is not set CONFIG_TLAN=m @@ -3545,7 +3706,7 @@ CONFIG_NET_VENDOR_VERTEXCOM=y # CONFIG_MSE102X is not set CONFIG_NET_VENDOR_VIA=y CONFIG_VIA_RHINE=m -# CONFIG_VIA_RHINE_MMIO is not set +CONFIG_VIA_RHINE_MMIO=y CONFIG_VIA_VELOCITY=m CONFIG_NET_VENDOR_WANGXUN=y CONFIG_LIBWX=m @@ -3568,17 +3729,18 @@ CONFIG_FDDI=y CONFIG_DEFXX=m CONFIG_SKFP=m # CONFIG_HIPPI is not set -CONFIG_NET_SB1000=m CONFIG_PHYLINK=m CONFIG_PHYLIB=m CONFIG_SWPHY=y -# CONFIG_LED_TRIGGER_PHY is not set +CONFIG_LED_TRIGGER_PHY=y +CONFIG_PHYLIB_LEDS=y CONFIG_FIXED_PHY=m CONFIG_SFP=m # # MII PHY device drivers # +# CONFIG_AIR_EN8811H_PHY is not set CONFIG_AMD_PHY=m CONFIG_ADIN_PHY=m CONFIG_ADIN1100_PHY=m @@ -3590,6 +3752,7 @@ CONFIG_BCM7XXX_PHY=m CONFIG_BCM84881_PHY=m CONFIG_BCM87XX_PHY=m CONFIG_BCM_NET_PHYLIB=m +CONFIG_BCM_NET_PHYPTP=m CONFIG_CICADA_PHY=m CONFIG_CORTINA_PHY=m CONFIG_DAVICOM_PHY=m @@ -3614,7 +3777,11 @@ CONFIG_NATIONAL_PHY=m # CONFIG_NXP_C45_TJA11XX_PHY is not set CONFIG_NXP_TJA11XX_PHY=m CONFIG_NCN26000_PHY=m +CONFIG_QCOM_NET_PHYLIB=m CONFIG_AT803X_PHY=m +# CONFIG_QCA83XX_PHY is not set +# CONFIG_QCA808X_PHY is not set +CONFIG_QCA807X_PHY=m CONFIG_QSEMI_PHY=m CONFIG_REALTEK_PHY=m CONFIG_RENESAS_PHY=m @@ -3628,11 +3795,14 @@ CONFIG_DP83848_PHY=m CONFIG_DP83867_PHY=m CONFIG_DP83869_PHY=m CONFIG_DP83TD510_PHY=m +# CONFIG_DP83TG720_PHY is not set CONFIG_VITESSE_PHY=m CONFIG_XILINX_GMII2RGMII=m CONFIG_MICREL_KS8995MA=m CONFIG_PSE_CONTROLLER=y CONFIG_PSE_REGULATOR=m +# CONFIG_PSE_PD692X0 is not set +# CONFIG_PSE_TPS23881 is not set CONFIG_CAN_DEV=m CONFIG_CAN_VCAN=m CONFIG_CAN_VXCAN=m @@ -3640,6 +3810,8 @@ CONFIG_CAN_NETLINK=y CONFIG_CAN_CALC_BITTIMING=y CONFIG_CAN_RX_OFFLOAD=y CONFIG_CAN_CAN327=m +CONFIG_CAN_FLEXCAN=m +CONFIG_CAN_GRCAN=m CONFIG_CAN_JANZ_ICAN3=m CONFIG_CAN_KVASER_PCIEFD=m CONFIG_CAN_SLCAN=m @@ -3647,10 +3819,12 @@ CONFIG_CAN_C_CAN=m CONFIG_CAN_C_CAN_PLATFORM=m CONFIG_CAN_C_CAN_PCI=m CONFIG_CAN_CC770=m -CONFIG_CAN_CC770_ISA=m +# CONFIG_CAN_CC770_ISA is not set CONFIG_CAN_CC770_PLATFORM=m CONFIG_CAN_CTUCANFD=m CONFIG_CAN_CTUCANFD_PCI=m +CONFIG_CAN_CTUCANFD_PLATFORM=m +# CONFIG_CAN_ESD_402_PCI is not set CONFIG_CAN_IFI_CANFD=m CONFIG_CAN_M_CAN=m # CONFIG_CAN_M_CAN_PCI is not set @@ -3666,7 +3840,7 @@ CONFIG_CAN_PEAK_PCI=m CONFIG_CAN_PEAK_PCIEC=y CONFIG_CAN_PEAK_PCMCIA=m CONFIG_CAN_PLX_PCI=m -CONFIG_CAN_SJA1000_ISA=m +# CONFIG_CAN_SJA1000_ISA is not set # CONFIG_CAN_SJA1000_PLATFORM is not set CONFIG_CAN_SOFTING=m CONFIG_CAN_SOFTING_CS=m @@ -3701,26 +3875,36 @@ CONFIG_CAN_UCAN=m # CONFIG_MCTP_SERIAL=m CONFIG_MCTP_TRANSPORT_I2C=m +# CONFIG_MCTP_TRANSPORT_I3C is not set # end of MCTP Device Drivers CONFIG_MDIO_DEVICE=m CONFIG_MDIO_BUS=m CONFIG_FWNODE_MDIO=m +CONFIG_OF_MDIO=m CONFIG_ACPI_MDIO=m CONFIG_MDIO_DEVRES=m CONFIG_MDIO_BITBANG=m CONFIG_MDIO_BCM_UNIMAC=m CONFIG_MDIO_CAVIUM=m CONFIG_MDIO_GPIO=m +CONFIG_MDIO_HISI_FEMAC=m CONFIG_MDIO_I2C=m CONFIG_MDIO_MVUSB=m CONFIG_MDIO_MSCC_MIIM=m +CONFIG_MDIO_OCTEON=m +CONFIG_MDIO_IPQ4019=m +CONFIG_MDIO_IPQ8064=m CONFIG_MDIO_REGMAP=m CONFIG_MDIO_THUNDER=m # # MDIO Multiplexers # +CONFIG_MDIO_BUS_MUX=m +CONFIG_MDIO_BUS_MUX_GPIO=m +CONFIG_MDIO_BUS_MUX_MULTIPLEXER=m +CONFIG_MDIO_BUS_MUX_MMIOREG=m # # PCS device drivers @@ -3815,7 +3999,6 @@ CONFIG_ATH9K_BTCOEX_SUPPORT=y CONFIG_ATH9K=m CONFIG_ATH9K_PCI=y CONFIG_ATH9K_AHB=y -# CONFIG_ATH9K_DEBUGFS is not set # CONFIG_ATH9K_DYNACK is not set CONFIG_ATH9K_WOW=y CONFIG_ATH9K_RFKILL=y @@ -3842,10 +4025,12 @@ CONFIG_WIL6210_TRACING=y CONFIG_ATH10K=m CONFIG_ATH10K_CE=y CONFIG_ATH10K_PCI=m +# CONFIG_ATH10K_AHB is not set CONFIG_ATH10K_SDIO=m CONFIG_ATH10K_USB=m CONFIG_ATH10K_DEBUG=y # CONFIG_ATH10K_DEBUGFS is not set +CONFIG_ATH10K_LEDS=y # CONFIG_ATH10K_TRACING is not set CONFIG_WCN36XX=m # CONFIG_WCN36XX_DEBUGFS is not set @@ -3857,9 +4042,6 @@ CONFIG_ATH12K=m # CONFIG_ATH12K_DEBUG is not set # CONFIG_ATH12K_TRACING is not set CONFIG_WLAN_VENDOR_ATMEL=y -CONFIG_ATMEL=m -CONFIG_PCI_ATMEL=m -CONFIG_PCMCIA_ATMEL=m CONFIG_AT76C50X_USB=m CONFIG_WLAN_VENDOR_BROADCOM=y CONFIG_B43=m @@ -3902,9 +4084,6 @@ CONFIG_BRCMFMAC_USB=y CONFIG_BRCMFMAC_PCIE=y # CONFIG_BRCM_TRACING is not set # CONFIG_BRCMDBG is not set -CONFIG_WLAN_VENDOR_CISCO=y -CONFIG_AIRO=m -CONFIG_AIRO_CS=m CONFIG_WLAN_VENDOR_INTEL=y CONFIG_IPW2100=m CONFIG_IPW2100_MONITOR=y @@ -3941,22 +4120,6 @@ CONFIG_IWLWIFI_DEBUG=y # end of Debugging Options CONFIG_WLAN_VENDOR_INTERSIL=y -CONFIG_HOSTAP=m -CONFIG_HOSTAP_FIRMWARE=y -CONFIG_HOSTAP_FIRMWARE_NVRAM=y -CONFIG_HOSTAP_PLX=m -CONFIG_HOSTAP_PCI=m -CONFIG_HOSTAP_CS=m -CONFIG_HERMES=m -CONFIG_HERMES_PRISM=y -CONFIG_HERMES_CACHE_FW_ON_INIT=y -CONFIG_PLX_HERMES=m -CONFIG_TMD_HERMES=m -CONFIG_NORTEL_HERMES=m -CONFIG_PCI_HERMES=m -CONFIG_PCMCIA_HERMES=m -CONFIG_PCMCIA_SPECTRUM=m -CONFIG_ORINOCO_USB=m CONFIG_P54_COMMON=m CONFIG_P54_USB=m CONFIG_P54_PCI=m @@ -3966,12 +4129,13 @@ CONFIG_P54_LEDS=y CONFIG_WLAN_VENDOR_MARVELL=y CONFIG_LIBERTAS=m CONFIG_LIBERTAS_USB=m -CONFIG_LIBERTAS_CS=m CONFIG_LIBERTAS_SDIO=m CONFIG_LIBERTAS_SPI=m # CONFIG_LIBERTAS_DEBUG is not set CONFIG_LIBERTAS_MESH=y -# CONFIG_LIBERTAS_THINFIRM is not set +CONFIG_LIBERTAS_THINFIRM=m +# CONFIG_LIBERTAS_THINFIRM_DEBUG is not set +CONFIG_LIBERTAS_THINFIRM_USB=m CONFIG_MWIFIEX=m CONFIG_MWIFIEX_SDIO=m CONFIG_MWIFIEX_PCIE=m @@ -4006,11 +4170,14 @@ CONFIG_MT7921E=m CONFIG_MT7921S=m CONFIG_MT7921U=m CONFIG_MT7996E=m +CONFIG_MT7925_COMMON=m +CONFIG_MT7925E=m +CONFIG_MT7925U=m CONFIG_WLAN_VENDOR_MICROCHIP=y CONFIG_WILC1000=m CONFIG_WILC1000_SDIO=m -# CONFIG_WILC1000_SPI is not set -# CONFIG_WILC1000_HW_OOB_INTR is not set +CONFIG_WILC1000_SPI=m +CONFIG_WILC1000_HW_OOB_INTR=y CONFIG_WLAN_VENDOR_PURELIFI=y CONFIG_PLFXLC=m CONFIG_WLAN_VENDOR_RALINK=y @@ -4056,11 +4223,13 @@ CONFIG_RTL8188EE=m CONFIG_RTL8192EE=m CONFIG_RTL8821AE=m CONFIG_RTL8192CU=m +CONFIG_RTL8192DU=m CONFIG_RTLWIFI=m CONFIG_RTLWIFI_PCI=m CONFIG_RTLWIFI_USB=m CONFIG_RTLWIFI_DEBUG=y CONFIG_RTL8192C_COMMON=m +CONFIG_RTL8192D_COMMON=m CONFIG_RTL8723_COMMON=m CONFIG_RTLBTCOEXIST=m CONFIG_RTL8XXXU=m @@ -4072,6 +4241,8 @@ CONFIG_RTW88_SDIO=m CONFIG_RTW88_USB=m CONFIG_RTW88_8822B=m CONFIG_RTW88_8822C=m +CONFIG_RTW88_8723X=m +CONFIG_RTW88_8703B=m CONFIG_RTW88_8723D=m CONFIG_RTW88_8821C=m CONFIG_RTW88_8822BE=m @@ -4082,6 +4253,7 @@ CONFIG_RTW88_8822CS=m CONFIG_RTW88_8822CU=m CONFIG_RTW88_8723DE=m CONFIG_RTW88_8723DS=m +CONFIG_RTW88_8723CS=m CONFIG_RTW88_8723DU=m CONFIG_RTW88_8821CE=m CONFIG_RTW88_8821CS=m @@ -4093,12 +4265,17 @@ CONFIG_RTW89_CORE=m CONFIG_RTW89_PCI=m CONFIG_RTW89_8851B=m CONFIG_RTW89_8852A=m +CONFIG_RTW89_8852B_COMMON=m CONFIG_RTW89_8852B=m +CONFIG_RTW89_8852BT=m CONFIG_RTW89_8852C=m +CONFIG_RTW89_8922A=m CONFIG_RTW89_8851BE=m CONFIG_RTW89_8852AE=m CONFIG_RTW89_8852BE=m +CONFIG_RTW89_8852BTE=m CONFIG_RTW89_8852CE=m +CONFIG_RTW89_8922AE=m CONFIG_RTW89_DEBUG=y CONFIG_RTW89_DEBUGMSG=y CONFIG_RTW89_DEBUGFS=y @@ -4121,17 +4298,14 @@ CONFIG_WL1251_SDIO=m CONFIG_WL12XX=m CONFIG_WL18XX=m CONFIG_WLCORE=m +CONFIG_WLCORE_SPI=m CONFIG_WLCORE_SDIO=m CONFIG_WLAN_VENDOR_ZYDAS=y -CONFIG_USB_ZD1201=m CONFIG_ZD1211RW=m # CONFIG_ZD1211RW_DEBUG is not set CONFIG_WLAN_VENDOR_QUANTENNA=y CONFIG_QTNFMAC=m CONFIG_QTNFMAC_PCIE=m -CONFIG_PCMCIA_RAYCS=m -CONFIG_PCMCIA_WL3501=m -CONFIG_USB_NET_RNDIS_WLAN=m CONFIG_MAC80211_HWSIM=m CONFIG_VIRT_WIFI=m CONFIG_WAN=y @@ -4142,6 +4316,9 @@ CONFIG_HDLC_CISCO=m CONFIG_HDLC_FR=m CONFIG_HDLC_PPP=m CONFIG_HDLC_X25=m +CONFIG_FRAMER=m +CONFIG_GENERIC_FRAMER=y +CONFIG_FRAMER_PEF2256=m CONFIG_PCI200SYN=m CONFIG_WANXL=m CONFIG_PC300TOO=m @@ -4164,10 +4341,10 @@ CONFIG_IEEE802154_CA8210=m # CONFIG_WWAN=y CONFIG_WWAN_DEBUGFS=y -# CONFIG_WWAN_HWSIM is not set +CONFIG_WWAN_HWSIM=m CONFIG_MHI_WWAN_CTRL=m CONFIG_MHI_WWAN_MBIM=m -# CONFIG_RPMSG_WWAN_CTRL is not set +CONFIG_RPMSG_WWAN_CTRL=m CONFIG_IOSM=m CONFIG_MTK_T7XX=m # end of Wireless WAN @@ -4182,8 +4359,6 @@ CONFIG_HYPERV_NET=m CONFIG_NET_FAILOVER=m CONFIG_ISDN=y CONFIG_ISDN_CAPI=y -CONFIG_CAPI_TRACE=y -CONFIG_ISDN_CAPI_MIDDLEWARE=y CONFIG_MISDN=m CONFIG_MISDN_DSP=m CONFIG_MISDN_L1OIP=m @@ -4247,7 +4422,6 @@ CONFIG_KEYBOARD_MATRIX=m CONFIG_KEYBOARD_LM8323=m CONFIG_KEYBOARD_LM8333=m CONFIG_KEYBOARD_MAX7359=m -CONFIG_KEYBOARD_MCS=m CONFIG_KEYBOARD_MPR121=m CONFIG_KEYBOARD_NEWTON=m CONFIG_KEYBOARD_OPENCORES=m @@ -4256,10 +4430,13 @@ CONFIG_KEYBOARD_SAMSUNG=m CONFIG_KEYBOARD_STOWAWAY=m CONFIG_KEYBOARD_SUNKBD=m CONFIG_KEYBOARD_IQS62X=m +CONFIG_KEYBOARD_OMAP4=m CONFIG_KEYBOARD_TM2_TOUCHKEY=m CONFIG_KEYBOARD_TWL4030=m CONFIG_KEYBOARD_XTKBD=m CONFIG_KEYBOARD_CROS_EC=m +CONFIG_KEYBOARD_CAP11XX=m +CONFIG_KEYBOARD_BCM=m CONFIG_KEYBOARD_CYPRESS_SF=m CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=m @@ -4327,6 +4504,7 @@ CONFIG_JOYSTICK_PXRC=m CONFIG_JOYSTICK_QWIIC=m CONFIG_JOYSTICK_FSIA6B=m CONFIG_JOYSTICK_SENSEHAT=m +CONFIG_JOYSTICK_SEESAW=m CONFIG_INPUT_TABLET=y CONFIG_TABLET_USB_ACECAD=m CONFIG_TABLET_USB_AIPTEK=m @@ -4342,30 +4520,33 @@ CONFIG_TOUCHSCREEN_AD7879=m CONFIG_TOUCHSCREEN_AD7879_I2C=m CONFIG_TOUCHSCREEN_AD7879_SPI=m CONFIG_TOUCHSCREEN_ADC=m +CONFIG_TOUCHSCREEN_AR1021_I2C=m CONFIG_TOUCHSCREEN_ATMEL_MXT=m CONFIG_TOUCHSCREEN_ATMEL_MXT_T37=y CONFIG_TOUCHSCREEN_AUO_PIXCIR=m CONFIG_TOUCHSCREEN_BU21013=m CONFIG_TOUCHSCREEN_BU21029=m +CONFIG_TOUCHSCREEN_CHIPONE_ICN8318=m CONFIG_TOUCHSCREEN_CHIPONE_ICN8505=m CONFIG_TOUCHSCREEN_CY8CTMA140=m CONFIG_TOUCHSCREEN_CY8CTMG110=m CONFIG_TOUCHSCREEN_CYTTSP_CORE=m CONFIG_TOUCHSCREEN_CYTTSP_I2C=m CONFIG_TOUCHSCREEN_CYTTSP_SPI=m -CONFIG_TOUCHSCREEN_CYTTSP4_CORE=m -CONFIG_TOUCHSCREEN_CYTTSP4_I2C=m -CONFIG_TOUCHSCREEN_CYTTSP4_SPI=m CONFIG_TOUCHSCREEN_CYTTSP5=m CONFIG_TOUCHSCREEN_DA9034=m CONFIG_TOUCHSCREEN_DA9052=m CONFIG_TOUCHSCREEN_DYNAPRO=m CONFIG_TOUCHSCREEN_HAMPSHIRE=m CONFIG_TOUCHSCREEN_EETI=m +CONFIG_TOUCHSCREEN_EGALAX=m CONFIG_TOUCHSCREEN_EGALAX_SERIAL=m CONFIG_TOUCHSCREEN_EXC3000=m CONFIG_TOUCHSCREEN_FUJITSU=m CONFIG_TOUCHSCREEN_GOODIX=m +CONFIG_TOUCHSCREEN_GOODIX_BERLIN_CORE=m +CONFIG_TOUCHSCREEN_GOODIX_BERLIN_I2C=m +CONFIG_TOUCHSCREEN_GOODIX_BERLIN_SPI=m CONFIG_TOUCHSCREEN_HIDEEP=m CONFIG_TOUCHSCREEN_HYCON_HY46XX=m CONFIG_TOUCHSCREEN_HYNITRON_CSTXXX=m @@ -4379,13 +4560,13 @@ CONFIG_TOUCHSCREEN_ELO=m CONFIG_TOUCHSCREEN_WACOM_W8001=m CONFIG_TOUCHSCREEN_WACOM_I2C=m CONFIG_TOUCHSCREEN_MAX11801=m -CONFIG_TOUCHSCREEN_MCS5000=m CONFIG_TOUCHSCREEN_MMS114=m CONFIG_TOUCHSCREEN_MELFAS_MIP4=m CONFIG_TOUCHSCREEN_MSG2638=m CONFIG_TOUCHSCREEN_MTOUCH=m CONFIG_TOUCHSCREEN_NOVATEK_NVT_TS=m CONFIG_TOUCHSCREEN_IMAGIS=m +CONFIG_TOUCHSCREEN_IMX6UL_TSC=m CONFIG_TOUCHSCREEN_INEXIO=m CONFIG_TOUCHSCREEN_PENMOUNT=m CONFIG_TOUCHSCREEN_EDT_FT5X06=m @@ -4446,13 +4627,17 @@ CONFIG_TOUCHSCREEN_HIMAX_HX83112B=m CONFIG_INPUT_MISC=y CONFIG_INPUT_88PM860X_ONKEY=m CONFIG_INPUT_88PM80X_ONKEY=m +# CONFIG_INPUT_88PM886_ONKEY is not set CONFIG_INPUT_AD714X=m CONFIG_INPUT_AD714X_I2C=m CONFIG_INPUT_AD714X_SPI=m CONFIG_INPUT_ARIZONA_HAPTICS=m +CONFIG_INPUT_ATMEL_CAPTOUCH=m CONFIG_INPUT_BMA150=m +CONFIG_INPUT_CS40L50_VIBRA=m CONFIG_INPUT_E3X0_BUTTON=m CONFIG_INPUT_PCSPKR=m +# CONFIG_INPUT_MAX77650_ONKEY is not set CONFIG_INPUT_MAX77693_HAPTIC=m CONFIG_INPUT_MAX8925_ONKEY=m CONFIG_INPUT_MAX8997_HAPTIC=m @@ -4462,6 +4647,7 @@ CONFIG_INPUT_APANEL=m CONFIG_INPUT_GPIO_BEEPER=m CONFIG_INPUT_GPIO_DECODER=m CONFIG_INPUT_GPIO_VIBRA=m +# CONFIG_INPUT_CPCAP_PWRBUTTON is not set CONFIG_INPUT_ATLAS_BTNS=m CONFIG_INPUT_ATI_REMOTE2=m CONFIG_INPUT_KEYSPAN_REMOTE=m @@ -4471,6 +4657,8 @@ CONFIG_INPUT_YEALINK=m CONFIG_INPUT_CM109=m CONFIG_INPUT_REGULATOR_HAPTIC=m CONFIG_INPUT_RETU_PWRBUTTON=m +# CONFIG_INPUT_TPS65218_PWRBUTTON is not set +# CONFIG_INPUT_TPS65219_PWRBUTTON is not set CONFIG_INPUT_AXP20X_PEK=m CONFIG_INPUT_TWL4030_PWRBUTTON=m CONFIG_INPUT_TWL4030_VIBRA=m @@ -4480,6 +4668,7 @@ CONFIG_INPUT_PALMAS_PWRBUTTON=m CONFIG_INPUT_PCF8574=m CONFIG_INPUT_PWM_BEEPER=m CONFIG_INPUT_PWM_VIBRA=m +# CONFIG_INPUT_RK805_PWRKEY is not set CONFIG_INPUT_GPIO_ROTARY_ENCODER=m CONFIG_INPUT_DA7280_HAPTICS=m CONFIG_INPUT_DA9052_ONKEY=m @@ -4503,6 +4692,7 @@ CONFIG_INPUT_SOC_BUTTON_ARRAY=m CONFIG_INPUT_DRV260X_HAPTICS=m CONFIG_INPUT_DRV2665_HAPTICS=m CONFIG_INPUT_DRV2667_HAPTICS=m +# CONFIG_INPUT_STPMIC1_ONKEY is not set CONFIG_RMI4_CORE=m CONFIG_RMI4_I2C=m CONFIG_RMI4_SPI=m @@ -4533,6 +4723,7 @@ CONFIG_SERIO_RAW=m CONFIG_SERIO_ALTERA_PS2=m CONFIG_SERIO_PS2MULT=m CONFIG_SERIO_ARC_PS2=m +CONFIG_SERIO_APBPS2=m CONFIG_HYPERV_KEYBOARD=m CONFIG_SERIO_GPIO_PS2=m CONFIG_USERIO=m @@ -4550,7 +4741,6 @@ CONFIG_VT=y CONFIG_CONSOLE_TRANSLATIONS=y CONFIG_VT_CONSOLE=y CONFIG_VT_CONSOLE_SLEEP=y -CONFIG_HW_CONSOLE=y CONFIG_VT_HW_CONSOLE_BINDING=y CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y @@ -4574,7 +4764,7 @@ CONFIG_SERIAL_8250_PCI=y CONFIG_SERIAL_8250_EXAR=y CONFIG_SERIAL_8250_CS=m CONFIG_SERIAL_8250_NR_UARTS=32 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=8 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_PCI1XXXX=m @@ -4587,6 +4777,7 @@ CONFIG_SERIAL_8250_RT288X=y CONFIG_SERIAL_8250_LPSS=m CONFIG_SERIAL_8250_MID=m CONFIG_SERIAL_8250_PERICOM=m +CONFIG_SERIAL_OF_PLATFORM=m # # Non-8250 serial port support @@ -4598,23 +4789,26 @@ CONFIG_SERIAL_UARTLITE_NR_UARTS=1 CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_SERIAL_JSM=m +CONFIG_SERIAL_SIFIVE=m # CONFIG_SERIAL_LANTIQ is not set CONFIG_SERIAL_SCCNXP=m -CONFIG_SERIAL_SC16IS7XX_CORE=m CONFIG_SERIAL_SC16IS7XX=m -CONFIG_SERIAL_SC16IS7XX_I2C=y -# CONFIG_SERIAL_SC16IS7XX_SPI is not set +CONFIG_SERIAL_SC16IS7XX_I2C=m +CONFIG_SERIAL_SC16IS7XX_SPI=m CONFIG_SERIAL_ALTERA_JTAGUART=m CONFIG_SERIAL_ALTERA_UART=m CONFIG_SERIAL_ALTERA_UART_MAXPORTS=4 CONFIG_SERIAL_ALTERA_UART_BAUDRATE=115200 +CONFIG_SERIAL_XILINX_PS_UART=m CONFIG_SERIAL_ARC=m CONFIG_SERIAL_ARC_NR_PORTS=1 CONFIG_SERIAL_RP2=m CONFIG_SERIAL_RP2_NR_UARTS=32 CONFIG_SERIAL_FSL_LPUART=m CONFIG_SERIAL_FSL_LINFLEXUART=m +CONFIG_SERIAL_CONEXANT_DIGICOLOR=m CONFIG_SERIAL_SPRD=m +# CONFIG_SERIAL_LITEUART is not set # end of Serial drivers CONFIG_SERIAL_MCTRL_GPIO=y @@ -4658,6 +4852,7 @@ CONFIG_HW_RANDOM_AMD=m CONFIG_HW_RANDOM_BA431=m CONFIG_HW_RANDOM_VIA=m CONFIG_HW_RANDOM_VIRTIO=m +CONFIG_HW_RANDOM_CCTRNG=m CONFIG_HW_RANDOM_XIPHERA=m CONFIG_APPLICOM=m CONFIG_MWAVE=m @@ -4669,6 +4864,7 @@ CONFIG_HPET_MMAP=y CONFIG_HPET_MMAP_DEFAULT=y CONFIG_HANGCHECK_TIMER=m CONFIG_TCG_TPM=m +CONFIG_TCG_TPM2_HMAC=y CONFIG_HW_RANDOM_TPM=y CONFIG_TCG_TIS_CORE=m CONFIG_TCG_TIS=m @@ -4692,6 +4888,7 @@ CONFIG_TELCLOCK=m CONFIG_XILLYBUS_CLASS=m CONFIG_XILLYBUS=m CONFIG_XILLYBUS_PCIE=m +CONFIG_XILLYBUS_OF=m CONFIG_XILLYUSB=m # end of Character devices @@ -4701,21 +4898,26 @@ CONFIG_XILLYUSB=m CONFIG_I2C=y CONFIG_ACPI_I2C_OPREGION=y CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_COMPAT=y CONFIG_I2C_CHARDEV=m CONFIG_I2C_MUX=m # # Multiplexer I2C Chip support # +CONFIG_I2C_ARB_GPIO_CHALLENGE=m CONFIG_I2C_MUX_GPIO=m +CONFIG_I2C_MUX_GPMUX=m CONFIG_I2C_MUX_LTC4306=m CONFIG_I2C_MUX_PCA9541=m CONFIG_I2C_MUX_PCA954x=m +CONFIG_I2C_MUX_PINCTRL=m CONFIG_I2C_MUX_REG=m +CONFIG_I2C_DEMUX_PINCTRL=m CONFIG_I2C_MUX_MLXCPLD=m +CONFIG_I2C_MUX_MULE=m # end of Multiplexer I2C Chip support +CONFIG_I2C_ATR=m CONFIG_I2C_HELPER_AUTO=y CONFIG_I2C_SMBUS=m CONFIG_I2C_ALGOBIT=m @@ -4737,6 +4939,7 @@ CONFIG_I2C_AMD756_S4882=m CONFIG_I2C_AMD8111=m CONFIG_I2C_AMD_MP2=m CONFIG_I2C_I801=m +CONFIG_I2C_I801_MUX=y CONFIG_I2C_ISCH=m CONFIG_I2C_ISMT=m CONFIG_I2C_PIIX4=m @@ -4749,6 +4952,7 @@ CONFIG_I2C_SIS630=m CONFIG_I2C_SIS96X=m CONFIG_I2C_VIA=m CONFIG_I2C_VIAPRO=m +CONFIG_I2C_ZHAOXIN=m # # ACPI drivers @@ -4767,9 +4971,11 @@ CONFIG_I2C_DESIGNWARE_PCI=m CONFIG_I2C_EMEV2=m CONFIG_I2C_GPIO=m # CONFIG_I2C_GPIO_FAULT_INJECTOR is not set +CONFIG_I2C_KEBA=m CONFIG_I2C_KEMPLD=m CONFIG_I2C_OCORES=m CONFIG_I2C_PCA_PLATFORM=m +CONFIG_I2C_RK3X=m CONFIG_I2C_SIMTEC=m CONFIG_I2C_XILINX=m @@ -4778,6 +4984,7 @@ CONFIG_I2C_XILINX=m # CONFIG_I2C_DIOLAN_U2C=m CONFIG_I2C_DLN2=m +CONFIG_I2C_LJCA=m CONFIG_I2C_CP2615=m CONFIG_I2C_PARPORT=m CONFIG_I2C_PCI1XXXX=m @@ -4808,6 +5015,7 @@ CONFIG_CDNS_I3C_MASTER=m CONFIG_DW_I3C_MASTER=m CONFIG_SVC_I3C_MASTER=m CONFIG_MIPI_I3C_HCI=m +CONFIG_MIPI_I3C_HCI_PCI=m CONFIG_SPI=y # CONFIG_SPI_DEBUG is not set CONFIG_SPI_MASTER=y @@ -4822,6 +5030,9 @@ CONFIG_SPI_AXI_SPI_ENGINE=m CONFIG_SPI_BITBANG=m CONFIG_SPI_BUTTERFLY=m CONFIG_SPI_CADENCE=m +CONFIG_SPI_CADENCE_QUADSPI=m +CONFIG_SPI_CADENCE_XSPI=m +CONFIG_SPI_CH341=m CONFIG_SPI_CS42L43=m CONFIG_SPI_DESIGNWARE=m # CONFIG_SPI_DW_DMA is not set @@ -4833,6 +5044,9 @@ CONFIG_SPI_INTEL=m CONFIG_SPI_INTEL_PCI=m CONFIG_SPI_INTEL_PLATFORM=m CONFIG_SPI_LM70_LLP=m +CONFIG_SPI_FSL_LIB=m +CONFIG_SPI_FSL_SPI=m +CONFIG_SPI_LJCA=m # CONFIG_SPI_MICROCHIP_CORE is not set # CONFIG_SPI_MICROCHIP_CORE_QSPI is not set CONFIG_SPI_LANTIQ_SSC=m @@ -4842,6 +5056,7 @@ CONFIG_SPI_PXA2XX=m CONFIG_SPI_PXA2XX_PCI=m CONFIG_SPI_SC18IS602=m CONFIG_SPI_SIFIVE=m +CONFIG_SPI_SN_F_OSPI=m CONFIG_SPI_MXIC=m CONFIG_SPI_XCOMM=m CONFIG_SPI_XILINX=m @@ -4894,31 +5109,45 @@ CONFIG_PPS_CLIENT_GPIO=m # CONFIG_PTP_1588_CLOCK=m CONFIG_PTP_1588_CLOCK_OPTIONAL=m - -# -# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. -# +CONFIG_DP83640_PHY=m +CONFIG_PTP_1588_CLOCK_INES=m CONFIG_PTP_1588_CLOCK_KVM=m CONFIG_PTP_1588_CLOCK_IDT82P33=m CONFIG_PTP_1588_CLOCK_IDTCM=m +# CONFIG_PTP_1588_CLOCK_FC3W is not set CONFIG_PTP_1588_CLOCK_MOCK=m CONFIG_PTP_1588_CLOCK_VMW=m CONFIG_PTP_1588_CLOCK_OCP=m # end of PTP clock support CONFIG_PINCTRL=y +CONFIG_GENERIC_PINCTRL_GROUPS=y CONFIG_PINMUX=y +CONFIG_GENERIC_PINMUX_FUNCTIONS=y CONFIG_PINCONF=y CONFIG_GENERIC_PINCONF=y # CONFIG_DEBUG_PINCTRL is not set CONFIG_PINCTRL_AMD=y +# CONFIG_PINCTRL_AS3722 is not set +# CONFIG_PINCTRL_AXP209 is not set +# CONFIG_PINCTRL_AW9523 is not set CONFIG_PINCTRL_CY8C95X0=m CONFIG_PINCTRL_DA9062=m +# CONFIG_PINCTRL_EQUILIBRIUM is not set CONFIG_PINCTRL_MCP23S08_I2C=m CONFIG_PINCTRL_MCP23S08_SPI=m CONFIG_PINCTRL_MCP23S08=m +# CONFIG_PINCTRL_MICROCHIP_SGPIO is not set +CONFIG_PINCTRL_OCELOT=m +CONFIG_PINCTRL_PALMAS=m +CONFIG_PINCTRL_PEF2256=m +# CONFIG_PINCTRL_RK805 is not set +CONFIG_PINCTRL_SINGLE=m +CONFIG_PINCTRL_STMFX=m CONFIG_PINCTRL_SX150X=y +CONFIG_PINCTRL_TPS6594=m CONFIG_PINCTRL_CS42L43=m +# CONFIG_PINCTRL_LOCHNAGAR is not set CONFIG_PINCTRL_MADERA=m CONFIG_PINCTRL_CS47L15=y CONFIG_PINCTRL_CS47L35=y @@ -4933,6 +5162,7 @@ CONFIG_PINCTRL_BAYTRAIL=y CONFIG_PINCTRL_CHERRYVIEW=y CONFIG_PINCTRL_LYNXPOINT=y CONFIG_PINCTRL_INTEL=y +CONFIG_PINCTRL_INTEL_PLATFORM=y CONFIG_PINCTRL_ALDERLAKE=y CONFIG_PINCTRL_BROXTON=y CONFIG_PINCTRL_CANNONLAKE=y @@ -4946,6 +5176,7 @@ CONFIG_PINCTRL_JASPERLAKE=y CONFIG_PINCTRL_LAKEFIELD=y CONFIG_PINCTRL_LEWISBURG=y CONFIG_PINCTRL_METEORLAKE=y +CONFIG_PINCTRL_METEORPOINT=y CONFIG_PINCTRL_SUNRISEPOINT=y CONFIG_PINCTRL_TIGERLAKE=y # end of Intel pinctrl drivers @@ -4957,27 +5188,41 @@ CONFIG_PINCTRL_TIGERLAKE=y CONFIG_GPIOLIB=y CONFIG_GPIOLIB_FASTPATH_LIMIT=512 +CONFIG_OF_GPIO=y CONFIG_GPIO_ACPI=y CONFIG_GPIOLIB_IRQCHIP=y +CONFIG_OF_GPIO_MM_GPIOCHIP=y # CONFIG_DEBUG_GPIO is not set CONFIG_GPIO_SYSFS=y CONFIG_GPIO_CDEV=y CONFIG_GPIO_CDEV_V1=y -CONFIG_GPIO_GENERIC=m +CONFIG_GPIO_GENERIC=y CONFIG_GPIO_REGMAP=m +CONFIG_GPIO_SWNODE_UNDEFINED=y CONFIG_GPIO_MAX730X=m CONFIG_GPIO_IDIO_16=m # # Memory mapped GPIO drivers # +CONFIG_GPIO_74XX_MMIO=m +CONFIG_GPIO_ALTERA=m CONFIG_GPIO_AMDPT=m +CONFIG_GPIO_CADENCE=m CONFIG_GPIO_DWAPB=m CONFIG_GPIO_EXAR=m +CONFIG_GPIO_FTGPIO010=y CONFIG_GPIO_GENERIC_PLATFORM=m +CONFIG_GPIO_GRANITERAPIDS=m +CONFIG_GPIO_GRGPIO=m +CONFIG_GPIO_HLWD=m CONFIG_GPIO_ICH=m +CONFIG_GPIO_LOGICVC=m CONFIG_GPIO_MB86S7X=m +CONFIG_GPIO_SIFIVE=m +CONFIG_GPIO_SYSCON=m CONFIG_GPIO_TANGIER=m +CONFIG_GPIO_XILINX=m CONFIG_GPIO_AMD_FCH=m # end of Memory mapped GPIO drivers @@ -4996,8 +5241,10 @@ CONFIG_GPIO_WS16C48=m # # I2C GPIO expanders # +CONFIG_GPIO_ADNP=m CONFIG_GPIO_FXL6408=m CONFIG_GPIO_DS4520=m +CONFIG_GPIO_GW_PLD=m CONFIG_GPIO_MAX7300=m CONFIG_GPIO_MAX732X=m CONFIG_GPIO_PCA953X=m @@ -5011,8 +5258,12 @@ CONFIG_GPIO_TPIC2810=m # MFD GPIO expanders # CONFIG_GPIO_ADP5520=m +CONFIG_GPIO_ADP5585=m CONFIG_GPIO_ARIZONA=m +# CONFIG_GPIO_BD71815 is not set +# CONFIG_GPIO_BD71828 is not set CONFIG_GPIO_BD9571MWV=m +# CONFIG_GPIO_CROS_EC is not set CONFIG_GPIO_CRYSTAL_COVE=m CONFIG_GPIO_DA9052=m CONFIG_GPIO_DA9055=m @@ -5020,11 +5271,16 @@ CONFIG_GPIO_DLN2=m CONFIG_GPIO_ELKHARTLAKE=m # CONFIG_GPIO_JANZ_TTL is not set CONFIG_GPIO_KEMPLD=m +CONFIG_GPIO_LJCA=m CONFIG_GPIO_LP3943=m +# CONFIG_GPIO_LP87565 is not set CONFIG_GPIO_MADERA=m +# CONFIG_GPIO_MAX77650 is not set CONFIG_GPIO_PALMAS=y CONFIG_GPIO_RC5T583=y CONFIG_GPIO_TPS65086=m +# CONFIG_GPIO_TPS65218 is not set +CONFIG_GPIO_TPS65219=m CONFIG_GPIO_TPS6586X=y CONFIG_GPIO_TPS65910=y CONFIG_GPIO_TPS65912=m @@ -5045,11 +5301,13 @@ CONFIG_GPIO_ML_IOH=m CONFIG_GPIO_PCI_IDIO_16=m CONFIG_GPIO_PCIE_IDIO_24=m CONFIG_GPIO_RDC321X=m +CONFIG_GPIO_SODAVILLE=y # end of PCI GPIO expanders # # SPI GPIO expanders # +CONFIG_GPIO_74X164=m CONFIG_GPIO_MAX3191X=m CONFIG_GPIO_MAX7301=m CONFIG_GPIO_MC33880=m @@ -5073,17 +5331,26 @@ CONFIG_GPIO_VIRTIO=m CONFIG_GPIO_SIM=m # end of Virtual GPIO drivers +# +# GPIO Debugging utilities +# +CONFIG_GPIO_SLOPPY_LOGIC_ANALYZER=m +CONFIG_GPIO_VIRTUSER=m +# end of GPIO Debugging utilities + CONFIG_W1=m CONFIG_W1_CON=y # # 1-wire Bus Masters # +# CONFIG_W1_MASTER_AMD_AXI is not set CONFIG_W1_MASTER_MATROX=m CONFIG_W1_MASTER_DS2490=m CONFIG_W1_MASTER_DS2482=m CONFIG_W1_MASTER_GPIO=m CONFIG_W1_MASTER_SGI=m +# CONFIG_W1_MASTER_UART is not set # end of 1-wire Bus Masters # @@ -5101,7 +5368,7 @@ CONFIG_W1_SLAVE_DS2805=m CONFIG_W1_SLAVE_DS2430=m CONFIG_W1_SLAVE_DS2431=m CONFIG_W1_SLAVE_DS2433=m -# CONFIG_W1_SLAVE_DS2433_CRC is not set +CONFIG_W1_SLAVE_DS2433_CRC=y CONFIG_W1_SLAVE_DS2438=m CONFIG_W1_SLAVE_DS250X=m CONFIG_W1_SLAVE_DS2780=m @@ -5111,12 +5378,24 @@ CONFIG_W1_SLAVE_DS28E17=m # end of 1-wire Slaves CONFIG_POWER_RESET=y -# CONFIG_POWER_RESET_RESTART is not set +# CONFIG_POWER_RESET_AS3722 is not set +# CONFIG_POWER_RESET_GPIO is not set +# CONFIG_POWER_RESET_GPIO_RESTART is not set +# CONFIG_POWER_RESET_LTC2952 is not set +# CONFIG_POWER_RESET_REGULATOR is not set +CONFIG_POWER_RESET_RESTART=y CONFIG_POWER_RESET_TPS65086=y +# CONFIG_POWER_RESET_SYSCON is not set +# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set +CONFIG_REBOOT_MODE=m +# CONFIG_SYSCON_REBOOT_MODE is not set +CONFIG_NVMEM_REBOOT_MODE=m +CONFIG_POWER_SEQUENCING=m +CONFIG_POWER_SEQUENCING_QCOM_WCN=m CONFIG_POWER_SUPPLY=y # CONFIG_POWER_SUPPLY_DEBUG is not set CONFIG_GENERIC_ADC_BATTERY=m -# CONFIG_IP5XXX_POWER is not set +CONFIG_IP5XXX_POWER=m CONFIG_MAX8925_POWER=m CONFIG_WM831X_BACKUP=m CONFIG_WM831X_POWER=m @@ -5124,12 +5403,15 @@ CONFIG_WM8350_POWER=m CONFIG_TEST_POWER=m CONFIG_BATTERY_88PM860X=m CONFIG_CHARGER_ADP5061=m -# CONFIG_BATTERY_CW2015 is not set +CONFIG_BATTERY_ACT8945A=m +CONFIG_BATTERY_CPCAP=m +CONFIG_BATTERY_CW2015=m CONFIG_BATTERY_DS2760=m CONFIG_BATTERY_DS2780=m CONFIG_BATTERY_DS2781=m CONFIG_BATTERY_DS2782=m -# CONFIG_BATTERY_SAMSUNG_SDI is not set +# CONFIG_BATTERY_QCOM_BATTMGR is not set +CONFIG_BATTERY_SAMSUNG_SDI=y CONFIG_BATTERY_SBS=m CONFIG_CHARGER_SBS=m CONFIG_MANAGER_SBS=m @@ -5144,9 +5426,10 @@ CONFIG_CHARGER_DA9150=m CONFIG_AXP20X_POWER=m CONFIG_AXP288_CHARGER=m CONFIG_AXP288_FUEL_GAUGE=m -# CONFIG_BATTERY_MAX17040 is not set +CONFIG_BATTERY_MAX17040=m CONFIG_BATTERY_MAX17042=m -# CONFIG_BATTERY_MAX1721X is not set +CONFIG_BATTERY_MAX1720X=m +CONFIG_BATTERY_MAX1721X=m CONFIG_BATTERY_TWL4030_MADC=m CONFIG_CHARGER_88PM860X=m CONFIG_BATTERY_RX51=m @@ -5158,10 +5441,12 @@ CONFIG_CHARGER_LP8788=m CONFIG_CHARGER_GPIO=m CONFIG_CHARGER_MANAGER=y CONFIG_CHARGER_LT3651=m -# CONFIG_CHARGER_LTC4162L is not set +CONFIG_CHARGER_LTC4162L=m CONFIG_CHARGER_MAX14577=m -# CONFIG_CHARGER_MAX77693 is not set -# CONFIG_CHARGER_MAX77976 is not set +CONFIG_CHARGER_DETECTOR_MAX14656=m +CONFIG_CHARGER_MAX77650=m +CONFIG_CHARGER_MAX77693=m +CONFIG_CHARGER_MAX77976=m CONFIG_CHARGER_MAX8997=m CONFIG_CHARGER_MAX8998=m CONFIG_CHARGER_MP2629=m @@ -5172,22 +5457,27 @@ CONFIG_CHARGER_BQ24735=m CONFIG_CHARGER_BQ2515X=m CONFIG_CHARGER_BQ25890=m CONFIG_CHARGER_BQ25980=m -# CONFIG_CHARGER_BQ256XX is not set +CONFIG_CHARGER_BQ256XX=m +CONFIG_CHARGER_RK817=m CONFIG_CHARGER_SMB347=m CONFIG_CHARGER_TPS65090=m -# CONFIG_BATTERY_GAUGE_LTC2941 is not set -# CONFIG_BATTERY_GOLDFISH is not set +CONFIG_CHARGER_TPS65217=m +CONFIG_BATTERY_GAUGE_LTC2941=m +CONFIG_BATTERY_GOLDFISH=m CONFIG_BATTERY_RT5033=m CONFIG_CHARGER_RT9455=m -# CONFIG_CHARGER_RT9467 is not set -# CONFIG_CHARGER_RT9471 is not set +CONFIG_CHARGER_RT9467=m +CONFIG_CHARGER_RT9471=m CONFIG_CHARGER_CROS_USBPD=m CONFIG_CHARGER_CROS_PCHG=m -# CONFIG_CHARGER_BD99954 is not set +CONFIG_CHARGER_CROS_CONTROL=m +CONFIG_CHARGER_UCS1002=m +CONFIG_CHARGER_BD99954=m CONFIG_CHARGER_WILCO=m CONFIG_BATTERY_SURFACE=m CONFIG_CHARGER_SURFACE=m -# CONFIG_BATTERY_UG3105 is not set +CONFIG_BATTERY_UG3105=m +CONFIG_FUEL_GAUGE_MM8013=m CONFIG_HWMON=m CONFIG_HWMON_VID=m # CONFIG_HWMON_DEBUG_CHIP is not set @@ -5218,6 +5508,7 @@ CONFIG_SENSORS_AHT10=m CONFIG_SENSORS_AQUACOMPUTER_D5NEXT=m CONFIG_SENSORS_AS370=m CONFIG_SENSORS_ASC7621=m +CONFIG_SENSORS_ASUS_ROG_RYUJIN=m CONFIG_SENSORS_AXI_FAN_CONTROL=m CONFIG_SENSORS_K8TEMP=m CONFIG_SENSORS_K10TEMP=m @@ -5225,8 +5516,10 @@ CONFIG_SENSORS_FAM15H_POWER=m CONFIG_SENSORS_APPLESMC=m CONFIG_SENSORS_ASB100=m CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_CHIPCAP2=m CONFIG_SENSORS_CORSAIR_CPRO=m CONFIG_SENSORS_CORSAIR_PSU=m +CONFIG_SENSORS_CROS_EC=m CONFIG_SENSORS_DRIVETEMP=m CONFIG_SENSORS_DS620=m CONFIG_SENSORS_DS1621=m @@ -5238,13 +5531,16 @@ CONFIG_SENSORS_I5K_AMB=m CONFIG_SENSORS_F71805F=m CONFIG_SENSORS_F71882FG=m CONFIG_SENSORS_F75375S=m +CONFIG_SENSORS_GSC=m CONFIG_SENSORS_MC13783_ADC=m CONFIG_SENSORS_FSCHMD=m CONFIG_SENSORS_FTSTEUTATES=m +CONFIG_SENSORS_GIGABYTE_WATERFORCE=m CONFIG_SENSORS_GL518SM=m CONFIG_SENSORS_GL520SM=m CONFIG_SENSORS_G760A=m CONFIG_SENSORS_G762=m +CONFIG_SENSORS_GPIO_FAN=m CONFIG_SENSORS_HIH6130=m CONFIG_SENSORS_HS3001=m CONFIG_SENSORS_IBMAEM=m @@ -5254,13 +5550,17 @@ CONFIG_SENSORS_I5500=m CONFIG_SENSORS_CORETEMP=m CONFIG_SENSORS_IT87=m CONFIG_SENSORS_JC42=m +CONFIG_SENSORS_POWERZ=m CONFIG_SENSORS_POWR1220=m +CONFIG_SENSORS_LENOVO_EC=m CONFIG_SENSORS_LINEAGE=m +CONFIG_SENSORS_LOCHNAGAR=m CONFIG_SENSORS_LTC2945=m CONFIG_SENSORS_LTC2947=m CONFIG_SENSORS_LTC2947_I2C=m CONFIG_SENSORS_LTC2947_SPI=m CONFIG_SENSORS_LTC2990=m +CONFIG_SENSORS_LTC2991=m CONFIG_SENSORS_LTC2992=m CONFIG_SENSORS_LTC4151=m CONFIG_SENSORS_LTC4215=m @@ -5268,6 +5568,7 @@ CONFIG_SENSORS_LTC4222=m CONFIG_SENSORS_LTC4245=m CONFIG_SENSORS_LTC4260=m CONFIG_SENSORS_LTC4261=m +CONFIG_SENSORS_LTC4282=m CONFIG_SENSORS_MAX1111=m CONFIG_SENSORS_MAX127=m CONFIG_SENSORS_MAX16065=m @@ -5319,9 +5620,11 @@ CONFIG_SENSORS_NCT7802=m CONFIG_SENSORS_NCT7904=m CONFIG_SENSORS_NPCM7XX=m CONFIG_SENSORS_NZXT_KRAKEN2=m +CONFIG_SENSORS_NZXT_KRAKEN3=m CONFIG_SENSORS_NZXT_SMART2=m -# CONFIG_SENSORS_OCC_P8_I2C is not set -# CONFIG_SENSORS_OXP is not set +CONFIG_SENSORS_OCC_P8_I2C=m +CONFIG_SENSORS_OCC=m +CONFIG_SENSORS_OXP=m CONFIG_SENSORS_PCF8591=m CONFIG_SENSORS_PECI_CPUTEMP=m CONFIG_SENSORS_PECI_DIMMTEMP=m @@ -5331,6 +5634,7 @@ CONFIG_SENSORS_PMBUS=m CONFIG_SENSORS_ACBEL_FSG032=m CONFIG_SENSORS_ADM1266=m CONFIG_SENSORS_ADM1275=m +CONFIG_SENSORS_ADP1050=m CONFIG_SENSORS_BEL_PFE=m CONFIG_SENSORS_BPA_RS600=m CONFIG_SENSORS_DELTA_AHE50DC_FAN=m @@ -5350,7 +5654,8 @@ CONFIG_SENSORS_LT7182S=m CONFIG_SENSORS_LTC2978=m CONFIG_SENSORS_LTC2978_REGULATOR=y CONFIG_SENSORS_LTC3815=m -# CONFIG_SENSORS_MAX15301 is not set +CONFIG_SENSORS_LTC4286=y +CONFIG_SENSORS_MAX15301=m CONFIG_SENSORS_MAX16064=m CONFIG_SENSORS_MAX16601=m CONFIG_SENSORS_MAX20730=m @@ -5358,12 +5663,19 @@ CONFIG_SENSORS_MAX20751=m CONFIG_SENSORS_MAX31785=m CONFIG_SENSORS_MAX34440=m CONFIG_SENSORS_MAX8688=m +CONFIG_SENSORS_MP2856=m CONFIG_SENSORS_MP2888=m +CONFIG_SENSORS_MP2891=m CONFIG_SENSORS_MP2975=m +CONFIG_SENSORS_MP2993=m CONFIG_SENSORS_MP2975_REGULATOR=y CONFIG_SENSORS_MP5023=m +CONFIG_SENSORS_MP5920=m +CONFIG_SENSORS_MP5990=m +CONFIG_SENSORS_MP9941=m CONFIG_SENSORS_MPQ7932_REGULATOR=y CONFIG_SENSORS_MPQ7932=m +CONFIG_SENSORS_MPQ8785=m CONFIG_SENSORS_PIM4328=m CONFIG_SENSORS_PLI1209BC=m CONFIG_SENSORS_PLI1209BC_REGULATOR=y @@ -5372,16 +5684,19 @@ CONFIG_SENSORS_PXE1610=m CONFIG_SENSORS_Q54SJ108A2=m CONFIG_SENSORS_STPDDC60=m CONFIG_SENSORS_TDA38640=m -# CONFIG_SENSORS_TDA38640_REGULATOR is not set +CONFIG_SENSORS_TDA38640_REGULATOR=y CONFIG_SENSORS_TPS40422=m CONFIG_SENSORS_TPS53679=m CONFIG_SENSORS_TPS546D24=m CONFIG_SENSORS_UCD9000=m CONFIG_SENSORS_UCD9200=m +CONFIG_SENSORS_XDP710=m CONFIG_SENSORS_XDPE152=m CONFIG_SENSORS_XDPE122=m CONFIG_SENSORS_XDPE122_REGULATOR=y CONFIG_SENSORS_ZL6100=m +CONFIG_SENSORS_PT5161L=m +CONFIG_SENSORS_PWM_FAN=m CONFIG_SENSORS_SBTSI=m CONFIG_SENSORS_SBRMI=m CONFIG_SENSORS_SHT15=m @@ -5402,6 +5717,8 @@ CONFIG_SENSORS_SCH56XX_COMMON=m CONFIG_SENSORS_SCH5627=m CONFIG_SENSORS_SCH5636=m CONFIG_SENSORS_STTS751=m +CONFIG_SENSORS_SURFACE_FAN=m +CONFIG_SENSORS_SURFACE_TEMP=m CONFIG_SENSORS_ADC128D818=m CONFIG_SENSORS_ADS7828=m CONFIG_SENSORS_ADS7871=m @@ -5410,6 +5727,8 @@ CONFIG_SENSORS_INA209=m CONFIG_SENSORS_INA2XX=m CONFIG_SENSORS_INA238=m CONFIG_SENSORS_INA3221=m +CONFIG_SENSORS_SPD5118=m +CONFIG_SENSORS_SPD5118_DETECT=y CONFIG_SENSORS_TC74=m CONFIG_SENSORS_THMC50=m CONFIG_SENSORS_TMP102=m @@ -5450,9 +5769,10 @@ CONFIG_SENSORS_HP_WMI=m CONFIG_THERMAL=y CONFIG_THERMAL_NETLINK=y CONFIG_THERMAL_STATISTICS=y +# CONFIG_THERMAL_DEBUGFS is not set +# CONFIG_THERMAL_CORE_TESTING is not set CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 -CONFIG_THERMAL_ACPI=y -CONFIG_THERMAL_WRITABLE_TRIPS=y +CONFIG_THERMAL_OF=y CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y # CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set # CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set @@ -5462,8 +5782,11 @@ CONFIG_THERMAL_GOV_STEP_WISE=y CONFIG_THERMAL_GOV_BANG_BANG=y CONFIG_THERMAL_GOV_USER_SPACE=y # CONFIG_THERMAL_GOV_POWER_ALLOCATOR is not set +# CONFIG_CPU_THERMAL is not set CONFIG_DEVFREQ_THERMAL=y CONFIG_THERMAL_EMULATION=y +CONFIG_THERMAL_MMIO=m +# CONFIG_DA9062_THERMAL is not set # # Intel thermal drivers @@ -5514,10 +5837,15 @@ CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC=y # CONFIG_SOFT_WATCHDOG=m # CONFIG_SOFT_WATCHDOG_PRETIMEOUT is not set +# CONFIG_BD957XMUF_WATCHDOG is not set +# CONFIG_BD96801_WATCHDOG is not set +# CONFIG_CROS_EC_WATCHDOG is not set CONFIG_DA9052_WATCHDOG=m CONFIG_DA9055_WATCHDOG=m CONFIG_DA9063_WATCHDOG=m CONFIG_DA9062_WATCHDOG=m +CONFIG_GPIO_WATCHDOG=m +# CONFIG_LENOVO_SE10_WDT is not set CONFIG_MENF21BMC_WATCHDOG=m CONFIG_WDAT_WDT=m CONFIG_WM831X_WATCHDOG=m @@ -5527,9 +5855,12 @@ CONFIG_ZIIRAVE_WATCHDOG=m CONFIG_MLX_WDT=m # CONFIG_CADENCE_WATCHDOG is not set CONFIG_DW_WATCHDOG=m +# CONFIG_RN5T618_WATCHDOG is not set CONFIG_TWL4030_WATCHDOG=m CONFIG_MAX63XX_WATCHDOG=m +# CONFIG_MAX77620_WATCHDOG is not set CONFIG_RETU_WATCHDOG=m +# CONFIG_STPMIC1_WATCHDOG is not set CONFIG_ACQUIRE_WDT=m CONFIG_ADVANTECH_WDT=m CONFIG_ADVANTECH_EC_WDT=m @@ -5612,10 +5943,15 @@ CONFIG_BCMA_DRIVER_GPIO=y # Multifunction device drivers # CONFIG_MFD_CORE=y +CONFIG_MFD_ADP5585=m +CONFIG_MFD_ACT8945A=m CONFIG_MFD_AS3711=y CONFIG_MFD_SMPRO=m +CONFIG_MFD_AS3722=m CONFIG_PMIC_ADP5520=y CONFIG_MFD_AAT2870_CORE=y +CONFIG_MFD_ATMEL_FLEXCOM=m +CONFIG_MFD_ATMEL_HLCDC=m CONFIG_MFD_BCM590XX=m CONFIG_MFD_BD9571MWV=m CONFIG_MFD_AXP20X=m @@ -5627,6 +5963,7 @@ CONFIG_MFD_CS42L43_SDW=m CONFIG_MFD_MADERA=m CONFIG_MFD_MADERA_I2C=m CONFIG_MFD_MADERA_SPI=m +CONFIG_MFD_MAX5970=m CONFIG_MFD_CS47L15=y CONFIG_MFD_CS47L35=y CONFIG_MFD_CS47L85=y @@ -5641,10 +5978,13 @@ CONFIG_MFD_DA9062=m CONFIG_MFD_DA9063=y CONFIG_MFD_DA9150=m CONFIG_MFD_DLN2=m +CONFIG_MFD_GATEWORKS_GSC=m CONFIG_MFD_MC13XXX=m CONFIG_MFD_MC13XXX_SPI=m CONFIG_MFD_MC13XXX_I2C=m CONFIG_MFD_MP2629=m +CONFIG_MFD_HI6421_PMIC=m +CONFIG_MFD_HI6421_SPMI=m CONFIG_MFD_INTEL_QUARK_I2C_GPIO=m CONFIG_LPC_ICH=m CONFIG_LPC_SCH=m @@ -5663,9 +6003,14 @@ CONFIG_MFD_KEMPLD=m CONFIG_MFD_88PM800=m CONFIG_MFD_88PM805=m CONFIG_MFD_88PM860X=y +CONFIG_MFD_88PM886_PMIC=y CONFIG_MFD_MAX14577=y CONFIG_MFD_MAX77541=m +# CONFIG_MFD_MAX77620 is not set +CONFIG_MFD_MAX77650=m +CONFIG_MFD_MAX77686=m CONFIG_MFD_MAX77693=y +CONFIG_MFD_MAX77714=m # CONFIG_MFD_MAX77843 is not set CONFIG_MFD_MAX8907=m CONFIG_MFD_MAX8925=y @@ -5677,7 +6022,9 @@ CONFIG_MFD_MAX8998=y CONFIG_MFD_MENF21BMC=m CONFIG_MFD_OCELOT=m CONFIG_EZX_PCAP=y +CONFIG_MFD_CPCAP=m CONFIG_MFD_VIPERBOARD=m +CONFIG_MFD_NTXEC=m CONFIG_MFD_RETU=m # CONFIG_MFD_PCF50633 is not set # CONFIG_MFD_SY7636A is not set @@ -5686,10 +6033,16 @@ CONFIG_MFD_RDC321X=m # CONFIG_MFD_RT5033 is not set # CONFIG_MFD_RT5120 is not set CONFIG_MFD_RC5T583=y +CONFIG_MFD_RK8XX=m +CONFIG_MFD_RK8XX_I2C=m +CONFIG_MFD_RK8XX_SPI=m +CONFIG_MFD_RN5T618=m +CONFIG_MFD_SEC_CORE=m CONFIG_MFD_SI476X_CORE=m CONFIG_MFD_SIMPLE_MFD_I2C=m # CONFIG_MFD_SM501 is not set # CONFIG_MFD_SKY81452 is not set +# CONFIG_MFD_STMPE is not set CONFIG_MFD_SYSCON=y CONFIG_MFD_LP3943=m CONFIG_MFD_LP8788=y @@ -5700,7 +6053,11 @@ CONFIG_MFD_PALMAS=y # CONFIG_TPS6507X is not set CONFIG_MFD_TPS65086=m CONFIG_MFD_TPS65090=y +CONFIG_MFD_TPS65217=m # CONFIG_MFD_TI_LP873X is not set +CONFIG_MFD_TI_LP87565=m +CONFIG_MFD_TPS65218=m +CONFIG_MFD_TPS65219=m CONFIG_MFD_TPS6586X=y CONFIG_MFD_TPS65910=y CONFIG_MFD_TPS65912=y @@ -5714,8 +6071,10 @@ CONFIG_MFD_TWL4030_AUDIO=y CONFIG_TWL6040_CORE=y CONFIG_MFD_WL1273_CORE=m # CONFIG_MFD_LM3533 is not set +# CONFIG_MFD_TC3589X is not set # CONFIG_MFD_TQMX86 is not set CONFIG_MFD_VX855=m +CONFIG_MFD_LOCHNAGAR=y CONFIG_MFD_ARIZONA=m CONFIG_MFD_ARIZONA_I2C=m CONFIG_MFD_ARIZONA_SPI=m @@ -5731,10 +6090,22 @@ CONFIG_MFD_WM831X_SPI=y CONFIG_MFD_WM8350=y CONFIG_MFD_WM8350_I2C=y CONFIG_MFD_WM8994=y +CONFIG_MFD_ROHM_BD718XX=m +CONFIG_MFD_ROHM_BD71828=m +CONFIG_MFD_ROHM_BD957XMUF=m +CONFIG_MFD_ROHM_BD96801=m +CONFIG_MFD_STPMIC1=m +CONFIG_MFD_STMFX=m # CONFIG_MFD_ATC260X_I2C is not set +CONFIG_MFD_QCOM_PM8008=m +CONFIG_MFD_CS40L50_CORE=m +CONFIG_MFD_CS40L50_I2C=m +CONFIG_MFD_CS40L50_SPI=m # CONFIG_RAVE_SP_CORE is not set CONFIG_MFD_INTEL_M10_BMC_CORE=m CONFIG_MFD_INTEL_M10_BMC_SPI=m +CONFIG_MFD_RSMU_I2C=m +CONFIG_MFD_RSMU_SPI=m # end of Multifunction device drivers CONFIG_REGULATOR=y @@ -5742,40 +6113,62 @@ CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=m CONFIG_REGULATOR_VIRTUAL_CONSUMER=m CONFIG_REGULATOR_USERSPACE_CONSUMER=m +# CONFIG_REGULATOR_NETLINK_EVENTS is not set # CONFIG_REGULATOR_88PG86X is not set CONFIG_REGULATOR_88PM800=m CONFIG_REGULATOR_88PM8607=m +CONFIG_REGULATOR_88PM886=m CONFIG_REGULATOR_ACT8865=m +CONFIG_REGULATOR_ACT8945A=m CONFIG_REGULATOR_AD5398=m CONFIG_REGULATOR_AAT2870=m # CONFIG_REGULATOR_ARIZONA_LDO1 is not set # CONFIG_REGULATOR_ARIZONA_MICSUPP is not set CONFIG_REGULATOR_AS3711=m +CONFIG_REGULATOR_AS3722=m CONFIG_REGULATOR_AW37503=m CONFIG_REGULATOR_AXP20X=m CONFIG_REGULATOR_BCM590XX=m +CONFIG_REGULATOR_BD71815=m +CONFIG_REGULATOR_BD71828=m +CONFIG_REGULATOR_BD718XX=m CONFIG_REGULATOR_BD9571MWV=m +CONFIG_REGULATOR_BD957XMUF=m +CONFIG_REGULATOR_BD96801=m +CONFIG_REGULATOR_CPCAP=m +CONFIG_REGULATOR_CROS_EC=m CONFIG_REGULATOR_DA903X=m CONFIG_REGULATOR_DA9052=m CONFIG_REGULATOR_DA9055=m CONFIG_REGULATOR_DA9062=m +CONFIG_REGULATOR_DA9063=m +CONFIG_REGULATOR_DA9121=m CONFIG_REGULATOR_DA9210=m CONFIG_REGULATOR_DA9211=m CONFIG_REGULATOR_FAN53555=m +CONFIG_REGULATOR_FAN53880=m CONFIG_REGULATOR_GPIO=m +CONFIG_REGULATOR_HI6421=m +CONFIG_REGULATOR_HI6421V530=m +CONFIG_REGULATOR_HI6421V600=m CONFIG_REGULATOR_ISL9305=m CONFIG_REGULATOR_ISL6271A=m # CONFIG_REGULATOR_LM363X is not set +CONFIG_REGULATOR_LOCHNAGAR=m CONFIG_REGULATOR_LP3971=m CONFIG_REGULATOR_LP3972=m CONFIG_REGULATOR_LP872X=m CONFIG_REGULATOR_LP8755=m +CONFIG_REGULATOR_LP87565=m CONFIG_REGULATOR_LP8788=m CONFIG_REGULATOR_LTC3589=m # CONFIG_REGULATOR_LTC3676 is not set CONFIG_REGULATOR_MAX14577=m CONFIG_REGULATOR_MAX1586=m +CONFIG_REGULATOR_MAX5970=m +# CONFIG_REGULATOR_MAX77503 is not set CONFIG_REGULATOR_MAX77541=m +CONFIG_REGULATOR_MAX77650=m CONFIG_REGULATOR_MAX77857=m CONFIG_REGULATOR_MAX8649=m CONFIG_REGULATOR_MAX8660=m @@ -5783,29 +6176,43 @@ CONFIG_REGULATOR_MAX8660=m CONFIG_REGULATOR_MAX8907=m CONFIG_REGULATOR_MAX8925=m CONFIG_REGULATOR_MAX8952=m +CONFIG_REGULATOR_MAX8973=m CONFIG_REGULATOR_MAX8997=m CONFIG_REGULATOR_MAX8998=m # CONFIG_REGULATOR_MAX20086 is not set CONFIG_REGULATOR_MAX20411=m +CONFIG_REGULATOR_MAX77686=m CONFIG_REGULATOR_MAX77693=m +CONFIG_REGULATOR_MAX77802=m # CONFIG_REGULATOR_MAX77826 is not set CONFIG_REGULATOR_MC13XXX_CORE=m CONFIG_REGULATOR_MC13783=m CONFIG_REGULATOR_MC13892=m +CONFIG_REGULATOR_MCP16502=m +CONFIG_REGULATOR_MP5416=m CONFIG_REGULATOR_MP8859=m +CONFIG_REGULATOR_MP886X=m +CONFIG_REGULATOR_MPQ7920=m CONFIG_REGULATOR_MT6311=m # CONFIG_REGULATOR_MT6315 is not set CONFIG_REGULATOR_PALMAS=m CONFIG_REGULATOR_PCA9450=m CONFIG_REGULATOR_PCAP=m +CONFIG_REGULATOR_PF8X00=m +CONFIG_REGULATOR_PFUZE100=m CONFIG_REGULATOR_PV88060=m CONFIG_REGULATOR_PV88080=m CONFIG_REGULATOR_PV88090=m CONFIG_REGULATOR_PWM=m +CONFIG_REGULATOR_QCOM_PM8008=m CONFIG_REGULATOR_QCOM_SPMI=m CONFIG_REGULATOR_QCOM_USB_VBUS=m CONFIG_REGULATOR_RAA215300=m +CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY=m CONFIG_REGULATOR_RC5T583=m +CONFIG_REGULATOR_RK808=m +CONFIG_REGULATOR_RN5T618=m +CONFIG_REGULATOR_ROHM=m # CONFIG_REGULATOR_RT4801 is not set # CONFIG_REGULATOR_RT4803 is not set # CONFIG_REGULATOR_RT5190A is not set @@ -5818,20 +6225,34 @@ CONFIG_REGULATOR_RC5T583=m # CONFIG_REGULATOR_RTMV20 is not set # CONFIG_REGULATOR_RTQ6752 is not set CONFIG_REGULATOR_RTQ2208=m +CONFIG_REGULATOR_S2MPA01=m +CONFIG_REGULATOR_S2MPS11=m +CONFIG_REGULATOR_S5M8767=m # CONFIG_REGULATOR_SLG51000 is not set +CONFIG_REGULATOR_STPMIC1=m +CONFIG_REGULATOR_SY8106A=m +CONFIG_REGULATOR_SY8824X=m +CONFIG_REGULATOR_SY8827N=m CONFIG_REGULATOR_TPS51632=m CONFIG_REGULATOR_TPS62360=m +CONFIG_REGULATOR_TPS6286X=m +CONFIG_REGULATOR_TPS6287X=m CONFIG_REGULATOR_TPS65023=m CONFIG_REGULATOR_TPS6507X=m CONFIG_REGULATOR_TPS65086=m CONFIG_REGULATOR_TPS65090=m CONFIG_REGULATOR_TPS65132=m +CONFIG_REGULATOR_TPS65217=m +CONFIG_REGULATOR_TPS65218=m +CONFIG_REGULATOR_TPS65219=m +CONFIG_REGULATOR_TPS6594=m CONFIG_REGULATOR_TPS6524X=m CONFIG_REGULATOR_TPS6586X=m CONFIG_REGULATOR_TPS65910=m CONFIG_REGULATOR_TPS65912=m CONFIG_REGULATOR_TPS68470=m CONFIG_REGULATOR_TWL4030=m +CONFIG_REGULATOR_VCTRL=m CONFIG_REGULATOR_WM831X=m CONFIG_REGULATOR_WM8350=m CONFIG_REGULATOR_WM8400=m @@ -5855,6 +6276,9 @@ CONFIG_IR_XMP_DECODER=m CONFIG_RC_DEVICES=y CONFIG_IR_ENE=m CONFIG_IR_FINTEK=m +CONFIG_IR_GPIO_CIR=m +CONFIG_IR_GPIO_TX=m +CONFIG_IR_HIX5HD2=m CONFIG_IR_IGORPLUGUSB=m CONFIG_IR_IGUANA=m CONFIG_IR_IMON=m @@ -5862,9 +6286,11 @@ CONFIG_IR_IMON_RAW=m CONFIG_IR_ITE_CIR=m CONFIG_IR_MCEUSB=m CONFIG_IR_NUVOTON=m +CONFIG_IR_PWM_TX=m CONFIG_IR_REDRAT3=m CONFIG_IR_SERIAL=m CONFIG_IR_SERIAL_TRANSMITTER=y +CONFIG_IR_SPI=m CONFIG_IR_STREAMZAP=m CONFIG_IR_TOY=m CONFIG_IR_TTUSBIR=m @@ -5886,6 +6312,7 @@ CONFIG_CEC_CH7322=m CONFIG_CEC_CROS_EC=m CONFIG_CEC_GPIO=m # CONFIG_CEC_SECO is not set +# CONFIG_USB_EXTRON_DA_HD_4K_PLUS_CEC is not set CONFIG_USB_PULSE8_CEC=m CONFIG_USB_RAINSHADOW_CEC=m # end of CEC support @@ -5930,7 +6357,6 @@ CONFIG_V4L2_CCI_I2C=m # Media controller options # CONFIG_MEDIA_CONTROLLER_DVB=y -CONFIG_MEDIA_CONTROLLER_REQUEST_API=y # end of Media controller options # @@ -6115,6 +6541,7 @@ CONFIG_MEDIA_PCI_SUPPORT=y # # Media capture support # +# CONFIG_VIDEO_MGB4 is not set CONFIG_VIDEO_SOLO6X10=m CONFIG_VIDEO_TW5864=m CONFIG_VIDEO_TW68=m @@ -6187,6 +6614,7 @@ CONFIG_DVB_BUDGET=m CONFIG_DVB_BUDGET_CI=m CONFIG_DVB_BUDGET_AV=m CONFIG_VIDEO_IPU3_CIO2=m +CONFIG_VIDEO_INTEL_IPU6=m CONFIG_INTEL_VSC=m CONFIG_IPU_BRIDGE=m CONFIG_RADIO_ADAPTERS=m @@ -6211,13 +6639,13 @@ CONFIG_I2C_SI470X=m CONFIG_USB_SI4713=m CONFIG_PLATFORM_SI4713=m CONFIG_I2C_SI4713=m -CONFIG_RADIO_WL128X=m CONFIG_MEDIA_PLATFORM_DRIVERS=y CONFIG_V4L_PLATFORM_DRIVERS=y # CONFIG_SDR_PLATFORM_DRIVERS is not set CONFIG_DVB_PLATFORM_DRIVERS=y CONFIG_V4L_MEM2MEM_DRIVERS=y CONFIG_VIDEO_MEM2MEM_DEINTERLACE=m +CONFIG_VIDEO_MUX=m # # Allegro DVT media platform drivers @@ -6266,6 +6694,10 @@ CONFIG_VIDEO_CAFE_CCIC=m # Microchip Technology, Inc. media platform drivers # +# +# Nuvoton media platform drivers +# + # # NVidia media platform drivers # @@ -6278,6 +6710,10 @@ CONFIG_VIDEO_CAFE_CCIC=m # Qualcomm media platform drivers # +# +# Raspberry Pi media platform drivers +# + # # Renesas media platform drivers # @@ -6314,6 +6750,10 @@ CONFIG_VIDEO_VIA_CAMERA=m # # Xilinx media platform drivers # +CONFIG_VIDEO_XILINX=m +CONFIG_VIDEO_XILINX_CSI2RXSS=m +CONFIG_VIDEO_XILINX_TPG=m +CONFIG_VIDEO_XILINX_VTC=m # # MMC/SDIO DVB adapters @@ -6374,7 +6814,12 @@ CONFIG_VIDEO_IR_I2C=m CONFIG_VIDEO_CAMERA_SENSOR=y CONFIG_VIDEO_APTINA_PLL=m CONFIG_VIDEO_CCS_PLL=m +CONFIG_VIDEO_ALVIUM_CSI2=m CONFIG_VIDEO_AR0521=m +CONFIG_VIDEO_GC0308=m +CONFIG_VIDEO_GC05A2=m +CONFIG_VIDEO_GC08A3=m +CONFIG_VIDEO_GC2145=m CONFIG_VIDEO_HI556=m CONFIG_VIDEO_HI846=m CONFIG_VIDEO_HI847=m @@ -6383,13 +6828,19 @@ CONFIG_VIDEO_IMX214=m CONFIG_VIDEO_IMX219=m CONFIG_VIDEO_IMX258=m CONFIG_VIDEO_IMX274=m +CONFIG_VIDEO_IMX283=m CONFIG_VIDEO_IMX290=m CONFIG_VIDEO_IMX296=m CONFIG_VIDEO_IMX319=m +CONFIG_VIDEO_IMX334=m +CONFIG_VIDEO_IMX335=m CONFIG_VIDEO_IMX355=m +CONFIG_VIDEO_IMX412=m +CONFIG_VIDEO_IMX415=m CONFIG_VIDEO_MAX9271_LIB=m CONFIG_VIDEO_MT9M001=m CONFIG_VIDEO_MT9M111=m +CONFIG_VIDEO_MT9M114=m CONFIG_VIDEO_MT9P031=m CONFIG_VIDEO_MT9T112=m CONFIG_VIDEO_MT9V011=m @@ -6408,12 +6859,15 @@ CONFIG_VIDEO_OV2680=m CONFIG_VIDEO_OV2685=m CONFIG_VIDEO_OV2740=m CONFIG_VIDEO_OV4689=m +CONFIG_VIDEO_OV5640=m +CONFIG_VIDEO_OV5645=m CONFIG_VIDEO_OV5647=m CONFIG_VIDEO_OV5648=m CONFIG_VIDEO_OV5670=m CONFIG_VIDEO_OV5675=m CONFIG_VIDEO_OV5693=m CONFIG_VIDEO_OV5695=m +CONFIG_VIDEO_OV64A40=m CONFIG_VIDEO_OV6650=m CONFIG_VIDEO_OV7251=m CONFIG_VIDEO_OV7640=m @@ -6423,6 +6877,7 @@ CONFIG_VIDEO_OV7740=m CONFIG_VIDEO_OV8856=m CONFIG_VIDEO_OV8858=m CONFIG_VIDEO_OV8865=m +CONFIG_VIDEO_OV9282=m CONFIG_VIDEO_OV9640=m CONFIG_VIDEO_OV9650=m CONFIG_VIDEO_OV9734=m @@ -6432,9 +6887,16 @@ CONFIG_VIDEO_RJ54N1=m CONFIG_VIDEO_S5C73M3=m CONFIG_VIDEO_S5K5BAF=m CONFIG_VIDEO_S5K6A3=m +CONFIG_VIDEO_VGXY61=m CONFIG_VIDEO_CCS=m CONFIG_VIDEO_ET8EK8=m +# +# Camera ISPs +# +CONFIG_VIDEO_THP7312=m +# end of Camera ISPs + # # Lens drivers # @@ -6486,6 +6948,7 @@ CONFIG_VIDEO_SAA6588=m # CONFIG_VIDEO_ADV7180=m CONFIG_VIDEO_ADV7183=m +CONFIG_VIDEO_ADV748X=m CONFIG_VIDEO_ADV7604=m CONFIG_VIDEO_ADV7604_CEC=y CONFIG_VIDEO_ADV7842=m @@ -6493,7 +6956,9 @@ CONFIG_VIDEO_ADV7842_CEC=y CONFIG_VIDEO_BT819=m CONFIG_VIDEO_BT856=m CONFIG_VIDEO_BT866=m +CONFIG_VIDEO_ISL7998X=m CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_MAX9286=m CONFIG_VIDEO_ML86V7667=m CONFIG_VIDEO_SAA7110=m CONFIG_VIDEO_SAA711X=m @@ -6504,6 +6969,7 @@ CONFIG_VIDEO_TVP514X=m CONFIG_VIDEO_TVP5150=m CONFIG_VIDEO_TVP7002=m CONFIG_VIDEO_TW2804=m +CONFIG_VIDEO_TW9900=m CONFIG_VIDEO_TW9903=m CONFIG_VIDEO_TW9906=m CONFIG_VIDEO_TW9910=m @@ -6523,8 +6989,6 @@ CONFIG_VIDEO_ADV7170=m CONFIG_VIDEO_ADV7175=m CONFIG_VIDEO_ADV7343=m CONFIG_VIDEO_ADV7393=m -CONFIG_VIDEO_ADV7511=m -CONFIG_VIDEO_ADV7511_CEC=y CONFIG_VIDEO_AK881X=m CONFIG_VIDEO_SAA7127=m CONFIG_VIDEO_SAA7185=m @@ -6555,13 +7019,18 @@ CONFIG_SDR_MAX2175=m # CONFIG_VIDEO_I2C=m CONFIG_VIDEO_M52790=m -# CONFIG_VIDEO_ST_MIPID02 is not set +CONFIG_VIDEO_ST_MIPID02=m CONFIG_VIDEO_THS7303=m # end of Miscellaneous helper chips # # Video serializers and deserializers # +CONFIG_VIDEO_DS90UB913=m +CONFIG_VIDEO_DS90UB953=m +CONFIG_VIDEO_DS90UB960=m +CONFIG_VIDEO_MAX96714=m +CONFIG_VIDEO_MAX96717=m # end of Video serializers and deserializers # @@ -6791,19 +7260,11 @@ CONFIG_DVB_DUMMY_FE=m # CONFIG_APERTURE_HELPERS=y CONFIG_SCREEN_INFO=y -CONFIG_VIDEO_CMDLINE=y -CONFIG_VIDEO_NOMODESET=y +CONFIG_VIDEO=y CONFIG_AUXDISPLAY=y CONFIG_CHARLCD=m CONFIG_HD44780_COMMON=m # CONFIG_HD44780 is not set -CONFIG_KS0108=m -CONFIG_KS0108_PORT=0x378 -CONFIG_KS0108_DELAY=2 -CONFIG_CFAG12864B=m -CONFIG_CFAG12864B_RATE=20 -# CONFIG_IMG_ASCII_LCD is not set -# CONFIG_HT16K33 is not set # CONFIG_LCD2S is not set CONFIG_PARPORT_PANEL=m CONFIG_PANEL_PARPORT=0 @@ -6812,6 +7273,16 @@ CONFIG_PANEL_PROFILE=5 # CONFIG_CHARLCD_BL_OFF is not set # CONFIG_CHARLCD_BL_ON is not set CONFIG_CHARLCD_BL_FLASH=y +CONFIG_KS0108=m +CONFIG_KS0108_PORT=0x378 +CONFIG_KS0108_DELAY=2 +CONFIG_CFAG12864B=m +CONFIG_CFAG12864B_RATE=20 +CONFIG_LINEDISP=m +CONFIG_IMG_ASCII_LCD=m +CONFIG_HT16K33=m +CONFIG_MAX6959=m +CONFIG_SEG_LED_GPIO=m CONFIG_PANEL=m CONFIG_AGP=y CONFIG_AGP_AMD64=y @@ -6823,21 +7294,34 @@ CONFIG_VGA_SWITCHEROO=y CONFIG_DRM=m CONFIG_DRM_MIPI_DBI=m CONFIG_DRM_MIPI_DSI=y +# CONFIG_DRM_DEBUG_MM is not set CONFIG_DRM_KMS_HELPER=m +CONFIG_DRM_PANIC=y +CONFIG_DRM_PANIC_FOREGROUND_COLOR=0xffffff +CONFIG_DRM_PANIC_BACKGROUND_COLOR=0x1e4a6b +# CONFIG_DRM_PANIC_DEBUG is not set +CONFIG_DRM_PANIC_SCREEN="kmsg" # CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS is not set # CONFIG_DRM_DEBUG_MODESET_LOCK is not set +CONFIG_DRM_CLIENT_SELECTION=y +CONFIG_DRM_CLIENT_SETUP=y CONFIG_DRM_FBDEV_EMULATION=y CONFIG_DRM_FBDEV_OVERALLOC=300 # CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM is not set CONFIG_DRM_LOAD_EDID_FIRMWARE=y +CONFIG_DRM_DISPLAY_DP_AUX_BUS=m CONFIG_DRM_DISPLAY_HELPER=m +CONFIG_DRM_BRIDGE_CONNECTOR=y +CONFIG_DRM_DISPLAY_DP_AUX_CEC=y +CONFIG_DRM_DISPLAY_DP_AUX_CHARDEV=y CONFIG_DRM_DISPLAY_DP_HELPER=y +CONFIG_DRM_DISPLAY_DP_TUNNEL=y CONFIG_DRM_DISPLAY_HDCP_HELPER=y CONFIG_DRM_DISPLAY_HDMI_HELPER=y -CONFIG_DRM_DP_AUX_CHARDEV=y -CONFIG_DRM_DP_CEC=y +CONFIG_DRM_DISPLAY_HDMI_STATE_HELPER=y CONFIG_DRM_TTM=m CONFIG_DRM_EXEC=m +CONFIG_DRM_GPUVM=m CONFIG_DRM_BUDDY=m CONFIG_DRM_VRAM_HELPER=m CONFIG_DRM_TTM_HELPER=m @@ -6858,6 +7342,7 @@ CONFIG_DRM_I2C_NXP_TDA9950=m # # ARM devices # +CONFIG_DRM_KOMEDA=m # end of ARM devices CONFIG_DRM_RADEON=m @@ -6866,6 +7351,7 @@ CONFIG_DRM_AMDGPU=m CONFIG_DRM_AMDGPU_SI=y CONFIG_DRM_AMDGPU_CIK=y CONFIG_DRM_AMDGPU_USERPTR=y +CONFIG_DRM_AMD_ISP=y # CONFIG_DRM_AMDGPU_WERROR is not set # @@ -6892,6 +7378,7 @@ CONFIG_NOUVEAU_DEBUG_DEFAULT=3 # CONFIG_NOUVEAU_DEBUG_PUSH is not set CONFIG_DRM_NOUVEAU_BACKLIGHT=y # CONFIG_DRM_NOUVEAU_SVM is not set +CONFIG_DRM_NOUVEAU_GSP_DEFAULT=y CONFIG_DRM_I915=m CONFIG_DRM_I915_FORCE_PROBE="" CONFIG_DRM_I915_CAPTURE_ERROR=y @@ -6899,11 +7386,13 @@ CONFIG_DRM_I915_COMPRESS_ERROR=y CONFIG_DRM_I915_USERPTR=y CONFIG_DRM_I915_GVT_KVMGT=m CONFIG_DRM_I915_PXP=y +CONFIG_DRM_I915_DP_TUNNEL=y # # drm/i915 Debugging # # CONFIG_DRM_I915_WERROR is not set +# CONFIG_DRM_I915_REPLAY_GPU_HANGS_API is not set # CONFIG_DRM_I915_DEBUG is not set # CONFIG_DRM_I915_DEBUG_MMIO is not set # CONFIG_DRM_I915_SW_FENCE_DEBUG_OBJECTS is not set @@ -6913,6 +7402,7 @@ CONFIG_DRM_I915_PXP=y # CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS is not set # CONFIG_DRM_I915_DEBUG_VBLANK_EVADE is not set # CONFIG_DRM_I915_DEBUG_RUNTIME_PM is not set +# CONFIG_DRM_I915_DEBUG_WAKEREF is not set # end of drm/i915 Debugging # @@ -6930,6 +7420,35 @@ CONFIG_DRM_I915_TIMESLICE_DURATION=1 # end of drm/i915 Profile Guided Optimisation CONFIG_DRM_I915_GVT=y +CONFIG_DRM_XE=m +CONFIG_DRM_XE_DISPLAY=y +CONFIG_DRM_XE_FORCE_PROBE="" + +# +# drm/Xe Debugging +# +# CONFIG_DRM_XE_WERROR is not set +# CONFIG_DRM_XE_DEBUG is not set +# CONFIG_DRM_XE_DEBUG_VM is not set +# CONFIG_DRM_XE_DEBUG_SRIOV is not set +# CONFIG_DRM_XE_DEBUG_MEM is not set +# CONFIG_DRM_XE_LARGE_GUC_BUFFER is not set +# CONFIG_DRM_XE_USERPTR_INVAL_INJECT is not set +# end of drm/Xe Debugging + +# +# drm/xe Profile Guided Optimisation +# +CONFIG_DRM_XE_JOB_TIMEOUT_MAX=10000 +CONFIG_DRM_XE_JOB_TIMEOUT_MIN=1 +CONFIG_DRM_XE_TIMESLICE_MAX=10000000 +CONFIG_DRM_XE_TIMESLICE_MIN=1 +CONFIG_DRM_XE_PREEMPT_TIMEOUT=640000 +CONFIG_DRM_XE_PREEMPT_TIMEOUT_MAX=10000000 +CONFIG_DRM_XE_PREEMPT_TIMEOUT_MIN=1 +CONFIG_DRM_XE_ENABLE_SCHEDTIMEOUT_LIMIT=y +# end of drm/xe Profile Guided Optimisation + CONFIG_DRM_VGEM=m CONFIG_DRM_VKMS=m CONFIG_DRM_VMWGFX=m @@ -6946,25 +7465,164 @@ CONFIG_DRM_PANEL=y # # Display Panels # -# CONFIG_DRM_PANEL_AUO_A030JTN01 is not set -# CONFIG_DRM_PANEL_ILITEK_ILI9341 is not set +CONFIG_DRM_PANEL_ABT_Y030XX067A=m +CONFIG_DRM_PANEL_ARM_VERSATILE=m +CONFIG_DRM_PANEL_ASUS_Z00T_TM5P5_NT35596=m +CONFIG_DRM_PANEL_AUO_A030JTN01=m +CONFIG_DRM_PANEL_BOE_BF060Y8M_AJ0=m +CONFIG_DRM_PANEL_BOE_HIMAX8279D=m +CONFIG_DRM_PANEL_BOE_TH101MB31UIG002_28A=m +CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m +CONFIG_DRM_PANEL_BOE_TV101WUM_LL2=m +CONFIG_DRM_PANEL_EBBG_FT8719=m +CONFIG_DRM_PANEL_ELIDA_KD35T133=m +CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02=m +CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D=m +CONFIG_DRM_PANEL_DSI_CM=m +CONFIG_DRM_PANEL_LVDS=m +CONFIG_DRM_PANEL_HIMAX_HX83102=m +CONFIG_DRM_PANEL_HIMAX_HX83112A=m +CONFIG_DRM_PANEL_HIMAX_HX8394=m +CONFIG_DRM_PANEL_ILITEK_IL9322=m +CONFIG_DRM_PANEL_ILITEK_ILI9341=m +CONFIG_DRM_PANEL_ILITEK_ILI9805=m +CONFIG_DRM_PANEL_ILITEK_ILI9806E=m +CONFIG_DRM_PANEL_ILITEK_ILI9881C=m +CONFIG_DRM_PANEL_ILITEK_ILI9882T=m +CONFIG_DRM_PANEL_INNOLUX_EJ030NA=m +CONFIG_DRM_PANEL_INNOLUX_P079ZCA=m +CONFIG_DRM_PANEL_JADARD_JD9365DA_H3=m +CONFIG_DRM_PANEL_JDI_LPM102A188A=m +CONFIG_DRM_PANEL_JDI_LT070ME05000=m +CONFIG_DRM_PANEL_JDI_R63452=m +CONFIG_DRM_PANEL_KHADAS_TS050=m +CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04=m +CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W=m +CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829=m +CONFIG_DRM_PANEL_LINCOLNTECH_LCD197=m +CONFIG_DRM_PANEL_LG_LB035Q02=m +CONFIG_DRM_PANEL_LG_LG4573=m +CONFIG_DRM_PANEL_LG_SW43408=m +CONFIG_DRM_PANEL_MAGNACHIP_D53E6EA8966=m +CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m +CONFIG_DRM_PANEL_NEC_NL8048HL11=m +CONFIG_DRM_PANEL_NEWVISION_NV3051D=m +CONFIG_DRM_PANEL_NEWVISION_NV3052C=m +CONFIG_DRM_PANEL_NOVATEK_NT35510=m +CONFIG_DRM_PANEL_NOVATEK_NT35560=m +CONFIG_DRM_PANEL_NOVATEK_NT35950=m +CONFIG_DRM_PANEL_NOVATEK_NT36523=m +CONFIG_DRM_PANEL_NOVATEK_NT36672A=m +CONFIG_DRM_PANEL_NOVATEK_NT36672E=m +CONFIG_DRM_PANEL_NOVATEK_NT39016=m +CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO=m # CONFIG_DRM_PANEL_ORISETECH_OTA5601A is not set +CONFIG_DRM_PANEL_ORISETECH_OTM8009A=m +CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS=m +CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00=m # CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN is not set -# CONFIG_DRM_PANEL_WIDECHIPS_WS2401 is not set +CONFIG_DRM_PANEL_RAYDIUM_RM67191=m +CONFIG_DRM_PANEL_RAYDIUM_RM68200=m +CONFIG_DRM_PANEL_RAYDIUM_RM692E5=m +CONFIG_DRM_PANEL_RAYDIUM_RM69380=m +CONFIG_DRM_PANEL_RONBO_RB070D30=m +CONFIG_DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01=m +CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20=m +CONFIG_DRM_PANEL_SAMSUNG_DB7430=m +CONFIG_DRM_PANEL_SAMSUNG_LD9040=m +CONFIG_DRM_PANEL_SAMSUNG_S6E3FA7=m +CONFIG_DRM_PANEL_SAMSUNG_S6D16D0=m +CONFIG_DRM_PANEL_SAMSUNG_S6D27A1=m +CONFIG_DRM_PANEL_SAMSUNG_S6D7AA0=m +CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2=m +CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03=m +CONFIG_DRM_PANEL_SAMSUNG_S6E63M0=m +CONFIG_DRM_PANEL_SAMSUNG_S6E63M0_SPI=m +CONFIG_DRM_PANEL_SAMSUNG_S6E63M0_DSI=m +CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=m +CONFIG_DRM_PANEL_SAMSUNG_SOFEF00=m +CONFIG_DRM_PANEL_SEIKO_43WVF1G=m +CONFIG_DRM_PANEL_SHARP_LQ101R1SX01=m +CONFIG_DRM_PANEL_SHARP_LS037V7DW01=m +CONFIG_DRM_PANEL_SHARP_LS043T1LE01=m +CONFIG_DRM_PANEL_SHARP_LS060T1SX01=m +CONFIG_DRM_PANEL_SITRONIX_ST7701=m +CONFIG_DRM_PANEL_SITRONIX_ST7703=m +CONFIG_DRM_PANEL_SITRONIX_ST7789V=m +CONFIG_DRM_PANEL_SONY_ACX565AKM=m +CONFIG_DRM_PANEL_SONY_TD4353_JDI=m +CONFIG_DRM_PANEL_SONY_TULIP_TRULY_NT35521=m +CONFIG_DRM_PANEL_STARTEK_KD070FHFID015=m +CONFIG_DRM_PANEL_EDP=m +CONFIG_DRM_PANEL_SIMPLE=m +CONFIG_DRM_PANEL_SYNAPTICS_R63353=m +CONFIG_DRM_PANEL_TDO_TL070WSH30=m +CONFIG_DRM_PANEL_TPO_TD028TTEC1=m +CONFIG_DRM_PANEL_TPO_TD043MTEA1=m +CONFIG_DRM_PANEL_TPO_TPG110=m +CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m +CONFIG_DRM_PANEL_VISIONOX_R66451=m +CONFIG_DRM_PANEL_VISIONOX_RM69299=m +CONFIG_DRM_PANEL_VISIONOX_VTDR6130=m +CONFIG_DRM_PANEL_WIDECHIPS_WS2401=m +CONFIG_DRM_PANEL_XINPENG_XPP055C272=m # end of Display Panels CONFIG_DRM_BRIDGE=y CONFIG_DRM_PANEL_BRIDGE=y +CONFIG_DRM_AUX_BRIDGE=m +CONFIG_DRM_AUX_HPD_BRIDGE=m # # Display Interface Bridges # +CONFIG_DRM_CHIPONE_ICN6211=m +CONFIG_DRM_CHRONTEL_CH7033=m +CONFIG_DRM_CROS_EC_ANX7688=m +CONFIG_DRM_DISPLAY_CONNECTOR=m +CONFIG_DRM_ITE_IT6505=m +CONFIG_DRM_LONTIUM_LT8912B=m +CONFIG_DRM_LONTIUM_LT9211=m +CONFIG_DRM_LONTIUM_LT9611=m +CONFIG_DRM_LONTIUM_LT9611UXC=m +CONFIG_DRM_ITE_IT66121=m +CONFIG_DRM_LVDS_CODEC=m +CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW=m +CONFIG_DRM_NWL_MIPI_DSI=m +CONFIG_DRM_NXP_PTN3460=m +CONFIG_DRM_PARADE_PS8622=m +CONFIG_DRM_PARADE_PS8640=m +CONFIG_DRM_SAMSUNG_DSIM=m +CONFIG_DRM_SIL_SII8620=m +CONFIG_DRM_SII902X=m +CONFIG_DRM_SII9234=m +CONFIG_DRM_SIMPLE_BRIDGE=m +CONFIG_DRM_THINE_THC63LVD1024=m +CONFIG_DRM_TOSHIBA_TC358762=m +CONFIG_DRM_TOSHIBA_TC358764=m +CONFIG_DRM_TOSHIBA_TC358767=m +CONFIG_DRM_TOSHIBA_TC358768=m +CONFIG_DRM_TOSHIBA_TC358775=m +CONFIG_DRM_TI_DLPC3433=m +CONFIG_DRM_TI_TFP410=m +CONFIG_DRM_TI_SN65DSI83=m +CONFIG_DRM_TI_SN65DSI86=m +CONFIG_DRM_TI_TPD12S015=m +CONFIG_DRM_ANALOGIX_ANX6345=m CONFIG_DRM_ANALOGIX_ANX78XX=m CONFIG_DRM_ANALOGIX_DP=m +CONFIG_DRM_ANALOGIX_ANX7625=m +CONFIG_DRM_I2C_ADV7511=m +CONFIG_DRM_I2C_ADV7511_AUDIO=y +CONFIG_DRM_I2C_ADV7511_CEC=y +CONFIG_DRM_CDNS_DSI=m +CONFIG_DRM_CDNS_DSI_J721E=y +CONFIG_DRM_CDNS_MHDP8546=m # end of Display Interface Bridges -CONFIG_DRM_LOONGSON=m # CONFIG_DRM_ETNAVIV is not set +CONFIG_DRM_LOGICVC=m +CONFIG_DRM_ARCPGU=m CONFIG_DRM_BOCHS=m CONFIG_DRM_CIRRUS_QEMU=m CONFIG_DRM_GM12U320=m @@ -6987,9 +7645,9 @@ CONFIG_DRM_SSD130X=m CONFIG_DRM_SSD130X_I2C=m CONFIG_DRM_SSD130X_SPI=m CONFIG_DRM_HYPERV=m -CONFIG_DRM_LEGACY=y -CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y CONFIG_DRM_PRIVACY_SCREEN=y +# CONFIG_DRM_WERROR is not set +CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y # # Frame buffer Devices @@ -7012,30 +7670,19 @@ CONFIG_FB_EFI=y # CONFIG_FB_HGA is not set CONFIG_FB_OPENCORES=m # CONFIG_FB_S1D13XXX is not set -CONFIG_FB_NVIDIA=m -CONFIG_FB_NVIDIA_I2C=y -# CONFIG_FB_NVIDIA_DEBUG is not set -CONFIG_FB_NVIDIA_BACKLIGHT=y +# CONFIG_FB_NVIDIA is not set CONFIG_FB_RIVA=m # CONFIG_FB_RIVA_I2C is not set # CONFIG_FB_RIVA_DEBUG is not set CONFIG_FB_RIVA_BACKLIGHT=y CONFIG_FB_I740=m -CONFIG_FB_LE80578=m -CONFIG_FB_CARILLO_RANCH=m -CONFIG_FB_INTEL=m -# CONFIG_FB_INTEL_DEBUG is not set -CONFIG_FB_INTEL_I2C=y CONFIG_FB_MATROX=m CONFIG_FB_MATROX_MILLENIUM=y CONFIG_FB_MATROX_MYSTIQUE=y CONFIG_FB_MATROX_G=y CONFIG_FB_MATROX_I2C=m CONFIG_FB_MATROX_MAVEN=m -CONFIG_FB_RADEON=m -CONFIG_FB_RADEON_I2C=y -CONFIG_FB_RADEON_BACKLIGHT=y -# CONFIG_FB_RADEON_DEBUG is not set +# CONFIG_FB_RADEON is not set CONFIG_FB_ATY128=m CONFIG_FB_ATY128_BACKLIGHT=y CONFIG_FB_ATY=m @@ -7095,11 +7742,13 @@ 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_SYSMEM_FOPS=y CONFIG_FB_DEFERRED_IO=y CONFIG_FB_DMAMEM_HELPERS=y +CONFIG_FB_DMAMEM_HELPERS_DEFERRED=y CONFIG_FB_IOMEM_FOPS=y CONFIG_FB_IOMEM_HELPERS=y +CONFIG_FB_IOMEM_HELPERS_DEFERRED=y CONFIG_FB_SYSMEM_HELPERS=y CONFIG_FB_SYSMEM_HELPERS_DEFERRED=y CONFIG_FB_BACKLIGHT=m @@ -7125,8 +7774,8 @@ CONFIG_LCD_HX8357=m CONFIG_LCD_OTM3225A=m CONFIG_BACKLIGHT_CLASS_DEVICE=y CONFIG_BACKLIGHT_KTD253=m +CONFIG_BACKLIGHT_KTD2801=m CONFIG_BACKLIGHT_KTZ8866=m -CONFIG_BACKLIGHT_CARILLO_RANCH=m CONFIG_BACKLIGHT_PWM=m CONFIG_BACKLIGHT_DA903X=m CONFIG_BACKLIGHT_DA9052=m @@ -7140,16 +7789,20 @@ CONFIG_BACKLIGHT_ADP8860=m CONFIG_BACKLIGHT_ADP8870=m CONFIG_BACKLIGHT_88PM860X=m CONFIG_BACKLIGHT_AAT2870=m +CONFIG_BACKLIGHT_LM3509=m CONFIG_BACKLIGHT_LM3630A=m CONFIG_BACKLIGHT_LM3639=m CONFIG_BACKLIGHT_LP855X=m CONFIG_BACKLIGHT_LP8788=m +CONFIG_BACKLIGHT_MP3309C=m CONFIG_BACKLIGHT_PANDORA=m +CONFIG_BACKLIGHT_TPS65217=m CONFIG_BACKLIGHT_AS3711=m CONFIG_BACKLIGHT_GPIO=m CONFIG_BACKLIGHT_LV5207LP=m CONFIG_BACKLIGHT_BD6107=m CONFIG_BACKLIGHT_ARCXCNN=m +CONFIG_BACKLIGHT_LED=m # end of Backlight & LCD device support CONFIG_VGASTATE=m @@ -7167,10 +7820,13 @@ CONFIG_FRAMEBUFFER_CONSOLE=y # CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION is not set CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y -# CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set +CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER=y # end of Console display driver support -# CONFIG_LOGO is not set +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y # end of Graphics support CONFIG_DRM_ACCEL=y @@ -7205,7 +7861,6 @@ CONFIG_SND_MAX_CARDS=32 CONFIG_SND_SUPPORT_OLD_API=y CONFIG_SND_PROC_FS=y CONFIG_SND_VERBOSE_PROCFS=y -# CONFIG_SND_VERBOSE_PRINTK is not set CONFIG_SND_CTL_FAST_LOOKUP=y CONFIG_SND_DEBUG=y # CONFIG_SND_DEBUG_VERBOSE is not set @@ -7213,6 +7868,7 @@ CONFIG_SND_PCM_XRUN_DEBUG=y # CONFIG_SND_CTL_INPUT_VALIDATION is not set # CONFIG_SND_CTL_DEBUG is not set # CONFIG_SND_JACK_INJECTION_DEBUG is not set +CONFIG_SND_UTIMER=y CONFIG_SND_VMASTER=y CONFIG_SND_DMA_SGBUF=y CONFIG_SND_CTL_LED=m @@ -7240,6 +7896,7 @@ CONFIG_SND_VIRMIDI=m CONFIG_SND_MTPAV=m CONFIG_SND_MTS64=m CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_SERIAL_GENERIC=m CONFIG_SND_MPU401=m CONFIG_SND_PORTMAN2X4=m CONFIG_SND_AC97_POWER_SAVE=y @@ -7330,8 +7987,10 @@ CONFIG_SND_HDA_RECONFIG=y CONFIG_SND_HDA_INPUT_BEEP=y CONFIG_SND_HDA_INPUT_BEEP_MODE=1 CONFIG_SND_HDA_PATCH_LOADER=y +CONFIG_SND_HDA_CIRRUS_SCODEC=m CONFIG_SND_HDA_SCODEC_CS35L41=m CONFIG_SND_HDA_CS_DSP_CONTROLS=m +CONFIG_SND_HDA_SCODEC_COMPONENT=m CONFIG_SND_HDA_SCODEC_CS35L41_I2C=m CONFIG_SND_HDA_SCODEC_CS35L41_SPI=m CONFIG_SND_HDA_SCODEC_CS35L56=m @@ -7346,6 +8005,7 @@ CONFIG_SND_HDA_CODEC_HDMI=m CONFIG_SND_HDA_CODEC_CIRRUS=m CONFIG_SND_HDA_CODEC_CS8409=m CONFIG_SND_HDA_CODEC_CONEXANT=m +CONFIG_SND_HDA_CODEC_SENARYTECH=m CONFIG_SND_HDA_CODEC_CA0110=m CONFIG_SND_HDA_CODEC_CA0132=m CONFIG_SND_HDA_CODEC_CA0132_DSP=y @@ -7422,6 +8082,7 @@ CONFIG_SND_SOC_AMD_ACP6x=m CONFIG_SND_SOC_AMD_YC_MACH=m CONFIG_SND_AMD_ACP_CONFIG=m CONFIG_SND_SOC_AMD_ACP_COMMON=m +CONFIG_SND_SOC_ACPI_AMD_MATCH=m CONFIG_SND_SOC_AMD_ACP_PDM=m CONFIG_SND_SOC_AMD_ACP_LEGACY_COMMON=m CONFIG_SND_SOC_AMD_ACP_I2S=m @@ -7429,10 +8090,17 @@ CONFIG_SND_SOC_AMD_ACP_PCM=m CONFIG_SND_SOC_AMD_ACP_PCI=m CONFIG_SND_AMD_ASOC_RENOIR=m CONFIG_SND_AMD_ASOC_REMBRANDT=m +CONFIG_SND_AMD_ASOC_ACP63=m +CONFIG_SND_AMD_ASOC_ACP70=m CONFIG_SND_SOC_AMD_MACH_COMMON=m CONFIG_SND_SOC_AMD_LEGACY_MACH=m CONFIG_SND_SOC_AMD_SOF_MACH=m +CONFIG_SND_SOC_AMD_SOF_SDW_MACH=m +CONFIG_SND_AMD_SOUNDWIRE_ACPI=m CONFIG_SND_SOC_AMD_RPL_ACP6x=m +CONFIG_SND_SOC_AMD_ACP63_TOPLEVEL=m +CONFIG_SND_SOC_AMD_SOUNDWIRE_LINK_BASELINE=m +CONFIG_SND_SOC_AMD_SOUNDWIRE=m CONFIG_SND_SOC_AMD_PS=m CONFIG_SND_SOC_AMD_PS_MACH=m # CONFIG_SND_ATMEL_SOC is not set @@ -7455,7 +8123,7 @@ CONFIG_SND_DESIGNWARE_PCM=y # CONFIG_SND_SOC_FSL_ESAI is not set # CONFIG_SND_SOC_FSL_MICFIL is not set # CONFIG_SND_SOC_FSL_XCVR is not set -# CONFIG_SND_SOC_FSL_RPMSG is not set +CONFIG_SND_SOC_FSL_RPMSG=m # CONFIG_SND_SOC_IMX_AUDMUX is not set # end of SoC Audio for Freescale CPUs @@ -7469,24 +8137,10 @@ CONFIG_SND_SOC_IMG_SPDIF_IN=m CONFIG_SND_SOC_IMG_SPDIF_OUT=m CONFIG_SND_SOC_IMG_PISTACHIO_INTERNAL_DAC=m CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y -CONFIG_SND_SOC_INTEL_SST=m CONFIG_SND_SOC_INTEL_CATPT=m CONFIG_SND_SST_ATOM_HIFI2_PLATFORM=m CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_PCI=m CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI=m -CONFIG_SND_SOC_INTEL_SKYLAKE=m -CONFIG_SND_SOC_INTEL_SKL=m -CONFIG_SND_SOC_INTEL_APL=m -CONFIG_SND_SOC_INTEL_KBL=m -CONFIG_SND_SOC_INTEL_GLK=m -CONFIG_SND_SOC_INTEL_CNL=m -CONFIG_SND_SOC_INTEL_CFL=m -CONFIG_SND_SOC_INTEL_CML_H=m -CONFIG_SND_SOC_INTEL_CML_LP=m -CONFIG_SND_SOC_INTEL_SKYLAKE_FAMILY=m -CONFIG_SND_SOC_INTEL_SKYLAKE_SSP_CLK=m -CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC=y -CONFIG_SND_SOC_INTEL_SKYLAKE_COMMON=m CONFIG_SND_SOC_ACPI_INTEL_MATCH=m CONFIG_SND_SOC_INTEL_AVS=m @@ -7510,6 +8164,7 @@ CONFIG_SND_SOC_INTEL_AVS_MACH_PROBE=m CONFIG_SND_SOC_INTEL_AVS_MACH_RT274=m CONFIG_SND_SOC_INTEL_AVS_MACH_RT286=m CONFIG_SND_SOC_INTEL_AVS_MACH_RT298=m +CONFIG_SND_SOC_INTEL_AVS_MACH_RT5514=m CONFIG_SND_SOC_INTEL_AVS_MACH_RT5663=m CONFIG_SND_SOC_INTEL_AVS_MACH_RT5682=m CONFIG_SND_SOC_INTEL_AVS_MACH_SSM4567=m @@ -7521,6 +8176,8 @@ CONFIG_SND_SOC_INTEL_HDA_DSP_COMMON=m CONFIG_SND_SOC_INTEL_SOF_MAXIM_COMMON=m CONFIG_SND_SOC_INTEL_SOF_REALTEK_COMMON=m CONFIG_SND_SOC_INTEL_SOF_CIRRUS_COMMON=m +CONFIG_SND_SOC_INTEL_SOF_NUVOTON_COMMON=m +CONFIG_SND_SOC_INTEL_SOF_BOARD_HELPERS=m CONFIG_SND_SOC_INTEL_HASWELL_MACH=m CONFIG_SND_SOC_INTEL_BDW_RT5650_MACH=m CONFIG_SND_SOC_INTEL_BDW_RT5677_MACH=m @@ -7536,19 +8193,7 @@ CONFIG_SND_SOC_INTEL_BYT_CHT_CX2072X_MACH=m CONFIG_SND_SOC_INTEL_BYT_CHT_DA7213_MACH=m CONFIG_SND_SOC_INTEL_BYT_CHT_ES8316_MACH=m CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH=m -CONFIG_SND_SOC_INTEL_SKL_RT286_MACH=m -CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH=m -CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH=m -CONFIG_SND_SOC_INTEL_DA7219_MAX98357A_GENERIC=m -CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON=m -CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH=m -CONFIG_SND_SOC_INTEL_BXT_RT298_MACH=m CONFIG_SND_SOC_INTEL_SOF_WM8804_MACH=m -CONFIG_SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH=m -CONFIG_SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH=m -CONFIG_SND_SOC_INTEL_KBL_DA7219_MAX98357A_MACH=m -CONFIG_SND_SOC_INTEL_KBL_DA7219_MAX98927_MACH=m -CONFIG_SND_SOC_INTEL_KBL_RT5660_MACH=m CONFIG_SND_SOC_INTEL_GLK_DA7219_MAX98357A_MACH=m CONFIG_SND_SOC_INTEL_GLK_RT5682_MAX98357A_MACH=m CONFIG_SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH=m @@ -7559,7 +8204,7 @@ CONFIG_SND_SOC_INTEL_SOF_ES8336_MACH=m CONFIG_SND_SOC_INTEL_SOF_NAU8825_MACH=m CONFIG_SND_SOC_INTEL_CML_LP_DA7219_MAX98357A_MACH=m CONFIG_SND_SOC_INTEL_SOF_CML_RT1011_RT5682_MACH=m -CONFIG_SND_SOC_INTEL_SOF_DA7219_MAX98373_MACH=m +CONFIG_SND_SOC_INTEL_SOF_DA7219_MACH=m CONFIG_SND_SOC_INTEL_SOF_SSP_AMP_MACH=m CONFIG_SND_SOC_INTEL_EHL_RT5660_MACH=m CONFIG_SND_SOC_INTEL_SOUNDWIRE_SOF_MACH=m @@ -7569,19 +8214,24 @@ CONFIG_SND_SOC_SOF_PCI_DEV=m CONFIG_SND_SOC_SOF_PCI=m CONFIG_SND_SOC_SOF_ACPI=m CONFIG_SND_SOC_SOF_ACPI_DEV=m +CONFIG_SND_SOC_SOF_OF=m CONFIG_SND_SOC_SOF_DEBUG_PROBES=m CONFIG_SND_SOC_SOF_CLIENT=m # CONFIG_SND_SOC_SOF_DEVELOPER_SUPPORT is not set CONFIG_SND_SOC_SOF=m CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE=y CONFIG_SND_SOC_SOF_IPC3=y -CONFIG_SND_SOC_SOF_INTEL_IPC4=y +CONFIG_SND_SOC_SOF_IPC4=y CONFIG_SND_SOC_SOF_AMD_TOPLEVEL=m CONFIG_SND_SOC_SOF_AMD_COMMON=m CONFIG_SND_SOC_SOF_AMD_RENOIR=m CONFIG_SND_SOC_SOF_AMD_VANGOGH=m CONFIG_SND_SOC_SOF_AMD_REMBRANDT=m CONFIG_SND_SOC_SOF_ACP_PROBES=m +CONFIG_SND_SOC_SOF_AMD_SOUNDWIRE_LINK_BASELINE=m +CONFIG_SND_SOC_SOF_AMD_SOUNDWIRE=m +CONFIG_SND_SOC_SOF_AMD_ACP63=m +CONFIG_SND_SOC_SOF_AMD_ACP70=m CONFIG_SND_SOC_SOF_INTEL_TOPLEVEL=y CONFIG_SND_SOC_SOF_INTEL_HIFI_EP_IPC=m CONFIG_SND_SOC_SOF_INTEL_ATOM_HIFI_EP=m @@ -7610,7 +8260,10 @@ CONFIG_SND_SOC_SOF_INTEL_MTL=m CONFIG_SND_SOC_SOF_METEORLAKE=m CONFIG_SND_SOC_SOF_INTEL_LNL=m CONFIG_SND_SOC_SOF_LUNARLAKE=m +CONFIG_SND_SOC_SOF_INTEL_PTL=m +CONFIG_SND_SOC_SOF_PANTHERLAKE=m CONFIG_SND_SOC_SOF_HDA_COMMON=m +CONFIG_SND_SOC_SOF_HDA_GENERIC=m CONFIG_SND_SOC_SOF_HDA_MLINK=m CONFIG_SND_SOC_SOF_HDA_LINK=y CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC=y @@ -7657,6 +8310,7 @@ CONFIG_SND_SOC_AK4375=m CONFIG_SND_SOC_AK4458=m CONFIG_SND_SOC_AK4554=m CONFIG_SND_SOC_AK4613=m +CONFIG_SND_SOC_AK4619=m CONFIG_SND_SOC_AK4642=m CONFIG_SND_SOC_AK5386=m CONFIG_SND_SOC_AK5558=m @@ -7666,10 +8320,14 @@ CONFIG_SND_SOC_AW8738=m CONFIG_SND_SOC_AW88395_LIB=m CONFIG_SND_SOC_AW88395=m CONFIG_SND_SOC_AW88261=m +CONFIG_SND_SOC_AW87390=m +CONFIG_SND_SOC_AW88399=m CONFIG_SND_SOC_BD28623=m CONFIG_SND_SOC_BT_SCO=m CONFIG_SND_SOC_CHV3_CODEC=m +CONFIG_SND_SOC_CPCAP=m CONFIG_SND_SOC_CROS_EC_CODEC=m +CONFIG_SND_SOC_CS_AMP_LIB=m CONFIG_SND_SOC_CS35L32=m CONFIG_SND_SOC_CS35L33=m CONFIG_SND_SOC_CS35L34=m @@ -7687,6 +8345,7 @@ CONFIG_SND_SOC_CS35L56_SHARED=m CONFIG_SND_SOC_CS35L56_I2C=m CONFIG_SND_SOC_CS35L56_SPI=m CONFIG_SND_SOC_CS35L56_SDW=m +CONFIG_SND_SOC_CS40L50=m CONFIG_SND_SOC_CS42L42_CORE=m CONFIG_SND_SOC_CS42L42=m CONFIG_SND_SOC_CS42L42_SDW=m @@ -7710,6 +8369,8 @@ CONFIG_SND_SOC_CS43130=m CONFIG_SND_SOC_CS4341=m CONFIG_SND_SOC_CS4349=m CONFIG_SND_SOC_CS53L30=m +CONFIG_SND_SOC_CS530X=m +CONFIG_SND_SOC_CS530X_I2C=m CONFIG_SND_SOC_CX2072X=m CONFIG_SND_SOC_DA7213=m CONFIG_SND_SOC_DA7219=m @@ -7717,22 +8378,24 @@ CONFIG_SND_SOC_DMIC=m CONFIG_SND_SOC_HDMI_CODEC=m CONFIG_SND_SOC_ES7134=m CONFIG_SND_SOC_ES7241=m +CONFIG_SND_SOC_ES83XX_DSM_COMMON=m +CONFIG_SND_SOC_ES8311=m CONFIG_SND_SOC_ES8316=m CONFIG_SND_SOC_ES8326=m CONFIG_SND_SOC_ES8328=m CONFIG_SND_SOC_ES8328_I2C=m CONFIG_SND_SOC_ES8328_SPI=m -# CONFIG_SND_SOC_GTM601 is not set -CONFIG_SND_SOC_HDAC_HDMI=m +CONFIG_SND_SOC_FRAMER=m +CONFIG_SND_SOC_GTM601=m CONFIG_SND_SOC_HDAC_HDA=m CONFIG_SND_SOC_HDA=m CONFIG_SND_SOC_ICS43432=m CONFIG_SND_SOC_IDT821034=m -# CONFIG_SND_SOC_INNO_RK3036 is not set +CONFIG_SND_SOC_LOCHNAGAR_SC=m CONFIG_SND_SOC_MAX98088=m CONFIG_SND_SOC_MAX98090=m CONFIG_SND_SOC_MAX98357A=m -# CONFIG_SND_SOC_MAX98504 is not set +CONFIG_SND_SOC_MAX98504=m CONFIG_SND_SOC_MAX9867=m CONFIG_SND_SOC_MAX98927=m CONFIG_SND_SOC_MAX98520=m @@ -7743,28 +8406,31 @@ CONFIG_SND_SOC_MAX98373_SDW=m CONFIG_SND_SOC_MAX98388=m CONFIG_SND_SOC_MAX98390=m CONFIG_SND_SOC_MAX98396=m -# CONFIG_SND_SOC_MAX9860 is not set -# CONFIG_SND_SOC_MSM8916_WCD_ANALOG is not set -# CONFIG_SND_SOC_MSM8916_WCD_DIGITAL is not set -# CONFIG_SND_SOC_PCM1681 is not set +CONFIG_SND_SOC_MAX9860=m +CONFIG_SND_SOC_MSM8916_WCD_ANALOG=m +CONFIG_SND_SOC_MSM8916_WCD_DIGITAL=m +CONFIG_SND_SOC_PCM1681=m CONFIG_SND_SOC_PCM1789=m CONFIG_SND_SOC_PCM1789_I2C=m -# CONFIG_SND_SOC_PCM179X_I2C is not set -# CONFIG_SND_SOC_PCM179X_SPI is not set +CONFIG_SND_SOC_PCM179X=m +CONFIG_SND_SOC_PCM179X_I2C=m +CONFIG_SND_SOC_PCM179X_SPI=m CONFIG_SND_SOC_PCM186X=m CONFIG_SND_SOC_PCM186X_I2C=m CONFIG_SND_SOC_PCM186X_SPI=m CONFIG_SND_SOC_PCM3060=m CONFIG_SND_SOC_PCM3060_I2C=m CONFIG_SND_SOC_PCM3060_SPI=m -# CONFIG_SND_SOC_PCM3168A_I2C is not set -# CONFIG_SND_SOC_PCM3168A_SPI is not set -# CONFIG_SND_SOC_PCM5102A is not set +CONFIG_SND_SOC_PCM3168A=m +CONFIG_SND_SOC_PCM3168A_I2C=m +CONFIG_SND_SOC_PCM3168A_SPI=m +CONFIG_SND_SOC_PCM5102A=m CONFIG_SND_SOC_PCM512x=m CONFIG_SND_SOC_PCM512x_I2C=m -# CONFIG_SND_SOC_PCM512x_SPI is not set -# CONFIG_SND_SOC_PEB2466 is not set -# CONFIG_SND_SOC_RK3328 is not set +CONFIG_SND_SOC_PCM512x_SPI=m +CONFIG_SND_SOC_PCM6240=m +CONFIG_SND_SOC_PEB2466=m +CONFIG_SND_SOC_RK817=m CONFIG_SND_SOC_RL6231=m CONFIG_SND_SOC_RL6347A=m CONFIG_SND_SOC_RT274=m @@ -7779,8 +8445,8 @@ CONFIG_SND_SOC_RT1308=m CONFIG_SND_SOC_RT1308_SDW=m CONFIG_SND_SOC_RT1316_SDW=m CONFIG_SND_SOC_RT1318_SDW=m +CONFIG_SND_SOC_RT1320_SDW=m CONFIG_SND_SOC_RT5514=m -CONFIG_SND_SOC_RT5514_SPI=m CONFIG_SND_SOC_RT5616=m CONFIG_SND_SOC_RT5631=m CONFIG_SND_SOC_RT5640=m @@ -7808,8 +8474,9 @@ CONFIG_SND_SOC_RT715=m CONFIG_SND_SOC_RT715_SDW=m CONFIG_SND_SOC_RT715_SDCA_SDW=m CONFIG_SND_SOC_RT9120=m -# CONFIG_SND_SOC_SDW_MOCKUP is not set -# CONFIG_SND_SOC_SGTL5000 is not set +CONFIG_SND_SOC_RTQ9128=m +CONFIG_SND_SOC_SDW_MOCKUP=m +CONFIG_SND_SOC_SGTL5000=m CONFIG_SND_SOC_SI476X=m CONFIG_SND_SOC_SIGMADSP=m CONFIG_SND_SOC_SIGMADSP_I2C=m @@ -7820,15 +8487,17 @@ CONFIG_SND_SOC_SMA1303=m CONFIG_SND_SOC_SPDIF=m CONFIG_SND_SOC_SRC4XXX_I2C=m CONFIG_SND_SOC_SRC4XXX=m -# CONFIG_SND_SOC_SSM2305 is not set -# CONFIG_SND_SOC_SSM2518 is not set -# CONFIG_SND_SOC_SSM2602_SPI is not set -# CONFIG_SND_SOC_SSM2602_I2C is not set +CONFIG_SND_SOC_SSM2305=m +CONFIG_SND_SOC_SSM2518=m +CONFIG_SND_SOC_SSM2602=m +CONFIG_SND_SOC_SSM2602_SPI=m +CONFIG_SND_SOC_SSM2602_I2C=m +CONFIG_SND_SOC_SSM3515=m CONFIG_SND_SOC_SSM4567=m -# CONFIG_SND_SOC_STA32X is not set -# CONFIG_SND_SOC_STA350 is not set -# CONFIG_SND_SOC_STI_SAS is not set -# CONFIG_SND_SOC_TAS2552 is not set +CONFIG_SND_SOC_STA32X=m +CONFIG_SND_SOC_STA350=m +CONFIG_SND_SOC_STI_SAS=m +CONFIG_SND_SOC_TAS2552=m CONFIG_SND_SOC_TAS2562=m CONFIG_SND_SOC_TAS2764=m CONFIG_SND_SOC_TAS2770=m @@ -7836,67 +8505,76 @@ CONFIG_SND_SOC_TAS2780=m CONFIG_SND_SOC_TAS2781_COMLIB=m CONFIG_SND_SOC_TAS2781_FMWLIB=m CONFIG_SND_SOC_TAS2781_I2C=m -# CONFIG_SND_SOC_TAS5086 is not set -# CONFIG_SND_SOC_TAS571X is not set -# CONFIG_SND_SOC_TAS5720 is not set +CONFIG_SND_SOC_TAS5086=m +CONFIG_SND_SOC_TAS571X=m +CONFIG_SND_SOC_TAS5720=m CONFIG_SND_SOC_TAS5805M=m CONFIG_SND_SOC_TAS6424=m CONFIG_SND_SOC_TDA7419=m -# CONFIG_SND_SOC_TFA9879 is not set -# CONFIG_SND_SOC_TFA989X is not set -# CONFIG_SND_SOC_TLV320ADC3XXX is not set +CONFIG_SND_SOC_TFA9879=m +CONFIG_SND_SOC_TFA989X=m +CONFIG_SND_SOC_TLV320ADC3XXX=m CONFIG_SND_SOC_TLV320AIC23=m CONFIG_SND_SOC_TLV320AIC23_I2C=m CONFIG_SND_SOC_TLV320AIC23_SPI=m -# CONFIG_SND_SOC_TLV320AIC31XX is not set +CONFIG_SND_SOC_TLV320AIC31XX=m CONFIG_SND_SOC_TLV320AIC32X4=m CONFIG_SND_SOC_TLV320AIC32X4_I2C=m CONFIG_SND_SOC_TLV320AIC32X4_SPI=m -# CONFIG_SND_SOC_TLV320AIC3X_I2C is not set -# CONFIG_SND_SOC_TLV320AIC3X_SPI is not set +CONFIG_SND_SOC_TLV320AIC3X=m +CONFIG_SND_SOC_TLV320AIC3X_I2C=m +CONFIG_SND_SOC_TLV320AIC3X_SPI=m CONFIG_SND_SOC_TLV320ADCX140=m CONFIG_SND_SOC_TS3A227E=m CONFIG_SND_SOC_TSCS42XX=m -# CONFIG_SND_SOC_TSCS454 is not set -# CONFIG_SND_SOC_UDA1334 is not set -# CONFIG_SND_SOC_WCD938X_SDW is not set +CONFIG_SND_SOC_TSCS454=m +CONFIG_SND_SOC_UDA1334=m +CONFIG_SND_SOC_WCD_CLASSH=m +CONFIG_SND_SOC_WCD_MBHC=m +CONFIG_SND_SOC_WCD937X=m +CONFIG_SND_SOC_WCD937X_SDW=m +CONFIG_SND_SOC_WCD938X=m +CONFIG_SND_SOC_WCD938X_SDW=m +CONFIG_SND_SOC_WCD939X=m +CONFIG_SND_SOC_WCD939X_SDW=m CONFIG_SND_SOC_WM5102=m -# CONFIG_SND_SOC_WM8510 is not set -# CONFIG_SND_SOC_WM8523 is not set +CONFIG_SND_SOC_WM8510=m +CONFIG_SND_SOC_WM8523=m CONFIG_SND_SOC_WM8524=m -# CONFIG_SND_SOC_WM8580 is not set -# CONFIG_SND_SOC_WM8711 is not set -# CONFIG_SND_SOC_WM8728 is not set +CONFIG_SND_SOC_WM8580=m +CONFIG_SND_SOC_WM8711=m +CONFIG_SND_SOC_WM8728=m CONFIG_SND_SOC_WM8731=m CONFIG_SND_SOC_WM8731_I2C=m CONFIG_SND_SOC_WM8731_SPI=m -# CONFIG_SND_SOC_WM8737 is not set -# CONFIG_SND_SOC_WM8741 is not set -# CONFIG_SND_SOC_WM8750 is not set -# CONFIG_SND_SOC_WM8753 is not set -# CONFIG_SND_SOC_WM8770 is not set -# CONFIG_SND_SOC_WM8776 is not set +CONFIG_SND_SOC_WM8737=m +CONFIG_SND_SOC_WM8741=m +CONFIG_SND_SOC_WM8750=m +CONFIG_SND_SOC_WM8753=m +CONFIG_SND_SOC_WM8770=m +CONFIG_SND_SOC_WM8776=m CONFIG_SND_SOC_WM8782=m CONFIG_SND_SOC_WM8804=m CONFIG_SND_SOC_WM8804_I2C=m -# CONFIG_SND_SOC_WM8804_SPI is not set -# CONFIG_SND_SOC_WM8903 is not set -# CONFIG_SND_SOC_WM8904 is not set +CONFIG_SND_SOC_WM8804_SPI=m +CONFIG_SND_SOC_WM8903=m +CONFIG_SND_SOC_WM8904=m CONFIG_SND_SOC_WM8940=m -# CONFIG_SND_SOC_WM8960 is not set +CONFIG_SND_SOC_WM8960=m CONFIG_SND_SOC_WM8961=m -# CONFIG_SND_SOC_WM8962 is not set -# CONFIG_SND_SOC_WM8974 is not set -# CONFIG_SND_SOC_WM8978 is not set -# CONFIG_SND_SOC_WM8985 is not set +CONFIG_SND_SOC_WM8962=m +CONFIG_SND_SOC_WM8974=m +CONFIG_SND_SOC_WM8978=m +CONFIG_SND_SOC_WM8985=m CONFIG_SND_SOC_WSA881X=m CONFIG_SND_SOC_WSA883X=m CONFIG_SND_SOC_WSA884X=m CONFIG_SND_SOC_ZL38060=m CONFIG_SND_SOC_MAX9759=m -# CONFIG_SND_SOC_MT6351 is not set -# CONFIG_SND_SOC_MT6358 is not set -# CONFIG_SND_SOC_MT6660 is not set +CONFIG_SND_SOC_MT6351=m +CONFIG_SND_SOC_MT6357=m +CONFIG_SND_SOC_MT6358=m +CONFIG_SND_SOC_MT6660=m CONFIG_SND_SOC_NAU8315=m CONFIG_SND_SOC_NAU8540=m CONFIG_SND_SOC_NAU8810=m @@ -7911,8 +8589,13 @@ CONFIG_SND_SOC_TPA6130A2=m # CONFIG_SND_SOC_LPASS_TX_MACRO is not set # end of CODEC drivers +CONFIG_SND_SOC_SDW_UTILS=m CONFIG_SND_SIMPLE_CARD_UTILS=m CONFIG_SND_SIMPLE_CARD=m +CONFIG_SND_AUDIO_GRAPH_CARD=m +CONFIG_SND_AUDIO_GRAPH_CARD2=m +CONFIG_SND_AUDIO_GRAPH_CARD2_CUSTOM_SAMPLE=m +CONFIG_SND_TEST_COMPONENT=m CONFIG_SND_X86=y CONFIG_HDMI_LPE_AUDIO=m CONFIG_SND_SYNTH_EMUX=m @@ -7965,6 +8648,7 @@ CONFIG_HID_GLORIOUS=m CONFIG_HID_HOLTEK=m CONFIG_HOLTEK_FF=y CONFIG_HID_VIVALDI_COMMON=m +# CONFIG_HID_GOODIX_SPI is not set CONFIG_HID_GOOGLE_HAMMER=m CONFIG_HID_GOOGLE_STADIA_FF=m CONFIG_HID_VIVALDI=m @@ -8054,6 +8738,7 @@ CONFIG_HID_U2FZERO=m CONFIG_HID_UNIVERSAL_PIDFF=m CONFIG_HID_WACOM=m CONFIG_HID_WIIMOTE=m +CONFIG_HID_WINWING=m CONFIG_HID_XINMO=m CONFIG_HID_ZEROPLUS=m CONFIG_ZEROPLUS_FF=y @@ -8068,7 +8753,7 @@ CONFIG_HID_MCP2221=m # # HID-BPF support # -# CONFIG_HID_BPF is not set +CONFIG_HID_BPF=y # end of HID-BPF support # @@ -8082,6 +8767,8 @@ CONFIG_USB_HIDDEV=y CONFIG_I2C_HID=y CONFIG_I2C_HID_ACPI=m CONFIG_I2C_HID_OF=m +CONFIG_I2C_HID_OF_ELAN=m +CONFIG_I2C_HID_OF_GOODIX=m CONFIG_I2C_HID_CORE=m # @@ -8114,6 +8801,7 @@ CONFIG_USB_CONN_GPIO=m CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB=y CONFIG_USB_PCI=y +CONFIG_USB_PCI_AMD=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y # @@ -8128,6 +8816,7 @@ CONFIG_USB_OTG=y CONFIG_USB_OTG_FSM=m CONFIG_USB_LEDS_TRIGGER_USBPORT=y CONFIG_USB_AUTOSUSPEND_DELAY=2 +CONFIG_USB_DEFAULT_AUTHORIZATION_MODE=1 CONFIG_USB_MON=m # @@ -8136,7 +8825,7 @@ CONFIG_USB_MON=m CONFIG_USB_C67X00_HCD=m CONFIG_USB_XHCI_HCD=y # CONFIG_USB_XHCI_DBGCAP is not set -CONFIG_USB_XHCI_PCI=m +CONFIG_USB_XHCI_PCI=y CONFIG_USB_XHCI_PCI_RENESAS=m CONFIG_USB_XHCI_PLATFORM=m CONFIG_USB_EHCI_HCD=y @@ -8233,6 +8922,7 @@ CONFIG_USB_DWC3_HOST=y # CONFIG_USB_DWC3_PCI=m CONFIG_USB_DWC3_HAPS=m +CONFIG_USB_DWC3_OF_SIMPLE=m CONFIG_USB_DWC2=m CONFIG_USB_DWC2_HOST=y @@ -8246,7 +8936,10 @@ CONFIG_USB_CHIPIDEA=m CONFIG_USB_CHIPIDEA_HOST=y CONFIG_USB_CHIPIDEA_PCI=m CONFIG_USB_CHIPIDEA_MSM=m +CONFIG_USB_CHIPIDEA_NPCM=m +CONFIG_USB_CHIPIDEA_IMX=m CONFIG_USB_CHIPIDEA_GENERIC=m +CONFIG_USB_CHIPIDEA_TEGRA=m CONFIG_USB_ISP1760=m CONFIG_USB_ISP1760_HCD=y CONFIG_USB_ISP1760_HOST_ROLE=y @@ -8327,6 +9020,7 @@ CONFIG_USB_CYTHERM=m CONFIG_USB_IDMOUSE=m CONFIG_USB_APPLEDISPLAY=m CONFIG_APPLE_MFI_FASTCHARGE=m +CONFIG_USB_LJCA=m CONFIG_USB_SISUSBVGA=m CONFIG_USB_LD=m CONFIG_USB_TRANCEVIBRATOR=m @@ -8341,6 +9035,8 @@ CONFIG_USB_HSIC_USB3503=m CONFIG_USB_HSIC_USB4604=m CONFIG_USB_LINK_LAYER_TEST=m CONFIG_USB_CHAOSKEY=m +CONFIG_USB_ONBOARD_DEV=m +CONFIG_USB_ONBOARD_DEV_USB5744=y CONFIG_USB_ATM=m CONFIG_USB_SPEEDTOUCH=m CONFIG_USB_CXACRU=m @@ -8352,7 +9048,7 @@ CONFIG_USB_XUSBATM=m # CONFIG_USB_PHY=y CONFIG_NOP_USB_XCEIV=m -CONFIG_USB_GPIO_VBUS=m +# CONFIG_USB_GPIO_VBUS is not set CONFIG_TAHVO_USB=m # CONFIG_TAHVO_USB_HOST_BY_DEFAULT is not set CONFIG_USB_ISP1301=m @@ -8370,6 +9066,7 @@ CONFIG_TYPEC_UCSI=m CONFIG_UCSI_CCG=m CONFIG_UCSI_ACPI=m CONFIG_UCSI_STM32G0=m +# CONFIG_UCSI_PMIC_GLINK is not set CONFIG_TYPEC_TPS6598X=m CONFIG_TYPEC_ANX7411=m CONFIG_TYPEC_RT1719=m @@ -8384,7 +9081,10 @@ CONFIG_TYPEC_MUX_FSA4480=m CONFIG_TYPEC_MUX_GPIO_SBU=m CONFIG_TYPEC_MUX_PI3USB30532=m CONFIG_TYPEC_MUX_INTEL_PMC=m +CONFIG_TYPEC_MUX_IT5205=m CONFIG_TYPEC_MUX_NB7VPQ904M=m +CONFIG_TYPEC_MUX_PTN36502=m +CONFIG_TYPEC_MUX_WCD939X_USBSS=m # end of USB Type-C Multiplexer/DeMultiplexer Switch support # @@ -8397,6 +9097,9 @@ CONFIG_TYPEC_NVIDIA_ALTMODE=m CONFIG_USB_ROLE_SWITCH=m CONFIG_USB_ROLES_INTEL_XHCI=m CONFIG_MMC=m +CONFIG_PWRSEQ_EMMC=m +CONFIG_PWRSEQ_SD8787=m +CONFIG_PWRSEQ_SIMPLE=m CONFIG_MMC_BLOCK=m CONFIG_MMC_BLOCK_MINORS=8 CONFIG_SDIO_UART=m @@ -8413,7 +9116,12 @@ CONFIG_MMC_SDHCI_PCI=m CONFIG_MMC_RICOH_MMC=y CONFIG_MMC_SDHCI_ACPI=m CONFIG_MMC_SDHCI_PLTFM=m +CONFIG_MMC_SDHCI_OF_ARASAN=m +CONFIG_MMC_SDHCI_OF_AT91=m +CONFIG_MMC_SDHCI_OF_DWCMSHC=m +CONFIG_MMC_SDHCI_CADENCE=m CONFIG_MMC_SDHCI_F_SDH30=m +CONFIG_MMC_SDHCI_MILBEAUT=m CONFIG_MMC_WBSD=m CONFIG_MMC_ALCOR=m CONFIG_MMC_TIFM_SD=m @@ -8431,6 +9139,7 @@ CONFIG_MMC_HSQ=m CONFIG_MMC_TOSHIBA_PCI=m CONFIG_MMC_MTK=m CONFIG_MMC_SDHCI_XENON=m +# CONFIG_MMC_LITEX is not set CONFIG_SCSI_UFSHCD=m CONFIG_SCSI_UFS_BSG=y CONFIG_SCSI_UFS_CRYPTO=y @@ -8439,6 +9148,7 @@ CONFIG_SCSI_UFSHCD_PCI=m CONFIG_SCSI_UFS_DWC_TC_PCI=m CONFIG_SCSI_UFSHCD_PLATFORM=m CONFIG_SCSI_UFS_CDNS_PLATFORM=m +CONFIG_SCSI_UFS_DWC_TC_PLATFORM=m CONFIG_MEMSTICK=m # CONFIG_MEMSTICK_DEBUG is not set @@ -8455,8 +9165,8 @@ CONFIG_MS_BLOCK=m CONFIG_MEMSTICK_TIFM_MS=m CONFIG_MEMSTICK_JMICRON_38X=m CONFIG_MEMSTICK_R592=m -CONFIG_MEMSTICK_REALTEK_PCI=m CONFIG_MEMSTICK_REALTEK_USB=m +CONFIG_LEDS_EXPRESSWIRE=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y CONFIG_LEDS_CLASS_FLASH=m @@ -8467,20 +9177,37 @@ CONFIG_LEDS_BRIGHTNESS_HW_CHANGED=y # LED drivers # CONFIG_LEDS_88PM860X=m +CONFIG_LEDS_AN30259A=m CONFIG_LEDS_APU=m CONFIG_LEDS_AW200XX=m +CONFIG_LEDS_AW2013=m +CONFIG_LEDS_BCM6328=m +CONFIG_LEDS_BCM6358=m CONFIG_LEDS_CHT_WCOVE=m +CONFIG_LEDS_CPCAP=m +CONFIG_LEDS_CR0014114=m +CONFIG_LEDS_CROS_EC=m +CONFIG_LEDS_EL15203000=m CONFIG_LEDS_LM3530=m CONFIG_LEDS_LM3532=m CONFIG_LEDS_LM3642=m +CONFIG_LEDS_LM3692X=m CONFIG_LEDS_PCA9532=m CONFIG_LEDS_PCA9532_GPIO=y CONFIG_LEDS_GPIO=m -# CONFIG_LEDS_LP3944 is not set -# CONFIG_LEDS_LP3952 is not set -# CONFIG_LEDS_LP50XX is not set -# CONFIG_LEDS_LP8788 is not set -# CONFIG_LEDS_PCA955X is not set +CONFIG_LEDS_LP3944=m +CONFIG_LEDS_LP3952=m +CONFIG_LEDS_LP50XX=m +CONFIG_LEDS_LP55XX_COMMON=m +CONFIG_LEDS_LP5521=m +CONFIG_LEDS_LP5523=m +CONFIG_LEDS_LP5562=m +CONFIG_LEDS_LP5569=m +CONFIG_LEDS_LP8501=m +CONFIG_LEDS_LP8788=m +CONFIG_LEDS_LP8860=m +CONFIG_LEDS_PCA955X=m +CONFIG_LEDS_PCA955X_GPIO=y CONFIG_LEDS_PCA963X=m CONFIG_LEDS_PCA995X=m CONFIG_LEDS_WM831X_STATUS=m @@ -8490,42 +9217,59 @@ CONFIG_LEDS_DA9052=m CONFIG_LEDS_DAC124S085=m CONFIG_LEDS_PWM=m CONFIG_LEDS_REGULATOR=m -# CONFIG_LEDS_BD2606MVV is not set -# CONFIG_LEDS_BD2802 is not set +CONFIG_LEDS_BD2606MVV=m +CONFIG_LEDS_BD2802=m CONFIG_LEDS_INTEL_SS4200=m CONFIG_LEDS_LT3593=m CONFIG_LEDS_ADP5520=m +CONFIG_LEDS_MAX5970=m CONFIG_LEDS_MC13783=m CONFIG_LEDS_TCA6507=m CONFIG_LEDS_TLC591XX=m +CONFIG_LEDS_MAX77650=m CONFIG_LEDS_MAX8997=m CONFIG_LEDS_LM355x=m CONFIG_LEDS_MENF21BMC=m CONFIG_LEDS_IS31FL319X=m +CONFIG_LEDS_IS31FL32XX=m # # LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) # CONFIG_LEDS_BLINKM=m +CONFIG_LEDS_BLINKM_MULTICOLOR=y +CONFIG_LEDS_SYSCON=y CONFIG_LEDS_MLXCPLD=m CONFIG_LEDS_MLXREG=m CONFIG_LEDS_USER=m CONFIG_LEDS_NIC78BX=m +CONFIG_LEDS_SPI_BYTE=m CONFIG_LEDS_TI_LMU_COMMON=m +CONFIG_LEDS_LM3697=m CONFIG_LEDS_LM36274=m +CONFIG_LEDS_LGM=m # # Flash and Torch LED drivers # +CONFIG_LEDS_AAT1290=m # CONFIG_LEDS_AS3645A is not set +CONFIG_LEDS_KTD2692=m # CONFIG_LEDS_LM3601X is not set +CONFIG_LEDS_MAX77693=m +CONFIG_LEDS_RT4505=m CONFIG_LEDS_RT8515=m # CONFIG_LEDS_SGM3140 is not set +CONFIG_LEDS_SY7802=m # # RGB LED drivers # +CONFIG_LEDS_GROUP_MULTICOLOR=m +CONFIG_LEDS_KTD202X=m +CONFIG_LEDS_NCP5623=m CONFIG_LEDS_PWM_MULTICOLOR=m +CONFIG_LEDS_QCOM_LPG=m # # LED Triggers @@ -8534,11 +9278,12 @@ CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=m CONFIG_LEDS_TRIGGER_ONESHOT=m CONFIG_LEDS_TRIGGER_DISK=y -# CONFIG_LEDS_TRIGGER_MTD is not set +CONFIG_LEDS_TRIGGER_MTD=y CONFIG_LEDS_TRIGGER_HEARTBEAT=m CONFIG_LEDS_TRIGGER_BACKLIGHT=m CONFIG_LEDS_TRIGGER_CPU=y CONFIG_LEDS_TRIGGER_ACTIVITY=m +# CONFIG_LEDS_TRIGGER_GPIO is not set CONFIG_LEDS_TRIGGER_DEFAULT_ON=m # @@ -8549,8 +9294,8 @@ CONFIG_LEDS_TRIGGER_CAMERA=m CONFIG_LEDS_TRIGGER_PANIC=y CONFIG_LEDS_TRIGGER_NETDEV=m CONFIG_LEDS_TRIGGER_PATTERN=m -CONFIG_LEDS_TRIGGER_AUDIO=m CONFIG_LEDS_TRIGGER_TTY=m +CONFIG_LEDS_TRIGGER_INPUT_EVENTS=m # # Simple LED drivers @@ -8606,14 +9351,16 @@ CONFIG_INFINIBAND_RDMAVT=m CONFIG_RDMA_RXE=m CONFIG_RDMA_SIW=m CONFIG_INFINIBAND_IPOIB=m -# CONFIG_INFINIBAND_IPOIB_CM is not set -# CONFIG_INFINIBAND_IPOIB_DEBUG is not set +CONFIG_INFINIBAND_IPOIB_CM=y +CONFIG_INFINIBAND_IPOIB_DEBUG=y +CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y CONFIG_INFINIBAND_SRP=m CONFIG_INFINIBAND_SRPT=m CONFIG_INFINIBAND_ISER=m CONFIG_INFINIBAND_ISERT=m -# CONFIG_INFINIBAND_RTRS_CLIENT is not set -# CONFIG_INFINIBAND_RTRS_SERVER is not set +CONFIG_INFINIBAND_RTRS=m +CONFIG_INFINIBAND_RTRS_CLIENT=m +CONFIG_INFINIBAND_RTRS_SERVER=m CONFIG_INFINIBAND_OPA_VNIC=m CONFIG_EDAC_ATOMIC_SCRUB=y CONFIG_EDAC_SUPPORT=y @@ -8621,7 +9368,7 @@ CONFIG_EDAC=y CONFIG_EDAC_LEGACY_SYSFS=y # CONFIG_EDAC_DEBUG is not set CONFIG_EDAC_DECODE_MCE=y -# CONFIG_EDAC_GHES is not set +CONFIG_EDAC_GHES=y CONFIG_EDAC_AMD64=m CONFIG_EDAC_E752X=m CONFIG_EDAC_I82975X=m @@ -8665,20 +9412,27 @@ CONFIG_RTC_DRV_88PM80X=m CONFIG_RTC_DRV_ABB5ZES3=m CONFIG_RTC_DRV_ABEOZ9=m CONFIG_RTC_DRV_ABX80X=m +CONFIG_RTC_DRV_AS3722=m CONFIG_RTC_DRV_DS1307=m CONFIG_RTC_DRV_DS1307_CENTURY=y CONFIG_RTC_DRV_DS1374=m CONFIG_RTC_DRV_DS1374_WDT=y CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_HYM8563=m CONFIG_RTC_DRV_LP8788=m CONFIG_RTC_DRV_MAX6900=m CONFIG_RTC_DRV_MAX8907=m CONFIG_RTC_DRV_MAX8925=m CONFIG_RTC_DRV_MAX8998=m CONFIG_RTC_DRV_MAX8997=m +# CONFIG_RTC_DRV_MAX31335 is not set +CONFIG_RTC_DRV_MAX77686=m +CONFIG_RTC_DRV_NCT3018Y=m +CONFIG_RTC_DRV_RK808=m CONFIG_RTC_DRV_RS5C372=m CONFIG_RTC_DRV_ISL1208=m CONFIG_RTC_DRV_ISL12022=m +CONFIG_RTC_DRV_ISL12026=m CONFIG_RTC_DRV_X1205=m CONFIG_RTC_DRV_PCF8523=m CONFIG_RTC_DRV_PCF85063=m @@ -8687,20 +9441,27 @@ CONFIG_RTC_DRV_PCF8563=m CONFIG_RTC_DRV_PCF8583=m CONFIG_RTC_DRV_M41T80=m CONFIG_RTC_DRV_M41T80_WDT=y +CONFIG_RTC_DRV_BD70528=m CONFIG_RTC_DRV_BQ32K=m +CONFIG_RTC_DRV_TWL4030=m CONFIG_RTC_DRV_PALMAS=m CONFIG_RTC_DRV_TPS6586X=m +CONFIG_RTC_DRV_TPS6594=m CONFIG_RTC_DRV_TPS65910=m CONFIG_RTC_DRV_RC5T583=m +CONFIG_RTC_DRV_RC5T619=m CONFIG_RTC_DRV_S35390A=m CONFIG_RTC_DRV_FM3130=m CONFIG_RTC_DRV_RX8010=m +# CONFIG_RTC_DRV_RX8111 is not set CONFIG_RTC_DRV_RX8581=m CONFIG_RTC_DRV_RX8025=m CONFIG_RTC_DRV_EM3027=m CONFIG_RTC_DRV_RV3028=m CONFIG_RTC_DRV_RV3032=m CONFIG_RTC_DRV_RV8803=m +CONFIG_RTC_DRV_S5M=m +# CONFIG_RTC_DRV_SD2405AL is not set CONFIG_RTC_DRV_SD3078=m # @@ -8758,14 +9519,19 @@ CONFIG_RTC_DRV_MSM6242=m CONFIG_RTC_DRV_RP5C01=m CONFIG_RTC_DRV_WM831X=m CONFIG_RTC_DRV_WM8350=m +CONFIG_RTC_DRV_ZYNQMP=m CONFIG_RTC_DRV_CROS_EC=m +CONFIG_RTC_DRV_NTXEC=m # # on-CPU RTC drivers # +CONFIG_RTC_DRV_CADENCE=m # CONFIG_RTC_DRV_FTRTC010 is not set CONFIG_RTC_DRV_PCAP=m CONFIG_RTC_DRV_MC13XXX=m +CONFIG_RTC_DRV_R7301=m +CONFIG_RTC_DRV_CPCAP=m # # HID Sensor RTC drivers @@ -8782,7 +9548,10 @@ CONFIG_DMADEVICES=y CONFIG_DMA_ENGINE=y CONFIG_DMA_VIRTUAL_CHANNELS=y CONFIG_DMA_ACPI=y +CONFIG_DMA_OF=y CONFIG_ALTERA_MSGDMA=m +CONFIG_DW_AXI_DMAC=m +CONFIG_FSL_EDMA=m CONFIG_INTEL_IDMA64=m CONFIG_INTEL_IDXD_BUS=m CONFIG_INTEL_IDXD=m @@ -8793,6 +9562,8 @@ CONFIG_INTEL_IOATDMA=m CONFIG_PLX_DMA=m CONFIG_XILINX_DMA=m # CONFIG_XILINX_XDMA is not set +CONFIG_XILINX_ZYNQMP_DPDMA=m +CONFIG_AMD_QDMA=m CONFIG_AMD_PTDMA=m CONFIG_QCOM_HIDMA_MGMT=m CONFIG_QCOM_HIDMA=m @@ -8808,7 +9579,7 @@ CONFIG_INTEL_LDMA=y # # DMA Clients # -# CONFIG_ASYNC_TX_DMA is not set +CONFIG_ASYNC_TX_DMA=y CONFIG_DMATEST=m CONFIG_DMA_ENGINE_RAID=y @@ -8836,7 +9607,6 @@ CONFIG_UIO_AEC=m CONFIG_UIO_SERCOS3=m CONFIG_UIO_PCI_GENERIC=m CONFIG_UIO_NETX=m -CONFIG_UIO_PRUSS=m CONFIG_UIO_MF624=m CONFIG_UIO_HV_GENERIC=m CONFIG_VFIO=m @@ -8844,8 +9614,9 @@ CONFIG_VFIO_DEVICE_CDEV=y CONFIG_VFIO_GROUP=y CONFIG_VFIO_CONTAINER=y CONFIG_VFIO_IOMMU_TYPE1=m -# CONFIG_VFIO_NOIOMMU is not set +CONFIG_VFIO_NOIOMMU=y CONFIG_VFIO_VIRQFD=y +# CONFIG_VFIO_DEBUGFS is not set # # VFIO support for PCI devices @@ -8858,6 +9629,8 @@ CONFIG_VFIO_PCI_VGA=y CONFIG_VFIO_PCI_IGD=y CONFIG_MLX5_VFIO_PCI=m CONFIG_PDS_VFIO_PCI=m +CONFIG_VIRTIO_VFIO_PCI=m +CONFIG_QAT_VFIO_PCI=m # end of VFIO support for PCI devices CONFIG_VFIO_MDEV=m @@ -8867,7 +9640,9 @@ CONFIG_VMGENID=y CONFIG_VBOXGUEST=m CONFIG_NITRO_ENCLAVES=m CONFIG_ACRN_HSM=m +CONFIG_TSM_REPORTS=m CONFIG_EFI_SECRET=m +CONFIG_SEV_GUEST=m CONFIG_TDX_GUEST_DRIVER=m CONFIG_VIRTIO_ANCHOR=y CONFIG_VIRTIO=m @@ -8875,6 +9650,7 @@ CONFIG_VIRTIO_PCI_LIB=m CONFIG_VIRTIO_PCI_LIB_LEGACY=m CONFIG_VIRTIO_MENU=y CONFIG_VIRTIO_PCI=m +CONFIG_VIRTIO_PCI_ADMIN_LEGACY=y CONFIG_VIRTIO_PCI_LEGACY=y CONFIG_VIRTIO_VDPA=m CONFIG_VIRTIO_PMEM=m @@ -8884,6 +9660,7 @@ CONFIG_VIRTIO_INPUT=m CONFIG_VIRTIO_MMIO=m CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y CONFIG_VIRTIO_DMA_SHARED_BUFFER=m +# CONFIG_VIRTIO_DEBUG is not set CONFIG_VDPA=m CONFIG_VDPA_SIM=m CONFIG_VDPA_SIM_NET=m @@ -8897,6 +9674,7 @@ CONFIG_VP_VDPA=m CONFIG_ALIBABA_ENI_VDPA=m CONFIG_SNET_VDPA=m CONFIG_PDS_VDPA=m +CONFIG_OCTEONEP_VDPA=m CONFIG_VHOST_IOTLB=m CONFIG_VHOST_RING=m CONFIG_VHOST_TASK=y @@ -8942,7 +9720,7 @@ CONFIG_XEN_PVCALLS_FRONTEND=m # CONFIG_XEN_PVCALLS_BACKEND is not set CONFIG_XEN_SCSI_BACKEND=m CONFIG_XEN_PRIVCMD=m -CONFIG_XEN_PRIVCMD_IRQFD=y +CONFIG_XEN_PRIVCMD_EVENTFD=y CONFIG_XEN_ACPI_PROCESSOR=m # CONFIG_XEN_MCE_LOG is not set CONFIG_XEN_HAVE_PVMMU=y @@ -8953,6 +9731,7 @@ CONFIG_XEN_SYMS=y CONFIG_XEN_HAVE_VPMU=y CONFIG_XEN_FRONT_PGDIR_SHBUF=m CONFIG_XEN_UNPOPULATED_ALLOC=y +CONFIG_XEN_GRANT_DMA_IOMMU=y CONFIG_XEN_GRANT_DMA_OPS=y CONFIG_XEN_VIRTIO=y # CONFIG_XEN_VIRTIO_FORCE_GRANT is not set @@ -9048,8 +9827,6 @@ CONFIG_COMEDI_NI_TIO=m CONFIG_COMEDI_NI_ROUTING=m # CONFIG_COMEDI_TESTS is not set CONFIG_STAGING=y -CONFIG_PRISM2_USB=m -CONFIG_RTL8192U=m CONFIG_RTLLIB=m CONFIG_RTLLIB_CRYPTO_CCMP=m CONFIG_RTLLIB_CRYPTO_TKIP=m @@ -9099,12 +9876,6 @@ CONFIG_AD9834=m # CONFIG_AD5933=m # end of Network Analyzer, Impedance Converters - -# -# Resolver to digital converters -# -CONFIG_AD2S1210=m -# end of Resolver to digital converters # end of IIO staging drivers # CONFIG_FB_SM750 is not set @@ -9113,17 +9884,22 @@ CONFIG_STAGING_MEDIA=y CONFIG_DVB_AV7110_IR=y CONFIG_DVB_AV7110=m CONFIG_DVB_AV7110_OSD=y -CONFIG_DVB_BUDGET_PATCH=m CONFIG_DVB_SP8870=m CONFIG_VIDEO_IPU3_IMGU=m +CONFIG_VIDEO_MAX96712=m + +# +# StarFive media platform drivers +# # CONFIG_STAGING_MEDIA_DEPRECATED is not set CONFIG_LTE_GDM724X=m # CONFIG_FB_TFT is not set # CONFIG_MOST_COMPONENTS is not set -CONFIG_KS7010=m -# CONFIG_PI433 is not set +CONFIG_XIL_AXIS_FIFO=m CONFIG_FIELDBUS_DEV=m -CONFIG_QLGE=m +CONFIG_HMS_ANYBUSS_BUS=m +CONFIG_ARCX_ANYBUS_CONTROLLER=m +CONFIG_HMS_PROFINET=m CONFIG_VME_BUS=y # @@ -9136,6 +9912,7 @@ CONFIG_VME_TSI148=m # VME Device Drivers # CONFIG_VME_USER=m +# CONFIG_GOLDFISH is not set CONFIG_CHROME_PLATFORMS=y CONFIG_CHROMEOS_ACPI=m CONFIG_CHROMEOS_LAPTOP=m @@ -9143,6 +9920,7 @@ CONFIG_CHROMEOS_PSTORE=m CONFIG_CHROMEOS_TBMC=m CONFIG_CROS_EC=m CONFIG_CROS_EC_I2C=m +CONFIG_CROS_EC_RPMSG=m CONFIG_CROS_EC_ISHTP=m CONFIG_CROS_EC_SPI=m CONFIG_CROS_EC_UART=m @@ -9151,6 +9929,7 @@ CONFIG_CROS_EC_PROTO=y CONFIG_CROS_KBD_LED_BACKLIGHT=m CONFIG_CROS_EC_CHARDEV=m CONFIG_CROS_EC_LIGHTBAR=m +CONFIG_CROS_EC_VBC=m CONFIG_CROS_EC_DEBUGFS=m CONFIG_CROS_EC_SENSORHUB=m CONFIG_CROS_EC_SYSFS=m @@ -9194,13 +9973,16 @@ CONFIG_NVIDIA_WMI_EC_BACKLIGHT=m CONFIG_XIAOMI_WMI=m CONFIG_GIGABYTE_WMI=m CONFIG_YOGABOOK=m +CONFIG_YT2_1380=m CONFIG_ACERHDF=m CONFIG_ACER_WIRELESS=m CONFIG_ACER_WMI=m CONFIG_AMD_PMF=m # CONFIG_AMD_PMF_DEBUG is not set CONFIG_AMD_PMC=m +CONFIG_AMD_MP2_STB=y CONFIG_AMD_HSMP=m +CONFIG_AMD_WBRF=y CONFIG_ADV_SWBUTTON=m CONFIG_APPLE_GMUX=m CONFIG_ASUS_LAPTOP=m @@ -9217,10 +9999,12 @@ CONFIG_DCDBAS=m CONFIG_DELL_LAPTOP=m # CONFIG_DELL_RBU is not set CONFIG_DELL_RBTN=m +CONFIG_DELL_PC=m CONFIG_DELL_SMBIOS=m CONFIG_DELL_SMBIOS_WMI=y CONFIG_DELL_SMBIOS_SMM=y CONFIG_DELL_SMO8800=m +# CONFIG_DELL_UART_BACKLIGHT is not set CONFIG_DELL_WMI=m CONFIG_DELL_WMI_PRIVACY=y CONFIG_DELL_WMI_AIO=m @@ -9252,10 +10036,10 @@ CONFIG_THINKPAD_LMI=m CONFIG_INTEL_ATOMISP2_PDX86=y # CONFIG_INTEL_ATOMISP2_LED is not set CONFIG_INTEL_ATOMISP2_PM=m -# CONFIG_INTEL_IFS is not set +CONFIG_INTEL_IFS=m CONFIG_INTEL_SAR_INT1092=m CONFIG_INTEL_SKL_INT3472=m -CONFIG_INTEL_PMC_CORE=y +CONFIG_INTEL_PMC_CORE=m CONFIG_INTEL_PMT_CLASS=m CONFIG_INTEL_PMT_TELEMETRY=m CONFIG_INTEL_PMT_CRASHLOG=m @@ -9293,12 +10077,17 @@ CONFIG_INTEL_PUNIT_IPC=m CONFIG_INTEL_RST=m CONFIG_INTEL_SDSI=m CONFIG_INTEL_SMARTCONNECT=m +CONFIG_INTEL_TPMI_POWER_DOMAINS=m CONFIG_INTEL_TPMI=m +CONFIG_INTEL_PLR_TPMI=m CONFIG_INTEL_TURBO_MAX_3=y CONFIG_INTEL_VSEC=m +# CONFIG_ACPI_QUICKSTART is not set +CONFIG_MEEGOPAD_ANX7428=m CONFIG_MSI_EC=m CONFIG_MSI_LAPTOP=m CONFIG_MSI_WMI=m +CONFIG_MSI_WMI_PLATFORM=m CONFIG_PCENGINES_APU2=m CONFIG_BARCO_P50_GPIO=m CONFIG_SAMSUNG_LAPTOP=m @@ -9311,7 +10100,7 @@ CONFIG_ACPI_CMPC=m CONFIG_COMPAL_LAPTOP=m CONFIG_LG_LAPTOP=m CONFIG_PANASONIC_LAPTOP=m -CONFIG_SHUTTLE_WMI=m +# CONFIG_SHUTTLE_WMI is not set CONFIG_SONY_LAPTOP=m CONFIG_SONYPI_COMPAT=y CONFIG_SYSTEM76_ACPI=m @@ -9319,6 +10108,8 @@ CONFIG_TOPSTAR_LAPTOP=m CONFIG_SERIAL_MULTI_INSTANTIATE=m CONFIG_MLX_PLATFORM=m CONFIG_TOUCHSCREEN_DMI=y +CONFIG_INSPUR_PLATFORM_PROFILE=m +CONFIG_LENOVO_WMI_CAMERA=m CONFIG_X86_ANDROID_TABLETS=m CONFIG_FW_ATTR_CLASS=m CONFIG_INTEL_IPS=m @@ -9328,7 +10119,8 @@ CONFIG_INTEL_SCU_PCI=y CONFIG_INTEL_SCU_PLATFORM=m CONFIG_INTEL_SCU_IPC_UTIL=m # CONFIG_SIEMENS_SIMATIC_IPC is not set -# CONFIG_WINMATE_FM07_KEYS is not set +# CONFIG_SILICOM_PLATFORM is not set +CONFIG_WINMATE_FM07_KEYS=m CONFIG_SEL3350_PLATFORM=m CONFIG_P2SB=y CONFIG_HAVE_CLK=y @@ -9336,17 +10128,35 @@ CONFIG_HAVE_CLK_PREPARE=y CONFIG_COMMON_CLK=y CONFIG_COMMON_CLK_WM831X=m CONFIG_LMK04832=m +CONFIG_COMMON_CLK_MAX77686=m CONFIG_COMMON_CLK_MAX9485=m +CONFIG_COMMON_CLK_RK808=m CONFIG_COMMON_CLK_SI5341=m CONFIG_COMMON_CLK_SI5351=m +CONFIG_COMMON_CLK_SI514=m CONFIG_COMMON_CLK_SI544=m +CONFIG_COMMON_CLK_SI570=m CONFIG_COMMON_CLK_CDCE706=m CONFIG_COMMON_CLK_TPS68470=m +CONFIG_COMMON_CLK_CDCE925=m CONFIG_COMMON_CLK_CS2000_CP=m +CONFIG_COMMON_CLK_S2MPS11=m +# CONFIG_CLK_TWL is not set CONFIG_CLK_TWL6040=m +CONFIG_COMMON_CLK_AXI_CLKGEN=m +CONFIG_COMMON_CLK_LOCHNAGAR=m CONFIG_COMMON_CLK_PALMAS=m CONFIG_COMMON_CLK_PWM=m +CONFIG_COMMON_CLK_RS9_PCIE=m +CONFIG_COMMON_CLK_SI521XX=m +CONFIG_COMMON_CLK_VC3=m +CONFIG_COMMON_CLK_VC5=m +CONFIG_COMMON_CLK_VC7=m +CONFIG_COMMON_CLK_BD718XX=m +# CONFIG_COMMON_CLK_FIXED_MMIO is not set +# CONFIG_CLK_LGM_CGU is not set CONFIG_XILINX_VCU=m +CONFIG_COMMON_CLK_XLNX_CLKWZRD=m # CONFIG_HWSPINLOCK is not set # @@ -9358,10 +10168,13 @@ CONFIG_CLKBLD_I8253=y # end of Clock Source drivers CONFIG_MAILBOX=y +CONFIG_PLATFORM_MHU=m CONFIG_PCC=y CONFIG_ALTERA_MBOX=m +CONFIG_MAILBOX_TEST=m CONFIG_IOMMU_IOVA=y CONFIG_IOMMU_API=y +CONFIG_IOMMUFD_DRIVER=y CONFIG_IOMMU_SUPPORT=y # @@ -9374,16 +10187,17 @@ CONFIG_IOMMU_IO_PGTABLE=y # CONFIG_IOMMU_DEFAULT_DMA_STRICT is not set CONFIG_IOMMU_DEFAULT_DMA_LAZY=y # CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set +CONFIG_OF_IOMMU=y CONFIG_IOMMU_DMA=y CONFIG_IOMMU_SVA=y +CONFIG_IOMMU_IOPF=y CONFIG_AMD_IOMMU=y -CONFIG_AMD_IOMMU_V2=m CONFIG_DMAR_TABLE=y CONFIG_INTEL_IOMMU=y CONFIG_INTEL_IOMMU_SVM=y -# CONFIG_INTEL_IOMMU_DEFAULT_ON is not set +CONFIG_INTEL_IOMMU_DEFAULT_ON=y CONFIG_INTEL_IOMMU_FLOPPY_WA=y -# CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON is not set +CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON=y CONFIG_INTEL_IOMMU_PERF_EVENTS=y CONFIG_IOMMUFD=m CONFIG_IRQ_REMAP=y @@ -9451,6 +10265,8 @@ CONFIG_SOUNDWIRE_GENERIC_ALLOCATION=m # # Enable LiteX SoC Builder specific drivers # +CONFIG_LITEX=y +CONFIG_LITEX_SOC_CONTROLLER=m # end of Enable LiteX SoC Builder specific drivers CONFIG_WPCM450_SOC=m @@ -9458,7 +10274,12 @@ CONFIG_WPCM450_SOC=m # # Qualcomm SoC drivers # +CONFIG_QCOM_PDR_HELPERS=m +CONFIG_QCOM_PDR_MSG=m +# CONFIG_QCOM_PMIC_PDCHARGER_ULOG is not set +CONFIG_QCOM_PMIC_GLINK=m CONFIG_QCOM_QMI_HELPERS=m +# CONFIG_QCOM_PBS is not set # end of Qualcomm SoC drivers # CONFIG_SOC_TI is not set @@ -9469,6 +10290,31 @@ CONFIG_QCOM_QMI_HELPERS=m # end of Xilinx SoC drivers # end of SOC (System On Chip) specific Drivers +# +# PM Domains +# + +# +# Amlogic PM Domains +# +# end of Amlogic PM Domains + +# +# Broadcom PM Domains +# +# end of Broadcom PM Domains + +# +# i.MX PM Domains +# +# end of i.MX PM Domains + +# +# Qualcomm PM Domains +# +# end of Qualcomm PM Domains +# end of PM Domains + CONFIG_PM_DEVFREQ=y # @@ -9478,7 +10324,7 @@ CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y CONFIG_DEVFREQ_GOV_PERFORMANCE=y CONFIG_DEVFREQ_GOV_POWERSAVE=y CONFIG_DEVFREQ_GOV_USERSPACE=y -CONFIG_DEVFREQ_GOV_PASSIVE=m +CONFIG_DEVFREQ_GOV_PASSIVE=y # # DEVFREQ Drivers @@ -9496,6 +10342,7 @@ CONFIG_EXTCON_GPIO=m CONFIG_EXTCON_INTEL_INT3496=m CONFIG_EXTCON_INTEL_CHT_WC=m CONFIG_EXTCON_INTEL_MRFLD=m +# CONFIG_EXTCON_LC824206XA is not set CONFIG_EXTCON_MAX14577=m CONFIG_EXTCON_MAX3355=m CONFIG_EXTCON_MAX77693=m @@ -9517,6 +10364,7 @@ CONFIG_IIO_BUFFER_HW_CONSUMER=m CONFIG_IIO_KFIFO_BUF=m CONFIG_IIO_TRIGGERED_BUFFER=m CONFIG_IIO_CONFIGFS=m +CONFIG_IIO_GTS_HELPER=m CONFIG_IIO_TRIGGER=y CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 CONFIG_IIO_SW_DEVICE=m @@ -9537,6 +10385,8 @@ CONFIG_ADIS16209=m # CONFIG_ADXL367_I2C is not set # CONFIG_ADXL372_SPI is not set # CONFIG_ADXL372_I2C is not set +# CONFIG_ADXL380_SPI is not set +# CONFIG_ADXL380_I2C is not set CONFIG_BMA220=m # CONFIG_BMA400 is not set CONFIG_BMC150_ACCEL=m @@ -9582,15 +10432,21 @@ CONFIG_STK8BA50=m # Analog to digital converters # CONFIG_AD_SIGMA_DELTA=m +# CONFIG_AD4000 is not set CONFIG_AD4130=m +# CONFIG_AD4695 is not set +CONFIG_AD7091R=m CONFIG_AD7091R5=m +# CONFIG_AD7091R8 is not set CONFIG_AD7124=m +# CONFIG_AD7173 is not set CONFIG_AD7192=m CONFIG_AD7266=m CONFIG_AD7280=m CONFIG_AD7291=m CONFIG_AD7292=m CONFIG_AD7298=m +CONFIG_AD7380=m CONFIG_AD7476=m CONFIG_AD7606=m CONFIG_AD7606_IFACE_PARALLEL=m @@ -9602,13 +10458,14 @@ CONFIG_AD7791=m CONFIG_AD7793=m CONFIG_AD7887=m CONFIG_AD7923=m +# CONFIG_AD7944 is not set CONFIG_AD7949=m CONFIG_AD799X=m CONFIG_AD9467=m -CONFIG_ADI_AXI_ADC=m # CONFIG_AXP20X_ADC is not set CONFIG_AXP288_ADC=m # CONFIG_CC10001_ADC is not set +CONFIG_CPCAP_ADC=m CONFIG_DA9150_GPADC=m CONFIG_DLN2_ADC=m # CONFIG_ENVELOPE_DETECTOR is not set @@ -9617,6 +10474,7 @@ CONFIG_HI8435=m CONFIG_INA2XX_ADC=m CONFIG_INTEL_MRFLD_ADC=m CONFIG_LP8788_ADC=m +# CONFIG_LTC2309 is not set CONFIG_LTC2471=m # CONFIG_LTC2485 is not set # CONFIG_LTC2496 is not set @@ -9628,17 +10486,22 @@ CONFIG_MAX1027=m CONFIG_MAX11410=m # CONFIG_MAX1241 is not set CONFIG_MAX1363=m +# CONFIG_MAX34408 is not set CONFIG_MAX77541_ADC=m # CONFIG_MAX9611 is not set CONFIG_MCP320X=m CONFIG_MCP3422=m +# CONFIG_MCP3564 is not set # CONFIG_MCP3911 is not set CONFIG_MP2629_ADC=m CONFIG_NAU7802=m +# CONFIG_PAC1921 is not set +# CONFIG_PAC1934 is not set CONFIG_PALMAS_GPADC=m CONFIG_QCOM_SPMI_IADC=m # CONFIG_QCOM_SPMI_VADC is not set # CONFIG_QCOM_SPMI_ADC5 is not set +# CONFIG_RN5T618_ADC is not set # CONFIG_RICHTEK_RTQ6056 is not set # CONFIG_SD_ADC_MODULATOR is not set CONFIG_TI_ADC081C=m @@ -9649,8 +10512,10 @@ CONFIG_TI_ADC108S102=m CONFIG_TI_ADC128S052=m # CONFIG_TI_ADC161S626 is not set CONFIG_TI_ADS1015=m +CONFIG_TI_ADS1119=m CONFIG_TI_ADS7924=m CONFIG_TI_ADS1100=m +# CONFIG_TI_ADS1298 is not set # CONFIG_TI_ADS7950 is not set # CONFIG_TI_ADS8344 is not set # CONFIG_TI_ADS8688 is not set @@ -9697,10 +10562,14 @@ CONFIG_AD7746=m # # Chemical Sensors # +# CONFIG_AOSONG_AGS02MA is not set CONFIG_ATLAS_PH_SENSOR=m # CONFIG_ATLAS_EZO_SENSOR is not set # CONFIG_BME680 is not set CONFIG_CCS811=m +CONFIG_ENS160=m +CONFIG_ENS160_I2C=m +CONFIG_ENS160_SPI=m CONFIG_IAQCORE=m # CONFIG_PMS7003 is not set CONFIG_SCD30_CORE=m @@ -9759,6 +10628,7 @@ CONFIG_AD5592R=m CONFIG_AD5593R=m CONFIG_AD5504=m CONFIG_AD5624R_SPI=m +# CONFIG_AD9739A is not set CONFIG_LTC2688=m CONFIG_AD5686=m CONFIG_AD5686_SPI=m @@ -9778,12 +10648,14 @@ CONFIG_AD7303=m # CONFIG_DS4424 is not set CONFIG_LTC1660=m # CONFIG_LTC2632 is not set +# CONFIG_LTC2664 is not set CONFIG_M62332=m CONFIG_MAX517=m CONFIG_MAX5522=m # CONFIG_MAX5821 is not set CONFIG_MCP4725=m CONFIG_MCP4728=m +# CONFIG_MCP4821 is not set CONFIG_MCP4922=m # CONFIG_TI_DAC082S085 is not set # CONFIG_TI_DAC5571 is not set @@ -9820,6 +10692,7 @@ CONFIG_AD9523=m CONFIG_ADF4350=m CONFIG_ADF4371=m CONFIG_ADF4377=m +# CONFIG_ADMFM2000 is not set # CONFIG_ADMV1013 is not set # CONFIG_ADMV1014 is not set # CONFIG_ADMV4420 is not set @@ -9867,8 +10740,10 @@ CONFIG_MAX30102=m # CONFIG_AM2315=m CONFIG_DHT11=m +# CONFIG_ENS210 is not set CONFIG_HDC100X=m CONFIG_HDC2010=m +# CONFIG_HDC3020 is not set CONFIG_HID_SENSOR_HUMIDITY=m CONFIG_HTS221=m CONFIG_HTS221_I2C=m @@ -9888,6 +10763,8 @@ CONFIG_ADIS16480=m CONFIG_BMI160=m CONFIG_BMI160_I2C=m CONFIG_BMI160_SPI=m +# CONFIG_BMI323_I2C is not set +# CONFIG_BMI323_SPI is not set # CONFIG_BOSCH_BNO055_SERIAL is not set # CONFIG_BOSCH_BNO055_I2C is not set CONFIG_FXOS8700=m @@ -9916,8 +10793,10 @@ CONFIG_ADJD_S311=m # CONFIG_AL3010 is not set CONFIG_AL3320A=m CONFIG_APDS9300=m +# CONFIG_APDS9306 is not set CONFIG_APDS9960=m # CONFIG_AS73211 is not set +# CONFIG_BH1745 is not set CONFIG_BH1750=m CONFIG_BH1780=m CONFIG_CM32181=m @@ -9932,12 +10811,14 @@ CONFIG_IQS621_ALS=m CONFIG_SENSORS_ISL29018=m CONFIG_SENSORS_ISL29028=m CONFIG_ISL29125=m +# CONFIG_ISL76682 is not set CONFIG_HID_SENSOR_ALS=m CONFIG_HID_SENSOR_PROX=m # CONFIG_JSA1212 is not set -# CONFIG_ROHM_BU27008 is not set +CONFIG_ROHM_BU27008=m # CONFIG_ROHM_BU27034 is not set CONFIG_RPR0521=m +# CONFIG_LTR390 is not set CONFIG_LTR501=m # CONFIG_LTRF216A is not set # CONFIG_LV0104CS is not set @@ -9964,7 +10845,9 @@ CONFIG_US5182D=m CONFIG_VCNL4000=m # CONFIG_VCNL4035 is not set # CONFIG_VEML6030 is not set +CONFIG_VEML6040=m CONFIG_VEML6070=m +# CONFIG_VEML6075 is not set # CONFIG_VL6180 is not set # CONFIG_ZOPT2201 is not set # end of Light sensors @@ -9972,7 +10855,8 @@ CONFIG_VEML6070=m # # Magnetometer sensors # -# CONFIG_AK8974 is not set +CONFIG_AF8133J=m +CONFIG_AK8974=m CONFIG_AK8975=m CONFIG_AK09911=m CONFIG_BMC150_MAGN=m @@ -9987,10 +10871,11 @@ CONFIG_IIO_ST_MAGN_SPI_3AXIS=m CONFIG_SENSORS_HMC5843=m CONFIG_SENSORS_HMC5843_I2C=m CONFIG_SENSORS_HMC5843_SPI=m -# CONFIG_SENSORS_RM3100_I2C is not set -# CONFIG_SENSORS_RM3100_SPI is not set +CONFIG_SENSORS_RM3100=m +CONFIG_SENSORS_RM3100_I2C=m +CONFIG_SENSORS_RM3100_SPI=m CONFIG_TI_TMAG5273=m -# CONFIG_YAMAHA_YAS530 is not set +CONFIG_YAMAHA_YAS530=m # end of Magnetometer sensors # @@ -10049,20 +10934,25 @@ CONFIG_X9250=m # Pressure sensors # # CONFIG_ABP060MG is not set +# CONFIG_ROHM_BM1390 is not set # CONFIG_BMP280 is not set CONFIG_IIO_CROS_EC_BARO=m # CONFIG_DLHL60D is not set # CONFIG_DPS310 is not set CONFIG_HID_SENSOR_PRESS=m CONFIG_HP03=m +# CONFIG_HSC030PA is not set # CONFIG_ICP10100 is not set CONFIG_MPL115=m CONFIG_MPL115_I2C=m CONFIG_MPL115_SPI=m # CONFIG_MPL3115 is not set CONFIG_MPRLS0025PA=m +CONFIG_MPRLS0025PA_I2C=m +CONFIG_MPRLS0025PA_SPI=m # CONFIG_MS5611 is not set CONFIG_MS5637=m +# CONFIG_SDP500 is not set CONFIG_IIO_ST_PRESS=m CONFIG_IIO_ST_PRESS_I2C=m CONFIG_IIO_ST_PRESS_SPI=m @@ -10081,6 +10971,7 @@ CONFIG_AS3935=m # Proximity and distance sensors # CONFIG_CROS_EC_MKBP_PROXIMITY=m +# CONFIG_HX9023S is not set CONFIG_IRSD200=m # CONFIG_ISL29501 is not set CONFIG_LIDAR_LITE_V2=m @@ -10095,6 +10986,7 @@ CONFIG_LIDAR_LITE_V2=m # CONFIG_SRF08 is not set # CONFIG_VCNL3020 is not set # CONFIG_VL53L0X_I2C is not set +# CONFIG_AW96103 is not set # end of Proximity and distance sensors # @@ -10102,6 +10994,7 @@ CONFIG_LIDAR_LITE_V2=m # CONFIG_AD2S90=m CONFIG_AD2S1200=m +CONFIG_AD2S1210=m # end of Resolver to digital converters # @@ -10113,6 +11006,7 @@ CONFIG_IQS620AT_TEMP=m CONFIG_HID_SENSOR_TEMP=m CONFIG_MLX90614=m CONFIG_MLX90632=m +# CONFIG_MLX90635 is not set CONFIG_TMP006=m # CONFIG_TMP007 is not set # CONFIG_TMP117 is not set @@ -10121,6 +11015,7 @@ CONFIG_TSYS02D=m CONFIG_MAX30208=m # CONFIG_MAX31856 is not set # CONFIG_MAX31865 is not set +# CONFIG_MCP9600 is not set # end of Temperature sensors CONFIG_NTB=m @@ -10135,29 +11030,42 @@ CONFIG_NTB_TOOL=m CONFIG_NTB_PERF=m CONFIG_NTB_TRANSPORT=m CONFIG_PWM=y -CONFIG_PWM_SYSFS=y # CONFIG_PWM_DEBUG is not set +# CONFIG_PWM_ADP5585 is not set +# CONFIG_PWM_ATMEL_HLCDC_PWM is not set +# CONFIG_PWM_ATMEL_TCB is not set CONFIG_PWM_CLK=y CONFIG_PWM_CRC=y CONFIG_PWM_CROS_EC=m +CONFIG_PWM_DWC_CORE=m CONFIG_PWM_DWC=m +# CONFIG_PWM_FSL_FTM is not set +CONFIG_PWM_GPIO=m +# CONFIG_PWM_INTEL_LGM is not set CONFIG_PWM_IQS620A=m CONFIG_PWM_LP3943=m CONFIG_PWM_LPSS=m CONFIG_PWM_LPSS_PCI=m CONFIG_PWM_LPSS_PLATFORM=m +# CONFIG_PWM_NTXEC is not set CONFIG_PWM_PCA9685=m CONFIG_PWM_TWL=m CONFIG_PWM_TWL_LED=m +# CONFIG_PWM_XILINX is not set # # IRQ chip support # +CONFIG_IRQCHIP=y +# CONFIG_AL_FIC is not set CONFIG_MADERA_IRQ=m +# CONFIG_XILINX_INTC is not set # end of IRQ chip support # CONFIG_IPACK_BUS is not set CONFIG_RESET_CONTROLLER=y +# CONFIG_RESET_GPIO is not set +# CONFIG_RESET_INTEL_GW is not set # CONFIG_RESET_SIMPLE is not set CONFIG_RESET_TI_SYSCON=m # CONFIG_RESET_TI_TPS380X is not set @@ -10176,13 +11084,22 @@ CONFIG_PHY_CAN_TRANSCEIVER=m CONFIG_BCM_KONA_USB2_PHY=m # end of PHY drivers for Broadcom platforms +# CONFIG_PHY_CADENCE_TORRENT is not set +# CONFIG_PHY_CADENCE_DPHY is not set +# CONFIG_PHY_CADENCE_DPHY_RX is not set +# CONFIG_PHY_CADENCE_SIERRA is not set +# CONFIG_PHY_CADENCE_SALVO is not set CONFIG_PHY_PXA_28NM_HSIC=m CONFIG_PHY_PXA_28NM_USB2=m +# CONFIG_PHY_LAN966X_SERDES is not set CONFIG_PHY_CPCAP_USB=m +# CONFIG_PHY_MAPPHONE_MDM6600 is not set +# CONFIG_PHY_OCELOT_SERDES is not set CONFIG_PHY_QCOM_USB_HS=m CONFIG_PHY_QCOM_USB_HSIC=m CONFIG_PHY_SAMSUNG_USB2=m CONFIG_PHY_TUSB1210=m +# CONFIG_PHY_INTEL_LGM_COMBO is not set CONFIG_PHY_INTEL_LGM_EMMC=m # end of PHY Subsystem @@ -10191,15 +11108,21 @@ CONFIG_INTEL_RAPL_CORE=m CONFIG_INTEL_RAPL=m CONFIG_INTEL_RAPL_TPMI=m CONFIG_IDLE_INJECT=y +# CONFIG_DTPM is not set # CONFIG_MCB is not set # # Performance monitor support # +# CONFIG_DWC_PCIE_PMU is not set # end of Performance monitor support CONFIG_RAS=y -# CONFIG_RAS_CEC is not set +CONFIG_RAS_CEC=y +# CONFIG_RAS_CEC_DEBUG is not set +CONFIG_AMD_ATL=m +CONFIG_AMD_ATL_PRM=y +CONFIG_RAS_FMPM=m CONFIG_USB4=m # CONFIG_USB4_DEBUGFS_WRITE is not set # CONFIG_USB4_DMA_TEST is not set @@ -10213,7 +11136,7 @@ CONFIG_ANDROID_BINDER_DEVICES="binder,hwbinder,vndbinder" # CONFIG_ANDROID_BINDER_IPC_SELFTEST is not set # end of Android -CONFIG_LIBNVDIMM=m +CONFIG_LIBNVDIMM=y CONFIG_BLK_DEV_PMEM=m CONFIG_ND_CLAIM=y CONFIG_ND_BTT=m @@ -10221,6 +11144,7 @@ CONFIG_BTT=y CONFIG_ND_PFN=m CONFIG_NVDIMM_PFN=y CONFIG_NVDIMM_DAX=y +CONFIG_OF_PMEM=m CONFIG_NVDIMM_KEYS=y # CONFIG_NVDIMM_SECURITY_TEST is not set CONFIG_DAX=y @@ -10231,16 +11155,19 @@ CONFIG_DEV_DAX_HMEM_DEVICES=y CONFIG_DEV_DAX_KMEM=m CONFIG_NVMEM=y CONFIG_NVMEM_SYSFS=y +CONFIG_NVMEM_LAYOUTS=y # # Layout Types # # CONFIG_NVMEM_LAYOUT_SL28_VPD is not set # CONFIG_NVMEM_LAYOUT_ONIE_TLV is not set +# CONFIG_NVMEM_LAYOUT_U_BOOT_ENV is not set # end of Layout Types # CONFIG_NVMEM_RMEM is not set CONFIG_NVMEM_SPMI_SDAM=m +# CONFIG_NVMEM_U_BOOT_ENV is not set # # HW tracing support @@ -10266,13 +11193,16 @@ CONFIG_FPGA=m # CONFIG_ALTERA_PR_IP_CORE is not set # CONFIG_FPGA_MGR_ALTERA_PS_SPI is not set # CONFIG_FPGA_MGR_ALTERA_CVP is not set +# CONFIG_FPGA_MGR_XILINX_SELECTMAP is not set # CONFIG_FPGA_MGR_XILINX_SPI is not set +# CONFIG_FPGA_MGR_ICE40_SPI is not set # CONFIG_FPGA_MGR_MACHXO2_SPI is not set # CONFIG_FPGA_BRIDGE is not set # CONFIG_FPGA_DFL is not set CONFIG_FPGA_M10_BMC_SEC_UPDATE=m # CONFIG_FPGA_MGR_MICROCHIP_SPI is not set # CONFIG_FPGA_MGR_LATTICE_SYSCONFIG_SPI is not set +# CONFIG_FSI is not set CONFIG_TEE=m CONFIG_AMDTEE=m CONFIG_MULTIPLEXER=m @@ -10283,6 +11213,7 @@ CONFIG_MULTIPLEXER=m CONFIG_MUX_ADG792A=m CONFIG_MUX_ADGS1408=m CONFIG_MUX_GPIO=m +# CONFIG_MUX_MMIO is not set # end of Multiplexer drivers CONFIG_PM_OPP=y @@ -10299,6 +11230,7 @@ CONFIG_MOST_SND=m CONFIG_PECI=m CONFIG_PECI_CPU=m CONFIG_HTE=y +CONFIG_DPLL=y # end of Device Drivers # @@ -10307,6 +11239,7 @@ CONFIG_HTE=y CONFIG_DCACHE_WORD_ACCESS=y # CONFIG_VALIDATE_FS_PARSER is not set CONFIG_FS_IOMAP=y +CONFIG_FS_STACK=y CONFIG_BUFFER_HEAD=y CONFIG_LEGACY_DIRECT_IO=y CONFIG_EXT2_FS=y @@ -10325,10 +11258,8 @@ CONFIG_JBD2=y CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set -CONFIG_REISERFS_PROC_INFO=y -CONFIG_REISERFS_FS_XATTR=y -CONFIG_REISERFS_FS_POSIX_ACL=y -CONFIG_REISERFS_FS_SECURITY=y +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_REISERFS_FS_XATTR is not set CONFIG_JFS_FS=m CONFIG_JFS_POSIX_ACL=y CONFIG_JFS_SECURITY=y @@ -10336,7 +11267,7 @@ CONFIG_JFS_SECURITY=y CONFIG_JFS_STATISTICS=y CONFIG_XFS_FS=m CONFIG_XFS_SUPPORT_V4=y -CONFIG_XFS_SUPPORT_ASCII_CI=y +# CONFIG_XFS_SUPPORT_ASCII_CI is not set CONFIG_XFS_QUOTA=y CONFIG_XFS_POSIX_ACL=y CONFIG_XFS_RT=y @@ -10353,7 +11284,6 @@ CONFIG_OCFS2_DEBUG_MASKLOG=y # CONFIG_OCFS2_DEBUG_FS is not set CONFIG_BTRFS_FS=y CONFIG_BTRFS_FS_POSIX_ACL=y -# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set # CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set # CONFIG_BTRFS_DEBUG is not set # CONFIG_BTRFS_ASSERT is not set @@ -10374,6 +11304,16 @@ CONFIG_F2FS_FS_LZ4HC=y CONFIG_F2FS_FS_ZSTD=y # CONFIG_F2FS_IOSTAT is not set # CONFIG_F2FS_UNFAIR_RWSEM is not set +CONFIG_BCACHEFS_FS=m +CONFIG_BCACHEFS_QUOTA=y +# CONFIG_BCACHEFS_ERASURE_CODING is not set +CONFIG_BCACHEFS_POSIX_ACL=y +CONFIG_BCACHEFS_DEBUG=y +# CONFIG_BCACHEFS_TESTS is not set +# CONFIG_BCACHEFS_LOCK_TIME_STATS is not set +# CONFIG_BCACHEFS_NO_LATENCY_ACCT is not set +CONFIG_BCACHEFS_SIX_OPTIMISTIC_SPIN=y +# CONFIG_BCACHEFS_PATH_TRACEPOINTS is not set CONFIG_ZONEFS_FS=m CONFIG_FS_DAX=y CONFIG_FS_DAX_PMD=y @@ -10384,7 +11324,8 @@ CONFIG_FILE_LOCKING=y CONFIG_FS_ENCRYPTION=y CONFIG_FS_ENCRYPTION_ALGS=y CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y -# CONFIG_FS_VERITY is not set +CONFIG_FS_VERITY=y +# CONFIG_FS_VERITY_BUILTIN_SIGNATURES is not set CONFIG_FSNOTIFY=y CONFIG_DNOTIFY=y CONFIG_INOTIFY_USER=y @@ -10402,6 +11343,7 @@ CONFIG_FUSE_FS=m CONFIG_CUSE=m CONFIG_VIRTIO_FS=m CONFIG_FUSE_DAX=y +CONFIG_FUSE_PASSTHROUGH=y CONFIG_OVERLAY_FS=m # CONFIG_OVERLAY_FS_REDIRECT_DIR is not set CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y @@ -10413,15 +11355,15 @@ CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y # # Caches # -CONFIG_NETFS_SUPPORT=y +CONFIG_NETFS_SUPPORT=m CONFIG_NETFS_STATS=y +# CONFIG_NETFS_DEBUG is not set CONFIG_FSCACHE=y CONFIG_FSCACHE_STATS=y -CONFIG_FSCACHE_DEBUG=y CONFIG_CACHEFILES=m CONFIG_CACHEFILES_DEBUG=y # CONFIG_CACHEFILES_ERROR_INJECTION is not set -# CONFIG_CACHEFILES_ONDEMAND is not set +CONFIG_CACHEFILES_ONDEMAND=y # end of Caches # @@ -10444,13 +11386,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="ascii" CONFIG_FAT_DEFAULT_UTF8=y CONFIG_EXFAT_FS=m CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8" -CONFIG_NTFS_FS=m -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_RW is not set CONFIG_NTFS3_FS=m # CONFIG_NTFS3_64BIT_CLUSTER is not set CONFIG_NTFS3_LZX_XPRESS=y # CONFIG_NTFS3_FS_POSIX_ACL is not set +CONFIG_NTFS_FS=m # end of DOS/FAT/EXFAT/NT Filesystems # @@ -10473,11 +11413,12 @@ CONFIG_TMPFS_XATTR=y CONFIG_TMPFS_INODE64=y # CONFIG_TMPFS_QUOTA is not set CONFIG_HUGETLBFS=y +# CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP_DEFAULT_ON is not set CONFIG_HUGETLB_PAGE=y CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP=y -# CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP_DEFAULT_ON is not set +CONFIG_HUGETLB_PMD_PAGE_TABLE_SHARING=y CONFIG_ARCH_HAS_GIGANTIC_PAGE=y -CONFIG_CONFIGFS_FS=y +CONFIG_CONFIGFS_FS=m CONFIG_EFIVAR_FS=y # end of Pseudo filesystems @@ -10519,12 +11460,11 @@ CONFIG_CRAMFS_BLOCKDEV=y CONFIG_SQUASHFS=m # CONFIG_SQUASHFS_FILE_CACHE is not set CONFIG_SQUASHFS_FILE_DIRECT=y -CONFIG_SQUASHFS_DECOMP_MULTI=y +CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y # CONFIG_SQUASHFS_CHOICE_DECOMP_BY_MOUNT is not set # CONFIG_SQUASHFS_COMPILE_DECOMP_SINGLE is not set -CONFIG_SQUASHFS_COMPILE_DECOMP_MULTI=y -# CONFIG_SQUASHFS_COMPILE_DECOMP_MULTI_PERCPU is not set -CONFIG_SQUASHFS_MOUNT_DECOMP_THREADS=y +# CONFIG_SQUASHFS_COMPILE_DECOMP_MULTI is not set +CONFIG_SQUASHFS_COMPILE_DECOMP_MULTI_PERCPU=y CONFIG_SQUASHFS_XATTR=y CONFIG_SQUASHFS_ZLIB=y CONFIG_SQUASHFS_LZ4=y @@ -10568,9 +11508,12 @@ CONFIG_EROFS_FS=m CONFIG_EROFS_FS_XATTR=y CONFIG_EROFS_FS_POSIX_ACL=y CONFIG_EROFS_FS_SECURITY=y +CONFIG_EROFS_FS_BACKED_BY_FILE=y CONFIG_EROFS_FS_ZIP=y CONFIG_EROFS_FS_ZIP_LZMA=y CONFIG_EROFS_FS_ZIP_DEFLATE=y +# CONFIG_EROFS_FS_ZIP_ZSTD is not set +# CONFIG_EROFS_FS_ONDEMAND is not set CONFIG_EROFS_FS_PCPU_KTHREAD=y # CONFIG_EROFS_FS_PCPU_KTHREAD_HIPRI is not set CONFIG_VBOXSF_FS=m @@ -10626,12 +11569,14 @@ CONFIG_NFSD_BLOCKLAYOUT=y CONFIG_NFSD_SCSILAYOUT=y CONFIG_NFSD_FLEXFILELAYOUT=y CONFIG_NFSD_V4_2_INTER_SSC=y -# CONFIG_NFSD_V4_SECURITY_LABEL is not set +CONFIG_NFSD_V4_SECURITY_LABEL=y +# CONFIG_NFSD_LEGACY_CLIENT_TRACKING is not set CONFIG_GRACE_PERIOD=m CONFIG_LOCKD=m CONFIG_LOCKD_V4=y CONFIG_NFS_ACL_SUPPORT=m CONFIG_NFS_COMMON=y +# CONFIG_NFS_LOCALIO is not set CONFIG_NFS_V4_2_SSC_HELPER=y CONFIG_SUNRPC=m CONFIG_SUNRPC_GSS=m @@ -10660,6 +11605,7 @@ CONFIG_CIFS_DFS_UPCALL=y CONFIG_CIFS_SWN_UPCALL=y # CONFIG_CIFS_SMB_DIRECT is not set CONFIG_CIFS_FSCACHE=y +# CONFIG_CIFS_COMPRESSION is not set CONFIG_SMB_SERVER=m CONFIG_SMB_SERVER_SMBDIRECT=y CONFIG_SMB_SERVER_CHECK_CAP_NET_ADMIN=y @@ -10739,13 +11685,14 @@ CONFIG_KEYS=y # CONFIG_KEYS_REQUEST_CACHE is not set # CONFIG_PERSISTENT_KEYRINGS is not set CONFIG_TRUSTED_KEYS=m +CONFIG_HAVE_TRUSTED_KEYS=y CONFIG_TRUSTED_KEYS_TPM=y CONFIG_TRUSTED_KEYS_TEE=y CONFIG_ENCRYPTED_KEYS=y # CONFIG_USER_DECRYPTED_DATA is not set CONFIG_KEY_DH_OPERATIONS=y # CONFIG_KEY_NOTIFICATIONS is not set -# CONFIG_SECURITY_DMESG_RESTRICT is not set +CONFIG_SECURITY_DMESG_RESTRICT=y CONFIG_PROC_MEM_ALWAYS_FORCE=y # CONFIG_PROC_MEM_FORCE_PTRACE is not set # CONFIG_PROC_MEM_NO_FORCE is not set @@ -10774,12 +11721,15 @@ CONFIG_SECURITY_APPARMOR_PARANOID_LOAD=y # CONFIG_SECURITY_SAFESETID is not set # CONFIG_SECURITY_LOCKDOWN_LSM is not set CONFIG_SECURITY_LANDLOCK=y +# CONFIG_SECURITY_IPE is not set CONFIG_INTEGRITY=y # CONFIG_INTEGRITY_SIGNATURE is not set CONFIG_INTEGRITY_AUDIT=y # CONFIG_IMA is not set # CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT is not set -# CONFIG_EVM is not set +CONFIG_EVM=y +# CONFIG_EVM_ATTR_FSUUID is not set +# CONFIG_EVM_ADD_XATTRS is not set CONFIG_DEFAULT_SECURITY_APPARMOR=y # CONFIG_DEFAULT_SECURITY_DAC is not set CONFIG_LSM="" @@ -10794,11 +11744,11 @@ CONFIG_LSM="" CONFIG_CC_HAS_AUTO_VAR_INIT_PATTERN=y CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO_BARE=y CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO=y -CONFIG_INIT_STACK_NONE=y +# CONFIG_INIT_STACK_NONE is not set # CONFIG_INIT_STACK_ALL_PATTERN is not set -# CONFIG_INIT_STACK_ALL_ZERO is not set +CONFIG_INIT_STACK_ALL_ZERO=y # CONFIG_GCC_PLUGIN_STACKLEAK is not set -# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set +CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y # CONFIG_INIT_ON_FREE_DEFAULT_ON is not set CONFIG_CC_HAS_ZERO_CALL_USED_REGS=y # CONFIG_ZERO_CALL_USED_REGS is not set @@ -10870,7 +11820,6 @@ CONFIG_CRYPTO_ECC=m CONFIG_CRYPTO_ECDH=m CONFIG_CRYPTO_ECDSA=m CONFIG_CRYPTO_ECRDSA=m -CONFIG_CRYPTO_SM2=m CONFIG_CRYPTO_CURVE25519=m # end of Public-key cryptography @@ -10906,14 +11855,12 @@ CONFIG_CRYPTO_ADIANTUM=m CONFIG_CRYPTO_ARC4=m CONFIG_CRYPTO_CHACHA20=m CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_CFB=m CONFIG_CRYPTO_CTR=y CONFIG_CRYPTO_CTS=y CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_HCTR2=m CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_LRW=m -CONFIG_CRYPTO_OFB=m CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_XCTR=m CONFIG_CRYPTO_XTS=y @@ -10989,7 +11936,9 @@ CONFIG_CRYPTO_DRBG_HASH=y CONFIG_CRYPTO_DRBG_CTR=y CONFIG_CRYPTO_DRBG=y CONFIG_CRYPTO_JITTERENTROPY=y -# CONFIG_CRYPTO_JITTERENTROPY_TESTINTERFACE is not set +CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKS=64 +CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKSIZE=32 +CONFIG_CRYPTO_JITTERENTROPY_OSR=1 CONFIG_CRYPTO_KDF800108_CTR=y # end of Random number generation @@ -11003,7 +11952,6 @@ CONFIG_CRYPTO_USER_API_RNG=m # CONFIG_CRYPTO_USER_API_RNG_CAVP is not set CONFIG_CRYPTO_USER_API_AEAD=m CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE=y -# CONFIG_CRYPTO_STATS is not set # end of Userspace interface CONFIG_CRYPTO_HASH_INFO=y @@ -11044,7 +11992,7 @@ CONFIG_CRYPTO_SHA512_SSSE3=m CONFIG_CRYPTO_SM3_AVX_X86_64=m CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL=m CONFIG_CRYPTO_CRC32C_INTEL=m -CONFIG_CRYPTO_CRC32_PCLMUL=m +CONFIG_CRYPTO_CRC32_PCLMUL=y CONFIG_CRYPTO_CRCT10DIF_PCLMUL=y # end of Accelerated Cryptographic Algorithms for CPU (x86) @@ -11068,12 +12016,16 @@ CONFIG_CRYPTO_DEV_QAT_DH895xCC=m CONFIG_CRYPTO_DEV_QAT_C3XXX=m CONFIG_CRYPTO_DEV_QAT_C62X=m CONFIG_CRYPTO_DEV_QAT_4XXX=m +# CONFIG_CRYPTO_DEV_QAT_420XX is not set CONFIG_CRYPTO_DEV_QAT_DH895xCCVF=m CONFIG_CRYPTO_DEV_QAT_C3XXXVF=m CONFIG_CRYPTO_DEV_QAT_C62XVF=m +# CONFIG_CRYPTO_DEV_QAT_ERROR_INJECTION is not set +# CONFIG_CRYPTO_DEV_IAA_CRYPTO is not set CONFIG_CRYPTO_DEV_CHELSIO=m CONFIG_CRYPTO_DEV_VIRTIO=m CONFIG_CRYPTO_DEV_SAFEXCEL=m +# CONFIG_CRYPTO_DEV_CCREE is not set CONFIG_CRYPTO_DEV_AMLOGIC_GXL=m # CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG is not set CONFIG_ASYMMETRIC_KEY_TYPE=y @@ -11111,7 +12063,6 @@ CONFIG_GENERIC_NET_UTILS=y CONFIG_CORDIC=m # CONFIG_PRIME_NUMBERS is not set CONFIG_RATIONAL=y -CONFIG_GENERIC_PCI_IOMAP=y CONFIG_GENERIC_IOMAP=y CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y CONFIG_ARCH_HAS_FAST_MULTIPLIER=y @@ -11122,20 +12073,24 @@ CONFIG_ARCH_USE_SYM_ANNOTATIONS=y # CONFIG_CRYPTO_LIB_UTILS=y CONFIG_CRYPTO_LIB_AES=y +CONFIG_CRYPTO_LIB_AESCFB=m CONFIG_CRYPTO_LIB_ARC4=m CONFIG_CRYPTO_LIB_GF128MUL=m CONFIG_CRYPTO_ARCH_HAVE_LIB_BLAKE2S=y CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y -CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=m +CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=y CONFIG_CRYPTO_LIB_CHACHA_GENERIC=m +CONFIG_CRYPTO_LIB_CHACHA_INTERNAL=m CONFIG_CRYPTO_LIB_CHACHA=m -CONFIG_CRYPTO_ARCH_HAVE_LIB_CURVE25519=m +CONFIG_CRYPTO_ARCH_HAVE_LIB_CURVE25519=y CONFIG_CRYPTO_LIB_CURVE25519_GENERIC=m +CONFIG_CRYPTO_LIB_CURVE25519_INTERNAL=m CONFIG_CRYPTO_LIB_CURVE25519=m CONFIG_CRYPTO_LIB_DES=m CONFIG_CRYPTO_LIB_POLY1305_RSIZE=11 -CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305=m +CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305=y CONFIG_CRYPTO_LIB_POLY1305_GENERIC=m +CONFIG_CRYPTO_LIB_POLY1305_INTERNAL=m CONFIG_CRYPTO_LIB_POLY1305=m CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m CONFIG_CRYPTO_LIB_SHA1=y @@ -11148,7 +12103,7 @@ CONFIG_CRC_T10DIF=y CONFIG_CRC64_ROCKSOFT=y CONFIG_CRC_ITU_T=m CONFIG_CRC32=y -# CONFIG_CRC32_SELFTEST is not set +CONFIG_CRC32_SELFTEST=m CONFIG_CRC32_SLICEBY8=y # CONFIG_CRC32_SLICEBY4 is not set # CONFIG_CRC32_SARWATE is not set @@ -11175,10 +12130,11 @@ CONFIG_ZSTD_DECOMPRESS=y CONFIG_XZ_DEC=y CONFIG_XZ_DEC_X86=y # CONFIG_XZ_DEC_POWERPC is not set -# CONFIG_XZ_DEC_IA64 is not set # CONFIG_XZ_DEC_ARM is not set # CONFIG_XZ_DEC_ARMTHUMB is not set +CONFIG_XZ_DEC_ARM64=y # CONFIG_XZ_DEC_SPARC is not set +CONFIG_XZ_DEC_RISCV=y CONFIG_XZ_DEC_MICROLZMA=y CONFIG_XZ_DEC_BCJ=y # CONFIG_XZ_DEC_TEST is not set @@ -11204,18 +12160,23 @@ CONFIG_INTERVAL_TREE=y CONFIG_INTERVAL_TREE_SPAN_ITER=y CONFIG_XARRAY_MULTI=y CONFIG_ASSOCIATIVE_ARRAY=y +CONFIG_CLOSURES=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_IOPORT_MAP=y CONFIG_HAS_DMA=y -CONFIG_DMA_OPS=y +CONFIG_DMA_OPS_HELPERS=y CONFIG_NEED_SG_DMA_FLAGS=y CONFIG_NEED_SG_DMA_LENGTH=y CONFIG_NEED_DMA_MAP_STATE=y CONFIG_ARCH_DMA_ADDR_T_64BIT=y +CONFIG_DMA_DECLARE_COHERENT=y CONFIG_ARCH_HAS_FORCE_DMA_UNENCRYPTED=y CONFIG_SWIOTLB=y # CONFIG_SWIOTLB_DYNAMIC is not set +CONFIG_DMA_NEED_SYNC=y +# CONFIG_DMA_RESTRICTED_POOL is not set +CONFIG_DMA_COHERENT_POOL=y CONFIG_DMA_CMA=y # CONFIG_DMA_NUMA_CMA is not set @@ -11243,26 +12204,18 @@ CONFIG_CLZ_TAB=y CONFIG_IRQ_POLL=y CONFIG_MPILIB=y CONFIG_DIMLIB=y +CONFIG_LIBFDT=y CONFIG_OID_REGISTRY=y CONFIG_UCS2_STRING=y CONFIG_HAVE_GENERIC_VDSO=y CONFIG_GENERIC_GETTIMEOFDAY=y CONFIG_GENERIC_VDSO_TIME_NS=y +CONFIG_GENERIC_VDSO_OVERFLOW_PROTECT=y +CONFIG_VDSO_GETRANDOM=y CONFIG_FONT_SUPPORT=y -CONFIG_FONTS=y +# CONFIG_FONTS is not set CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y -# CONFIG_FONT_6x11 is not set -# CONFIG_FONT_7x14 is not set -# CONFIG_FONT_PEARL_8x8 is not set -# CONFIG_FONT_ACORN_8x8 is not set -# CONFIG_FONT_MINI_4x6 is not set -# CONFIG_FONT_6x10 is not set -CONFIG_FONT_10x18=y -# CONFIG_FONT_SUN8x16 is not set -CONFIG_FONT_SUN12x22=y -CONFIG_FONT_TER16x32=y -# CONFIG_FONT_6x8 is not set CONFIG_SG_POOL=y CONFIG_ARCH_HAS_PMEM_API=y CONFIG_MEMREGION=y @@ -11271,14 +12224,17 @@ CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE=y CONFIG_ARCH_HAS_COPY_MC=y CONFIG_ARCH_STACKWALK=y CONFIG_STACKDEPOT=y +CONFIG_STACKDEPOT_MAX_FRAMES=64 CONFIG_SBITMAP=y CONFIG_PARMAN=m CONFIG_OBJAGG=m +# CONFIG_LWQ_TEST is not set # end of Library routines CONFIG_PLDMFW=y CONFIG_ASN1_ENCODER=m CONFIG_POLYNOMIAL=m +CONFIG_FIRMWARE_TABLE=y # # Kernel hacking @@ -11306,7 +12262,7 @@ CONFIG_DEBUG_MISC=y # # Compile-time checks and compiler options # -CONFIG_AS_HAS_NON_CONST_LEB128=y +CONFIG_AS_HAS_NON_CONST_ULEB128=y CONFIG_DEBUG_INFO_NONE=y # CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT is not set # CONFIG_DEBUG_INFO_DWARF4 is not set @@ -11336,7 +12292,7 @@ CONFIG_DEBUG_FS_ALLOW_ALL=y # CONFIG_DEBUG_FS_ALLOW_NONE is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set -CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y +CONFIG_ARCH_HAS_UBSAN=y # CONFIG_UBSAN is not set CONFIG_HAVE_ARCH_KCSAN=y CONFIG_HAVE_KCSAN_COMPILER=y @@ -11385,6 +12341,7 @@ CONFIG_MEMORY_NOTIFIER_ERROR_INJECT=m # CONFIG_DEBUG_PER_CPU_MAPS is not set CONFIG_ARCH_SUPPORTS_KMAP_LOCAL_FORCE_MAP=y # CONFIG_DEBUG_KMAP_LOCAL_FORCE_MAP is not set +# CONFIG_MEM_ALLOC_PROFILING is not set CONFIG_HAVE_ARCH_KASAN=y CONFIG_HAVE_ARCH_KASAN_VMALLOC=y CONFIG_CC_HAS_KASAN_GENERIC=y @@ -11436,7 +12393,6 @@ CONFIG_SCHED_INFO=y CONFIG_SCHEDSTATS=y # end of Scheduler Debugging -# CONFIG_DEBUG_TIMEKEEPING is not set # CONFIG_DEBUG_PREEMPT is not set # @@ -11459,7 +12415,7 @@ CONFIG_LOCK_DEBUGGING_SUPPORT=y # CONFIG_CSD_LOCK_WAIT_DEBUG is not set # end of Lock Debugging (spinlocks, mutexes, etc...) -CONFIG_NMI_CHECK_CPU=y +# CONFIG_NMI_CHECK_CPU is not set # CONFIG_DEBUG_IRQFLAGS is not set CONFIG_STACKTRACE=y # CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set @@ -11472,6 +12428,7 @@ CONFIG_STACKTRACE=y # CONFIG_DEBUG_PLIST is not set # CONFIG_DEBUG_SG is not set # CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CLOSURES is not set # CONFIG_DEBUG_MAPLE_TREE is not set # end of Debug kernel data structures @@ -11484,6 +12441,7 @@ CONFIG_STACKTRACE=y CONFIG_RCU_CPU_STALL_TIMEOUT=60 CONFIG_RCU_EXP_CPU_STALL_TIMEOUT=0 # CONFIG_RCU_CPU_STALL_CPUTIME is not set +# CONFIG_RCU_CPU_STALL_NOTIFIER is not set # CONFIG_RCU_TRACE is not set # CONFIG_RCU_EQS_DEBUG is not set # end of RCU Debugging @@ -11523,12 +12481,13 @@ CONFIG_TRACING_SUPPORT=y CONFIG_FTRACE=y CONFIG_BOOTTIME_TRACING=y CONFIG_FUNCTION_TRACER=y -# CONFIG_FUNCTION_GRAPH_TRACER is not set +CONFIG_FUNCTION_GRAPH_TRACER=y +# CONFIG_FUNCTION_GRAPH_RETVAL is not set CONFIG_DYNAMIC_FTRACE=y CONFIG_DYNAMIC_FTRACE_WITH_REGS=y CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y CONFIG_DYNAMIC_FTRACE_WITH_ARGS=y -# CONFIG_FPROBE is not set +CONFIG_FPROBE=y CONFIG_FUNCTION_PROFILER=y CONFIG_STACK_TRACER=y # CONFIG_IRQSOFF_TRACER is not set @@ -11544,13 +12503,14 @@ CONFIG_TRACER_SNAPSHOT=y CONFIG_BRANCH_PROFILE_NONE=y # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_FPROBE_EVENTS=y CONFIG_KPROBE_EVENTS=y # CONFIG_KPROBE_EVENTS_ON_NOTRACE is not set CONFIG_UPROBE_EVENTS=y CONFIG_BPF_EVENTS=y CONFIG_DYNAMIC_EVENTS=y CONFIG_PROBE_EVENTS=y -# CONFIG_BPF_KPROBE_OVERRIDE is not set +CONFIG_BPF_KPROBE_OVERRIDE=y CONFIG_FTRACE_MCOUNT_RECORD=y CONFIG_FTRACE_MCOUNT_USE_CC=y # CONFIG_SYNTH_EVENTS is not set @@ -11561,6 +12521,7 @@ CONFIG_FTRACE_MCOUNT_USE_CC=y CONFIG_RING_BUFFER_BENCHMARK=m # CONFIG_TRACE_EVAL_MAP_FILE is not set # CONFIG_FTRACE_RECORD_RECURSION is not set +# CONFIG_FTRACE_VALIDATE_RCU_IS_WATCHING is not set # CONFIG_FTRACE_STARTUP_TEST is not set # CONFIG_FTRACE_SORT_STARTUP_TEST is not set # CONFIG_RING_BUFFER_STARTUP_TEST is not set @@ -11580,10 +12541,11 @@ CONFIG_IO_STRICT_DEVMEM=y # # x86 Debugging # +CONFIG_EARLY_PRINTK_USB=y # CONFIG_X86_VERBOSE_BOOTUP is not set CONFIG_EARLY_PRINTK=y -# CONFIG_EARLY_PRINTK_DBGP is not set -# CONFIG_EARLY_PRINTK_USB_XDBC is not set +CONFIG_EARLY_PRINTK_DBGP=y +CONFIG_EARLY_PRINTK_USB_XDBC=y # CONFIG_EFI_PGT_DUMP is not set # CONFIG_DEBUG_TLBFLUSH is not set # CONFIG_IOMMU_DEBUG is not set @@ -11609,6 +12571,7 @@ CONFIG_UNWINDER_ORC=y # CONFIG_KUNIT is not set CONFIG_NOTIFIER_ERROR_INJECTION=m CONFIG_PM_NOTIFIER_ERROR_INJECT=m +# CONFIG_OF_RECONFIG_NOTIFIER_ERROR_INJECT is not set # CONFIG_NETDEV_NOTIFIER_ERROR_INJECT is not set CONFIG_FUNCTION_ERROR_INJECTION=y # CONFIG_FAULT_INJECTION is not set @@ -11620,6 +12583,7 @@ CONFIG_RUNTIME_TESTING_MENU=y # CONFIG_LKDTM is not set # CONFIG_TEST_MIN_HEAP is not set # CONFIG_TEST_DIV64 is not set +# CONFIG_TEST_MULDIV64 is not set # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_TEST_REF_TRACKER is not set CONFIG_RBTREE_TEST=m @@ -11629,8 +12593,6 @@ CONFIG_INTERVAL_TREE_TEST=m # CONFIG_ATOMIC64_SELFTEST is not set # CONFIG_ASYNC_RAID6_TEST is not set # CONFIG_TEST_HEXDUMP is not set -# CONFIG_STRING_SELFTEST is not set -# CONFIG_TEST_STRING_HELPERS is not set # CONFIG_TEST_KSTRTOX is not set # CONFIG_TEST_PRINTF is not set # CONFIG_TEST_SCANF is not set @@ -11644,8 +12606,7 @@ CONFIG_TEST_XARRAY=m # CONFIG_TEST_LKM is not set # CONFIG_TEST_BITOPS is not set # CONFIG_TEST_VMALLOC is not set -# CONFIG_TEST_USER_COPY is not set -# CONFIG_TEST_BPF is not set +CONFIG_TEST_BPF=m # CONFIG_TEST_BLACKHOLE_DEV is not set # CONFIG_FIND_BIT_BENCHMARK is not set # CONFIG_TEST_FIRMWARE is not set @@ -11655,13 +12616,13 @@ CONFIG_TEST_XARRAY=m # CONFIG_TEST_DYNAMIC_DEBUG is not set # CONFIG_TEST_KMOD is not set # CONFIG_TEST_MEMCAT_P is not set -# CONFIG_TEST_LIVEPATCH is not set # CONFIG_TEST_OBJAGG is not set # CONFIG_TEST_MEMINIT is not set # CONFIG_TEST_HMM is not set # CONFIG_TEST_FREE_PAGES is not set # CONFIG_TEST_FPU is not set # CONFIG_TEST_CLOCKSOURCE_WATCHDOG is not set +# CONFIG_TEST_OBJPOOL is not set CONFIG_ARCH_USE_MEMTEST=y CONFIG_MEMTEST=y # CONFIG_HYPERV_TESTING is not set diff --git a/kernel/kernel/files/patches/aufs6/aufs6-base.patch b/kernel/kernel/files/patches/aufs6/aufs6-base.patch index 819d861f..24983178 100644 --- a/kernel/kernel/files/patches/aufs6/aufs6-base.patch +++ b/kernel/kernel/files/patches/aufs6/aufs6-base.patch @@ -1,13 +1,13 @@ SPDX-License-Identifier: GPL-2.0 -aufs6.6.84 base patch +aufs6.12 base patch diff --git a/MAINTAINERS b/MAINTAINERS -index ae4c0cec50736..2b5edd2836a7d 100644 +index b878ddc99f94e..8489754030b99 100644 --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -3334,6 +3334,19 @@ F: include/uapi/linux/audit.h - F: kernel/audit* +@@ -3666,6 +3666,19 @@ F: kernel/audit* F: lib/*audit.c + K: \baudit_[a-z_0-9]\+\b +AUFS (advanced multi layered unification filesystem) FILESYSTEM +M: "J. R. Okajima" @@ -26,10 +26,10 @@ index ae4c0cec50736..2b5edd2836a7d 100644 M: Greg Kroah-Hartman R: Dave Ertman diff --git a/drivers/block/loop.c b/drivers/block/loop.c -index 886c635990377..73dae3b1bd4e5 100644 +index 78a7bb28defe4..479480f25a6c0 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c -@@ -640,6 +640,24 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, +@@ -661,6 +661,26 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, goto done; } @@ -37,6 +37,8 @@ index 886c635990377..73dae3b1bd4e5 100644 + * for AUFS + * no get/put for file. + */ ++/* Just to make the compiler silence, declare it */ ++struct file *loop_backing_file(struct super_block *sb); +struct file *loop_backing_file(struct super_block *sb) +{ + struct file *ret; @@ -55,10 +57,20 @@ index 886c635990377..73dae3b1bd4e5 100644 static ssize_t loop_attr_show(struct device *dev, char *page, diff --git a/fs/dcache.c b/fs/dcache.c -index 4030c010a7682..e2877ac9a1e6c 100644 +index 0f6b16ba30d08..1ab11cad60e8c 100644 --- a/fs/dcache.c +++ b/fs/dcache.c -@@ -1350,7 +1350,7 @@ enum d_walk_ret { +@@ -1223,6 +1223,9 @@ enum d_walk_ret { + D_WALK_SKIP, + }; + ++/* AUFS calls d_walk(). Just to make the compiler silence, declare it */ ++void d_walk(struct dentry *parent, void *data, ++ enum d_walk_ret (*enter)(void *, struct dentry *)); + /** + * d_walk - walk the dentry tree + * @parent: start of walk +@@ -1231,7 +1234,7 @@ enum d_walk_ret { * * The @enter() callbacks are called with d_lock held. */ @@ -66,12 +78,12 @@ index 4030c010a7682..e2877ac9a1e6c 100644 +void d_walk(struct dentry *parent, void *data, enum d_walk_ret (*enter)(void *, struct dentry *)) { - struct dentry *this_parent; + struct dentry *this_parent, *dentry; diff --git a/fs/fcntl.c b/fs/fcntl.c -index 1484f062ee65e..1e44fc9b0f704 100644 +index 22dd9dcce7ecc..460791727fd9c 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c -@@ -34,7 +34,7 @@ +@@ -37,7 +37,7 @@ #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME) @@ -80,7 +92,7 @@ index 1484f062ee65e..1e44fc9b0f704 100644 { struct inode * inode = file_inode(filp); int error = 0; -@@ -64,6 +64,8 @@ static int setfl(int fd, struct file * filp, unsigned int arg) +@@ -67,6 +67,8 @@ static int setfl(int fd, struct file * filp, unsigned int arg) if (filp->f_op->check_flags) error = filp->f_op->check_flags(arg); @@ -90,10 +102,10 @@ index 1484f062ee65e..1e44fc9b0f704 100644 return error; diff --git a/fs/namespace.c b/fs/namespace.c -index b4385e2413d59..c9347fc5e14a0 100644 +index d26f5e6d2ca35..85739e2d64c00 100644 --- a/fs/namespace.c +++ b/fs/namespace.c -@@ -872,6 +872,12 @@ static inline int check_mnt(struct mount *mnt) +@@ -966,6 +966,12 @@ static inline int check_mnt(struct mount *mnt) return mnt->mnt_ns == current->nsproxy->mnt_ns; } @@ -107,25 +119,23 @@ index b4385e2413d59..c9347fc5e14a0 100644 * vfsmount lock must be held for write */ diff --git a/fs/splice.c b/fs/splice.c -index d983d375ff113..7216ef993b5f9 100644 +index 06232d7e505f6..b15fd6073b6d3 100644 --- a/fs/splice.c +++ b/fs/splice.c -@@ -925,8 +925,8 @@ static int warn_unsupported(struct file *file, const char *op) +@@ -933,7 +933,7 @@ static int warn_unsupported(struct file *file, const char *op) /* * Attempt to initiate a splice from pipe to file. */ --static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, -- loff_t *ppos, size_t len, unsigned int flags) -+long do_splice_from(struct pipe_inode_info *pipe, struct file *out, -+ loff_t *ppos, size_t len, unsigned int flags) +-static ssize_t do_splice_from(struct pipe_inode_info *pipe, struct file *out, ++ssize_t do_splice_from(struct pipe_inode_info *pipe, struct file *out, + loff_t *ppos, size_t len, unsigned int flags) { if (unlikely(!out->f_op->splice_write)) - return warn_unsupported(out, "write"); diff --git a/include/linux/fs.h b/include/linux/fs.h -index 81edfa1e66b60..534be34edab64 100644 +index 3559446279c15..51b64b2ad82c4 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h -@@ -1101,6 +1101,7 @@ extern void fasync_free(struct fasync_struct *); +@@ -1160,6 +1160,7 @@ extern void fasync_free(struct fasync_struct *); /* can be called from interrupts */ extern void kill_fasync(struct fasync_struct **, int, int); @@ -133,7 +143,7 @@ index 81edfa1e66b60..534be34edab64 100644 extern void __f_setown(struct file *filp, struct pid *, enum pid_type, int force); extern int f_setown(struct file *filp, int who, int force); extern void f_delown(struct file *filp); -@@ -1934,6 +1935,7 @@ struct file_operations { +@@ -2082,6 +2083,7 @@ struct file_operations { int (*lock) (struct file *, int, struct file_lock *); unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); int (*check_flags)(int); @@ -142,10 +152,10 @@ index 81edfa1e66b60..534be34edab64 100644 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h -index 919a5cb6368d1..e4be17a2efdb9 100644 +index 217f7abf2cbfa..0e17b8c23f105 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h -@@ -249,6 +249,8 @@ static inline int lockdep_match_key(struct lockdep_map *lock, +@@ -210,6 +210,8 @@ static inline int lockdep_match_key(struct lockdep_map *lock, return lock->key == key; } @@ -155,10 +165,10 @@ index 919a5cb6368d1..e4be17a2efdb9 100644 * Acquire a lock. * diff --git a/include/linux/mnt_namespace.h b/include/linux/mnt_namespace.h -index 8f882f5881e87..6b9808f098435 100644 +index 70b366b648160..08cfdabb2721f 100644 --- a/include/linux/mnt_namespace.h +++ b/include/linux/mnt_namespace.h -@@ -7,12 +7,15 @@ struct mnt_namespace; +@@ -10,6 +10,7 @@ struct mnt_namespace; struct fs_struct; struct user_namespace; struct ns_common; @@ -166,7 +176,8 @@ index 8f882f5881e87..6b9808f098435 100644 extern struct mnt_namespace *copy_mnt_ns(unsigned long, struct mnt_namespace *, struct user_namespace *, struct fs_struct *); - extern void put_mnt_ns(struct mnt_namespace *ns); +@@ -17,6 +18,8 @@ extern void put_mnt_ns(struct mnt_namespace *ns); + DEFINE_FREE(put_mnt_ns, struct mnt_namespace *, if (!IS_ERR_OR_NULL(_T)) put_mnt_ns(_T)) extern struct ns_common *from_mnt_ns(struct mnt_namespace *); +extern int is_current_mnt_ns(struct vfsmount *mnt); @@ -175,19 +186,19 @@ index 8f882f5881e87..6b9808f098435 100644 extern const struct file_operations proc_mountinfo_operations; extern const struct file_operations proc_mountstats_operations; diff --git a/include/linux/splice.h b/include/linux/splice.h -index 6c461573434dd..f08de37759877 100644 +index 9dec4861d09f6..14583d8468640 100644 --- a/include/linux/splice.h +++ b/include/linux/splice.h -@@ -99,4 +99,7 @@ extern void splice_shrink_spd(struct splice_pipe_desc *); +@@ -108,4 +108,7 @@ extern void splice_shrink_spd(struct splice_pipe_desc *); extern const struct pipe_buf_operations page_cache_pipe_buf_ops; extern const struct pipe_buf_operations default_pipe_buf_ops; + -+extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out, -+ loff_t *ppos, size_t len, unsigned int flags); ++extern ssize_t do_splice_from(struct pipe_inode_info *pipe, struct file *out, ++ loff_t *ppos, size_t len, unsigned int flags); #endif diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c -index 3468d8230e5f7..64b9aedbe941d 100644 +index 536bd471557f5..34b378cf7a95f 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -218,7 +218,7 @@ unsigned long max_lock_class_idx; diff --git a/kernel/kernel/files/patches/aufs6/aufs6-kbuild.patch b/kernel/kernel/files/patches/aufs6/aufs6-kbuild.patch index d4b41094..70c96059 100644 --- a/kernel/kernel/files/patches/aufs6/aufs6-kbuild.patch +++ b/kernel/kernel/files/patches/aufs6/aufs6-kbuild.patch @@ -1,11 +1,11 @@ SPDX-License-Identifier: GPL-2.0 -aufs6.6.84 kbuild patch +aufs6.12 kbuild patch diff --git a/fs/Kconfig b/fs/Kconfig -index 02a9237807a77..bb3f7ec67b867 100644 +index aae170fc27952..d5bb584649f50 100644 --- a/fs/Kconfig +++ b/fs/Kconfig -@@ -337,6 +337,7 @@ source "fs/sysv/Kconfig" +@@ -341,6 +341,7 @@ source "fs/sysv/Kconfig" source "fs/ufs/Kconfig" source "fs/erofs/Kconfig" source "fs/vboxsf/Kconfig" @@ -14,11 +14,11 @@ index 02a9237807a77..bb3f7ec67b867 100644 endif # MISC_FILESYSTEMS diff --git a/fs/Makefile b/fs/Makefile -index f9541f40be4e0..3a0e13ee39e7f 100644 +index 61679fd587b7e..b2539712b80d0 100644 --- a/fs/Makefile +++ b/fs/Makefile -@@ -129,3 +129,4 @@ obj-$(CONFIG_EFIVAR_FS) += efivarfs/ - obj-$(CONFIG_EROFS_FS) += erofs/ +@@ -130,3 +130,4 @@ obj-$(CONFIG_EROFS_FS) += erofs/ obj-$(CONFIG_VBOXSF_FS) += vboxsf/ obj-$(CONFIG_ZONEFS_FS) += zonefs/ + obj-$(CONFIG_BPF_LSM) += bpf_fs_kfuncs.o +obj-$(CONFIG_AUFS_FS) += aufs/ diff --git a/kernel/kernel/files/patches/aufs6/aufs6-loopback.patch b/kernel/kernel/files/patches/aufs6/aufs6-loopback.patch index 03e6249e..82c527f1 100644 --- a/kernel/kernel/files/patches/aufs6/aufs6-loopback.patch +++ b/kernel/kernel/files/patches/aufs6/aufs6-loopback.patch @@ -1,8 +1,8 @@ SPDX-License-Identifier: GPL-2.0 -aufs6.6.84 loopback patch +aufs6.12 loopback patch diff --git a/drivers/block/loop.c b/drivers/block/loop.c -index 73dae3b1bd4e5..ae84fb81acbf9 100644 +index 479480f25a6c0..ba3477c30e294 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -54,7 +54,7 @@ struct loop_device { @@ -14,7 +14,7 @@ index 73dae3b1bd4e5..ae84fb81acbf9 100644 struct block_device *lo_device; gfp_t old_gfp_mask; -@@ -505,6 +505,15 @@ static inline void loop_update_dio(struct loop_device *lo) +@@ -526,6 +526,15 @@ static inline void loop_update_dio(struct loop_device *lo) lo->use_dio); } @@ -30,7 +30,7 @@ index 73dae3b1bd4e5..ae84fb81acbf9 100644 static void loop_reread_partitions(struct loop_device *lo) { int rc; -@@ -562,6 +571,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, +@@ -583,6 +592,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, { struct file *file = fget(arg); struct file *old_file; @@ -38,7 +38,7 @@ index 73dae3b1bd4e5..ae84fb81acbf9 100644 int error; bool partscan; bool is_loop; -@@ -585,11 +595,19 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, +@@ -606,11 +616,19 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, if (!(lo->lo_flags & LO_FLAGS_READ_ONLY)) goto out_err; @@ -58,7 +58,7 @@ index 73dae3b1bd4e5..ae84fb81acbf9 100644 error = -EINVAL; -@@ -602,6 +620,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, +@@ -623,6 +641,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, blk_mq_freeze_queue(lo->lo_queue); mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask); lo->lo_backing_file = file; @@ -66,7 +66,7 @@ index 73dae3b1bd4e5..ae84fb81acbf9 100644 lo->old_gfp_mask = mapping_gfp_mask(file->f_mapping); mapping_set_gfp_mask(file->f_mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS)); -@@ -624,6 +643,8 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, +@@ -645,6 +664,8 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, * dependency. */ fput(old_file); @@ -75,7 +75,7 @@ index 73dae3b1bd4e5..ae84fb81acbf9 100644 if (partscan) loop_reread_partitions(lo); -@@ -637,6 +658,8 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, +@@ -658,6 +679,8 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, loop_global_unlock(lo, is_loop); out_putf: fput(file); @@ -84,15 +84,15 @@ index 73dae3b1bd4e5..ae84fb81acbf9 100644 goto done; } -@@ -1008,6 +1031,7 @@ static int loop_configure(struct loop_device *lo, blk_mode_t mode, +@@ -1039,6 +1062,7 @@ static int loop_configure(struct loop_device *lo, blk_mode_t mode, const struct loop_config *config) { struct file *file = fget(config->fd); + struct file *f, *virt_file = NULL; - struct inode *inode; struct address_space *mapping; int error; -@@ -1023,6 +1047,13 @@ static int loop_configure(struct loop_device *lo, blk_mode_t mode, + loff_t size; +@@ -1052,6 +1076,13 @@ static int loop_configure(struct loop_device *lo, blk_mode_t mode, /* This is safe, since we have a reference from open(). */ __module_get(THIS_MODULE); @@ -106,7 +106,7 @@ index 73dae3b1bd4e5..ae84fb81acbf9 100644 /* * If we don't hold exclusive handle for the device, upgrade to it * here to avoid changing device under exclusive owner. -@@ -1086,6 +1117,7 @@ static int loop_configure(struct loop_device *lo, blk_mode_t mode, +@@ -1108,6 +1139,7 @@ static int loop_configure(struct loop_device *lo, blk_mode_t mode, lo->use_dio = lo->lo_flags & LO_FLAGS_DIRECT_IO; lo->lo_device = bdev; lo->lo_backing_file = file; @@ -114,7 +114,7 @@ index 73dae3b1bd4e5..ae84fb81acbf9 100644 lo->old_gfp_mask = mapping_gfp_mask(mapping); mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS)); -@@ -1141,6 +1173,8 @@ static int loop_configure(struct loop_device *lo, blk_mode_t mode, +@@ -1150,6 +1182,8 @@ static int loop_configure(struct loop_device *lo, blk_mode_t mode, bd_abort_claiming(bdev, loop_configure); out_putf: fput(file); @@ -123,15 +123,13 @@ index 73dae3b1bd4e5..ae84fb81acbf9 100644 /* This is safe: open() is still holding a reference. */ module_put(THIS_MODULE); return error; -@@ -1149,6 +1183,7 @@ static int loop_configure(struct loop_device *lo, blk_mode_t mode, - static void __loop_clr_fd(struct loop_device *lo, bool release) +@@ -1159,11 +1193,13 @@ static void __loop_clr_fd(struct loop_device *lo) { + struct queue_limits lim; struct file *filp; + struct file *virt_filp = lo->lo_backing_virt_file; gfp_t gfp = lo->old_gfp_mask; - if (test_bit(QUEUE_FLAG_WC, &lo->lo_queue->queue_flags)) -@@ -1165,6 +1200,7 @@ static void __loop_clr_fd(struct loop_device *lo, bool release) spin_lock_irq(&lo->lo_lock); filp = lo->lo_backing_file; lo->lo_backing_file = NULL; @@ -139,7 +137,7 @@ index 73dae3b1bd4e5..ae84fb81acbf9 100644 spin_unlock_irq(&lo->lo_lock); lo->lo_device = NULL; -@@ -1227,6 +1263,8 @@ static void __loop_clr_fd(struct loop_device *lo, bool release) +@@ -1225,6 +1261,8 @@ static void __loop_clr_fd(struct loop_device *lo) * fput can take open_mutex which is usually taken before lo_mutex. */ fput(filp); @@ -224,10 +222,10 @@ index 9c30cba527421..8161108d0f6d5 100644 /* ---------------------------------------------------------------------- */ diff --git a/include/linux/fs.h b/include/linux/fs.h -index 534be34edab64..b7c27b0486b7d 100644 +index 51b64b2ad82c4..8c3ff295b020b 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h -@@ -2089,6 +2089,11 @@ struct super_operations { +@@ -2248,6 +2248,11 @@ struct super_operations { long (*free_cached_objects)(struct super_block *, struct shrink_control *); void (*shutdown)(struct super_block *sb); diff --git a/kernel/kernel/files/patches/aufs6/aufs6-mmap.patch b/kernel/kernel/files/patches/aufs6/aufs6-mmap.patch index 5ffe5158..879079c9 100644 --- a/kernel/kernel/files/patches/aufs6/aufs6-mmap.patch +++ b/kernel/kernel/files/patches/aufs6/aufs6-mmap.patch @@ -1,21 +1,21 @@ SPDX-License-Identifier: GPL-2.0 -aufs6.6.84 mmap patch +aufs6.12 mmap patch diff --git a/fs/proc/base.c b/fs/proc/base.c -index 91fe20b7657c0..b8573598ca4e6 100644 +index b31283d81c52e..644bd3d84cf76 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c -@@ -2277,7 +2277,7 @@ static int map_files_get_link(struct dentry *dentry, struct path *path) +@@ -2270,7 +2270,7 @@ static int map_files_get_link(struct dentry *dentry, struct path *path) rc = -ENOENT; vma = find_exact_vma(mm, vm_start, vm_end); if (vma && vma->vm_file) { -- *path = vma->vm_file->f_path; +- *path = *file_user_path(vma->vm_file); + *path = vma_pr_or_file(vma)->f_path; path_get(path); rc = 0; } diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c -index 4d3493579458f..42edd9a42c78b 100644 +index c6e7ebc637562..d7ccfd9097646 100644 --- a/fs/proc/nommu.c +++ b/fs/proc/nommu.c @@ -39,7 +39,10 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region) @@ -31,32 +31,40 @@ index 4d3493579458f..42edd9a42c78b 100644 ino = inode->i_ino; } diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c -index b8640f36ebf8a..fde14252ce111 100644 +index 7eb010de39fe2..0c576103f7f15 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c -@@ -271,7 +271,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma) - const char *name = NULL; +@@ -264,7 +264,8 @@ static void get_vma_name(struct vm_area_struct *vma, + *name_fmt = "[anon_shmem:%s]"; + *name = anon_name->name; + } else { +- *path = file_user_path(vma->vm_file); ++ struct file *f = vma_pr_or_file(vma); ++ *path = file_user_path(f); + } + return; + } +@@ -333,7 +334,8 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma) + dev_t dev = 0; + + if (vma->vm_file) { +- const struct inode *inode = file_user_inode(vma->vm_file); ++ const struct inode *inode ++ = file_inode(vma_pr_or_file(vma)); - if (file) { -- struct inode *inode = file_inode(vma->vm_file); -+ struct inode *inode; -+ -+ 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; -@@ -1947,7 +1950,7 @@ static int show_numa_map(struct seq_file *m, void *v) +@@ -3008,7 +3010,7 @@ static int show_numa_map(struct seq_file *m, void *v) 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 mempolicy *pol; char buffer[64]; + struct mempolicy *pol; diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c -index 7cebd397cc26e..81be1641c7fbd 100644 +index bce6745330003..b12b5a75c799c 100644 --- a/fs/proc/task_nommu.c +++ b/fs/proc/task_nommu.c @@ -137,7 +137,10 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma) @@ -72,10 +80,10 @@ index 7cebd397cc26e..81be1641c7fbd 100644 ino = inode->i_ino; pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT; diff --git a/include/linux/mm.h b/include/linux/mm.h -index 209370f644366..5c84e2330fd64 100644 +index 61fff5d34ed53..94b66987b4bb0 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h -@@ -2415,6 +2415,43 @@ static inline void unmap_shared_mapping_range(struct address_space *mapping, +@@ -2469,6 +2469,43 @@ static inline void unmap_shared_mapping_range(struct address_space *mapping, static inline struct vm_area_struct *vma_lookup(struct mm_struct *mm, unsigned long addr); @@ -120,10 +128,10 @@ index 209370f644366..5c84e2330fd64 100644 void *buf, int len, unsigned int gup_flags); extern int access_remote_vm(struct mm_struct *mm, unsigned long addr, diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h -index e77d4a5c0bace..5aa50ed123be1 100644 +index 6e3bdf8e38bca..c70247dc71022 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h -@@ -554,6 +554,9 @@ struct vm_region { +@@ -572,6 +572,9 @@ 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 */ @@ -133,7 +141,7 @@ index e77d4a5c0bace..5aa50ed123be1 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 -@@ -697,6 +700,9 @@ struct vm_area_struct { +@@ -747,6 +750,9 @@ struct vm_area_struct { unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE units */ struct file * vm_file; /* File we map to (can be NULL). */ @@ -144,32 +152,32 @@ index e77d4a5c0bace..5aa50ed123be1 100644 #ifdef CONFIG_ANON_VMA_NAME diff --git a/kernel/fork.c b/kernel/fork.c -index 23efaa2c42e4f..50b94374b715c 100644 +index 22f43721d031d..03abd72b3353d 100644 --- a/kernel/fork.c +++ b/kernel/fork.c -@@ -732,7 +732,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, +@@ -730,7 +730,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, if (file) { struct address_space *mapping = file->f_mapping; - get_file(file); + vma_get_file(tmp); i_mmap_lock_write(mapping); - if (tmp->vm_flags & VM_SHARED) + if (vma_is_shared_maywrite(tmp)) mapping_allow_writable(mapping); diff --git a/mm/Makefile b/mm/Makefile -index ec65984e2adee..d59461647ccd9 100644 +index d5639b0361663..bb57f616f0325 100644 --- a/mm/Makefile +++ b/mm/Makefile -@@ -138,3 +138,4 @@ obj-$(CONFIG_IO_MAPPING) += io-mapping.o - obj-$(CONFIG_HAVE_BOOTMEM_INFO_NODE) += bootmem_info.o - obj-$(CONFIG_GENERIC_IOREMAP) += ioremap.o +@@ -145,3 +145,4 @@ obj-$(CONFIG_GENERIC_IOREMAP) += ioremap.o obj-$(CONFIG_SHRINKER_DEBUG) += shrinker_debug.o + obj-$(CONFIG_EXECMEM) += execmem.o + obj-$(CONFIG_TMPFS_QUOTA) += shmem_quota.o +obj-y += prfile.o diff --git a/mm/filemap.c b/mm/filemap.c -index 056422e6a0be8..065b94fe81d90 100644 +index 56fa431c52af7..d55fe4e7bcfd1 100644 --- a/mm/filemap.c +++ b/mm/filemap.c -@@ -3661,7 +3661,7 @@ vm_fault_t filemap_page_mkwrite(struct vm_fault *vmf) +@@ -3707,7 +3707,7 @@ vm_fault_t filemap_page_mkwrite(struct vm_fault *vmf) vm_fault_t ret = VM_FAULT_LOCKED; sb_start_pagefault(mapping->host->i_sb); @@ -179,37 +187,10 @@ index 056422e6a0be8..065b94fe81d90 100644 if (folio->mapping != mapping) { folio_unlock(folio); diff --git a/mm/mmap.c b/mm/mmap.c -index 03a24cb3951d4..db6134d0458ec 100644 +index 79d541f1502b2..2dc64f6dc0181 100644 --- a/mm/mmap.c +++ b/mm/mmap.c -@@ -139,7 +139,7 @@ static void remove_vma(struct vm_area_struct *vma, bool unreachable) - might_sleep(); - vma_close(vma); - if (vma->vm_file) -- fput(vma->vm_file); -+ vma_fput(vma); - mpol_put(vma_policy(vma)); - if (unreachable) - __vm_area_free(vma); -@@ -553,7 +553,7 @@ static inline void vma_complete(struct vma_prepare *vp, - if (vp->file) { - uprobe_munmap(vp->remove, vp->remove->vm_start, - vp->remove->vm_end); -- fput(vp->file); -+ vma_fput(vp->vma); - } - if (vp->remove->anon_vma) - anon_vma_merge(vp->vma, vp->remove); -@@ -2391,7 +2391,7 @@ int __split_vma(struct vma_iterator *vmi, struct vm_area_struct *vma, - goto out_free_mpol; - - if (new->vm_file) -- get_file(new->vm_file); -+ vma_get_file(new); - - if (new->vm_ops && new->vm_ops->open) - new->vm_ops->open(new); -@@ -2810,7 +2810,7 @@ static unsigned long __mmap_region(struct file *file, unsigned long addr, +@@ -1484,7 +1484,7 @@ static unsigned long __mmap_region(struct file *file, unsigned long addr, * and cause general protection fault * ultimately. */ @@ -218,16 +199,7 @@ index 03a24cb3951d4..db6134d0458ec 100644 vm_area_free(vma); vma = merge; /* Update vm_flags to pick up the change. */ -@@ -2887,7 +2887,7 @@ static unsigned long __mmap_region(struct file *file, unsigned long addr, - return addr; - - unmap_and_free_file_vma: -- fput(vma->vm_file); -+ vma_fput(vma); - vma->vm_file = NULL; - - vma_iter_set(&vmi, vma->vm_end); -@@ -2982,6 +2982,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, +@@ -1654,6 +1654,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, unsigned long ret = -EINVAL; struct file *file; vm_flags_t vm_flags; @@ -235,7 +207,7 @@ index 03a24cb3951d4..db6134d0458ec 100644 pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. See Documentation/mm/remap_file_pages.rst.\n", current->comm, current->pid); -@@ -3024,14 +3025,18 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, +@@ -1696,14 +1697,18 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, /* Save vm_flags used to calculate prot and flags, and recheck later. */ vm_flags = vma->vm_flags; @@ -256,7 +228,7 @@ index 03a24cb3951d4..db6134d0458ec 100644 return ret; } -@@ -3039,7 +3044,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, +@@ -1711,7 +1716,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, /* OK security check passed, take write lock + let it rip. */ if (mmap_write_lock_killable(mm)) { @@ -265,7 +237,7 @@ index 03a24cb3951d4..db6134d0458ec 100644 return -EINTR; } -@@ -3081,9 +3086,27 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, +@@ -1753,9 +1758,27 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, ret = do_mmap(vma->vm_file, start, size, prot, flags, 0, pgoff, &populate, NULL); @@ -293,29 +265,11 @@ index 03a24cb3951d4..db6134d0458ec 100644 if (populate) mm_populate(ret, populate); if (!IS_ERR_VALUE(ret)) -@@ -3432,7 +3455,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) -- get_file(new_vma->vm_file); -+ vma_get_file(new_vma); - if (new_vma->vm_ops && new_vma->vm_ops->open) - new_vma->vm_ops->open(new_vma); - if (vma_link(mm, new_vma)) -@@ -3445,7 +3468,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, - vma_close(new_vma); - - if (new_vma->vm_file) -- fput(new_vma->vm_file); -+ vma_fput(new_vma); - - unlink_anon_vmas(new_vma); - out_free_mempol: diff --git a/mm/nommu.c b/mm/nommu.c -index 3228b2d3e4ab6..a1fc80e87fbd5 100644 +index 9cb6e99215e2b..5add36afa9786 100644 --- a/mm/nommu.c +++ b/mm/nommu.c -@@ -530,7 +530,7 @@ static void __put_nommu_region(struct vm_region *region) +@@ -512,7 +512,7 @@ static void __put_nommu_region(struct vm_region *region) up_write(&nommu_region_sem); if (region->vm_file) @@ -324,7 +278,7 @@ index 3228b2d3e4ab6..a1fc80e87fbd5 100644 /* IO memory and memory shared directly out of the pagecache * from ramfs/tmpfs mustn't be released here */ -@@ -609,7 +609,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma) +@@ -591,7 +591,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma) { vma_close(vma); if (vma->vm_file) @@ -333,7 +287,7 @@ index 3228b2d3e4ab6..a1fc80e87fbd5 100644 put_nommu_region(vma->vm_region); vm_area_free(vma); } -@@ -1141,7 +1141,7 @@ unsigned long do_mmap(struct file *file, +@@ -1123,7 +1123,7 @@ unsigned long do_mmap(struct file *file, goto error_just_free; } } @@ -342,7 +296,7 @@ index 3228b2d3e4ab6..a1fc80e87fbd5 100644 kmem_cache_free(vm_region_jar, region); region = pregion; result = start; -@@ -1227,10 +1227,10 @@ unsigned long do_mmap(struct file *file, +@@ -1209,10 +1209,10 @@ unsigned long do_mmap(struct file *file, error: vma_iter_free(&vmi); if (region->vm_file) @@ -447,3 +401,52 @@ index 0000000000000..b034d160a18f4 + fput(pr); +} +#endif /* !CONFIG_MMU */ +diff --git a/mm/vma.c b/mm/vma.c +index 7621384d64cf5..3bb41fe6ac48e 100644 +--- a/mm/vma.c ++++ b/mm/vma.c +@@ -248,7 +248,7 @@ static void vma_complete(struct vma_prepare *vp, struct vma_iterator *vmi, + if (vp->file) { + uprobe_munmap(vp->remove, vp->remove->vm_start, + vp->remove->vm_end); +- fput(vp->file); ++ vma_fput(vp->vma); + } + if (vp->remove->anon_vma) + anon_vma_merge(vp->vma, vp->remove); +@@ -328,7 +328,7 @@ void remove_vma(struct vm_area_struct *vma, bool unreachable) + might_sleep(); + vma_close(vma); + if (vma->vm_file) +- fput(vma->vm_file); ++ vma_fput(vma); + mpol_put(vma_policy(vma)); + if (unreachable) + __vm_area_free(vma); +@@ -405,7 +405,7 @@ static int __split_vma(struct vma_iterator *vmi, struct vm_area_struct *vma, + goto out_free_mpol; + + if (new->vm_file) +- get_file(new->vm_file); ++ vma_get_file(new); + + if (new->vm_ops && new->vm_ops->open) + new->vm_ops->open(new); +@@ -1671,7 +1671,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) +- get_file(new_vma->vm_file); ++ vma_get_file(new_vma); + if (new_vma->vm_ops && new_vma->vm_ops->open) + new_vma->vm_ops->open(new_vma); + if (vma_link(mm, new_vma)) +@@ -1684,7 +1684,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, + vma_close(new_vma); + + if (new_vma->vm_file) +- fput(new_vma->vm_file); ++ vma_fput(new_vma); + + unlink_anon_vmas(new_vma); + out_free_mempol: diff --git a/kernel/kernel/files/patches/aufs6/aufs6-standalone.patch b/kernel/kernel/files/patches/aufs6/aufs6-standalone.patch index db54abcb..828406cc 100644 --- a/kernel/kernel/files/patches/aufs6/aufs6-standalone.patch +++ b/kernel/kernel/files/patches/aufs6/aufs6-standalone.patch @@ -1,11 +1,11 @@ SPDX-License-Identifier: GPL-2.0 -aufs6.6.63 standalone patch +aufs6.12 standalone patch diff --git a/fs/dcache.c b/fs/dcache.c -index e2877ac9a1e6..f20b4ac29a1d 100644 +index 1ab11cad60e8c..3a01c42c6639e 100644 --- a/fs/dcache.c +++ b/fs/dcache.c -@@ -1455,6 +1455,7 @@ void d_walk(struct dentry *parent, void *data, +@@ -1333,6 +1333,7 @@ void d_walk(struct dentry *parent, void *data, seq = 1; goto again; } @@ -13,7 +13,7 @@ index e2877ac9a1e6..f20b4ac29a1d 100644 struct check_mount { struct vfsmount *mnt; -@@ -3058,6 +3059,7 @@ void d_exchange(struct dentry *dentry1, struct dentry *dentry2) +@@ -2899,6 +2900,7 @@ void d_exchange(struct dentry *dentry1, struct dentry *dentry2) write_sequnlock(&rename_lock); } @@ -22,10 +22,10 @@ index e2877ac9a1e6..f20b4ac29a1d 100644 /** * d_ancestor - search for an ancestor diff --git a/fs/exec.c b/fs/exec.c -index 7776209d98c1..372bbb606c38 100644 +index 6c53920795c2e..22e10087e34fa 100644 --- a/fs/exec.c +++ b/fs/exec.c -@@ -112,6 +112,7 @@ bool path_noexec(const struct path *path) +@@ -114,6 +114,7 @@ bool path_noexec(const struct path *path) return (path->mnt->mnt_flags & MNT_NOEXEC) || (path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC); } @@ -34,22 +34,22 @@ index 7776209d98c1..372bbb606c38 100644 #ifdef CONFIG_USELIB /* diff --git a/fs/fcntl.c b/fs/fcntl.c -index 1e44fc9b0f70..f5dd3c8b414e 100644 +index 460791727fd9c..75ab59a3df36f 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c -@@ -87,6 +87,7 @@ int setfl(int fd, struct file * filp, unsigned int arg) +@@ -90,6 +90,7 @@ int setfl(int fd, struct file * filp, unsigned int arg) out: return error; } +EXPORT_SYMBOL_GPL(setfl); - void __f_setown(struct file *filp, struct pid *pid, enum pid_type type, - int force) + /* + * Allocate an file->f_owner struct if it doesn't exist, handling racing diff --git a/fs/file_table.c b/fs/file_table.c -index ee21b3da9d08..c45ac36795dd 100644 +index eed5ffad9997c..2f6bead424786 100644 --- a/fs/file_table.c +++ b/fs/file_table.c -@@ -225,6 +225,7 @@ struct file *alloc_empty_file(int flags, const struct cred *cred) +@@ -228,6 +228,7 @@ struct file *alloc_empty_file(int flags, const struct cred *cred) } return ERR_PTR(-ENFILE); } @@ -58,18 +58,10 @@ index ee21b3da9d08..c45ac36795dd 100644 /* * Variant of alloc_empty_file() that doesn't check and modify nr_files. diff --git a/fs/namespace.c b/fs/namespace.c -index c9347fc5e14a..d47e357d65de 100644 +index 85739e2d64c00..8aa96de6c151e 100644 --- a/fs/namespace.c +++ b/fs/namespace.c -@@ -466,6 +466,7 @@ void __mnt_drop_write(struct vfsmount *mnt) - mnt_dec_writers(real_mount(mnt)); - preempt_enable(); - } -+EXPORT_SYMBOL_GPL(__mnt_drop_write); - - /** - * mnt_drop_write - give up write access to a mount -@@ -877,6 +878,7 @@ int is_current_mnt_ns(struct vfsmount *mnt) +@@ -971,6 +971,7 @@ int is_current_mnt_ns(struct vfsmount *mnt) { return check_mnt(real_mount(mnt)); } @@ -77,7 +69,23 @@ index c9347fc5e14a..d47e357d65de 100644 /* * vfsmount lock must be held for write -@@ -2152,6 +2154,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg, +@@ -2200,6 +2201,7 @@ struct vfsmount *collect_mounts(const struct path *path) + return ERR_CAST(tree); + return &tree->mnt; + } ++EXPORT_SYMBOL_GPL(collect_mounts); + + static void free_mnt_ns(struct mnt_namespace *); + static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *, bool); +@@ -2230,6 +2232,7 @@ void drop_collected_mounts(struct vfsmount *mnt) + unlock_mount_hash(); + namespace_unlock(); + } ++EXPORT_SYMBOL_GPL(drop_collected_mounts); + + bool has_locked_children(struct mount *mnt, struct dentry *dentry) + { +@@ -2301,6 +2304,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg, } return 0; } @@ -86,7 +94,7 @@ index c9347fc5e14a..d47e357d65de 100644 static void lock_mnt_tree(struct mount *mnt) { diff --git a/fs/notify/group.c b/fs/notify/group.c -index 1de6631a3925..3008eb37a18d 100644 +index 18446b7b0d495..09138e0b8a6a5 100644 --- a/fs/notify/group.c +++ b/fs/notify/group.c @@ -100,6 +100,7 @@ void fsnotify_get_group(struct fsnotify_group *group) @@ -98,10 +106,10 @@ index 1de6631a3925..3008eb37a18d 100644 /* * Drop a reference to a group. Free it if it's through. diff --git a/fs/open.c b/fs/open.c -index f9ac703ec1b2..d5c83814332e 100644 +index 5da4df2f9b18a..6024098fc6444 100644 --- a/fs/open.c +++ b/fs/open.c -@@ -67,6 +67,7 @@ int do_truncate(struct mnt_idmap *idmap, struct dentry *dentry, +@@ -66,6 +66,7 @@ int do_truncate(struct mnt_idmap *idmap, struct dentry *dentry, inode_unlock(dentry->d_inode); return ret; } @@ -110,10 +118,10 @@ index f9ac703ec1b2..d5c83814332e 100644 long vfs_truncate(const struct path *path, loff_t length) { diff --git a/fs/read_write.c b/fs/read_write.c -index 4771701c896b..c79270aba792 100644 +index 64dc24afdb3a7..ec1fd6aab1759 100644 --- a/fs/read_write.c +++ b/fs/read_write.c -@@ -477,6 +477,7 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) +@@ -576,6 +576,7 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) inc_syscr(current); return ret; } @@ -121,7 +129,7 @@ index 4771701c896b..c79270aba792 100644 static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) { -@@ -592,6 +593,7 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_ +@@ -691,6 +692,7 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_ file_end_write(file); return ret; } @@ -130,10 +138,10 @@ index 4771701c896b..c79270aba792 100644 /* file_ppos returns &file->f_pos or NULL if file is stream */ static inline loff_t *file_ppos(struct file *file) diff --git a/fs/splice.c b/fs/splice.c -index 7216ef993b5f..7ce1f1bc4268 100644 +index b15fd6073b6d3..0fdb86c3813e2 100644 --- a/fs/splice.c +++ b/fs/splice.c -@@ -932,6 +932,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out, +@@ -940,6 +940,7 @@ ssize_t do_splice_from(struct pipe_inode_info *pipe, struct file *out, return warn_unsupported(out, "write"); return out->f_op->splice_write(pipe, out, ppos, len, flags); } @@ -142,10 +150,10 @@ index 7216ef993b5f..7ce1f1bc4268 100644 /* * Indicate to the caller that there was a premature EOF when reading from the diff --git a/fs/xattr.c b/fs/xattr.c -index c20046548f21..1d66796705fb 100644 +index 05ec7e7d9e87e..e07ffa052dfb4 100644 --- a/fs/xattr.c +++ b/fs/xattr.c -@@ -406,6 +406,7 @@ vfs_getxattr_alloc(struct mnt_idmap *idmap, struct dentry *dentry, +@@ -405,6 +405,7 @@ vfs_getxattr_alloc(struct mnt_idmap *idmap, struct dentry *dentry, *xattr_value = value; return error; } @@ -154,7 +162,7 @@ index c20046548f21..1d66796705fb 100644 ssize_t __vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name, diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c -index 64b9aedbe941..903a23230775 100644 +index 34b378cf7a95f..df6a751298b32 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -239,6 +239,7 @@ inline struct lock_class *lockdep_hlock_class(struct held_lock *hlock) @@ -166,7 +174,7 @@ index 64b9aedbe941..903a23230775 100644 #ifdef CONFIG_LOCK_STAT diff --git a/kernel/task_work.c b/kernel/task_work.c -index c969f1f26be5..68eb672f425d 100644 +index c969f1f26be58..68eb672f425d9 100644 --- a/kernel/task_work.c +++ b/kernel/task_work.c @@ -242,3 +242,4 @@ void task_work_run(void) @@ -175,68 +183,68 @@ index c969f1f26be5..68eb672f425d 100644 } +EXPORT_SYMBOL_GPL(task_work_run); diff --git a/security/security.c b/security/security.c -index b6144833c7a8..3b15e084ecc3 100644 +index c5981e558bc26..045dd716e3400 100644 --- a/security/security.c +++ b/security/security.c -@@ -1750,6 +1750,7 @@ int security_path_rmdir(const struct path *dir, struct dentry *dentry) +@@ -1944,6 +1944,7 @@ int security_path_rmdir(const struct path *dir, struct dentry *dentry) return 0; - return call_int_hook(path_rmdir, 0, dir, dentry); + return call_int_hook(path_rmdir, dir, dentry); } +EXPORT_SYMBOL_GPL(security_path_rmdir); /** * security_path_unlink() - Check if removing a hard link is allowed -@@ -1785,6 +1786,7 @@ int security_path_symlink(const struct path *dir, struct dentry *dentry, +@@ -1979,6 +1980,7 @@ int security_path_symlink(const struct path *dir, struct dentry *dentry, return 0; - return call_int_hook(path_symlink, 0, dir, dentry, old_name); + return call_int_hook(path_symlink, dir, dentry, old_name); } +EXPORT_SYMBOL_GPL(security_path_symlink); /** * security_path_link - Check if creating a hard link is allowed -@@ -1803,6 +1805,7 @@ int security_path_link(struct dentry *old_dentry, const struct path *new_dir, +@@ -1997,6 +1999,7 @@ int security_path_link(struct dentry *old_dentry, const struct path *new_dir, return 0; - return call_int_hook(path_link, 0, old_dentry, new_dir, new_dentry); + return call_int_hook(path_link, old_dentry, new_dir, new_dentry); } +EXPORT_SYMBOL_GPL(security_path_link); /** * security_path_rename() - Check if renaming a file is allowed -@@ -1864,6 +1867,7 @@ int security_path_chmod(const struct path *path, umode_t mode) +@@ -2058,6 +2061,7 @@ int security_path_chmod(const struct path *path, umode_t mode) return 0; - return call_int_hook(path_chmod, 0, path, mode); + return call_int_hook(path_chmod, path, mode); } +EXPORT_SYMBOL_GPL(security_path_chmod); /** * security_path_chown() - Check if changing the file's owner/group is allowed -@@ -1881,6 +1885,7 @@ int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid) +@@ -2075,6 +2079,7 @@ int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid) return 0; - return call_int_hook(path_chown, 0, path, uid, gid); + return call_int_hook(path_chown, path, uid, gid); } +EXPORT_SYMBOL_GPL(security_path_chown); /** * security_path_chroot() - Check if changing the root directory is allowed -@@ -2110,6 +2115,7 @@ int security_inode_permission(struct inode *inode, int mask) +@@ -2319,6 +2324,7 @@ int security_inode_permission(struct inode *inode, int mask) return 0; - return call_int_hook(inode_permission, 0, inode, mask); + return call_int_hook(inode_permission, inode, mask); } +EXPORT_SYMBOL_GPL(security_inode_permission); /** * security_inode_setattr() - Check if setting file attributes is allowed -@@ -2588,6 +2594,7 @@ int security_file_permission(struct file *file, int mask) - - return fsnotify_perm(file, mask); +@@ -2840,6 +2846,7 @@ int security_file_permission(struct file *file, int mask) + { + return call_int_hook(file_permission, file, mask); } +EXPORT_SYMBOL_GPL(security_file_permission); /** * security_file_alloc() - Allocate and init a file's LSM blob -@@ -2872,6 +2879,7 @@ int security_file_truncate(struct file *file) +@@ -3144,6 +3151,7 @@ int security_file_truncate(struct file *file) { - return call_int_hook(file_truncate, 0, file); + return call_int_hook(file_truncate, file); } +EXPORT_SYMBOL_GPL(security_file_truncate); diff --git a/kernel/kernel/files/patches/aufs6/aufs6.6.84-20250414.patch b/kernel/kernel/files/patches/aufs6/aufs6.12-20250414.patch similarity index 98% rename from kernel/kernel/files/patches/aufs6/aufs6.6.84-20250414.patch rename to kernel/kernel/files/patches/aufs6/aufs6.12-20250414.patch index c7ea672b..d0af9e96 100644 --- a/kernel/kernel/files/patches/aufs6/aufs6.6.84-20250414.patch +++ b/kernel/kernel/files/patches/aufs6/aufs6.12-20250414.patch @@ -1,6 +1,6 @@ -diff -Naur null/Documentation/ABI/testing/debugfs-aufs linux-6.6.84/Documentation/ABI/testing/debugfs-aufs +diff -Naur null/Documentation/ABI/testing/debugfs-aufs linux-6.12.30/Documentation/ABI/testing/debugfs-aufs --- /dev/null -+++ linux-6.6.84/Documentation/ABI/testing/debugfs-aufs 2025-04-18 18:38:35.878448050 +0300 ++++ linux-6.12.30/Documentation/ABI/testing/debugfs-aufs 2025-05-27 19:28:00.097257513 +0300 @@ -0,0 +1,55 @@ +What: /debug/aufs/si_/ +Date: March 2009 @@ -57,9 +57,9 @@ diff -Naur null/Documentation/ABI/testing/debugfs-aufs linux-6.6.84/Documentatio + be created. + When the aufs mount option 'noxino' is specified, it + will be empty. About XINO files, see the aufs manual. -diff -Naur null/Documentation/ABI/testing/sysfs-aufs linux-6.6.84/Documentation/ABI/testing/sysfs-aufs +diff -Naur null/Documentation/ABI/testing/sysfs-aufs linux-6.12.30/Documentation/ABI/testing/sysfs-aufs --- /dev/null -+++ linux-6.6.84/Documentation/ABI/testing/sysfs-aufs 2025-04-18 18:38:35.878448050 +0300 ++++ linux-6.12.30/Documentation/ABI/testing/sysfs-aufs 2025-05-27 19:28:00.097257513 +0300 @@ -0,0 +1,31 @@ +What: /sys/fs/aufs/si_/ +Date: March 2009 @@ -92,9 +92,9 @@ diff -Naur null/Documentation/ABI/testing/sysfs-aufs linux-6.6.84/Documentation/ + even if it is the default path. + When the aufs mount option 'noxino' is specified, it + will be empty. About XINO files, see the aufs manual. -diff -Naur null/Documentation/filesystems/aufs/design/01intro.txt linux-6.6.84/Documentation/filesystems/aufs/design/01intro.txt +diff -Naur null/Documentation/filesystems/aufs/design/01intro.txt linux-6.12.30/Documentation/filesystems/aufs/design/01intro.txt --- /dev/null -+++ linux-6.6.84/Documentation/filesystems/aufs/design/01intro.txt 2025-04-18 18:38:35.878448050 +0300 ++++ linux-6.12.30/Documentation/filesystems/aufs/design/01intro.txt 2025-05-27 19:28:00.097257513 +0300 @@ -0,0 +1,171 @@ + +# Copyright (C) 2005-2025 Junjiro R. Okajima @@ -267,9 +267,9 @@ diff -Naur null/Documentation/filesystems/aufs/design/01intro.txt linux-6.6.84/D +Some people may think it is better to pass such work to user space +helper, instead of doing in kernel space. Actually I am still thinking +about it. But currently I have implemented it in kernel space. -diff -Naur null/Documentation/filesystems/aufs/design/02struct.txt linux-6.6.84/Documentation/filesystems/aufs/design/02struct.txt +diff -Naur null/Documentation/filesystems/aufs/design/02struct.txt linux-6.12.30/Documentation/filesystems/aufs/design/02struct.txt --- /dev/null -+++ linux-6.6.84/Documentation/filesystems/aufs/design/02struct.txt 2025-04-18 18:38:35.878448050 +0300 ++++ linux-6.12.30/Documentation/filesystems/aufs/design/02struct.txt 2025-05-27 19:28:00.097257513 +0300 @@ -0,0 +1,258 @@ + +# Copyright (C) 2005-2025 Junjiro R. Okajima @@ -529,9 +529,9 @@ diff -Naur null/Documentation/filesystems/aufs/design/02struct.txt linux-6.6.84/ +- etc. + +For this purpose, use "aumvdown" command in aufs-util.git. -diff -Naur null/Documentation/filesystems/aufs/design/03atomic_open.txt linux-6.6.84/Documentation/filesystems/aufs/design/03atomic_open.txt +diff -Naur null/Documentation/filesystems/aufs/design/03atomic_open.txt linux-6.12.30/Documentation/filesystems/aufs/design/03atomic_open.txt --- /dev/null -+++ linux-6.6.84/Documentation/filesystems/aufs/design/03atomic_open.txt 2025-04-18 18:38:35.878448050 +0300 ++++ linux-6.12.30/Documentation/filesystems/aufs/design/03atomic_open.txt 2025-05-27 19:28:00.097257513 +0300 @@ -0,0 +1,85 @@ + +# Copyright (C) 2015-2025 Junjiro R. Okajima @@ -618,9 +618,9 @@ diff -Naur null/Documentation/filesystems/aufs/design/03atomic_open.txt linux-6. + ->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 -Naur null/Documentation/filesystems/aufs/design/03lookup.txt linux-6.6.84/Documentation/filesystems/aufs/design/03lookup.txt +diff -Naur null/Documentation/filesystems/aufs/design/03lookup.txt linux-6.12.30/Documentation/filesystems/aufs/design/03lookup.txt --- /dev/null -+++ linux-6.6.84/Documentation/filesystems/aufs/design/03lookup.txt 2025-04-18 18:38:35.878448050 +0300 ++++ linux-6.12.30/Documentation/filesystems/aufs/design/03lookup.txt 2025-05-27 19:28:00.097257513 +0300 @@ -0,0 +1,113 @@ + +# Copyright (C) 2005-2025 Junjiro R. Okajima @@ -735,9 +735,9 @@ diff -Naur null/Documentation/filesystems/aufs/design/03lookup.txt linux-6.6.84/ + 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 -Naur null/Documentation/filesystems/aufs/design/04branch.txt linux-6.6.84/Documentation/filesystems/aufs/design/04branch.txt +diff -Naur null/Documentation/filesystems/aufs/design/04branch.txt linux-6.12.30/Documentation/filesystems/aufs/design/04branch.txt --- /dev/null -+++ linux-6.6.84/Documentation/filesystems/aufs/design/04branch.txt 2025-04-18 18:38:35.878448050 +0300 ++++ linux-6.12.30/Documentation/filesystems/aufs/design/04branch.txt 2025-05-27 19:28:00.098257501 +0300 @@ -0,0 +1,74 @@ + +# Copyright (C) 2005-2025 Junjiro R. Okajima @@ -813,9 +813,9 @@ diff -Naur null/Documentation/filesystems/aufs/design/04branch.txt linux-6.6.84/ + - a file on the branch is mmap-ed. + - a regular file on the branch is opened for write and there is no + same named entry on the upper branch. -diff -Naur null/Documentation/filesystems/aufs/design/05wbr_policy.txt linux-6.6.84/Documentation/filesystems/aufs/design/05wbr_policy.txt +diff -Naur null/Documentation/filesystems/aufs/design/05wbr_policy.txt linux-6.12.30/Documentation/filesystems/aufs/design/05wbr_policy.txt --- /dev/null -+++ linux-6.6.84/Documentation/filesystems/aufs/design/05wbr_policy.txt 2025-04-18 18:38:35.878448050 +0300 ++++ linux-6.12.30/Documentation/filesystems/aufs/design/05wbr_policy.txt 2025-05-27 19:28:00.098257501 +0300 @@ -0,0 +1,64 @@ + +# Copyright (C) 2005-2025 Junjiro R. Okajima @@ -881,9 +881,9 @@ diff -Naur null/Documentation/filesystems/aufs/design/05wbr_policy.txt linux-6.6 + where the source and the target exists and selects the higher + one. If the selected branch is readonly, then aufs follows the + copyup policy. -diff -Naur null/Documentation/filesystems/aufs/design/06dirren.dot linux-6.6.84/Documentation/filesystems/aufs/design/06dirren.dot +diff -Naur null/Documentation/filesystems/aufs/design/06dirren.dot linux-6.12.30/Documentation/filesystems/aufs/design/06dirren.dot --- /dev/null -+++ linux-6.6.84/Documentation/filesystems/aufs/design/06dirren.dot 2025-04-18 18:38:35.878448050 +0300 ++++ linux-6.12.30/Documentation/filesystems/aufs/design/06dirren.dot 2025-05-27 19:28:00.098257501 +0300 @@ -0,0 +1,44 @@ + +// to view this graph, run dot(1) command in GRAPHVIZ. @@ -929,9 +929,9 @@ diff -Naur null/Documentation/filesystems/aufs/design/06dirren.dot linux-6.6.84/ + +aufs_lookup -> whinfo [label="load/remove"]; +} -diff -Naur null/Documentation/filesystems/aufs/design/06dirren.txt linux-6.6.84/Documentation/filesystems/aufs/design/06dirren.txt +diff -Naur null/Documentation/filesystems/aufs/design/06dirren.txt linux-6.12.30/Documentation/filesystems/aufs/design/06dirren.txt --- /dev/null -+++ linux-6.6.84/Documentation/filesystems/aufs/design/06dirren.txt 2025-04-18 18:38:35.878448050 +0300 ++++ linux-6.12.30/Documentation/filesystems/aufs/design/06dirren.txt 2025-05-27 19:28:00.098257501 +0300 @@ -0,0 +1,102 @@ + +# Copyright (C) 2017-2025 Junjiro R. Okajima @@ -1035,9 +1035,9 @@ diff -Naur null/Documentation/filesystems/aufs/design/06dirren.txt linux-6.6.84/ +contains two names, before- and after-rename, the name comparision in +UDBA handler may not work correctly. In this case, the behaviour will be +equivalen to udba=reval case. -diff -Naur null/Documentation/filesystems/aufs/design/06fhsm.txt linux-6.6.84/Documentation/filesystems/aufs/design/06fhsm.txt +diff -Naur null/Documentation/filesystems/aufs/design/06fhsm.txt linux-6.12.30/Documentation/filesystems/aufs/design/06fhsm.txt --- /dev/null -+++ linux-6.6.84/Documentation/filesystems/aufs/design/06fhsm.txt 2025-04-18 18:38:35.879448037 +0300 ++++ linux-6.12.30/Documentation/filesystems/aufs/design/06fhsm.txt 2025-05-27 19:28:00.098257501 +0300 @@ -0,0 +1,118 @@ + +# Copyright (C) 2011-2025 Junjiro R. Okajima @@ -1157,9 +1157,9 @@ diff -Naur null/Documentation/filesystems/aufs/design/06fhsm.txt linux-6.6.84/Do + +And of course, in every step, an error may happen. So the operation +should restore the original file state after an error happens. -diff -Naur null/Documentation/filesystems/aufs/design/06mmap.txt linux-6.6.84/Documentation/filesystems/aufs/design/06mmap.txt +diff -Naur null/Documentation/filesystems/aufs/design/06mmap.txt linux-6.12.30/Documentation/filesystems/aufs/design/06mmap.txt --- /dev/null -+++ linux-6.6.84/Documentation/filesystems/aufs/design/06mmap.txt 2025-04-18 18:38:35.879448037 +0300 ++++ linux-6.12.30/Documentation/filesystems/aufs/design/06mmap.txt 2025-05-27 19:28:00.098257501 +0300 @@ -0,0 +1,72 @@ + +# Copyright (C) 2005-2025 Junjiro R. Okajima @@ -1233,9 +1233,9 @@ diff -Naur null/Documentation/filesystems/aufs/design/06mmap.txt linux-6.6.84/Do + equivalent to vm_prfile described above. + +I have to give up this "looks-smater" approach. -diff -Naur null/Documentation/filesystems/aufs/design/06xattr.txt linux-6.6.84/Documentation/filesystems/aufs/design/06xattr.txt +diff -Naur null/Documentation/filesystems/aufs/design/06xattr.txt linux-6.12.30/Documentation/filesystems/aufs/design/06xattr.txt --- /dev/null -+++ linux-6.6.84/Documentation/filesystems/aufs/design/06xattr.txt 2025-04-18 18:38:35.879448037 +0300 ++++ linux-6.12.30/Documentation/filesystems/aufs/design/06xattr.txt 2025-05-27 19:28:00.098257501 +0300 @@ -0,0 +1,94 @@ + +# Copyright (C) 2014-2025 Junjiro R. Okajima @@ -1331,9 +1331,9 @@ diff -Naur null/Documentation/filesystems/aufs/design/06xattr.txt linux-6.6.84/D +Some contradiction may happen I am afraid. +Do we need another attribute to stop copying XATTR? I am unsure. For +now, aufs implements the branch attributes to ignore the error. -diff -Naur null/Documentation/filesystems/aufs/design/07export.txt linux-6.6.84/Documentation/filesystems/aufs/design/07export.txt +diff -Naur null/Documentation/filesystems/aufs/design/07export.txt linux-6.12.30/Documentation/filesystems/aufs/design/07export.txt --- /dev/null -+++ linux-6.6.84/Documentation/filesystems/aufs/design/07export.txt 2025-04-18 18:38:35.879448037 +0300 ++++ linux-6.12.30/Documentation/filesystems/aufs/design/07export.txt 2025-05-27 19:28:00.098257501 +0300 @@ -0,0 +1,58 @@ + +# Copyright (C) 2005-2025 Junjiro R. Okajima @@ -1393,9 +1393,9 @@ diff -Naur null/Documentation/filesystems/aufs/design/07export.txt linux-6.6.84/ + convert it into ESTALE for NFSD. +- readdir(): call lockdep_on/off() because filldir in NFSD calls + lookup_one_len(), vfs_getattr(), encode_fh() and others. -diff -Naur null/Documentation/filesystems/aufs/design/08shwh.txt linux-6.6.84/Documentation/filesystems/aufs/design/08shwh.txt +diff -Naur null/Documentation/filesystems/aufs/design/08shwh.txt linux-6.12.30/Documentation/filesystems/aufs/design/08shwh.txt --- /dev/null -+++ linux-6.6.84/Documentation/filesystems/aufs/design/08shwh.txt 2025-04-18 18:38:35.879448037 +0300 ++++ linux-6.12.30/Documentation/filesystems/aufs/design/08shwh.txt 2025-05-27 19:28:00.098257501 +0300 @@ -0,0 +1,52 @@ + +# Copyright (C) 2005-2025 Junjiro R. Okajima @@ -1449,9 +1449,9 @@ diff -Naur null/Documentation/filesystems/aufs/design/08shwh.txt linux-6.6.84/Do + +This new squashfs archive can be stored on the boot device and the +initramfs will use it to replace the old one at the next boot. -diff -Naur null/Documentation/filesystems/aufs/design/10dynop.txt linux-6.6.84/Documentation/filesystems/aufs/design/10dynop.txt +diff -Naur null/Documentation/filesystems/aufs/design/10dynop.txt linux-6.12.30/Documentation/filesystems/aufs/design/10dynop.txt --- /dev/null -+++ linux-6.6.84/Documentation/filesystems/aufs/design/10dynop.txt 2025-04-18 18:38:35.879448037 +0300 ++++ linux-6.12.30/Documentation/filesystems/aufs/design/10dynop.txt 2025-05-27 19:28:00.098257501 +0300 @@ -0,0 +1,47 @@ + +# Copyright (C) 2010-2025 Junjiro R. Okajima @@ -1500,9 +1500,9 @@ diff -Naur null/Documentation/filesystems/aufs/design/10dynop.txt linux-6.6.84/D +XIP (DAX) mainly. +Currently this approach is applied to address_space_operations for +regular files only. -diff -Naur null/Documentation/filesystems/aufs/README linux-6.6.84/Documentation/filesystems/aufs/README +diff -Naur null/Documentation/filesystems/aufs/README linux-6.12.30/Documentation/filesystems/aufs/README --- /dev/null -+++ linux-6.6.84/Documentation/filesystems/aufs/README 2025-04-18 18:38:35.878448050 +0300 ++++ linux-6.12.30/Documentation/filesystems/aufs/README 2025-05-27 19:28:00.097257513 +0300 @@ -0,0 +1,409 @@ + +Aufs6 -- advanced multi layered unification filesystem version 6.x @@ -1913,9 +1913,9 @@ diff -Naur null/Documentation/filesystems/aufs/README linux-6.6.84/Documentation +# Local variables: ; +# mode: text; +# End: ; -diff -Naur null/fs/aufs/aufs.h linux-6.6.84/fs/aufs/aufs.h +diff -Naur null/fs/aufs/aufs.h linux-6.12.30/fs/aufs/aufs.h --- /dev/null -+++ linux-6.6.84/fs/aufs/aufs.h 2025-04-18 18:38:35.880448025 +0300 ++++ linux-6.12.30/fs/aufs/aufs.h 2025-05-27 19:28:00.099257488 +0300 @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -1979,9 +1979,9 @@ diff -Naur null/fs/aufs/aufs.h linux-6.6.84/fs/aufs/aufs.h + +#endif /* __KERNEL__ */ +#endif /* __AUFS_H__ */ -diff -Naur null/fs/aufs/branch.c linux-6.6.84/fs/aufs/branch.c +diff -Naur null/fs/aufs/branch.c linux-6.12.30/fs/aufs/branch.c --- /dev/null -+++ linux-6.6.84/fs/aufs/branch.c 2025-04-18 18:38:35.880448025 +0300 ++++ linux-6.12.30/fs/aufs/branch.c 2025-05-27 19:28:00.100257476 +0300 @@ -0,0 +1,1427 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -3278,7 +3278,7 @@ diff -Naur null/fs/aufs/branch.c linux-6.6.84/fs/aufs/branch.c + if (hf->f_mode & FMODE_READ) + i_readcount_inc(h_inode); + put_write_access(h_inode); -+ __mnt_drop_write(hf->f_path.mnt); ++ mnt_put_write_access(hf->f_path.mnt); + } + } + @@ -3410,9 +3410,9 @@ diff -Naur null/fs/aufs/branch.c linux-6.6.84/fs/aufs/branch.c + + return err; +} -diff -Naur null/fs/aufs/branch.h linux-6.6.84/fs/aufs/branch.h +diff -Naur null/fs/aufs/branch.h linux-6.12.30/fs/aufs/branch.h --- /dev/null -+++ linux-6.6.84/fs/aufs/branch.h 2025-04-18 18:38:35.880448025 +0300 ++++ linux-6.12.30/fs/aufs/branch.h 2025-05-27 19:28:00.100257476 +0300 @@ -0,0 +1,375 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -3789,9 +3789,9 @@ diff -Naur null/fs/aufs/branch.h linux-6.6.84/fs/aufs/branch.h + +#endif /* __KERNEL__ */ +#endif /* __AUFS_BRANCH_H__ */ -diff -Naur null/fs/aufs/conf.mk linux-6.6.84/fs/aufs/conf.mk +diff -Naur null/fs/aufs/conf.mk linux-6.12.30/fs/aufs/conf.mk --- /dev/null -+++ linux-6.6.84/fs/aufs/conf.mk 2025-04-18 18:38:35.881448012 +0300 ++++ linux-6.12.30/fs/aufs/conf.mk 2025-05-27 19:28:00.100257476 +0300 @@ -0,0 +1,40 @@ +# SPDX-License-Identifier: GPL-2.0 + @@ -3833,9 +3833,9 @@ diff -Naur null/fs/aufs/conf.mk linux-6.6.84/fs/aufs/conf.mk +${obj}/sysfs.o: ${AuConfName} + +-include ${srctree}/${src}/conf_priv.mk -diff -Naur null/fs/aufs/cpup.c linux-6.6.84/fs/aufs/cpup.c +diff -Naur null/fs/aufs/cpup.c linux-6.12.30/fs/aufs/cpup.c --- /dev/null -+++ linux-6.6.84/fs/aufs/cpup.c 2025-04-18 18:38:35.881448012 +0300 ++++ linux-6.12.30/fs/aufs/cpup.c 2025-05-27 19:28:00.100257476 +0300 @@ -0,0 +1,1458 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -3971,8 +3971,8 @@ diff -Naur null/fs/aufs/cpup.c linux-6.6.84/fs/aufs/cpup.c + dt->dt_dentry = dentry; + dt->dt_h_path = *h_path; + h_inode = d_inode(h_path->dentry); -+ dt->dt_atime = h_inode->i_atime; -+ dt->dt_mtime = h_inode->i_mtime; ++ dt->dt_atime = inode_get_atime(h_inode); ++ dt->dt_mtime = inode_get_mtime(h_inode); + /* smp_mb(); */ +} + @@ -4038,8 +4038,8 @@ diff -Naur null/fs/aufs/cpup.c linux-6.6.84/fs/aufs/cpup.c + } else { + ia.ia_uid = h_isrc->i_uid; + ia.ia_gid = h_isrc->i_gid; -+ ia.ia_atime = h_isrc->i_atime; -+ ia.ia_mtime = h_isrc->i_mtime; ++ ia.ia_atime = inode_get_atime(h_isrc); ++ ia.ia_mtime = inode_get_mtime(h_isrc); + if (h_idst->i_mode != h_isrc->i_mode + && !S_ISLNK(h_idst->i_mode)) { + ia.ia_valid |= ATTR_MODE; @@ -5295,10 +5295,10 @@ diff -Naur null/fs/aufs/cpup.c linux-6.6.84/fs/aufs/cpup.c + dput(parent); + return err; +} -diff -Naur null/fs/aufs/cpup.h linux-6.6.84/fs/aufs/cpup.h +diff -Naur null/fs/aufs/cpup.h linux-6.12.30/fs/aufs/cpup.h --- /dev/null -+++ linux-6.6.84/fs/aufs/cpup.h 2025-04-18 18:38:35.881448012 +0300 -@@ -0,0 +1,100 @@ ++++ linux-6.12.30/fs/aufs/cpup.h 2025-05-27 19:28:00.100257476 +0300 +@@ -0,0 +1,101 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2005-2025 Junjiro R. Okajima @@ -5327,6 +5327,7 @@ diff -Naur null/fs/aufs/cpup.h linux-6.6.84/fs/aufs/cpup.h +#ifdef __KERNEL__ + +#include ++#include + +struct inode; +struct file; @@ -5350,15 +5351,15 @@ diff -Naur null/fs/aufs/cpup.h linux-6.6.84/fs/aufs/cpup.h +}; + +/* cpup flags */ -+#define AuCpup_DTIME 1 /* do dtime_store/revert */ -+#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino, ++#define AuCpup_DTIME BIT(0) /* do dtime_store/revert */ ++#define AuCpup_KEEPLINO BIT(1) /* do not clear the lower xino, + for link(2) */ -+#define AuCpup_RENAME (1 << 2) /* rename after cpup */ -+#define AuCpup_HOPEN (1 << 3) /* call h_open_pre/post() in ++#define AuCpup_RENAME BIT(2) /* rename after cpup */ ++#define AuCpup_HOPEN BIT(3) /* call h_open_pre/post() in + cpup */ -+#define AuCpup_OVERWRITE (1 << 4) /* allow overwriting the ++#define AuCpup_OVERWRITE BIT(4) /* allow overwriting the + existing entry */ -+#define AuCpup_RWDST (1 << 5) /* force write target even if ++#define AuCpup_RWDST BIT(5) /* force write target even if + the branch is marked as RO */ + +#ifndef CONFIG_AUFS_BR_HFSPLUS @@ -5399,9 +5400,9 @@ diff -Naur null/fs/aufs/cpup.h linux-6.6.84/fs/aufs/cpup.h + +#endif /* __KERNEL__ */ +#endif /* __AUFS_CPUP_H__ */ -diff -Naur null/fs/aufs/dbgaufs.c linux-6.6.84/fs/aufs/dbgaufs.c +diff -Naur null/fs/aufs/dbgaufs.c linux-6.12.30/fs/aufs/dbgaufs.c --- /dev/null -+++ linux-6.6.84/fs/aufs/dbgaufs.c 2025-04-18 18:38:35.881448012 +0300 ++++ linux-6.12.30/fs/aufs/dbgaufs.c 2025-05-27 19:28:00.100257476 +0300 @@ -0,0 +1,526 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -5929,9 +5930,9 @@ diff -Naur null/fs/aufs/dbgaufs.c linux-6.6.84/fs/aufs/dbgaufs.c + err = 0; + return err; +} -diff -Naur null/fs/aufs/dbgaufs.h linux-6.6.84/fs/aufs/dbgaufs.h +diff -Naur null/fs/aufs/dbgaufs.h linux-6.12.30/fs/aufs/dbgaufs.h --- /dev/null -+++ linux-6.6.84/fs/aufs/dbgaufs.h 2025-04-18 18:38:35.881448012 +0300 ++++ linux-6.12.30/fs/aufs/dbgaufs.h 2025-05-27 19:28:00.100257476 +0300 @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -5986,9 +5987,9 @@ diff -Naur null/fs/aufs/dbgaufs.h linux-6.6.84/fs/aufs/dbgaufs.h + +#endif /* __KERNEL__ */ +#endif /* __DBGAUFS_H__ */ -diff -Naur null/fs/aufs/dcsub.c linux-6.6.84/fs/aufs/dcsub.c +diff -Naur null/fs/aufs/dcsub.c linux-6.12.30/fs/aufs/dcsub.c --- /dev/null -+++ linux-6.6.84/fs/aufs/dcsub.c 2025-04-18 18:38:35.881448012 +0300 ++++ linux-6.12.30/fs/aufs/dcsub.c 2025-05-27 19:28:00.100257476 +0300 @@ -0,0 +1,225 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -6215,9 +6216,9 @@ diff -Naur null/fs/aufs/dcsub.c linux-6.6.84/fs/aufs/dcsub.c + + return path_is_under(path + 0, path + 1); +} -diff -Naur null/fs/aufs/dcsub.h linux-6.6.84/fs/aufs/dcsub.h +diff -Naur null/fs/aufs/dcsub.h linux-6.12.30/fs/aufs/dcsub.h --- /dev/null -+++ linux-6.6.84/fs/aufs/dcsub.h 2025-04-18 18:38:35.881448012 +0300 ++++ linux-6.12.30/fs/aufs/dcsub.h 2025-05-27 19:28:00.100257476 +0300 @@ -0,0 +1,139 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -6358,10 +6359,10 @@ diff -Naur null/fs/aufs/dcsub.h linux-6.6.84/fs/aufs/dcsub.h + +#endif /* __KERNEL__ */ +#endif /* __AUFS_DCSUB_H__ */ -diff -Naur null/fs/aufs/debug.c linux-6.6.84/fs/aufs/debug.c +diff -Naur null/fs/aufs/debug.c linux-6.12.30/fs/aufs/debug.c --- /dev/null -+++ linux-6.6.84/fs/aufs/debug.c 2025-04-18 18:38:35.881448012 +0300 -@@ -0,0 +1,449 @@ ++++ linux-6.12.30/fs/aufs/debug.c 2025-05-27 19:28:00.101257463 +0300 +@@ -0,0 +1,448 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005-2025 Junjiro R. Okajima @@ -6492,13 +6493,12 @@ diff -Naur null/fs/aufs/debug.c linux-6.6.84/fs/aufs/debug.c + } + + ctime = inode_get_ctime(inode); -+ dpri("i%d: %p, i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu," ++ dpri("i%d: %p, i%lu, %s, cnt %d, nl %u?, 0%o, sz %llu, blk %llu," + " acl %p, def_acl %p," -+ " hn %d, ct %lld, np %lu, st 0x%lx, f 0x%x, v %llu, g %x%s%.*s\n", ++ " hn %d, ct %lld, np %lu, st 0x%x, f 0x%x, v %llu, g %x%s%.*s\n", + bindex, inode, + inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??", -+ atomic_read(&inode->i_count), -+ vfsub_inode_nlink(inode, AU_I_UNKNOWN), inode->i_mode, ++ atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode, + i_size_read(inode), (unsigned long long)inode->i_blocks, + inode->i_acl, inode->i_default_acl, + hn, (long long)timespec64_to_ns(&ctime) & 0x0ffff, @@ -6617,9 +6617,9 @@ diff -Naur null/fs/aufs/debug.c linux-6.6.84/fs/aufs/debug.c + && au_fi(file)) + snprintf(a, sizeof(a), ", gen %d, mmapped %d", + au_figen(file), atomic_read(&au_fi(file)->fi_mmapped)); -+ dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, v %llu, pos %llu%s\n", ++ dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, pos %llu%s\n", + bindex, file->f_mode, file->f_flags, (long)file_count(file), -+ file->f_version, file->f_pos, a); ++ file->f_pos, a); + if (!IS_ERR_OR_NULL(file->f_path.dentry)) + do_pri_dentry(bindex, file->f_path.dentry); + return 0; @@ -6811,9 +6811,9 @@ diff -Naur null/fs/aufs/debug.c linux-6.6.84/fs/aufs/debug.c + + return 0; +} -diff -Naur null/fs/aufs/debug.h linux-6.6.84/fs/aufs/debug.h +diff -Naur null/fs/aufs/debug.h linux-6.12.30/fs/aufs/debug.h --- /dev/null -+++ linux-6.6.84/fs/aufs/debug.h 2025-04-18 18:38:35.881448012 +0300 ++++ linux-6.12.30/fs/aufs/debug.h 2025-05-27 19:28:00.101257463 +0300 @@ -0,0 +1,226 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -7041,9 +7041,9 @@ diff -Naur null/fs/aufs/debug.h linux-6.6.84/fs/aufs/debug.h + +#endif /* __KERNEL__ */ +#endif /* __AUFS_DEBUG_H__ */ -diff -Naur null/fs/aufs/dentry.c linux-6.6.84/fs/aufs/dentry.c +diff -Naur null/fs/aufs/dentry.c linux-6.12.30/fs/aufs/dentry.c --- /dev/null -+++ linux-6.6.84/fs/aufs/dentry.c 2025-04-18 18:38:35.882448000 +0300 ++++ linux-6.12.30/fs/aufs/dentry.c 2025-05-27 19:28:00.101257463 +0300 @@ -0,0 +1,1176 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -8221,9 +8221,9 @@ diff -Naur null/fs/aufs/dentry.c linux-6.6.84/fs/aufs/dentry.c +const struct dentry_operations aufs_dop_noreval = { + .d_release = aufs_d_release +}; -diff -Naur null/fs/aufs/dentry.h linux-6.6.84/fs/aufs/dentry.h +diff -Naur null/fs/aufs/dentry.h linux-6.12.30/fs/aufs/dentry.h --- /dev/null -+++ linux-6.6.84/fs/aufs/dentry.h 2025-04-18 18:38:35.882448000 +0300 ++++ linux-6.12.30/fs/aufs/dentry.h 2025-05-27 19:28:00.101257463 +0300 @@ -0,0 +1,270 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -8275,9 +8275,9 @@ diff -Naur null/fs/aufs/dentry.h linux-6.6.84/fs/aufs/dentry.h +/* ---------------------------------------------------------------------- */ + +/* flags for au_lkup_dentry() */ -+#define AuLkup_ALLOW_NEG 1 -+#define AuLkup_IGNORE_PERM (1 << 1) -+#define AuLkup_DIRREN (1 << 2) ++#define AuLkup_ALLOW_NEG BIT(0) ++#define AuLkup_IGNORE_PERM BIT(1) ++#define AuLkup_DIRREN BIT(2) +#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name) +#define au_fset_lkup(flags, name) \ + do { (flags) |= AuLkup_##name; } while (0) @@ -8495,9 +8495,9 @@ diff -Naur null/fs/aufs/dentry.h linux-6.6.84/fs/aufs/dentry.h + +#endif /* __KERNEL__ */ +#endif /* __AUFS_DENTRY_H__ */ -diff -Naur null/fs/aufs/dinfo.c linux-6.6.84/fs/aufs/dinfo.c +diff -Naur null/fs/aufs/dinfo.c linux-6.12.30/fs/aufs/dinfo.c --- /dev/null -+++ linux-6.6.84/fs/aufs/dinfo.c 2025-04-18 18:38:35.882448000 +0300 ++++ linux-6.12.30/fs/aufs/dinfo.c 2025-05-27 19:28:00.101257463 +0300 @@ -0,0 +1,555 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -9054,9 +9054,9 @@ diff -Naur null/fs/aufs/dinfo.c linux-6.6.84/fs/aufs/dinfo.c + return bindex; + return -1; +} -diff -Naur null/fs/aufs/dir.c linux-6.6.84/fs/aufs/dir.c +diff -Naur null/fs/aufs/dir.c linux-6.12.30/fs/aufs/dir.c --- /dev/null -+++ linux-6.6.84/fs/aufs/dir.c 2025-04-18 18:38:35.882448000 +0300 ++++ linux-6.12.30/fs/aufs/dir.c 2025-05-27 19:28:00.101257463 +0300 @@ -0,0 +1,765 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -9167,6 +9167,7 @@ diff -Naur null/fs/aufs/dir.c linux-6.6.84/fs/aufs/dir.c + struct au_dir_ts_arg *a = arg; + struct au_dtime dt; + struct path h_path; ++ struct timespec64 ts; + struct inode *dir, *h_dir; + struct super_block *sb; + struct au_branch *br; @@ -9204,8 +9205,9 @@ diff -Naur null/fs/aufs/dir.c linux-6.6.84/fs/aufs/dir.c + hdir = au_hi(dir, btop); + au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT); + h_dir = au_h_iptr(dir, btop); ++ ts = inode_get_mtime(h_dir); + if (vfsub_inode_nlink(h_dir, AU_I_BRANCH) -+ && timespec64_compare(&h_dir->i_mtime, &dt.dt_mtime) < 0) { ++ && timespec64_compare(&ts, &dt.dt_mtime) < 0) { + dt.dt_h_path = h_path; + au_dtime_revert(&dt); + } @@ -9320,7 +9322,6 @@ diff -Naur null/fs/aufs/dir.c linux-6.6.84/fs/aufs/dir.c + err = 0; + mnt = file->f_path.mnt; + dentry = file->f_path.dentry; -+ file->f_version = inode_query_iversion(d_inode(dentry)); + bindex = au_dbtop(dentry); + au_set_fbtop(file, bindex); + btail = au_dbtaildir(dentry); @@ -9587,9 +9588,9 @@ diff -Naur null/fs/aufs/dir.c linux-6.6.84/fs/aufs/dir.c + +/* ---------------------------------------------------------------------- */ + -+#define AuTestEmpty_WHONLY 1 -+#define AuTestEmpty_CALLED (1 << 1) -+#define AuTestEmpty_SHWH (1 << 2) ++#define AuTestEmpty_WHONLY BIT(0) ++#define AuTestEmpty_CALLED BIT(1) ++#define AuTestEmpty_SHWH BIT(2) +#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name) +#define au_fset_testempty(flags, name) \ + do { (flags) |= AuTestEmpty_##name; } while (0) @@ -9620,8 +9621,7 @@ diff -Naur null/fs/aufs/dir.c linux-6.6.84/fs/aufs/dir.c + arg->err = 0; + au_fset_testempty(arg->flags, CALLED); + /* smp_mb(); */ -+ if (name[0] == '.' -+ && (namelen == 1 || (name[1] == '.' && namelen == 2))) ++ if (is_dot_dotdot(name, namelen)) + goto out; /* success */ + + if (namelen <= AUFS_WH_PFX_LEN @@ -9823,9 +9823,9 @@ diff -Naur null/fs/aufs/dir.c linux-6.6.84/fs/aufs/dir.c + .flush = aufs_flush_dir, + .fsync = aufs_fsync_dir +}; -diff -Naur null/fs/aufs/dir.h linux-6.6.84/fs/aufs/dir.h +diff -Naur null/fs/aufs/dir.h linux-6.12.30/fs/aufs/dir.h --- /dev/null -+++ linux-6.6.84/fs/aufs/dir.h 2025-04-18 18:38:35.882448000 +0300 ++++ linux-6.12.30/fs/aufs/dir.h 2025-05-27 19:28:00.101257463 +0300 @@ -0,0 +1,134 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -9961,9 +9961,9 @@ diff -Naur null/fs/aufs/dir.h linux-6.6.84/fs/aufs/dir.h + +#endif /* __KERNEL__ */ +#endif /* __AUFS_DIR_H__ */ -diff -Naur null/fs/aufs/dirren.c linux-6.6.84/fs/aufs/dirren.c +diff -Naur null/fs/aufs/dirren.c linux-6.12.30/fs/aufs/dirren.c --- /dev/null -+++ linux-6.6.84/fs/aufs/dirren.c 2025-04-18 18:38:35.882448000 +0300 ++++ linux-6.12.30/fs/aufs/dirren.c 2025-05-27 19:28:00.101257463 +0300 @@ -0,0 +1,1315 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -11280,9 +11280,9 @@ diff -Naur null/fs/aufs/dirren.c linux-6.6.84/fs/aufs/dirren.c +out: + return err; +} -diff -Naur null/fs/aufs/dirren.h linux-6.6.84/fs/aufs/dirren.h +diff -Naur null/fs/aufs/dirren.h linux-6.12.30/fs/aufs/dirren.h --- /dev/null -+++ linux-6.6.84/fs/aufs/dirren.h 2025-04-18 18:38:35.882448000 +0300 ++++ linux-6.12.30/fs/aufs/dirren.h 2025-05-27 19:28:00.102257451 +0300 @@ -0,0 +1,140 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -11424,9 +11424,9 @@ diff -Naur null/fs/aufs/dirren.h linux-6.6.84/fs/aufs/dirren.h + +#endif /* __KERNEL__ */ +#endif /* __AUFS_DIRREN_H__ */ -diff -Naur null/fs/aufs/dynop.c linux-6.6.84/fs/aufs/dynop.c +diff -Naur null/fs/aufs/dynop.c linux-6.12.30/fs/aufs/dynop.c --- /dev/null -+++ linux-6.6.84/fs/aufs/dynop.c 2025-04-18 18:38:35.882448000 +0300 ++++ linux-6.12.30/fs/aufs/dynop.c 2025-05-27 19:28:00.102257451 +0300 @@ -0,0 +1,365 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -11621,7 +11621,7 @@ diff -Naur null/fs/aufs/dynop.c linux-6.6.84/fs/aufs/dynop.c + DySetAop(launder_folio); + DySetAop(is_partially_uptodate); + DySetAop(is_dirty_writeback); -+ DySetAop(error_remove_page); ++ DySetAop(error_remove_folio); + DySetAop(swap_activate); + DySetAop(swap_deactivate); + DySetAop(swap_rw); @@ -11793,9 +11793,9 @@ diff -Naur null/fs/aufs/dynop.c linux-6.6.84/fs/aufs/dynop.c + for (i = 0; i < AuDyLast; i++) + WARN_ON(!hlist_bl_empty(dynop + i)); +} -diff -Naur null/fs/aufs/dynop.h linux-6.6.84/fs/aufs/dynop.h +diff -Naur null/fs/aufs/dynop.h linux-6.12.30/fs/aufs/dynop.h --- /dev/null -+++ linux-6.6.84/fs/aufs/dynop.h 2025-04-18 18:38:35.882448000 +0300 ++++ linux-6.12.30/fs/aufs/dynop.h 2025-05-27 19:28:00.102257451 +0300 @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -11874,10 +11874,10 @@ diff -Naur null/fs/aufs/dynop.h linux-6.6.84/fs/aufs/dynop.h + +#endif /* __KERNEL__ */ +#endif /* __AUFS_DYNOP_H__ */ -diff -Naur null/fs/aufs/export.c linux-6.6.84/fs/aufs/export.c +diff -Naur null/fs/aufs/export.c linux-6.12.30/fs/aufs/export.c --- /dev/null -+++ linux-6.6.84/fs/aufs/export.c 2025-04-18 18:38:35.883447987 +0300 -@@ -0,0 +1,830 @@ ++++ linux-6.12.30/fs/aufs/export.c 2025-05-27 19:28:00.102257451 +0300 +@@ -0,0 +1,846 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005-2025 Junjiro R. Okajima @@ -12174,17 +12174,33 @@ diff -Naur null/fs/aufs/export.c linux-6.6.84/fs/aufs/export.c +{ + int err; + struct path root; ++ struct vfsmount *mnt; + struct au_compare_mnt_args args = { + .sb = sb + }; + + get_fs_root(current->fs, &root); ++ /* ++ * as long as this sb is alive, this temporary unlock is safe. ++ * Really? ++ */ ++ si_read_unlock(sb); ++ mnt = collect_mounts(&root); ++ if (IS_ERR(mnt)) { ++ args.mnt = mnt; ++ goto out; ++ } ++ + rcu_read_lock(); -+ err = iterate_mounts(au_compare_mnt, &args, root.mnt); ++ err = iterate_mounts(au_compare_mnt, &args, mnt); + rcu_read_unlock(); -+ path_put(&root); ++ drop_collected_mounts(mnt); + AuDebugOn(!err); ++ ++out: ++ si_noflush_read_lock(sb); + AuDebugOn(!args.mnt); ++ path_put(&root); + return args.mnt; +} + @@ -12708,9 +12724,9 @@ diff -Naur null/fs/aufs/export.c linux-6.6.84/fs/aufs/export.c + BUILD_BUG_ON(sizeof(u) != sizeof(int)); + atomic_set(&sbinfo->si_xigen_next, u); +} -diff -Naur null/fs/aufs/fhsm.c linux-6.6.84/fs/aufs/fhsm.c +diff -Naur null/fs/aufs/fhsm.c linux-6.12.30/fs/aufs/fhsm.c --- /dev/null -+++ linux-6.6.84/fs/aufs/fhsm.c 2025-04-18 18:38:35.883447987 +0300 ++++ linux-6.12.30/fs/aufs/fhsm.c 2025-05-27 19:28:00.102257451 +0300 @@ -0,0 +1,426 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -13138,10 +13154,10 @@ diff -Naur null/fs/aufs/fhsm.c linux-6.6.84/fs/aufs/fhsm.c + if (u != AUFS_FHSM_CACHE_DEF_SEC) + seq_printf(seq, ",fhsm_sec=%u", u); +} -diff -Naur null/fs/aufs/file.c linux-6.6.84/fs/aufs/file.c +diff -Naur null/fs/aufs/file.c linux-6.12.30/fs/aufs/file.c --- /dev/null -+++ linux-6.6.84/fs/aufs/file.c 2025-04-18 18:38:35.883447987 +0300 -@@ -0,0 +1,866 @@ ++++ linux-6.12.30/fs/aufs/file.c 2025-05-27 19:28:00.102257451 +0300 +@@ -0,0 +1,858 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005-2025 Junjiro R. Okajima @@ -13239,14 +13255,6 @@ diff -Naur null/fs/aufs/file.c linux-6.6.84/fs/aufs/file.c + if (IS_ERR(h_file)) + goto out_br; + -+ if (flags & __FMODE_EXEC) { -+ err = deny_write_access(h_file); -+ if (unlikely(err)) { -+ fput(h_file); -+ h_file = ERR_PTR(err); -+ goto out_br; -+ } -+ } + fsnotify_open(h_file); + goto out; /* success */ + @@ -13944,11 +13952,11 @@ diff -Naur null/fs/aufs/file.c linux-6.6.84/fs/aufs/file.c +#ifdef CONFIG_AUFS_DEBUG +static int aufs_write_begin(struct file *file, struct address_space *mapping, + loff_t pos, unsigned len, -+ struct page **pagep, void **fsdata) ++ struct folio **foliop, void **fsdata) +{ AuUnsupport(); return 0; } +static int aufs_write_end(struct file *file, struct address_space *mapping, + loff_t pos, unsigned len, unsigned copied, -+ struct page *page, void *fsdata) ++ struct folio *folio, void *fsdata) +{ AuUnsupport(); return 0; } +static int aufs_writepage(struct page *page, struct writeback_control *wbc) +{ AuUnsupport(); return 0; } @@ -13972,8 +13980,8 @@ diff -Naur null/fs/aufs/file.c linux-6.6.84/fs/aufs/file.c +static void aufs_is_dirty_writeback(struct folio *folio, bool *dirty, + bool *writeback) +{ AuUnsupport(); } -+static int aufs_error_remove_page(struct address_space *mapping, -+ struct page *page) ++static int aufs_error_remove_folio(struct address_space *mapping, ++ struct folio *folio) +{ AuUnsupport(); return 0; } +static int aufs_swap_activate(struct swap_info_struct *sis, struct file *file, + sector_t *span) @@ -14002,15 +14010,15 @@ diff -Naur null/fs/aufs/file.c linux-6.6.84/fs/aufs/file.c + .launder_folio = aufs_launder_folio, + .is_partially_uptodate = aufs_is_partially_uptodate, + .is_dirty_writeback = aufs_is_dirty_writeback, -+ .error_remove_page = aufs_error_remove_page, ++ .error_remove_folio = aufs_error_remove_folio, + .swap_activate = aufs_swap_activate, + .swap_deactivate = aufs_swap_deactivate, + .swap_rw = aufs_swap_rw +#endif /* CONFIG_AUFS_DEBUG */ +}; -diff -Naur null/fs/aufs/file.h linux-6.6.84/fs/aufs/file.h +diff -Naur null/fs/aufs/file.h linux-6.12.30/fs/aufs/file.h --- /dev/null -+++ linux-6.6.84/fs/aufs/file.h 2025-04-18 18:38:35.883447987 +0300 ++++ linux-6.12.30/fs/aufs/file.h 2025-05-27 19:28:00.102257451 +0300 @@ -0,0 +1,342 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -14354,10 +14362,10 @@ diff -Naur null/fs/aufs/file.h linux-6.6.84/fs/aufs/file.h + +#endif /* __KERNEL__ */ +#endif /* __AUFS_FILE_H__ */ -diff -Naur null/fs/aufs/finfo.c linux-6.6.84/fs/aufs/finfo.c +diff -Naur null/fs/aufs/finfo.c linux-6.12.30/fs/aufs/finfo.c --- /dev/null -+++ linux-6.6.84/fs/aufs/finfo.c 2025-04-18 18:38:35.883447987 +0300 -@@ -0,0 +1,149 @@ ++++ linux-6.12.30/fs/aufs/finfo.c 2025-05-27 19:28:00.102257451 +0300 +@@ -0,0 +1,147 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005-2025 Junjiro R. Okajima @@ -14384,8 +14392,6 @@ diff -Naur null/fs/aufs/finfo.c linux-6.6.84/fs/aufs/finfo.c + +void au_hfput(struct au_hfile *hf, int execed) +{ -+ if (execed) -+ allow_write_access(hf->hf_file); + fput(hf->hf_file); + hf->hf_file = NULL; + au_lcnt_dec(&hf->hf_br->br_nfiles); @@ -14507,9 +14513,9 @@ diff -Naur null/fs/aufs/finfo.c linux-6.6.84/fs/aufs/finfo.c +out: + return err; +} -diff -Naur null/fs/aufs/f_op.c linux-6.6.84/fs/aufs/f_op.c +diff -Naur null/fs/aufs/f_op.c linux-6.12.30/fs/aufs/f_op.c --- /dev/null -+++ linux-6.6.84/fs/aufs/f_op.c 2025-04-18 18:38:35.883447987 +0300 ++++ linux-6.12.30/fs/aufs/f_op.c 2025-05-27 19:28:00.102257451 +0300 @@ -0,0 +1,782 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -15293,10 +15299,10 @@ diff -Naur null/fs/aufs/f_op.c linux-6.6.84/fs/aufs/f_op.c + .fallocate = aufs_fallocate, + .copy_file_range = aufs_copy_file_range +}; -diff -Naur null/fs/aufs/fsctx.c linux-6.6.84/fs/aufs/fsctx.c +diff -Naur null/fs/aufs/fsctx.c linux-6.12.30/fs/aufs/fsctx.c --- /dev/null -+++ linux-6.6.84/fs/aufs/fsctx.c 2025-04-18 18:38:35.883447987 +0300 -@@ -0,0 +1,1245 @@ ++++ linux-6.12.30/fs/aufs/fsctx.c 2025-05-27 19:28:00.103257438 +0300 +@@ -0,0 +1,1244 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022-2025 Junjiro R. Okajima @@ -15419,8 +15425,7 @@ diff -Naur null/fs/aufs/fsctx.c linux-6.6.84/fs/aufs/fsctx.c + au_sbilist_add(sb); + + /* all timestamps always follow the ones on the branch */ -+ sb->s_flags |= SB_NOATIME | SB_NODIRATIME; -+ sb->s_flags |= SB_I_VERSION; /* do we really need this? */ ++ sb->s_flags |= SB_NOATIME | SB_NODIRATIME | SB_I_VERSION; + sb->s_op = &aufs_sop; + sb->s_d_op = &aufs_dop; + sb->s_magic = AUFS_SUPER_MAGIC; @@ -16542,9 +16547,9 @@ diff -Naur null/fs/aufs/fsctx.c linux-6.6.84/fs/aufs/fsctx.c + AuTraceErr(err); + return err; +} -diff -Naur null/fs/aufs/fstype.h linux-6.6.84/fs/aufs/fstype.h +diff -Naur null/fs/aufs/fstype.h linux-6.12.30/fs/aufs/fstype.h --- /dev/null -+++ linux-6.6.84/fs/aufs/fstype.h 2025-04-18 18:38:35.883447987 +0300 ++++ linux-6.12.30/fs/aufs/fstype.h 2025-05-27 19:28:00.103257438 +0300 @@ -0,0 +1,419 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -16965,9 +16970,9 @@ diff -Naur null/fs/aufs/fstype.h linux-6.6.84/fs/aufs/fstype.h + +#endif /* __KERNEL__ */ +#endif /* __AUFS_FSTYPE_H__ */ -diff -Naur null/fs/aufs/hbl.h linux-6.6.84/fs/aufs/hbl.h +diff -Naur null/fs/aufs/hbl.h linux-6.12.30/fs/aufs/hbl.h --- /dev/null -+++ linux-6.6.84/fs/aufs/hbl.h 2025-04-18 18:38:35.884447975 +0300 ++++ linux-6.12.30/fs/aufs/hbl.h 2025-05-27 19:28:00.103257438 +0300 @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -17034,9 +17039,9 @@ diff -Naur null/fs/aufs/hbl.h linux-6.6.84/fs/aufs/hbl.h + +#endif /* __KERNEL__ */ +#endif /* __AUFS_HBL_H__ */ -diff -Naur null/fs/aufs/hfsnotify.c linux-6.6.84/fs/aufs/hfsnotify.c +diff -Naur null/fs/aufs/hfsnotify.c linux-6.12.30/fs/aufs/hfsnotify.c --- /dev/null -+++ linux-6.6.84/fs/aufs/hfsnotify.c 2025-04-18 18:38:35.884447975 +0300 ++++ linux-6.12.30/fs/aufs/hfsnotify.c 2025-05-27 19:28:00.103257438 +0300 @@ -0,0 +1,290 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -17328,9 +17333,9 @@ diff -Naur null/fs/aufs/hfsnotify.c linux-6.6.84/fs/aufs/hfsnotify.c + .fin_br = au_hfsn_fin_br, + .init_br = au_hfsn_init_br +}; -diff -Naur null/fs/aufs/hfsplus.c linux-6.6.84/fs/aufs/hfsplus.c +diff -Naur null/fs/aufs/hfsplus.c linux-6.12.30/fs/aufs/hfsplus.c --- /dev/null -+++ linux-6.6.84/fs/aufs/hfsplus.c 2025-04-18 18:38:35.884447975 +0300 ++++ linux-6.12.30/fs/aufs/hfsplus.c 2025-05-27 19:28:00.103257438 +0300 @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -17392,9 +17397,9 @@ diff -Naur null/fs/aufs/hfsplus.c linux-6.6.84/fs/aufs/hfsplus.c + au_lcnt_dec(&br->br_nfiles); + } +} -diff -Naur null/fs/aufs/hnotify.c linux-6.6.84/fs/aufs/hnotify.c +diff -Naur null/fs/aufs/hnotify.c linux-6.12.30/fs/aufs/hnotify.c --- /dev/null -+++ linux-6.6.84/fs/aufs/hnotify.c 2025-04-18 18:38:35.884447975 +0300 ++++ linux-6.12.30/fs/aufs/hnotify.c 2025-05-27 19:28:00.103257438 +0300 @@ -0,0 +1,715 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -17670,12 +17675,12 @@ diff -Naur null/fs/aufs/hnotify.c linux-6.6.84/fs/aufs/hnotify.c +/* ---------------------------------------------------------------------- */ + +/* hnotify job flags */ -+#define AuHnJob_XINO0 1 -+#define AuHnJob_GEN (1 << 1) -+#define AuHnJob_DIRENT (1 << 2) -+#define AuHnJob_ISDIR (1 << 3) -+#define AuHnJob_TRYXINO0 (1 << 4) -+#define AuHnJob_MNTPNT (1 << 5) ++#define AuHnJob_XINO0 BIT(0) ++#define AuHnJob_GEN BIT(1) ++#define AuHnJob_DIRENT BIT(2) ++#define AuHnJob_ISDIR BIT(3) ++#define AuHnJob_TRYXINO0 BIT(4) ++#define AuHnJob_MNTPNT BIT(5) +#define au_ftest_hnjob(flags, name) ((flags) & AuHnJob_##name) +#define au_fset_hnjob(flags, name) \ + do { (flags) |= AuHnJob_##name; } while (0) @@ -17768,7 +17773,7 @@ diff -Naur null/fs/aufs/hnotify.c linux-6.6.84/fs/aufs/hnotify.c + + dentry = NULL; + spin_lock(&parent->d_lock); -+ list_for_each_entry(d, &parent->d_subdirs, d_child) { ++ hlist_for_each_entry(d, &parent->d_children, d_sib) { + /* AuDbg("%pd\n", d); */ + spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED); + dname = &d->d_name; @@ -18111,9 +18116,9 @@ diff -Naur null/fs/aufs/hnotify.c linux-6.6.84/fs/aufs/hnotify.c + if (au_cache[AuCache_HNOTIFY]) + au_hn_destroy_cache(); +} -diff -Naur null/fs/aufs/iinfo.c linux-6.6.84/fs/aufs/iinfo.c +diff -Naur null/fs/aufs/iinfo.c linux-6.12.30/fs/aufs/iinfo.c --- /dev/null -+++ linux-6.6.84/fs/aufs/iinfo.c 2025-04-18 18:38:35.885447962 +0300 ++++ linux-6.12.30/fs/aufs/iinfo.c 2025-05-27 19:28:00.104257426 +0300 @@ -0,0 +1,287 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -18402,9 +18407,9 @@ diff -Naur null/fs/aufs/iinfo.c linux-6.6.84/fs/aufs/iinfo.c + au_kfree_rcu(iinfo->ii_hinode); + AuRwDestroy(&iinfo->ii_rwsem); +} -diff -Naur null/fs/aufs/inode.c linux-6.6.84/fs/aufs/inode.c +diff -Naur null/fs/aufs/inode.c linux-6.12.30/fs/aufs/inode.c --- /dev/null -+++ linux-6.6.84/fs/aufs/inode.c 2025-04-18 18:38:35.885447962 +0300 ++++ linux-6.12.30/fs/aufs/inode.c 2025-05-27 19:28:00.104257426 +0300 @@ -0,0 +1,532 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -18710,7 +18715,7 @@ diff -Naur null/fs/aufs/inode.c linux-6.6.84/fs/aufs/inode.c + * it can happen by UDBA and the obsoleted inode number. + */ + err = -EIO; -+ if (unlikely(inode->i_ino == parent_ino(dentry))) ++ if (unlikely(inode->i_ino == d_parent_ino(dentry))) + goto out; + + err = 1; @@ -18825,7 +18830,7 @@ diff -Naur null/fs/aufs/inode.c linux-6.6.84/fs/aufs/inode.c + if (IS_ERR(inode)) + goto out_xinondir; + -+ AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW)); ++ AuDbg("%x, new %d\n", inode->i_state, !!(inode->i_state & I_NEW)); + if (inode->i_state & I_NEW) { + ii_write_lock_new_child(inode); + err = set_inode(inode, dentry); @@ -18938,9 +18943,9 @@ diff -Naur null/fs/aufs/inode.c linux-6.6.84/fs/aufs/inode.c + mask |= MAY_READ; /* force permission check */ + return au_test_h_perm(h_idmap, h_inode, mask); +} -diff -Naur null/fs/aufs/inode.h linux-6.6.84/fs/aufs/inode.h +diff -Naur null/fs/aufs/inode.h linux-6.12.30/fs/aufs/inode.h --- /dev/null -+++ linux-6.6.84/fs/aufs/inode.h 2025-04-18 18:38:35.885447962 +0300 ++++ linux-6.12.30/fs/aufs/inode.h 2025-05-27 19:28:00.105257413 +0300 @@ -0,0 +1,727 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -19031,8 +19036,8 @@ diff -Naur null/fs/aufs/inode.h linux-6.6.84/fs/aufs/inode.h +} ____cacheline_aligned_in_smp; + +/* au_pin flags */ -+#define AuPin_DI_LOCKED 1 -+#define AuPin_MNT_WRITE (1 << 1) ++#define AuPin_DI_LOCKED BIT(0) ++#define AuPin_MNT_WRITE BIT(1) +#define au_ftest_pin(flags, name) ((flags) & AuPin_##name) +#define au_fset_pin(flags, name) \ + do { (flags) |= AuPin_##name; } while (0) @@ -19127,9 +19132,9 @@ diff -Naur null/fs/aufs/inode.h linux-6.6.84/fs/aufs/inode.h + aufs_iop_nogetattr[AuIop_Last]; + +/* au_wr_dir flags */ -+#define AuWrDir_ADD_ENTRY 1 -+#define AuWrDir_ISDIR (1 << 1) -+#define AuWrDir_TMPFILE (1 << 2) ++#define AuWrDir_ADD_ENTRY BIT(0) ++#define AuWrDir_ISDIR BIT(1) ++#define AuWrDir_TMPFILE BIT(2) +#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name) +#define au_fset_wrdir(flags, name) \ + do { (flags) |= AuWrDir_##name; } while (0) @@ -19217,8 +19222,8 @@ diff -Naur null/fs/aufs/inode.h linux-6.6.84/fs/aufs/inode.h +unsigned int au_hi_flags(struct inode *inode, int isdir); + +/* hinode flags */ -+#define AuHi_XINO 1 -+#define AuHi_HNOTIFY (1 << 1) ++#define AuHi_XINO BIT(0) ++#define AuHi_HNOTIFY BIT(1) +#define au_ftest_hi(flags, name) ((flags) & AuHi_##name) +#define au_fset_hi(flags, name) \ + do { (flags) |= AuHi_##name; } while (0) @@ -19669,9 +19674,9 @@ diff -Naur null/fs/aufs/inode.h linux-6.6.84/fs/aufs/inode.h + +#endif /* __KERNEL__ */ +#endif /* __AUFS_INODE_H__ */ -diff -Naur null/fs/aufs/ioctl.c linux-6.6.84/fs/aufs/ioctl.c +diff -Naur null/fs/aufs/ioctl.c linux-6.12.30/fs/aufs/ioctl.c --- /dev/null -+++ linux-6.6.84/fs/aufs/ioctl.c 2025-04-18 18:38:35.885447962 +0300 ++++ linux-6.12.30/fs/aufs/ioctl.c 2025-05-27 19:28:00.105257413 +0300 @@ -0,0 +1,220 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -19893,9 +19898,9 @@ diff -Naur null/fs/aufs/ioctl.c linux-6.6.84/fs/aufs/ioctl.c + return aufs_ioctl_nondir(file, cmd, (unsigned long)compat_ptr(arg)); +} +#endif -diff -Naur null/fs/aufs/i_op_add.c linux-6.6.84/fs/aufs/i_op_add.c +diff -Naur null/fs/aufs/i_op_add.c linux-6.12.30/fs/aufs/i_op_add.c --- /dev/null -+++ linux-6.6.84/fs/aufs/i_op_add.c 2025-04-18 18:38:35.884447975 +0300 ++++ linux-6.12.30/fs/aufs/i_op_add.c 2025-05-27 19:28:00.104257426 +0300 @@ -0,0 +1,971 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -20868,10 +20873,10 @@ diff -Naur null/fs/aufs/i_op_add.c linux-6.6.84/fs/aufs/i_op_add.c +out: + return err; +} -diff -Naur null/fs/aufs/i_op.c linux-6.6.84/fs/aufs/i_op.c +diff -Naur null/fs/aufs/i_op.c linux-6.12.30/fs/aufs/i_op.c --- /dev/null -+++ linux-6.6.84/fs/aufs/i_op.c 2025-04-18 18:38:35.884447975 +0300 -@@ -0,0 +1,1520 @@ ++++ linux-6.12.30/fs/aufs/i_op.c 2025-05-27 19:28:00.104257426 +0300 +@@ -0,0 +1,1526 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005-2025 Junjiro R. Okajima @@ -21512,7 +21517,13 @@ diff -Naur null/fs/aufs/i_op.c linux-6.6.84/fs/aufs/i_op.c + +static void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task) +{ ++ AuRwMustWriteLock(&p->hdir->hi_inode->i_rwsem); ++#ifndef CONFIG_PREEMPT_RT + atomic_long_set(&p->hdir->hi_inode->i_rwsem.owner, (long)task); ++#else ++ p->hdir->hi_inode->i_rwsem.rwbase.rtmutex.owner = task; ++ smp_mb(); /* advertise the owner */ ++#endif +} + +void au_pin_hdir_acquire_nest(struct au_pin *p) @@ -22041,8 +22052,8 @@ diff -Naur null/fs/aufs/i_op.c linux-6.6.84/fs/aufs/i_op.c + /* don't i_[ug]id_write() here */ + inode->i_uid = st->uid; + inode->i_gid = st->gid; -+ inode->i_atime = st->atime; -+ inode->i_mtime = st->mtime; ++ inode_set_atime_to_ts(inode, st->atime); ++ inode_set_mtime_to_ts(inode, st->mtime); + inode_set_ctime_to_ts(inode, st->ctime); + + au_cpup_attr_nlink(inode, /*force*/0); @@ -22392,9 +22403,9 @@ diff -Naur null/fs/aufs/i_op.c linux-6.6.84/fs/aufs/i_op.c + .update_time = aufs_update_time + } +}; -diff -Naur null/fs/aufs/i_op_del.c linux-6.6.84/fs/aufs/i_op_del.c +diff -Naur null/fs/aufs/i_op_del.c linux-6.12.30/fs/aufs/i_op_del.c --- /dev/null -+++ linux-6.6.84/fs/aufs/i_op_del.c 2025-04-18 18:38:35.884447975 +0300 ++++ linux-6.12.30/fs/aufs/i_op_del.c 2025-05-27 19:28:00.104257426 +0300 @@ -0,0 +1,523 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -22919,10 +22930,10 @@ diff -Naur null/fs/aufs/i_op_del.c linux-6.6.84/fs/aufs/i_op_del.c + AuTraceErr(err); + return err; +} -diff -Naur null/fs/aufs/i_op_ren.c linux-6.6.84/fs/aufs/i_op_ren.c +diff -Naur null/fs/aufs/i_op_ren.c linux-6.12.30/fs/aufs/i_op_ren.c --- /dev/null -+++ linux-6.6.84/fs/aufs/i_op_ren.c 2025-04-18 18:38:35.885447962 +0300 -@@ -0,0 +1,1260 @@ ++++ linux-6.12.30/fs/aufs/i_op_ren.c 2025-05-27 19:28:00.104257426 +0300 +@@ -0,0 +1,1264 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005-2025 Junjiro R. Okajima @@ -22952,18 +22963,18 @@ diff -Naur null/fs/aufs/i_op_ren.c linux-6.6.84/fs/aufs/i_op_ren.c +enum { AuSRC, AuDST, AuSrcDst }; +enum { AuPARENT, AuCHILD, AuParentChild }; + -+#define AuRen_ISDIR_SRC 1 -+#define AuRen_ISDIR_DST (1 << 1) -+#define AuRen_ISSAMEDIR (1 << 2) -+#define AuRen_WHSRC (1 << 3) -+#define AuRen_WHDST (1 << 4) -+#define AuRen_MNT_WRITE (1 << 5) -+#define AuRen_DT_DSTDIR (1 << 6) -+#define AuRen_DIROPQ_SRC (1 << 7) -+#define AuRen_DIROPQ_DST (1 << 8) -+#define AuRen_DIRREN (1 << 9) -+#define AuRen_DROPPED_SRC (1 << 10) -+#define AuRen_DROPPED_DST (1 << 11) ++#define AuRen_ISDIR_SRC BIT(0) ++#define AuRen_ISDIR_DST BIT(1) ++#define AuRen_ISSAMEDIR BIT(2) ++#define AuRen_WHSRC BIT(3) ++#define AuRen_WHDST BIT(4) ++#define AuRen_MNT_WRITE BIT(5) ++#define AuRen_DT_DSTDIR BIT(6) ++#define AuRen_DIROPQ_SRC BIT(7) ++#define AuRen_DIROPQ_DST BIT(8) ++#define AuRen_DIRREN BIT(9) ++#define AuRen_DROPPED_SRC BIT(10) ++#define AuRen_DROPPED_DST BIT(11) +#define au_ftest_ren(flags, name) ((flags) & AuRen_##name) +#define au_fset_ren(flags, name) \ + do { (flags) |= AuRen_##name; } while (0) @@ -23658,6 +23669,10 @@ diff -Naur null/fs/aufs/i_op_ren.c linux-6.6.84/fs/aufs/i_op_ren.c + } + a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir, + a->dst_h_parent, a->dst_hdir); ++ if (IS_ERR(a->h_trap)) { ++ err = PTR_ERR(a->h_trap); ++ goto out; ++ } + udba = au_opt_udba(a->src_dentry->d_sb); + if (unlikely(a->src_hdir->hi_inode != d_inode(a->src_h_parent) + || a->dst_hdir->hi_inode != d_inode(a->dst_h_parent))) @@ -24183,10 +24198,10 @@ diff -Naur null/fs/aufs/i_op_ren.c linux-6.6.84/fs/aufs/i_op_ren.c + AuTraceErr(err); + return err; +} -diff -Naur null/fs/aufs/Kconfig linux-6.6.84/fs/aufs/Kconfig +diff -Naur null/fs/aufs/Kconfig linux-6.12.30/fs/aufs/Kconfig --- /dev/null -+++ linux-6.6.84/fs/aufs/Kconfig 2025-04-18 18:38:35.880448025 +0300 -@@ -0,0 +1,199 @@ ++++ linux-6.12.30/fs/aufs/Kconfig 2025-05-27 19:28:00.099257488 +0300 +@@ -0,0 +1,201 @@ +# SPDX-License-Identifier: GPL-2.0 +config AUFS_FS + tristate "Aufs (Advanced multi layered unification filesystem) support" @@ -24251,13 +24266,15 @@ diff -Naur null/fs/aufs/Kconfig linux-6.6.84/fs/aufs/Kconfig + It will have a negative impact to the performance. + See detail in aufs.5. + ++if AUFS_HNOTIFY +choice -+ prompt "method" if AUFS_HNOTIFY ++ prompt "method" + default AUFS_HFSNOTIFY +config AUFS_HFSNOTIFY + bool "fsnotify" + select FSNOTIFY +endchoice ++endif + +config AUFS_EXPORT + bool "NFS-exportable aufs" @@ -24386,9 +24403,9 @@ diff -Naur null/fs/aufs/Kconfig linux-6.6.84/fs/aufs/Kconfig + Automatic configuration for internal use. + When aufs supports Magic SysRq, enabled automatically. +endif -diff -Naur null/fs/aufs/lcnt.h linux-6.6.84/fs/aufs/lcnt.h +diff -Naur null/fs/aufs/lcnt.h linux-6.12.30/fs/aufs/lcnt.h --- /dev/null -+++ linux-6.6.84/fs/aufs/lcnt.h 2025-04-18 18:38:35.885447962 +0300 ++++ linux-6.12.30/fs/aufs/lcnt.h 2025-05-27 19:28:00.105257413 +0300 @@ -0,0 +1,186 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -24576,9 +24593,9 @@ diff -Naur null/fs/aufs/lcnt.h linux-6.6.84/fs/aufs/lcnt.h + +#endif /* __KERNEL__ */ +#endif /* __AUFS_LCNT_H__ */ -diff -Naur null/fs/aufs/loop.c linux-6.6.84/fs/aufs/loop.c +diff -Naur null/fs/aufs/loop.c linux-6.12.30/fs/aufs/loop.c --- /dev/null -+++ linux-6.6.84/fs/aufs/loop.c 2025-04-18 18:38:35.885447962 +0300 ++++ linux-6.12.30/fs/aufs/loop.c 2025-05-27 19:28:00.105257413 +0300 @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -24728,9 +24745,9 @@ diff -Naur null/fs/aufs/loop.c linux-6.6.84/fs/aufs/loop.c + symbol_put(loop_backing_file); + au_kfree_try_rcu(au_warn_loopback_array); +} -diff -Naur null/fs/aufs/loop.h linux-6.6.84/fs/aufs/loop.h +diff -Naur null/fs/aufs/loop.h linux-6.12.30/fs/aufs/loop.h --- /dev/null -+++ linux-6.6.84/fs/aufs/loop.h 2025-04-18 18:38:35.885447962 +0300 ++++ linux-6.12.30/fs/aufs/loop.h 2025-05-27 19:28:00.105257413 +0300 @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -24787,9 +24804,9 @@ diff -Naur null/fs/aufs/loop.h linux-6.6.84/fs/aufs/loop.h + +#endif /* __KERNEL__ */ +#endif /* __AUFS_LOOP_H__ */ -diff -Naur null/fs/aufs/magic.mk linux-6.6.84/fs/aufs/magic.mk +diff -Naur null/fs/aufs/magic.mk linux-6.12.30/fs/aufs/magic.mk --- /dev/null -+++ linux-6.6.84/fs/aufs/magic.mk 2025-04-18 18:38:35.885447962 +0300 ++++ linux-6.12.30/fs/aufs/magic.mk 2025-05-27 19:28:00.105257413 +0300 @@ -0,0 +1,31 @@ +# SPDX-License-Identifier: GPL-2.0 + @@ -24822,9 +24839,9 @@ diff -Naur null/fs/aufs/magic.mk linux-6.6.84/fs/aufs/magic.mk +ifdef CONFIG_HFSPLUS_FS +ccflags-y += -DHFSPLUS_SUPER_MAGIC=0x482b +endif -diff -Naur null/fs/aufs/Makefile linux-6.6.84/fs/aufs/Makefile +diff -Naur null/fs/aufs/Makefile linux-6.12.30/fs/aufs/Makefile --- /dev/null -+++ linux-6.6.84/fs/aufs/Makefile 2025-04-18 18:38:35.880448025 +0300 ++++ linux-6.12.30/fs/aufs/Makefile 2025-05-27 19:28:00.099257488 +0300 @@ -0,0 +1,46 @@ +# SPDX-License-Identifier: GPL-2.0 + @@ -24872,9 +24889,9 @@ diff -Naur null/fs/aufs/Makefile linux-6.6.84/fs/aufs/Makefile +aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o +aufs-$(CONFIG_AUFS_DEBUG) += debug.o +aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o -diff -Naur null/fs/aufs/module.c linux-6.6.84/fs/aufs/module.c +diff -Naur null/fs/aufs/module.c linux-6.12.30/fs/aufs/module.c --- /dev/null -+++ linux-6.6.84/fs/aufs/module.c 2025-04-18 18:38:35.885447962 +0300 ++++ linux-6.12.30/fs/aufs/module.c 2025-05-27 19:28:00.105257413 +0300 @@ -0,0 +1,275 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -25151,9 +25168,9 @@ diff -Naur null/fs/aufs/module.c linux-6.6.84/fs/aufs/module.c + +module_init(aufs_init); +module_exit(aufs_exit); -diff -Naur null/fs/aufs/module.h linux-6.6.84/fs/aufs/module.h +diff -Naur null/fs/aufs/module.h linux-6.12.30/fs/aufs/module.h --- /dev/null -+++ linux-6.6.84/fs/aufs/module.h 2025-04-18 18:38:35.886447950 +0300 ++++ linux-6.12.30/fs/aufs/module.h 2025-05-27 19:28:00.105257413 +0300 @@ -0,0 +1,180 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -25286,7 +25303,7 @@ diff -Naur null/fs/aufs/module.h linux-6.6.84/fs/aufs/module.h + +extern struct kmem_cache *au_cache[AuCache_Last]; + -+#define AuCacheFlags (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD) ++#define AuCacheFlags SLAB_RECLAIM_ACCOUNT +#define AuCache(type) KMEM_CACHE(type, AuCacheFlags) +#define AuCacheCtor(type, ctor) \ + kmem_cache_create(#type, sizeof(struct type), \ @@ -25335,10 +25352,10 @@ diff -Naur null/fs/aufs/module.h linux-6.6.84/fs/aufs/module.h + +#endif /* __KERNEL__ */ +#endif /* __AUFS_MODULE_H__ */ -diff -Naur null/fs/aufs/mvdown.c linux-6.6.84/fs/aufs/mvdown.c +diff -Naur null/fs/aufs/mvdown.c linux-6.12.30/fs/aufs/mvdown.c --- /dev/null -+++ linux-6.6.84/fs/aufs/mvdown.c 2025-04-18 18:38:35.886447950 +0300 -@@ -0,0 +1,707 @@ ++++ linux-6.12.30/fs/aufs/mvdown.c 2025-05-27 19:28:00.105257413 +0300 +@@ -0,0 +1,714 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2011-2025 Junjiro R. Okajima @@ -25515,6 +25532,13 @@ diff -Naur null/fs/aufs/mvdown.c linux-6.6.84/fs/aufs/mvdown.c + au_pin_hdir_unlock(&a->mvd_pin_src); + h_trap = vfsub_lock_rename(a->mvd_h_src_parent, a->mvd_hdir_src, + a->mvd_h_dst_parent, a->mvd_hdir_dst); ++ if (IS_ERR(h_trap)) { ++ err = PTR_ERR(h_trap); ++ au_pin_hdir_lock(&a->mvd_pin_src); ++ au_unpin(&a->mvd_pin_src); ++ au_pin_hdir_lock(&a->mvd_pin_dst); ++ goto out_dst; ++ } + if (h_trap) { + err = (h_trap != a->mvd_h_src_parent); + if (err) @@ -26046,10 +26070,10 @@ diff -Naur null/fs/aufs/mvdown.c linux-6.6.84/fs/aufs/mvdown.c + AuTraceErr(err); + return err; +} -diff -Naur null/fs/aufs/opts.c linux-6.6.84/fs/aufs/opts.c +diff -Naur null/fs/aufs/opts.c linux-6.12.30/fs/aufs/opts.c --- /dev/null -+++ linux-6.6.84/fs/aufs/opts.c 2025-04-18 18:38:35.886447950 +0300 -@@ -0,0 +1,1032 @@ ++++ linux-6.12.30/fs/aufs/opts.c 2025-05-27 19:28:00.105257413 +0300 +@@ -0,0 +1,1030 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005-2025 Junjiro R. Okajima @@ -26561,10 +26585,8 @@ diff -Naur null/fs/aufs/opts.c linux-6.6.84/fs/aufs/opts.c + if (opt->tf) { + au_opt_set(sbinfo->si_mntflags, DIO); + au_fset_opts(opts->flags, REFRESH_DYAOP); -+ } else { -+ au_opt_clr(sbinfo->si_mntflags, DIO); -+ au_fset_opts(opts->flags, REFRESH_DYAOP); -+ } ++ } else ++ pr_warn_once("ignored nodio\n"); + break; + + case Opt_fhsm_sec: @@ -27082,10 +27104,10 @@ diff -Naur null/fs/aufs/opts.c linux-6.6.84/fs/aufs/opts.c +{ + return au_mntflags(sb) & AuOptMask_UDBA; +} -diff -Naur null/fs/aufs/opts.h linux-6.6.84/fs/aufs/opts.h +diff -Naur null/fs/aufs/opts.h linux-6.12.30/fs/aufs/opts.h --- /dev/null -+++ linux-6.6.84/fs/aufs/opts.h 2025-04-18 18:38:35.886447950 +0300 -@@ -0,0 +1,263 @@ ++++ linux-6.12.30/fs/aufs/opts.h 2025-05-27 19:28:00.105257413 +0300 +@@ -0,0 +1,264 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2005-2025 Junjiro R. Okajima @@ -27145,23 +27167,23 @@ diff -Naur null/fs/aufs/opts.h linux-6.6.84/fs/aufs/opts.h +/* ---------------------------------------------------------------------- */ + +/* mount flags */ -+#define AuOpt_XINO 1 /* external inode number bitmap ++#define AuOpt_XINO BIT(0) /* external inode number bitmap + and translation table */ -+#define AuOpt_TRUNC_XINO (1 << 1) /* truncate xino files */ -+#define AuOpt_UDBA_NONE (1 << 2) /* users direct branch access */ -+#define AuOpt_UDBA_REVAL (1 << 3) -+#define AuOpt_UDBA_HNOTIFY (1 << 4) -+#define AuOpt_SHWH (1 << 5) /* show whiteout */ -+#define AuOpt_PLINK (1 << 6) /* pseudo-link */ -+#define AuOpt_DIRPERM1 (1 << 7) /* ignore the lower dir's perm ++#define AuOpt_TRUNC_XINO BIT(1) /* truncate xino files */ ++#define AuOpt_UDBA_NONE BIT(2) /* users direct branch access */ ++#define AuOpt_UDBA_REVAL BIT(3) ++#define AuOpt_UDBA_HNOTIFY BIT(4) ++#define AuOpt_SHWH BIT(5) /* show whiteout */ ++#define AuOpt_PLINK BIT(6) /* pseudo-link */ ++#define AuOpt_DIRPERM1 BIT(7) /* ignore the lower dir's perm + bits */ -+#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 */ -+#define AuOpt_WARN_PERM (1 << 12) /* warn when add-branch */ -+#define AuOpt_VERBOSE (1 << 13) /* print the cause of error */ -+#define AuOpt_DIO (1 << 14) /* direct io */ -+#define AuOpt_DIRREN (1 << 15) /* directory rename */ ++#define AuOpt_ALWAYS_DIROPQ BIT(8) /* policy to creating diropq */ ++#define AuOpt_SUM BIT(9) /* summation for statfs(2) */ ++#define AuOpt_SUM_W BIT(10) /* unimplemented */ ++#define AuOpt_WARN_PERM BIT(11) /* warn when add-branch */ ++#define AuOpt_VERBOSE BIT(12) /* print the cause of error */ ++#define AuOpt_DIO BIT(13) /* direct io */ ++#define AuOpt_DIRREN BIT(14) /* directory rename */ + +#ifndef CONFIG_AUFS_HNOTIFY +#undef AuOpt_UDBA_HNOTIFY @@ -27180,7 +27202,8 @@ diff -Naur null/fs/aufs/opts.h linux-6.6.84/fs/aufs/opts.h + | AuOpt_UDBA_REVAL \ + | AuOpt_PLINK \ + /* | AuOpt_DIRPERM1 */ \ -+ | AuOpt_WARN_PERM) ++ | AuOpt_WARN_PERM \ ++ | AuOpt_DIO) +#define AuOptMask_UDBA (AuOpt_UDBA_NONE \ + | AuOpt_UDBA_REVAL \ + | AuOpt_UDBA_HNOTIFY) @@ -27295,12 +27318,12 @@ diff -Naur null/fs/aufs/opts.h linux-6.6.84/fs/aufs/opts.h +}; + +/* opts flags */ -+#define AuOpts_REMOUNT 1 -+#define AuOpts_REFRESH (1 << 1) -+#define AuOpts_TRUNC_XIB (1 << 2) -+#define AuOpts_REFRESH_DYAOP (1 << 3) -+#define AuOpts_REFRESH_IDOP (1 << 4) -+#define AuOpts_DR_FLUSHED (1 << 5) ++#define AuOpts_REMOUNT BIT(0) ++#define AuOpts_REFRESH BIT(1) ++#define AuOpts_TRUNC_XIB BIT(2) ++#define AuOpts_REFRESH_DYAOP BIT(3) ++#define AuOpts_REFRESH_IDOP BIT(4) ++#define AuOpts_DR_FLUSHED BIT(5) +#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name) +#define au_fset_opts(flags, name) \ + do { (flags) |= AuOpts_##name; } while (0) @@ -27349,9 +27372,9 @@ diff -Naur null/fs/aufs/opts.h linux-6.6.84/fs/aufs/opts.h + +#endif /* __KERNEL__ */ +#endif /* __AUFS_OPTS_H__ */ -diff -Naur null/fs/aufs/plink.c linux-6.6.84/fs/aufs/plink.c +diff -Naur null/fs/aufs/plink.c linux-6.12.30/fs/aufs/plink.c --- /dev/null -+++ linux-6.6.84/fs/aufs/plink.c 2025-04-18 18:38:35.886447950 +0300 ++++ linux-6.12.30/fs/aufs/plink.c 2025-05-27 19:28:00.106257401 +0300 @@ -0,0 +1,516 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -27869,9 +27892,9 @@ diff -Naur null/fs/aufs/plink.c linux-6.6.84/fs/aufs/plink.c + } + } +} -diff -Naur null/fs/aufs/poll.c linux-6.6.84/fs/aufs/poll.c +diff -Naur null/fs/aufs/poll.c linux-6.12.30/fs/aufs/poll.c --- /dev/null -+++ linux-6.6.84/fs/aufs/poll.c 2025-04-18 18:38:35.886447950 +0300 ++++ linux-6.12.30/fs/aufs/poll.c 2025-05-27 19:28:00.106257401 +0300 @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -27924,9 +27947,9 @@ diff -Naur null/fs/aufs/poll.c linux-6.6.84/fs/aufs/poll.c + AuDbg("mask 0x%x\n", mask); + return mask; +} -diff -Naur null/fs/aufs/posix_acl.c linux-6.6.84/fs/aufs/posix_acl.c +diff -Naur null/fs/aufs/posix_acl.c linux-6.12.30/fs/aufs/posix_acl.c --- /dev/null -+++ linux-6.6.84/fs/aufs/posix_acl.c 2025-04-18 18:38:35.886447950 +0300 ++++ linux-6.12.30/fs/aufs/posix_acl.c 2025-05-27 19:28:00.106257401 +0300 @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -28036,9 +28059,9 @@ diff -Naur null/fs/aufs/posix_acl.c linux-6.6.84/fs/aufs/posix_acl.c + + return err; +} -diff -Naur null/fs/aufs/procfs.c linux-6.6.84/fs/aufs/procfs.c +diff -Naur null/fs/aufs/procfs.c linux-6.12.30/fs/aufs/procfs.c --- /dev/null -+++ linux-6.6.84/fs/aufs/procfs.c 2025-04-18 18:38:35.886447950 +0300 ++++ linux-6.12.30/fs/aufs/procfs.c 2025-05-27 19:28:00.106257401 +0300 @@ -0,0 +1,168 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -28208,9 +28231,9 @@ diff -Naur null/fs/aufs/procfs.c linux-6.6.84/fs/aufs/procfs.c +out: + return err; +} -diff -Naur null/fs/aufs/rdu.c linux-6.6.84/fs/aufs/rdu.c +diff -Naur null/fs/aufs/rdu.c linux-6.12.30/fs/aufs/rdu.c --- /dev/null -+++ linux-6.6.84/fs/aufs/rdu.c 2025-04-18 18:38:35.886447950 +0300 ++++ linux-6.12.30/fs/aufs/rdu.c 2025-05-27 19:28:00.106257401 +0300 @@ -0,0 +1,384 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -28240,9 +28263,9 @@ diff -Naur null/fs/aufs/rdu.c linux-6.6.84/fs/aufs/rdu.c +#include "aufs.h" + +/* bits for struct aufs_rdu.flags */ -+#define AuRdu_CALLED 1 -+#define AuRdu_CONT (1 << 1) -+#define AuRdu_FULL (1 << 2) ++#define AuRdu_CALLED BIT(0) ++#define AuRdu_CONT BIT(1) ++#define AuRdu_FULL BIT(2) +#define au_ftest_rdu(flags, name) ((flags) & AuRdu_##name) +#define au_fset_rdu(flags, name) \ + do { (flags) |= AuRdu_##name; } while (0) @@ -28596,10 +28619,10 @@ diff -Naur null/fs/aufs/rdu.c linux-6.6.84/fs/aufs/rdu.c + return err; +} +#endif -diff -Naur null/fs/aufs/rwsem.h linux-6.6.84/fs/aufs/rwsem.h +diff -Naur null/fs/aufs/rwsem.h linux-6.12.30/fs/aufs/rwsem.h --- /dev/null -+++ linux-6.6.84/fs/aufs/rwsem.h 2025-04-18 18:38:35.886447950 +0300 -@@ -0,0 +1,85 @@ ++++ linux-6.12.30/fs/aufs/rwsem.h 2025-05-27 19:28:00.106257401 +0300 +@@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2005-2025 Junjiro R. Okajima @@ -28633,7 +28656,11 @@ diff -Naur null/fs/aufs/rwsem.h linux-6.6.84/fs/aufs/rwsem.h +#define au_rwsem rw_semaphore + +/* to debug easier, do not make them inlined functions */ ++#ifndef CONFIG_PREEMPT_RT +#define AuRwMustNoWaiters(rw) AuDebugOn(rwsem_is_contended(rw)) ++#else ++AuStubVoid(AuRwMustNoWaiters, struct rw_semaphore *rw) ++#endif + +#ifdef CONFIG_LOCKDEP +/* rwsem_is_locked() is unusable */ @@ -28685,9 +28712,9 @@ diff -Naur null/fs/aufs/rwsem.h linux-6.6.84/fs/aufs/rwsem.h + +#endif /* __KERNEL__ */ +#endif /* __AUFS_RWSEM_H__ */ -diff -Naur null/fs/aufs/sbinfo.c linux-6.6.84/fs/aufs/sbinfo.c +diff -Naur null/fs/aufs/sbinfo.c linux-6.12.30/fs/aufs/sbinfo.c --- /dev/null -+++ linux-6.6.84/fs/aufs/sbinfo.c 2025-04-18 18:38:35.886447950 +0300 ++++ linux-6.12.30/fs/aufs/sbinfo.c 2025-05-27 19:28:00.106257401 +0300 @@ -0,0 +1,316 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -29005,9 +29032,9 @@ diff -Naur null/fs/aufs/sbinfo.c linux-6.6.84/fs/aufs/sbinfo.c + di_write_unlock2(d1, d2); + si_read_unlock(d1->d_sb); +} -diff -Naur null/fs/aufs/super.c linux-6.6.84/fs/aufs/super.c +diff -Naur null/fs/aufs/super.c linux-6.12.30/fs/aufs/super.c --- /dev/null -+++ linux-6.6.84/fs/aufs/super.c 2025-04-18 18:38:35.887447937 +0300 ++++ linux-6.12.30/fs/aufs/super.c 2025-05-27 19:28:00.106257401 +0300 @@ -0,0 +1,871 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -29880,9 +29907,9 @@ diff -Naur null/fs/aufs/super.c linux-6.6.84/fs/aufs/super.c + /* no need to __module_get() and module_put(). */ + .owner = THIS_MODULE, +}; -diff -Naur null/fs/aufs/super.h linux-6.6.84/fs/aufs/super.h +diff -Naur null/fs/aufs/super.h linux-6.12.30/fs/aufs/super.h --- /dev/null -+++ linux-6.6.84/fs/aufs/super.h 2025-04-18 18:38:35.887447937 +0300 ++++ linux-6.12.30/fs/aufs/super.h 2025-05-27 19:28:00.106257401 +0300 @@ -0,0 +1,618 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -29923,8 +29950,8 @@ diff -Naur null/fs/aufs/super.h linux-6.6.84/fs/aufs/super.h + int (*copyup)(struct dentry *dentry); +}; + -+#define AuWbr_DIR 1 /* target is a dir */ -+#define AuWbr_PARENT (1 << 1) /* always require a parent */ ++#define AuWbr_DIR BIT(0) /* target is a dir */ ++#define AuWbr_PARENT BIT(1) /* always require a parent */ + +#define au_ftest_wbr(flags, name) ((flags) & AuWbr_##name) +#define au_fset_wbr(flags, name) { (flags) |= AuWbr_##name; } @@ -30095,9 +30122,9 @@ diff -Naur null/fs/aufs/super.h linux-6.6.84/fs/aufs/super.h + * then try refreshing dirs at access time again. + * if it is false, refreshing dirs at access time is unnecessary + */ -+#define AuSi_FAILED_REFRESH_DIR 1 -+#define AuSi_FHSM (1 << 1) /* fhsm is active now */ -+#define AuSi_NO_DREVAL (1 << 2) /* disable all d_revalidate */ ++#define AuSi_FAILED_REFRESH_DIR BIT(0) ++#define AuSi_FHSM BIT(1) /* fhsm is active now */ ++#define AuSi_NO_DREVAL BIT(2) /* disable all d_revalidate */ + +#ifndef CONFIG_AUFS_FHSM +#undef AuSi_FHSM @@ -30129,15 +30156,15 @@ diff -Naur null/fs/aufs/super.h linux-6.6.84/fs/aufs/super.h + ((sbinfo)->si_wbr_create_ops->create(__VA_ARGS__)) + +/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */ -+#define AuLock_DW 1 /* write-lock dentry */ -+#define AuLock_IR (1 << 1) /* read-lock inode */ -+#define AuLock_IW (1 << 2) /* write-lock inode */ -+#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */ -+#define AuLock_DIRS (1 << 4) /* target is a pair of dirs */ ++#define AuLock_DW BIT(0) /* write-lock dentry */ ++#define AuLock_IR BIT(1) /* read-lock inode */ ++#define AuLock_IW BIT(2) /* write-lock inode */ ++#define AuLock_FLUSH BIT(3) /* wait for 'nowait' tasks */ ++#define AuLock_DIRS BIT(4) /* target is a pair of dirs */ + /* except RENAME_EXCHANGE */ -+#define AuLock_NOPLM (1 << 5) /* return err in plm mode */ -+#define AuLock_NOPLMW (1 << 6) /* wait for plm mode ends */ -+#define AuLock_GEN (1 << 7) /* test digen/iigen */ ++#define AuLock_NOPLM BIT(5) /* return err in plm mode */ ++#define AuLock_NOPLMW BIT(6) /* wait for plm mode ends */ ++#define AuLock_GEN BIT(7) /* test digen/iigen */ +#define au_ftest_lock(flags, name) ((flags) & AuLock_##name) +#define au_fset_lock(flags, name) \ + do { (flags) |= AuLock_##name; } while (0) @@ -30502,9 +30529,9 @@ diff -Naur null/fs/aufs/super.h linux-6.6.84/fs/aufs/super.h + +#endif /* __KERNEL__ */ +#endif /* __AUFS_SUPER_H__ */ -diff -Naur null/fs/aufs/sysaufs.c linux-6.6.84/fs/aufs/sysaufs.c +diff -Naur null/fs/aufs/sysaufs.c linux-6.12.30/fs/aufs/sysaufs.c --- /dev/null -+++ linux-6.6.84/fs/aufs/sysaufs.c 2025-04-18 18:38:35.887447937 +0300 ++++ linux-6.12.30/fs/aufs/sysaufs.c 2025-05-27 19:28:00.106257401 +0300 @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -30600,9 +30627,9 @@ diff -Naur null/fs/aufs/sysaufs.c linux-6.6.84/fs/aufs/sysaufs.c +out: + return err; +} -diff -Naur null/fs/aufs/sysaufs.h linux-6.6.84/fs/aufs/sysaufs.h +diff -Naur null/fs/aufs/sysaufs.h linux-6.12.30/fs/aufs/sysaufs.h --- /dev/null -+++ linux-6.6.84/fs/aufs/sysaufs.h 2025-04-18 18:38:35.887447937 +0300 ++++ linux-6.12.30/fs/aufs/sysaufs.h 2025-05-27 19:28:00.106257401 +0300 @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -30706,9 +30733,9 @@ diff -Naur null/fs/aufs/sysaufs.h linux-6.6.84/fs/aufs/sysaufs.h + +#endif /* __KERNEL__ */ +#endif /* __SYSAUFS_H__ */ -diff -Naur null/fs/aufs/sysfs.c linux-6.6.84/fs/aufs/sysfs.c +diff -Naur null/fs/aufs/sysfs.c linux-6.12.30/fs/aufs/sysfs.c --- /dev/null -+++ linux-6.6.84/fs/aufs/sysfs.c 2025-04-18 18:38:35.887447937 +0300 ++++ linux-6.12.30/fs/aufs/sysfs.c 2025-05-27 19:28:00.106257401 +0300 @@ -0,0 +1,374 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -31084,9 +31111,9 @@ diff -Naur null/fs/aufs/sysfs.c linux-6.6.84/fs/aufs/sysfs.c + } + } +} -diff -Naur null/fs/aufs/sysrq.c linux-6.6.84/fs/aufs/sysrq.c +diff -Naur null/fs/aufs/sysrq.c linux-6.12.30/fs/aufs/sysrq.c --- /dev/null -+++ linux-6.6.84/fs/aufs/sysrq.c 2025-04-18 18:38:35.887447937 +0300 ++++ linux-6.12.30/fs/aufs/sysrq.c 2025-05-27 19:28:00.106257401 +0300 @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -31245,9 +31272,9 @@ diff -Naur null/fs/aufs/sysrq.c linux-6.6.84/fs/aufs/sysrq.c + if (unlikely(err)) + pr_err("err %d (ignored)\n", err); +} -diff -Naur null/fs/aufs/vdir.c linux-6.6.84/fs/aufs/vdir.c +diff -Naur null/fs/aufs/vdir.c linux-6.12.30/fs/aufs/vdir.c --- /dev/null -+++ linux-6.6.84/fs/aufs/vdir.c 2025-04-18 18:38:35.887447937 +0300 ++++ linux-6.12.30/fs/aufs/vdir.c 2025-05-27 19:28:00.107257388 +0300 @@ -0,0 +1,896 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -31678,9 +31705,9 @@ diff -Naur null/fs/aufs/vdir.c linux-6.6.84/fs/aufs/vdir.c + +/* ---------------------------------------------------------------------- */ + -+#define AuFillVdir_CALLED 1 -+#define AuFillVdir_WHABLE (1 << 1) -+#define AuFillVdir_SHWH (1 << 2) ++#define AuFillVdir_CALLED BIT(0) ++#define AuFillVdir_WHABLE BIT(1) ++#define AuFillVdir_SHWH BIT(2) +#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name) +#define au_fset_fillvdir(flags, name) \ + do { (flags) |= AuFillVdir_##name; } while (0) @@ -32004,6 +32031,7 @@ diff -Naur null/fs/aufs/vdir.c linux-6.6.84/fs/aufs/vdir.c + goto out; + + allocated = NULL; ++ inode = file_inode(file); + vdir_cache = au_fvdir_cache(file); + if (!vdir_cache) { + vdir_cache = alloc_vdir(file); @@ -32011,7 +32039,8 @@ diff -Naur null/fs/aufs/vdir.c linux-6.6.84/fs/aufs/vdir.c + if (IS_ERR(vdir_cache)) + goto out; + allocated = vdir_cache; -+ } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) { ++ } else if (!file->f_pos ++ && vdir_cache->vd_version != inode_query_iversion(inode)) { + /* test file->f_pos here instead of ctx->pos */ + err = reinit_vdir(vdir_cache); + if (unlikely(err)) @@ -32019,10 +32048,8 @@ diff -Naur null/fs/aufs/vdir.c linux-6.6.84/fs/aufs/vdir.c + } else + return 0; /* success */ + -+ inode = file_inode(file); + err = copy_vdir(vdir_cache, au_ivdir(inode)); + if (!err) { -+ file->f_version = inode_query_iversion(inode); + if (allocated) + au_set_fvdir_cache(file, allocated); + } else if (allocated) @@ -32145,10 +32172,10 @@ diff -Naur null/fs/aufs/vdir.c linux-6.6.84/fs/aufs/vdir.c + /* smp_mb(); */ + return 0; +} -diff -Naur null/fs/aufs/vfsub.c linux-6.6.84/fs/aufs/vfsub.c +diff -Naur null/fs/aufs/vfsub.c linux-6.12.30/fs/aufs/vfsub.c --- /dev/null -+++ linux-6.6.84/fs/aufs/vfsub.c 2025-04-18 18:38:35.887447937 +0300 -@@ -0,0 +1,965 @@ ++++ linux-6.12.30/fs/aufs/vfsub.c 2025-05-27 19:28:00.107257388 +0300 +@@ -0,0 +1,966 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005-2025 Junjiro R. Okajima @@ -32345,8 +32372,6 @@ diff -Naur null/fs/aufs/vfsub.c linux-6.6.84/fs/aufs/vfsub.c + + /* todo: call VFS:may_open() here */ + /* todo: ima_file_check() too? */ -+ if (!err && (args->open_flag & __FMODE_EXEC)) -+ err = deny_write_access(file); + if (!err) + fsnotify_open(file); + else @@ -32422,10 +32447,13 @@ diff -Naur null/fs/aufs/vfsub.c linux-6.6.84/fs/aufs/vfsub.c + lockdep_off(); + d = lock_rename(d1, d2); + lockdep_on(); ++ if (IS_ERR(d)) ++ goto out; + au_hn_suspend(hdir1); + if (hdir1 != hdir2) + au_hn_suspend(hdir2); + ++out: + return d; +} + @@ -32809,11 +32837,11 @@ diff -Naur null/fs/aufs/vfsub.c linux-6.6.84/fs/aufs/vfsub.c + return err; +} + -+long vfsub_splice_read(struct file *in, loff_t *ppos, -+ struct pipe_inode_info *pipe, size_t len, -+ unsigned int flags) ++ssize_t vfsub_splice_read(struct file *in, loff_t *ppos, ++ struct pipe_inode_info *pipe, size_t len, ++ unsigned int flags) +{ -+ long err; ++ ssize_t err; + + lockdep_off(); + err = vfs_splice_read(in, ppos, pipe, len, flags); @@ -32824,10 +32852,10 @@ diff -Naur null/fs/aufs/vfsub.c linux-6.6.84/fs/aufs/vfsub.c + return err; +} + -+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out, -+ loff_t *ppos, size_t len, unsigned int flags) ++ssize_t vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out, ++ loff_t *ppos, size_t len, unsigned int flags) +{ -+ long err; ++ ssize_t err; + + lockdep_off(); + err = do_splice_from(pipe, out, ppos, len, flags); @@ -33114,10 +33142,10 @@ diff -Naur null/fs/aufs/vfsub.c linux-6.6.84/fs/aufs/vfsub.c + + return err; +} -diff -Naur null/fs/aufs/vfsub.h linux-6.6.84/fs/aufs/vfsub.h +diff -Naur null/fs/aufs/vfsub.h linux-6.12.30/fs/aufs/vfsub.h --- /dev/null -+++ linux-6.6.84/fs/aufs/vfsub.h 2025-04-18 18:38:35.888447925 +0300 -@@ -0,0 +1,442 @@ ++++ linux-6.12.30/fs/aufs/vfsub.h 2025-05-27 19:28:00.107257388 +0300 +@@ -0,0 +1,441 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2005-2025 Junjiro R. Okajima @@ -33154,7 +33182,6 @@ diff -Naur null/fs/aufs/vfsub.h linux-6.6.84/fs/aufs/vfsub.h + +/* copied from linux/fs/internal.h */ +/* todo: BAD approach!! */ -+extern void __mnt_drop_write(struct vfsmount *); +extern struct file *alloc_empty_file(int, const struct cred *); + +/* ---------------------------------------------------------------------- */ @@ -33421,11 +33448,11 @@ diff -Naur null/fs/aufs/vfsub.h linux-6.6.84/fs/aufs/vfsub.h + struct dentry *h_dentry, umode_t h_mode); +#endif + -+long vfsub_splice_read(struct file *in, loff_t *ppos, -+ struct pipe_inode_info *pipe, size_t len, -+ unsigned int flags); -+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out, -+ loff_t *ppos, size_t len, unsigned int flags); ++ssize_t vfsub_splice_read(struct file *in, loff_t *ppos, ++ struct pipe_inode_info *pipe, size_t len, ++ unsigned int flags); ++ssize_t vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out, ++ loff_t *ppos, size_t len, unsigned int flags); + +static inline long vfsub_truncate(struct path *path, loff_t length) +{ @@ -33560,9 +33587,9 @@ diff -Naur null/fs/aufs/vfsub.h linux-6.6.84/fs/aufs/vfsub.h + +#endif /* __KERNEL__ */ +#endif /* __AUFS_VFSUB_H__ */ -diff -Naur null/fs/aufs/wbr_policy.c linux-6.6.84/fs/aufs/wbr_policy.c +diff -Naur null/fs/aufs/wbr_policy.c linux-6.12.30/fs/aufs/wbr_policy.c --- /dev/null -+++ linux-6.6.84/fs/aufs/wbr_policy.c 2025-04-18 18:38:35.888447925 +0300 ++++ linux-6.12.30/fs/aufs/wbr_policy.c 2025-05-27 19:28:00.107257388 +0300 @@ -0,0 +1,830 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -33617,10 +33644,10 @@ diff -Naur null/fs/aufs/wbr_policy.c linux-6.6.84/fs/aufs/wbr_policy.c + return err; +} + -+#define AuCpdown_PARENT_OPQ 1 -+#define AuCpdown_WHED (1 << 1) -+#define AuCpdown_MADE_DIR (1 << 2) -+#define AuCpdown_DIROPQ (1 << 3) ++#define AuCpdown_PARENT_OPQ BIT(0) ++#define AuCpdown_WHED BIT(1) ++#define AuCpdown_MADE_DIR BIT(2) ++#define AuCpdown_DIROPQ BIT(3) +#define au_ftest_cpdown(flags, name) ((flags) & AuCpdown_##name) +#define au_fset_cpdown(flags, name) \ + do { (flags) |= AuCpdown_##name; } while (0) @@ -34394,9 +34421,9 @@ diff -Naur null/fs/aufs/wbr_policy.c linux-6.6.84/fs/aufs/wbr_policy.c + .fin = au_wbr_create_fin_mfs + } +}; -diff -Naur null/fs/aufs/whout.c linux-6.6.84/fs/aufs/whout.c +diff -Naur null/fs/aufs/whout.c linux-6.12.30/fs/aufs/whout.c --- /dev/null -+++ linux-6.6.84/fs/aufs/whout.c 2025-04-18 18:38:35.888447925 +0300 ++++ linux-6.12.30/fs/aufs/whout.c 2025-05-27 19:28:00.107257388 +0300 @@ -0,0 +1,1072 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -35470,9 +35497,9 @@ diff -Naur null/fs/aufs/whout.c linux-6.6.84/fs/aufs/whout.c + au_whtmp_rmdir_free(args); + } +} -diff -Naur null/fs/aufs/whout.h linux-6.6.84/fs/aufs/whout.h +diff -Naur null/fs/aufs/whout.h linux-6.12.30/fs/aufs/whout.h --- /dev/null -+++ linux-6.6.84/fs/aufs/whout.h 2025-04-18 18:38:35.888447925 +0300 ++++ linux-6.12.30/fs/aufs/whout.h 2025-05-27 19:28:00.107257388 +0300 @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -35561,9 +35588,9 @@ diff -Naur null/fs/aufs/whout.h linux-6.6.84/fs/aufs/whout.h + +#endif /* __KERNEL__ */ +#endif /* __AUFS_WHOUT_H__ */ -diff -Naur null/fs/aufs/wkq.c linux-6.6.84/fs/aufs/wkq.c +diff -Naur null/fs/aufs/wkq.c linux-6.12.30/fs/aufs/wkq.c --- /dev/null -+++ linux-6.6.84/fs/aufs/wkq.c 2025-04-18 18:38:35.888447925 +0300 ++++ linux-6.12.30/fs/aufs/wkq.c 2025-05-27 19:28:00.107257388 +0300 @@ -0,0 +1,370 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -35935,9 +35962,9 @@ diff -Naur null/fs/aufs/wkq.c linux-6.6.84/fs/aufs/wkq.c + + return err; +} -diff -Naur null/fs/aufs/wkq.h linux-6.6.84/fs/aufs/wkq.h +diff -Naur null/fs/aufs/wkq.h linux-6.12.30/fs/aufs/wkq.h --- /dev/null -+++ linux-6.6.84/fs/aufs/wkq.h 2025-04-18 18:38:35.888447925 +0300 ++++ linux-6.12.30/fs/aufs/wkq.h 2025-05-27 19:28:00.108257376 +0300 @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -35986,8 +36013,8 @@ diff -Naur null/fs/aufs/wkq.h linux-6.6.84/fs/aufs/wkq.h +typedef void (*au_wkq_func_t)(void *args); + +/* wkq flags */ -+#define AuWkq_WAIT 1 -+#define AuWkq_NEST (1 << 1) ++#define AuWkq_WAIT BIT(0) ++#define AuWkq_NEST BIT(1) +#define au_ftest_wkq(flags, name) ((flags) & AuWkq_##name) +#define au_fset_wkq(flags, name) \ + do { (flags) |= AuWkq_##name; } while (0) @@ -36028,9 +36055,9 @@ diff -Naur null/fs/aufs/wkq.h linux-6.6.84/fs/aufs/wkq.h + +#endif /* __KERNEL__ */ +#endif /* __AUFS_WKQ_H__ */ -diff -Naur null/fs/aufs/xattr.c linux-6.6.84/fs/aufs/xattr.c +diff -Naur null/fs/aufs/xattr.c linux-6.12.30/fs/aufs/xattr.c --- /dev/null -+++ linux-6.6.84/fs/aufs/xattr.c 2025-04-18 18:38:35.888447925 +0300 ++++ linux-6.12.30/fs/aufs/xattr.c 2025-05-27 19:28:00.108257376 +0300 @@ -0,0 +1,360 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -36392,9 +36419,9 @@ diff -Naur null/fs/aufs/xattr.c linux-6.6.84/fs/aufs/xattr.c +{ + sb->s_xattr = au_xattr_handlers; +} -diff -Naur null/fs/aufs/xino.c linux-6.6.84/fs/aufs/xino.c +diff -Naur null/fs/aufs/xino.c linux-6.12.30/fs/aufs/xino.c --- /dev/null -+++ linux-6.6.84/fs/aufs/xino.c 2025-04-18 18:38:35.888447925 +0300 ++++ linux-6.12.30/fs/aufs/xino.c 2025-05-27 19:28:00.108257376 +0300 @@ -0,0 +1,1926 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -38322,9 +38349,9 @@ diff -Naur null/fs/aufs/xino.c linux-6.6.84/fs/aufs/xino.c +out: + return err; +} -diff -Naur null/include/uapi/linux/aufs_type.h linux-6.6.84/include/uapi/linux/aufs_type.h +diff -Naur null/include/uapi/linux/aufs_type.h linux-6.12.30/include/uapi/linux/aufs_type.h --- /dev/null -+++ linux-6.6.84/include/uapi/linux/aufs_type.h 2025-04-18 18:38:35.889447912 +0300 ++++ linux-6.12.30/include/uapi/linux/aufs_type.h 2025-05-27 19:28:00.108257376 +0300 @@ -0,0 +1,452 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* @@ -38368,7 +38395,7 @@ diff -Naur null/include/uapi/linux/aufs_type.h linux-6.6.84/include/uapi/linux/a +#include +#endif /* __KERNEL__ */ + -+#define AUFS_VERSION "6.6.84-20250414" ++#define AUFS_VERSION "6.12-20250414" + +/* todo? move this to linux-2.6.19/include/magic.h */ +#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's') diff --git a/kernel/kernel/files/patches/aufs6/aufs6.6.63-20241202.patch b/kernel/kernel/files/patches/aufs6/aufs6.6.63-20241202.patch deleted file mode 100644 index 1ea4751e..00000000 --- a/kernel/kernel/files/patches/aufs6/aufs6.6.63-20241202.patch +++ /dev/null @@ -1,38744 +0,0 @@ -diff -Naur null/Documentation/ABI/testing/debugfs-aufs linux-6.6.63/Documentation/ABI/testing/debugfs-aufs ---- /dev/null -+++ linux-6.6.63/Documentation/ABI/testing/debugfs-aufs 2024-12-18 15:12:59.290519651 +0300 -@@ -0,0 +1,55 @@ -+What: /debug/aufs/si_/ -+Date: March 2009 -+Contact: J. R. Okajima -+Description: -+ Under /debug/aufs, a directory named si_ is created -+ per aufs mount, where is a unique id generated -+ internally. -+ -+What: /debug/aufs/si_/plink -+Date: Apr 2013 -+Contact: J. R. Okajima -+Description: -+ It has three lines and shows the information about the -+ pseudo-link. The first line is a single number -+ representing a number of buckets. The second line is a -+ number of pseudo-links per buckets (separated by a -+ blank). The last line is a single number representing a -+ total number of psedo-links. -+ When the aufs mount option 'noplink' is specified, it -+ will show "1\n0\n0\n". -+ -+What: /debug/aufs/si_/xib -+Date: March 2009 -+Contact: J. R. Okajima -+Description: -+ It shows the consumed blocks by xib (External Inode Number -+ Bitmap), its block size and file size. -+ When the aufs mount option 'noxino' is specified, it -+ will be empty. About XINO files, see the aufs manual. -+ -+What: /debug/aufs/si_/xi -+Date: March 2009 -+Contact: J. R. Okajima -+Description: -+ It shows the consumed blocks by xino (External Inode Number -+ Translation Table), its link count, block size and file -+ size. -+ Due to the file size limit, there may exist multiple -+ xino files per branch. In this case, "-N" is added to -+ the filename and it corresponds to the index of the -+ internal xino array. "-0" is omitted. -+ When the aufs mount option 'noxino' is specified, Those -+ entries won't exist. About XINO files, see the aufs -+ manual. -+ -+What: /debug/aufs/si_/xigen -+Date: March 2009 -+Contact: J. R. Okajima -+Description: -+ It shows the consumed blocks by xigen (External Inode -+ Generation Table), its block size and file size. -+ If CONFIG_AUFS_EXPORT is disabled, this entry will not -+ be created. -+ When the aufs mount option 'noxino' is specified, it -+ will be empty. About XINO files, see the aufs manual. -diff -Naur null/Documentation/ABI/testing/sysfs-aufs linux-6.6.63/Documentation/ABI/testing/sysfs-aufs ---- /dev/null -+++ linux-6.6.63/Documentation/ABI/testing/sysfs-aufs 2024-12-18 15:12:59.290519651 +0300 -@@ -0,0 +1,31 @@ -+What: /sys/fs/aufs/si_/ -+Date: March 2009 -+Contact: J. R. Okajima -+Description: -+ Under /sys/fs/aufs, a directory named si_ is created -+ per aufs mount, where is a unique id generated -+ internally. -+ -+What: /sys/fs/aufs/si_/br -+Date: March 2009 -+Contact: J. R. Okajima -+Description: -+ It shows the abolute path of a member directory (which -+ is called branch) in aufs, and its permission. -+ -+What: /sys/fs/aufs/si_/brid -+Date: July 2013 -+Contact: J. R. Okajima -+Description: -+ It shows the id of a member directory (which is called -+ branch) in aufs. -+ -+What: /sys/fs/aufs/si_/xi_path -+Date: March 2009 -+Contact: J. R. Okajima -+Description: -+ It shows the abolute path of XINO (External Inode Number -+ Bitmap, Translation Table and Generation Table) file -+ even if it is the default path. -+ When the aufs mount option 'noxino' is specified, it -+ will be empty. About XINO files, see the aufs manual. -diff -Naur null/Documentation/filesystems/aufs/design/01intro.txt linux-6.6.63/Documentation/filesystems/aufs/design/01intro.txt ---- /dev/null -+++ linux-6.6.63/Documentation/filesystems/aufs/design/01intro.txt 2024-12-18 15:12:59.290519651 +0300 -@@ -0,0 +1,171 @@ -+ -+# Copyright (C) 2005-2022 Junjiro R. Okajima -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+Introduction -+---------------------------------------- -+ -+aufs [ei ju: ef es] | /ey-yoo-ef-es/ | [a u f s] -+1. abbrev. for "advanced multi-layered unification filesystem". -+2. abbrev. for "another unionfs". -+3. abbrev. for "auf das" in German which means "on the" in English. -+ Ex. "Butter aufs Brot"(G) means "butter onto bread"(E). -+ But "Filesystem aufs Filesystem" is hard to understand. -+4. abbrev. for "African Urban Fashion Show". -+ -+AUFS is a filesystem with features: -+- 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', etc. and their -+ combination. -+- internal "file copy-on-write". -+- logical deletion, whiteout. -+- dynamic branch manipulation, adding, deleting and changing permission. -+- allow bypassing aufs, user's direct branch access. -+- external inode number translation table and bitmap which maintains the -+ persistent aufs inode number. -+- seekable directory, including NFS readdir. -+- file mapping, mmap and sharing pages. -+- pseudo-link, hardlink over branches. -+- loopback mounted filesystem as a branch. -+- several policies to select one among multiple writable branches. -+- revert a single systemcall when an error occurs in aufs. -+- and more... -+ -+ -+Multi Layered Stackable Unification Filesystem -+---------------------------------------------------------------------- -+Most people already knows what it is. -+It is a filesystem which unifies several directories and provides a -+merged single directory. When users access a file, the access will be -+passed/re-directed/converted (sorry, I am not sure which English word is -+correct) to the real file on the member filesystem. The member -+filesystem is called 'lower filesystem' or 'branch' and has a mode -+'readonly' and 'readwrite.' And the deletion for a file on the lower -+readonly branch is handled by creating 'whiteout' on the upper writable -+branch. -+ -+On LKML, there have been discussions about UnionMount (Jan Blunck, -+Bharata B Rao and Valerie Aurora) and Unionfs (Erez Zadok). They took -+different approaches to implement the merged-view. -+The former tries putting it into VFS, and the latter implements as a -+separate filesystem. -+(If I misunderstand about these implementations, please let me know and -+I shall correct it. Because it is a long time ago when I read their -+source files last time). -+ -+UnionMount's approach will be able to small, but may be hard to share -+branches between several UnionMount since the whiteout in it is -+implemented in the inode on branch filesystem and always -+shared. According to Bharata's post, readdir does not seems to be -+finished yet. -+There are several missing features known in this implementations such as -+- for users, the inode number may change silently. eg. copy-up. -+- link(2) may break by copy-up. -+- read(2) may get an obsoleted filedata (fstat(2) too). -+- fcntl(F_SETLK) may be broken by copy-up. -+- unnecessary copy-up may happen, for example mmap(MAP_PRIVATE) after -+ open(O_RDWR). -+ -+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 -+totally different one. -+ -+Comparing DM snapshot and fs based implementation -+- the number of bytes to be copied between devices is much smaller. -+- the type of filesystem must be one and only. -+- the fs must be writable, no readonly fs, even for the lower original -+ device. so the compression fs will not be usable. but if we use -+ loopback mount, we may address this issue. -+ for instance, -+ mount /cdrom/squashfs.img /sq -+ losetup /sq/ext2.img -+ losetup /somewhere/cow -+ dmsetup "snapshot /dev/loop0 /dev/loop1 ..." -+- it will be difficult (or needs more operations) to extract the -+ difference between the original device and COW. -+- 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/persona of aufs -+---------------------------------------------------------------------- -+ -+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 -+4. reader/writer of files on branches such like an application -+ -+1. Callee of VFS Helper -+As an ordinary linux filesystem, aufs is a callee of VFS. For instance, -+unlink(2) from an application reaches sys_unlink() kernel function and -+then vfs_unlink() is called. vfs_unlink() is one of VFS helper and it -+calls filesystem specific unlink operation. Actually aufs implements the -+unlink operation but it behaves like a redirector. -+ -+2. Caller of VFS Helper for Branches -+aufs_unlink() passes the unlink request to the branch filesystem as if -+it were called from VFS. So the called unlink operation of the branch -+filesystem acts as usual. As a caller of VFS helper, aufs should handle -+every necessary pre/post operation for the branch filesystem. -+- acquire the lock for the parent dir on a branch -+- lookup in a branch -+- revalidate dentry on a branch -+- mnt_want_write() for a branch -+- vfs_unlink() for a branch -+- mnt_drop_write() for a branch -+- release the lock on a branch -+ -+3. Persistent Inode Number -+One of the most important issue for a filesystem is to maintain inode -+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 -+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 -+ persistent which will be important for aufs on NFS server. -+ -+4. Read/Write Files Internally (copy-on-write) -+Because a branch can be readonly, when you write a file on it, aufs will -+"copy-up" it to the upper writable branch internally. And then write the -+originally requested thing to the file. Generally kernel doesn't -+open/read/write file actively. In aufs, even a single write may cause a -+internal "file copy". This behaviour is very similar to cp(1) command. -+ -+Some people may think it is better to pass such work to user space -+helper, instead of doing in kernel space. Actually I am still thinking -+about it. But currently I have implemented it in kernel space. -diff -Naur null/Documentation/filesystems/aufs/design/02struct.txt linux-6.6.63/Documentation/filesystems/aufs/design/02struct.txt ---- /dev/null -+++ linux-6.6.63/Documentation/filesystems/aufs/design/02struct.txt 2024-12-18 15:12:59.291519638 +0300 -@@ -0,0 +1,258 @@ -+ -+# Copyright (C) 2005-2022 Junjiro R. Okajima -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+Basic Aufs Internal Structure -+ -+Superblock/Inode/Dentry/File Objects -+---------------------------------------------------------------------- -+As like an ordinary filesystem, aufs has its own -+superblock/inode/dentry/file objects. All these objects have a -+dynamically allocated array and store the same kind of pointers to the -+lower filesystem, branch. -+For example, when you build a union with one readwrite branch and one -+readonly, mounted /au, /rw and /ro respectively. -+- /au = /rw + /ro -+- /ro/fileA exists but /rw/fileA -+ -+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 (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 -+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 -+---------------------------------------------------------------------- -+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 -+wbr_policy.txt too. -+ -+ -+Branch and XINO(External Inode Number Translation Table) -+---------------------------------------------------------------------- -+Every branch has its own xino (external inode number translation table) -+file. The xino file is created and unlinked by aufs internally. When two -+members of a union exist on the same filesystem, they share the single -+xino file. -+The struct of a xino file is simple, just a sequence of aufs inode -+numbers which is indexed by the lower inode number. -+In the above sample, assume the inode number of /ro/fileA is i111 and -+aufs assigns the inode number i999 for fileA. Then aufs writes 999 as -+4(8) bytes at 111 * 4(8) bytes offset in the xino file. -+ -+When the inode numbers are not contiguous, the xino file will be sparse -+which has a hole in it and doesn't consume as much disk space as it -+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 their names are -+whiteout-ed doubly, so that users will never see their names in aufs -+hierarchy. -+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. -+ -+1. Whiteout Base -+ When you remove a file on a readonly branch, aufs handles it as a -+ logical deletion and creates a whiteout on the upper writable branch -+ as a hardlink of this file in order not to consume inode on the -+ writable branch. -+2. Pseudo-link Dir -+ See below, Pseudo-link. -+3. Step-Parent Dir -+ When "fileC" exists on the lower readonly branch only and it is -+ opened and removed with its parent dir, and then user writes -+ something into it, then aufs copies-up fileC to this -+ directory. Because there is no other dir to store fileC. After -+ 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. -+ -+ -+Pseudo-link -+---------------------------------------------------------------------- -+Assume "fileA" exists on the lower readonly branch only and it is -+hardlinked to "fileB" on the branch. When you write something to fileA, -+aufs copies-up it to the upper writable branch. Additionally aufs -+creates a hardlink under the Pseudo-link Directory of the writable -+branch. The inode of a pseudo-link is kept in aufs super_block as a -+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 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 -+to do this. The userspace helpers executed at remounting and unmounting -+aufs by default. -+During this utility is running, it puts aufs into the pseudo-link -+maintenance mode. In this mode, only the process which began the -+maintenance mode (and its child processes) is allowed to operate in -+aufs. Some other processes which are not related to the pseudo-link will -+be allowed to run too, but the rest have to return an error or wait -+until the maintenance mode ends. If a process already acquires an inode -+mutex (in VFS), it has to return an error. -+ -+ -+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 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. -+ -+As well as XINO files, aufs has a feature to truncate/refresh XIB to -+reduce the number of consumed disk blocks for these files. -+ -+ -+Virtual or Vertical Dir, and Readdir in Userspace -+---------------------------------------------------------------------- -+In order to support multiple layers (branches), aufs readdir operation -+constructs a virtual dir block on memory. For readdir, aufs calls -+vfs_readdir() internally for each dir on branches, merges their entries -+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 -+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 -+padding). Another block for each entry is handled by kmem_cache too. -+During building dir blocks, aufs creates hash list and judging whether -+the entry is whiteouted by its upper branch or already listed. -+The merged result is cached in the corresponding inode object and -+maintained by a customizable life-time option. -+ -+Some people may call it can be a security hole or invite DoS attack -+since the opened and once readdir-ed dir (file object) holds its entry -+list and becomes a pressure for system memory. But I'd say it is similar -+to files under /proc or /sys. The virtual files in them also holds a -+memory page (generally) while they are opened. When an idea to reduce -+memory for them is introduced, it will be applied to aufs too. -+For those who really hate this situation, I've developed readdir(3) -+library which operates this merging in userspace. You just need to set -+LD_PRELOAD environment variable, and aufs will not consume no memory in -+kernel space for readdir(3). -+ -+ -+Workqueue -+---------------------------------------------------------------------- -+Aufs sometimes requires privilege access to a branch. For instance, -+in copy-up/down operation. When a user process is going to make changes -+to a file which exists in the lower readonly branch only, and the mode -+of one of ancestor directories may not be writable by a user -+process. Here aufs copy-up the file with its ancestors and they may -+require privilege to set its owner/group/mode/etc. -+This is a typical case of a application character of aufs (see -+Introduction). -+ -+Aufs uses workqueue synchronously for this case. It creates its own -+workqueue. The workqueue is a kernel thread and has privilege. Aufs -+passes the request to call mkdir or write (for example), and wait for -+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, 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 -+whiteout base and etc. This is unrelated to a privilege. -+Most of aufs operation tries acquiring a rw_semaphore for aufs -+superblock at the beginning, at the same time waits for the completion -+of all queued asynchronous tasks. -+ -+ -+Whiteout -+---------------------------------------------------------------------- -+The whiteout in aufs is very similar to Unionfs's. That is represented -+by its filename. UnionMount takes an approach of a file mode, but I am -+afraid several utilities (find(1) or something) will have to support it. -+ -+Basically the whiteout represents "logical deletion" which stops aufs to -+lookup further, but also it represents "dir is opaque" which also stop -+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 -+revertible, aufs adopts an approach to rename a directory to a temporary -+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, -+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 -+temporary name completely and asynchronously to the system global -+workqueue. -+ -+ -+Copy-up -+---------------------------------------------------------------------- -+It is a well-known feature or concept. -+When user modifies a file on a readonly branch, aufs operate "copy-up" -+internally and makes change to the new file on the upper writable branch. -+When the trigger systemcall does not update the timestamps of the parent -+dir, aufs reverts it after copy-up. -+ -+ -+Move-down (aufs3.9 and later) -+---------------------------------------------------------------------- -+"Copy-up" is one of the essential feature in aufs. It copies a file from -+the lower readonly branch to the upper writable branch when a user -+changes something about the file. -+"Move-down" is an opposite action of copy-up. Basically this action is -+ran manually instead of automatically and internally. -+For desgin and implementation, aufs has to consider these issues. -+- whiteout for the file may exist on the lower branch. -+- ancestor directories may not exist on the lower branch. -+- 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 (see "Revalidate Dentry and UDBA"). -+- the file should not be hard-linked nor pseudo-linked. they should be -+ handled by auplink utility later. -+ -+Sometimes users want to move-down a file from the upper writable branch -+to the lower readonly or writable branch. For instance, -+- the free space of the upper writable branch is going to run out. -+- create a new intermediate branch between the upper and lower branch. -+- etc. -+ -+For this purpose, use "aumvdown" command in aufs-util.git. -diff -Naur null/Documentation/filesystems/aufs/design/03atomic_open.txt linux-6.6.63/Documentation/filesystems/aufs/design/03atomic_open.txt ---- /dev/null -+++ linux-6.6.63/Documentation/filesystems/aufs/design/03atomic_open.txt 2024-12-18 15:12:59.291519638 +0300 -@@ -0,0 +1,85 @@ -+ -+# Copyright (C) 2015-2022 Junjiro R. Okajima -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+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 -Naur null/Documentation/filesystems/aufs/design/03lookup.txt linux-6.6.63/Documentation/filesystems/aufs/design/03lookup.txt ---- /dev/null -+++ linux-6.6.63/Documentation/filesystems/aufs/design/03lookup.txt 2024-12-18 15:12:59.291519638 +0300 -@@ -0,0 +1,113 @@ -+ -+# Copyright (C) 2005-2022 Junjiro R. Okajima -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+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. 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. -+ -+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 -+"Revalidate Dentry and UDBA" in detail. -+ -+ -+Test Only the Highest One for the Directory Permission (dirperm1 option) -+---------------------------------------------------------------------- -+Let's try case study. -+- aufs has two branches, upper readwrite and lower readonly. -+ /au = /rw + /ro -+- "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 readable. -+- then "/au/dirA" becomes world readable? -+ -+In this case, /ro/dirA is still 0700 since it exists in readonly branch, -+or it may be a natively readonly filesystem. If aufs respects the lower -+branch, it should not respond readdir request from other users. But user -+allowed it by chmod. Should really aufs rejects showing the entries -+under /ro/dirA? -+ -+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. -+ -+As a side effect, dirperm1 option improves the performance of aufs -+because the number of permission check is reduced when the number of -+branch is many. -+ -+ -+Revalidate Dentry and UDBA (User's Direct Branch Access) -+---------------------------------------------------------------------- -+Generally VFS helpers re-validate a dentry as a part of lookup. -+0. digging down the directory hierarchy. -+1. lock the parent dir by its i_mutex. -+2. lookup the final (child) entry. -+3. revalidate it. -+4. call the actual operation (create, unlink, etc.) -+5. unlock the parent dir -+ -+If the filesystem implements its ->d_revalidate() (step 3), then it is -+called. Actually aufs implements it and checks the dentry on a branch is -+still valid. -+But it is not enough. Because aufs has to release the lock for the -+parent dir on a branch at the end of ->lookup() (step 2) and -+->d_revalidate() (step 3) while the i_mutex of the aufs dir is still -+held by VFS. -+If the file on a branch is changed directly, eg. bypassing aufs, after -+aufs released the lock, then the subsequent operation may cause -+something unpleasant result. -+ -+This situation is a result of VFS architecture, ->lookup() and -+->d_revalidate() is separated. But I never say it is wrong. It is a good -+design from VFS's point of view. It is just not suitable for sub-VFS -+character in aufs. -+ -+Aufs supports such case by three level of revalidation which is -+selectable by user. -+1. Simple Revalidate -+ Addition to the native flow in VFS's, confirm the child-parent -+ relationship on the branch just after locking the parent dir on the -+ branch in the "actual operation" (step 4). When this validation -+ fails, aufs returns EBUSY. ->d_revalidate() (step 3) in aufs still -+ checks the validation of the dentry on branches. -+2. Monitor Changes Internally by Inotify/Fsnotify -+ Addition to above, in the "actual operation" (step 4) aufs re-lookup -+ the dentry on the branch, and returns EBUSY if it finds different -+ dentry. -+ Additionally, aufs sets the inotify/fsnotify watch for every dir on branches -+ during it is in cache. When the event is notified, aufs registers a -+ function to kernel 'events' thread by schedule_work(). And the -+ function sets some special status to the cached aufs dentry and inode -+ private data. If they are not cached, then aufs has nothing to -+ do. When the same file is accessed through aufs (step 0-3) later, -+ aufs will detect the status and refresh all necessary data. -+ In this mode, aufs has to ignore the event which is fired by aufs -+ itself. -+3. No Extra Validation -+ This is the simplest test and doesn't add any additional revalidation -+ 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 -Naur null/Documentation/filesystems/aufs/design/04branch.txt linux-6.6.63/Documentation/filesystems/aufs/design/04branch.txt ---- /dev/null -+++ linux-6.6.63/Documentation/filesystems/aufs/design/04branch.txt 2024-12-18 15:12:59.291519638 +0300 -@@ -0,0 +1,74 @@ -+ -+# Copyright (C) 2005-2022 Junjiro R. Okajima -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+Branch Manipulation -+ -+Since aufs supports dynamic branch manipulation, ie. add/remove a branch -+and changing its permission/attribute, there are a lot of works to do. -+ -+ -+Add a Branch -+---------------------------------------------------------------------- -+o Confirm the adding dir exists outside of aufs, including loopback -+ mount, and its various attributes. -+o Initialize the xino file and whiteout bases if necessary. -+ See struct.txt. -+ -+o Check the owner/group/mode of the directory -+ When the owner/group/mode of the adding directory differs from the -+ existing branch, aufs issues a warning because it may impose a -+ security risk. -+ For example, when a upper writable branch has a world writable empty -+ top directory, a malicious user can create any files on the writable -+ branch directly, like copy-up and modify manually. If something like -+ /etc/{passwd,shadow} exists on the lower readonly branch but the upper -+ 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 aufs can do nothing except -+ producing a warning. -+ -+ -+Delete a Branch -+---------------------------------------------------------------------- -+o Confirm the deleting branch is not busy -+ To be general, there is one merit to adopt "remount" interface to -+ manipulate branches. It is to discard caches. At deleting a branch, -+ aufs checks the still cached (and connected) dentries and inodes. If -+ there are any, then they are all in-use. An inode without its -+ corresponding dentry can be alive alone (for example, inotify/fsnotify case). -+ -+ For the cached one, aufs checks whether the same named entry exists on -+ other branches. -+ If the cached one is a directory, because aufs provides a merged view -+ to users, as long as one dir is left on any branch aufs can show the -+ dir to users. In this case, the branch can be removed from aufs. -+ Otherwise aufs rejects deleting the branch. -+ -+ If any file on the deleting branch is opened by aufs, then aufs -+ rejects deleting. -+ -+ -+Modify the Permission of a Branch -+---------------------------------------------------------------------- -+o Re-initialize or remove the xino file and whiteout bases if necessary. -+ See struct.txt. -+ -+o rw --> ro: Confirm the modifying branch is not busy -+ Aufs rejects the request if any of these conditions are true. -+ - a file on the branch is mmap-ed. -+ - a regular file on the branch is opened for write and there is no -+ same named entry on the upper branch. -diff -Naur null/Documentation/filesystems/aufs/design/05wbr_policy.txt linux-6.6.63/Documentation/filesystems/aufs/design/05wbr_policy.txt ---- /dev/null -+++ linux-6.6.63/Documentation/filesystems/aufs/design/05wbr_policy.txt 2024-12-18 15:12:59.291519638 +0300 -@@ -0,0 +1,64 @@ -+ -+# Copyright (C) 2005-2022 Junjiro R. Okajima -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+Policies to Select One among Multiple Writable Branches -+---------------------------------------------------------------------- -+When the number of writable branch is more than one, aufs has to decide -+the target branch for file creation or copy-up. By default, the highest -+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 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 -+created for each branch. mkdir(2) systemcall is an exception. When you -+create 10 new directories, all will be created on the same branch. -+And the most-free-space policy selects the one which has most free -+space among the writable branches. The amount of free space will be -+checked by aufs internally, and users can specify its time interval. -+ -+The policies for copy-up is more simple, -+top-down-parent is equivalent to the same named on in create policy, -+bottom-up-parent selects the writable branch where the parent dir -+exists and the nearest upper one from the copyup-source, -+bottom-up selects the nearest upper writable branch from the -+copyup-source, regardless the existence of the parent dir. -+ -+There are some rules or exceptions to apply these policies. -+- If there is a readonly branch above the policy-selected branch and -+ the parent dir is marked as opaque (a variation of whiteout), or the -+ target (creating) file is whiteout-ed on the upper readonly branch, -+ then the result of the policy is ignored and the target file will be -+ created on the nearest upper writable branch than the readonly branch. -+- If there is a writable branch above the policy-selected branch and -+ the parent dir is marked as opaque or the target file is whiteouted -+ on the branch, then the result of the policy is ignored and the target -+ file will be created on the highest one among the upper writable -+ branches who has diropq or whiteout. In case of whiteout, aufs removes -+ it as usual. -+- link(2) and rename(2) systemcalls are exceptions in every policy. -+ They try selecting the branch where the source exists as possible -+ since copyup a large file will take long time. If it can't be, -+ ie. the branch where the source exists is readonly, then they will -+ follow the copyup policy. -+- There is an exception for rename(2) when the target exists. -+ If the rename target exists, aufs compares the index of the branches -+ where the source and the target exists and selects the higher -+ one. If the selected branch is readonly, then aufs follows the -+ copyup policy. -diff -Naur null/Documentation/filesystems/aufs/design/06dirren.dot linux-6.6.63/Documentation/filesystems/aufs/design/06dirren.dot ---- /dev/null -+++ linux-6.6.63/Documentation/filesystems/aufs/design/06dirren.dot 2024-12-18 15:12:59.291519638 +0300 -@@ -0,0 +1,44 @@ -+ -+// to view this graph, run dot(1) command in GRAPHVIZ. -+// -+// This program is free software; you can redistribute it and/or modify -+// it under the terms of the GNU General Public License as published by -+// the Free Software Foundation; either version 2 of the License, or -+// (at your option) any later version. -+// -+// This program is distributed in the hope that it will be useful, -+// but WITHOUT ANY WARRANTY; without even the implied warranty of -+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+// GNU General Public License for more details. -+// -+// You should have received a copy of the GNU General Public License -+// along with this program. If not, see . -+ -+digraph G { -+node [shape=box]; -+whinfo [label="detailed info file\n(lower_brid_root-hinum, h_inum, namelen, old name)"]; -+ -+node [shape=oval]; -+ -+aufs_rename -> whinfo [label="store/remove"]; -+ -+node [shape=oval]; -+inode_list [label="h_inum list in branch\ncache"]; -+ -+node [shape=box]; -+whinode [label="h_inum list file"]; -+ -+node [shape=oval]; -+brmgmt [label="br_add/del/mod/umount"]; -+ -+brmgmt -> inode_list [label="create/remove"]; -+brmgmt -> whinode [label="load/store"]; -+ -+inode_list -> whinode [style=dashed,dir=both]; -+ -+aufs_rename -> inode_list [label="add/del"]; -+ -+aufs_lookup -> inode_list [label="search"]; -+ -+aufs_lookup -> whinfo [label="load/remove"]; -+} -diff -Naur null/Documentation/filesystems/aufs/design/06dirren.txt linux-6.6.63/Documentation/filesystems/aufs/design/06dirren.txt ---- /dev/null -+++ linux-6.6.63/Documentation/filesystems/aufs/design/06dirren.txt 2024-12-18 15:12:59.291519638 +0300 -@@ -0,0 +1,102 @@ -+ -+# Copyright (C) 2017-2022 Junjiro R. Okajima -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+Special handling for renaming a directory (DIRREN) -+---------------------------------------------------------------------- -+First, let's assume we have a simple usecase. -+ -+- /u = /rw + /ro -+- /rw/dirA exists -+- /ro/dirA and /ro/dirA/file exist too -+- there is no dirB on both branches -+- a user issues rename("dirA", "dirB") -+ -+Now, what should aufs behave against this rename(2)? -+There are a few possible cases. -+ -+A. returns EROFS. -+ since dirA exists on a readonly branch which cannot be renamed. -+B. returns EXDEV. -+ it is possible to copy-up dirA (only the dir itself), but the child -+ entries ("file" in this case) should not be. it must be a bad -+ approach to copy-up recursively. -+C. returns a success. -+ even the branch /ro is readonly, aufs tries renaming it. Obviously it -+ is a violation of aufs' policy. -+D. construct an extra information which indicates that /ro/dirA should -+ be handled as the name of dirB. -+ overlayfs has a similar feature called REDIRECT. -+ -+Until now, aufs implements the case B only which returns EXDEV, and -+expects the userspace application behaves like mv(1) which tries -+issueing rename(2) recursively. -+ -+A new aufs feature called DIRREN is introduced which implements the case -+D. There are several "extra information" added. -+ -+1. detailed info per renamed directory -+ path: /rw/dirB/$AUFS_WH_DR_INFO_PFX. -+2. the inode-number list of directories on a branch -+ path: /rw/dirB/$AUFS_WH_DR_BRHINO -+ -+The filename of "detailed info per directory" represents the lower -+branch, and its format is -+- a type of the branch id -+ one of these. -+ + uuid (not implemented yet) -+ + fsid -+ + dev -+- the inode-number of the branch root dir -+ -+And it contains these info in a single regular file. -+- magic number -+- branch's inode-number of the logically renamed dir -+- the name of the before-renamed dir -+ -+The "detailed info per directory" file is created in aufs rename(2), and -+loaded in any lookup. -+The info is considered in lookup for the matching case only. Here -+"matching" means that the root of branch (in the info filename) is same -+to the current looking-up branch. After looking-up the before-renamed -+name, the inode-number is compared. And the matched dentry is used. -+ -+The "inode-number list of directories" is a regular file which contains -+simply the inode-numbers on the branch. The file is created or updated -+in removing the branch, and loaded in adding the branch. Its lifetime is -+equal to the branch. -+The list is referred in lookup, and when the current target inode is -+found in the list, the aufs tries loading the "detailed info per -+directory" and get the changed and valid name of the dir. -+ -+Theoretically these "extra informaiton" may be able to be put into XATTR -+in the dir inode. But aufs doesn't choose this way because -+1. XATTR may not be supported by the branch (or its configuration) -+2. XATTR may have its size limit. -+3. XATTR may be less easy to convert than a regular file, when the -+ format of the info is changed in the future. -+At the same time, I agree that the regular file approach is much slower -+than XATTR approach. So, in the future, aufs may take the XATTR or other -+better approach. -+ -+This DIRREN feature is enabled by aufs configuration, and is activated -+by a new mount option. -+ -+For the more complicated case, there is a work with UDBA option, which -+is to dected the direct access to the branches (by-passing aufs) and to -+maintain the cashes in aufs. Since a single cached aufs dentry may -+contains two names, before- and after-rename, the name comparision in -+UDBA handler may not work correctly. In this case, the behaviour will be -+equivalen to udba=reval case. -diff -Naur null/Documentation/filesystems/aufs/design/06fhsm.txt linux-6.6.63/Documentation/filesystems/aufs/design/06fhsm.txt ---- /dev/null -+++ linux-6.6.63/Documentation/filesystems/aufs/design/06fhsm.txt 2024-12-18 15:12:59.291519638 +0300 -@@ -0,0 +1,118 @@ -+ -+# Copyright (C) 2011-2022 Junjiro R. Okajima -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+File-based Hierarchical Storage Management (FHSM) -+---------------------------------------------------------------------- -+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, 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 vertically. -+These multiple writable branches are prioritized, ie. the topmost one -+should be the fastest drive and be used heavily. -+ -+o Characters in aufs FHSM story -+- aufs itself and a new branch attribute. -+- a new ioctl interface to move-down and to establish a connection with -+ the daemon ("move-down" is a converse of "copy-up"). -+- userspace tool and daemon. -+ -+The userspace daemon establishes a connection with aufs and waits for -+the notification. The notified information is very similar to struct -+statfs containing the number of consumed blocks and inodes. -+When the consumed blocks/inodes of a branch exceeds the user-specified -+upper watermark, the daemon activates its move-down process until the -+consumed blocks/inodes reaches the user-specified lower watermark. -+ -+The actual move-down is done by aufs based upon the request from -+user-space since we need to maintain the inode number and the internal -+pointer arrays in aufs. -+ -+Currently aufs FHSM handles the regular files only. Additionally they -+must not be hard-linked nor pseudo-linked. -+ -+ -+o Cowork of aufs and the user-space daemon -+ During the userspace daemon established the connection, aufs sends a -+ small notification to it whenever aufs writes something into the -+ writable branch. But it may cost high since aufs issues statfs(2) -+ internally. So user can specify a new option to cache the -+ info. Actually the notification is controlled by these factors. -+ + the specified cache time. -+ + classified as "force" by aufs internally. -+ Until the specified time expires, aufs doesn't send the info -+ except the forced cases. When aufs decide forcing, the info is always -+ notified to userspace. -+ For example, the number of free inodes is generally large enough and -+ the shortage of it happens rarely. So aufs doesn't force the -+ notification when creating a new file, directory and others. This is -+ the typical case which aufs doesn't force. -+ When aufs writes the actual filedata and the files consumes any of new -+ blocks, the aufs forces notifying. -+ -+ -+o Interfaces in aufs -+- New branch attribute. -+ + fhsm -+ Specifies that the branch is managed by FHSM feature. In other word, -+ participant in the FHSM. -+ When nofhsm is set to the branch, it will not be the source/target -+ branch of the move-down operation. This attribute is set -+ independently from coo and moo attributes, and if you want full -+ FHSM, you should specify them as well. -+- New mount option. -+ + fhsm_sec -+ Specifies a second to suppress many less important info to be -+ notified. -+- New ioctl. -+ + AUFS_CTL_FHSM_FD -+ create a new file descriptor which userspace can read the notification -+ (a subset of struct statfs) from aufs. -+- Module parameter 'brs' -+ It has to be set to 1. Otherwise the new mount option 'fhsm' will not -+ be set. -+- mount helpers /sbin/mount.aufs and /sbin/umount.aufs -+ When there are two or more branches with fhsm attributes, -+ /sbin/mount.aufs invokes the user-space daemon and /sbin/umount.aufs -+ terminates it. As a result of remounting and branch-manipulation, the -+ number of branches with fhsm attribute can be one. In this case, -+ /sbin/mount.aufs will terminate the user-space daemon. -+ -+ -+Finally the operation is done as these steps in kernel-space. -+- make sure that, -+ + no one else is using the file. -+ + the file is not hard-linked. -+ + the file is not pseudo-linked. -+ + the file is a regular file. -+ + the parent dir is not opaqued. -+- find the target writable branch. -+- make sure the file is not whiteout-ed by the upper (than the target) -+ branch. -+- make the parent dir on the target branch. -+- mutex lock the inode on the branch. -+- unlink the whiteout on the target branch (if exists). -+- lookup and create the whiteout-ed temporary name on the target branch. -+- copy the file as the whiteout-ed temporary name on the target branch. -+- rename the whiteout-ed temporary name to the original name. -+- unlink the file on the source branch. -+- maintain the internal pointer array and the external inode number -+ table (XINO). -+- maintain the timestamps and other attributes of the parent dir and the -+ file. -+ -+And of course, in every step, an error may happen. So the operation -+should restore the original file state after an error happens. -diff -Naur null/Documentation/filesystems/aufs/design/06mmap.txt linux-6.6.63/Documentation/filesystems/aufs/design/06mmap.txt ---- /dev/null -+++ linux-6.6.63/Documentation/filesystems/aufs/design/06mmap.txt 2024-12-18 15:12:59.291519638 +0300 -@@ -0,0 +1,72 @@ -+ -+# Copyright (C) 2005-2022 Junjiro R. Okajima -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+mmap(2) -- File Memory Mapping -+---------------------------------------------------------------------- -+In aufs, the file-mapped pages are handled by a branch fs directly, no -+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 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 -+user) may expect the path on aufs. -+ -+To address this issue, aufs adds a new member called vm_prfile in struct -+vm_area_struct (and struct vm_region). The original vm_file points to -+the file on the branch fs in order to handle everything correctly as -+usual. The new vm_prfile points to a virtual file in aufs, and the -+show-functions in procfs refers to vm_prfile if it is set. -+Also we need to maintain several other places where touching vm_file -+such like -+- fork()/clone() copies vma and the reference count of vm_file is -+ incremented. -+- merging vma maintains the ref count too. -+ -+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 -Naur null/Documentation/filesystems/aufs/design/06xattr.txt linux-6.6.63/Documentation/filesystems/aufs/design/06xattr.txt ---- /dev/null -+++ linux-6.6.63/Documentation/filesystems/aufs/design/06xattr.txt 2024-12-18 15:12:59.291519638 +0300 -@@ -0,0 +1,94 @@ -+ -+# Copyright (C) 2014-2022 Junjiro R. Okajima -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+Listing XATTR/EA and getting the value -+---------------------------------------------------------------------- -+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 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 -+entry allows it. This behaviour is necessary to respect the branch fs's -+security, but can make users confused since the user-visible standard -+attributes don't match the behaviour. -+To address this issue, aufs has a mount option called dirperm1 which -+checks the permission for the topmost entry only, and ignores the lower -+entry's permission. -+ -+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 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 categorized as these. -+- "security" for LSM and capability. -+- "system" for posix ACL, 'acl' mount option is required for the branch -+ fs generally. -+- "trusted" for userspace, CAP_SYS_ADMIN is required. -+- "user" for userspace, 'user_xattr' mount option is required for the -+ branch fs generally. -+ -+Moreover there are some other categories. Aufs handles these rather -+unpopular categories as the ordinary ones, ie. there is no special -+condition nor exception. -+ -+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 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 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 -+may NOT return an error even if the XATTR is not supported. It is -+totally up to the branch fs. -+ -+Anyway when the aufs internal copy-up gets an error from the dst branch -+fs, then aufs tries removing the just copied entry and returns the error -+to the userspace. The worst case of this situation will be all copy-up -+will fail. -+ -+For the copy-up operation, there two basic approaches. -+- copy the specified XATTR only (by category above), and return the -+ 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 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 "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. -+Note that aufs tries copying all XATTR unconditionally, and ignores the -+error from the dst branch according to the specified attributes. -+ -+Some XATTR may have its default value. The default value may come from -+the parent dir or the environment. If the default value is set at the -+file creating-time, it will be overwritten by copy-up. -+Some contradiction may happen I am afraid. -+Do we need another attribute to stop copying XATTR? I am unsure. For -+now, aufs implements the branch attributes to ignore the error. -diff -Naur null/Documentation/filesystems/aufs/design/07export.txt linux-6.6.63/Documentation/filesystems/aufs/design/07export.txt ---- /dev/null -+++ linux-6.6.63/Documentation/filesystems/aufs/design/07export.txt 2024-12-18 15:12:59.291519638 +0300 -@@ -0,0 +1,58 @@ -+ -+# Copyright (C) 2005-2022 Junjiro R. Okajima -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+Export Aufs via NFS -+---------------------------------------------------------------------- -+Here is an approach. -+- like xino/xib, add a new file 'xigen' which stores aufs inode -+ generation. -+- iget_locked(): initialize aufs inode generation for a new inode, and -+ store it in xigen file. -+- destroy_inode(): increment aufs inode generation and store it in xigen -+ file. it is necessary even if it is not unlinked, because any data of -+ inode may be changed by UDBA. -+- encode_fh(): for a root dir, simply return FILEID_ROOT. otherwise -+ build file handle by -+ + branch id (4 bytes) -+ + superblock generation (4 bytes) -+ + inode number (4 or 8 bytes) -+ + parent dir inode number (4 or 8 bytes) -+ + inode generation (4 bytes)) -+ + return value of exportfs_encode_fh() for the parent on a branch (4 -+ bytes) -+ + file handle for a branch (by exportfs_encode_fh()) -+- fh_to_dentry(): -+ + 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 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 -+ path_lookup(). now aufs gets a parent dir dentry, then handle it as -+ the 2nd level. -+ + to open the dir, aufs needs struct vfsmount. aufs keeps vfsmount -+ for every branch, but not itself. to get this, (currently) aufs -+ searches in current->nsproxy->mnt_ns list. it may not be a good -+ idea, but I didn't get other approach. -+ + test the generation of the gotten inode. -+- every inode operation: they may get EBUSY due to UDBA. in this case, -+ convert it into ESTALE for NFSD. -+- readdir(): call lockdep_on/off() because filldir in NFSD calls -+ lookup_one_len(), vfs_getattr(), encode_fh() and others. -diff -Naur null/Documentation/filesystems/aufs/design/08shwh.txt linux-6.6.63/Documentation/filesystems/aufs/design/08shwh.txt ---- /dev/null -+++ linux-6.6.63/Documentation/filesystems/aufs/design/08shwh.txt 2024-12-18 15:12:59.291519638 +0300 -@@ -0,0 +1,52 @@ -+ -+# Copyright (C) 2005-2022 Junjiro R. Okajima -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+Show Whiteout Mode (shwh) -+---------------------------------------------------------------------- -+Generally aufs hides the name of whiteouts. But in some cases, to show -+them is very useful for users. For instance, creating a new middle layer -+(branch) by merging existing layers. -+ -+(borrowing aufs1 HOW-TO from a user, Michael Towers) -+When you have three branches, -+- Bottom: 'system', squashfs (underlying base system), read-only -+- Middle: 'mods', squashfs, read-only -+- Top: 'overlay', ram (tmpfs), read-write -+ -+The top layer is loaded at boot time and saved at shutdown, to preserve -+the changes made to the system during the session. -+When larger changes have been made, or smaller changes have accumulated, -+the size of the saved top layer data grows. At this point, it would be -+nice to be able to merge the two overlay branches ('mods' and 'overlay') -+and rewrite the 'mods' squashfs, clearing the top layer and thus -+restoring save and load speed. -+ -+This merging is simplified by the use of another aufs mount, of just the -+two overlay branches using the 'shwh' option. -+# mount -t aufs -o ro,shwh,br:/livesys/overlay=ro+wh:/livesys/mods=rr+wh \ -+ aufs /livesys/merge_union -+ -+A merged view of these two branches is then available at -+/livesys/merge_union, and the new feature is that the whiteouts are -+visible! -+Note that in 'shwh' mode the aufs mount must be 'ro', which will disable -+writing to all branches. Also the default mode for all branches is 'ro'. -+It is now possible to save the combined contents of the two overlay -+branches to a new squashfs, e.g.: -+# mksquashfs /livesys/merge_union /path/to/newmods.squash -+ -+This new squashfs archive can be stored on the boot device and the -+initramfs will use it to replace the old one at the next boot. -diff -Naur null/Documentation/filesystems/aufs/design/10dynop.txt linux-6.6.63/Documentation/filesystems/aufs/design/10dynop.txt ---- /dev/null -+++ linux-6.6.63/Documentation/filesystems/aufs/design/10dynop.txt 2024-12-18 15:12:59.291519638 +0300 -@@ -0,0 +1,47 @@ -+ -+# Copyright (C) 2010-2022 Junjiro R. Okajima -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+Dynamically customizable FS operations -+---------------------------------------------------------------------- -+Generally FS operations (struct inode_operations, struct -+address_space_operations, struct file_operations, etc.) are defined as -+"static const", but it never means that FS have only one set of -+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 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 behaviour of VFS, -+aufs defines these operations dynamically. For instance, aufs defines -+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), Direct I/O and -+XIP (DAX) mainly. -+Currently this approach is applied to address_space_operations for -+regular files only. -diff -Naur null/Documentation/filesystems/aufs/README linux-6.6.63/Documentation/filesystems/aufs/README ---- /dev/null -+++ linux-6.6.63/Documentation/filesystems/aufs/README 2024-12-18 15:12:59.290519651 +0300 -@@ -0,0 +1,409 @@ -+ -+Aufs6 -- advanced multi layered unification filesystem version 6.x -+http://aufs.sf.net -+Junjiro R. Okajima -+ -+ -+0. Introduction -+---------------------------------------- -+In the early days, aufs was entirely re-designed and re-implemented -+Unionfs Version 1.x series. Adding many original ideas, approaches, -+improvements and implementations, it became totally different from -+Unionfs while keeping the basic features. -+Later, Unionfs Version 2.x series began taking some of the same -+approaches to aufs1's. -+Unionfs was being developed by Professor Erez Zadok at Stony Brook -+University and his team. -+ -+Aufs6 supports linux-v6.0 and later, try aufs6.0 branch in -+aufs-linux.git or aufs-standalone.git. -+If you want older kernel version support, -+- for linux-v5.x series, try aufs-linux.git or aufs-standalone.git -+- for linux-v4.x series, try aufs4-linux.git or aufs4-standalone.git -+- for linux-v3.x series, try aufs3-linux.git or aufs3-standalone.git -+- for linux-v2.6.16 and later, try aufs2-2.6.git, aufs2-standalone.git -+ or aufs1 from CVS on SourceForge. -+ -+Note: the name of aufs5-linux.git and aufs5-standalone.git on github -+ were changed. Now they are aufs-linux.git and -+ aufs-standalone.git and they contain aufs5 and later branches. -+ -+Note: it becomes clear that "Aufs was rejected. Let's give it up." -+ According to Christoph Hellwig, linux rejects all union-type -+ filesystems but UnionMount. -+ -+ -+PS. Al Viro seems have a plan to merge aufs as well as overlayfs and -+ UnionMount, and he pointed out an issue around a directory mutex -+ lock and aufs addressed it. But it is still unsure whether aufs will -+ be merged (or any other union solution). -+ -+ -+ -+1. Features -+---------------------------------------- -+- unite several directories into a single virtual filesystem. The member -+ directory is called as a branch. -+- you can specify the permission flags to the branch, which are 'readonly', -+ 'readwrite' and 'whiteout-able.' -+- by upper writable branch, internal copyup and whiteout, files/dirs on -+ readonly branch are modifiable logically. -+- dynamic branch manipulation, add, del. -+- etc... -+ -+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 -+- seekable directory, supporting NFS readdir. -+- whiteout is hardlinked in order to reduce the consumption of inodes -+ on branch -+- do not copyup, nor create a whiteout when it is unnecessary -+- revert a single systemcall when an error occurs in aufs -+- remount interface instead of ioctl -+- maintain /etc/mtab by an external command, /sbin/mount.aufs. -+- loopback mounted filesystem as a branch -+- kernel thread for removing the dir who has a plenty of whiteouts -+- support copyup sparse file (a file which has a 'hole' in it) -+- default permission flags for branches -+- selectable permission flags for ro branch, whether whiteout can -+ exist or not -+- export via NFS. -+- support /fs/aufs and /aufs. -+- support multiple writable branches, some policies to select one -+ among multiple writable branches. -+- a new semantics for link(2) and rename(2) to support multiple -+ writable branches. -+- no glibc changes are required. -+- pseudo hardlink (hardlink over branches) -+- allow a direct access manually to a file on branch, e.g. bypassing aufs. -+ including NFS or remote filesystem branch. -+- userspace wrapper for pathconf(3)/fpathconf(3) with _PC_LINK_MAX. -+- and more... -+ -+Currently these features are dropped temporary from aufs6. -+See design/08plan.txt in detail. -+- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs -+ (robr) -+- statistics of aufs thread (/sys/fs/aufs/stat) -+ -+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 -+- light version, without branch manipulation. (unnecessary?) -+- copyup in userspace -+- inotify in userspace -+- readv/writev -+ -+ -+2. Download -+---------------------------------------- -+There are three GIT trees for aufs6, aufs-linux.git, -+aufs-standalone.git, and aufs-util.git. -+While the aufs-util is always necessary, you need either of aufs-linux -+or aufs-standalone. -+ -+The aufs-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 aufs6 as an external kernel module. -+Several extra patches are not included in this tree. Only -+aufs-standalone tree contains them. They are described in the later -+section "Configuration and Compilation." -+ -+On the other hand, the aufs-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 "aufs6.x" where "x" -+represents the linux kernel version, "linux-6.x". For instance, -+"aufs6.0" is for linux-6.0. For latest "linux-6.x-rcN", use -+"aufs6.x-rcN" branch. -+ -+o aufs-linux tree -+$ git clone --reference /your/linux/git/tree \ -+ git://github.com/sfjro/aufs-linux.git aufs-linux.git -+- if you don't have linux GIT tree, then remove "--reference ..." -+$ cd aufs-linux.git -+$ git checkout origin/aufs6.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 aufs git://github.com/sfjro/aufs-linux.git -+$ git fetch aufs -+$ git checkout -b my6.0 v6.0 -+$ (add your local change...) -+$ git pull aufs aufs6.0 -+- now you have v6.0 + your_changes + aufs6.0 in you my6.0 branch. -+- you may need to solve some conflicts between your_changes and -+ aufs6.0. in this case, git-rerere is recommended so that you can -+ solve the similar conflicts automatically when you upgrade to 6.1 or -+ later in the future. -+ -+o aufs-standalone tree -+$ git clone git://github.com/sfjro/aufs-standalone.git aufs-standalone.git -+$ cd aufs-standalone.git -+$ git checkout origin/aufs6.0 -+ -+o aufs-util tree -+$ 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/aufs6.0 -+ -+Note: The 6.x-rcN branch is to be used with `rc' kernel versions ONLY. -+The minor version number, 'x' in '6.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. -+ -+Since aufs-util has its own minor version number, you may not be -+able to find a GIT branch in aufs-util for your kernel's -+exact minor version number. -+In this case, you should git-checkout the branch for the -+nearest lower number. -+ -+For (an unreleased) example: -+If you are using "linux-6.10" and the "aufs6.10" branch -+does not exist in aufs-util repository, then "aufs6.9", "aufs6.8" -+or something numerically smaller is the branch for your kernel. -+ -+Also you can view all branches by -+ $ git branch -a -+ -+ -+3. Configuration and Compilation -+---------------------------------------- -+Make sure you have git-checkout'ed the correct branch. -+ -+For aufs-linux tree, -+- enable CONFIG_AUFS_FS. -+- set other aufs configurations if necessary. -+- for aufs5.13 and later -+ Because aufs is not only an ordinary filesystem (callee of VFS), but -+ also a caller of VFS functions for branch filesystems, subclassing of -+ the internal locks for LOCKDEP is necessary. LOCKDEP is a debugging -+ feature of linux kernel. If you enable CONFIG_LOCKDEP, then you will -+ need to customize some LOCKDEP numbers. Here are what I use on my -+ test environment. -+ CONFIG_LOCKDEP_BITS=21 -+ CONFIG_LOCKDEP_CHAINS_BITS=21 -+ CONFIG_LOCKDEP_STACK_TRACE_BITS=24 -+ Also you will need to expand some constant values in LOCKDEP. Refer -+ to lockdep-debug.patch in aufs-standalone.git. -+ -+For aufs-standalone tree, -+There are several ways to build. -+ -+1. -+- apply ./aufs6-kbuild.patch to your kernel source files. -+- apply ./aufs6-base.patch too. -+- apply ./aufs6-mmap.patch too. -+- apply ./aufs6-standalone.patch too, if you have a plan to set -+ CONFIG_AUFS_FS=m. otherwise you don't need ./aufs-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 -+ =m or =y. -+- and build your kernel as usual. -+- install the built kernel. -+- install the header files too by "make headers_install" to the -+ directory where you specify. By default, it is $PWD/usr. -+ "make help" shows a brief note for headers_install. -+- and reboot your system. -+ -+2. -+- module only (CONFIG_AUFS_FS=m). -+- apply ./aufs6-base.patch to your kernel source files. -+- apply ./aufs6-mmap.patch too. -+- apply ./aufs6-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 -+ every aufs configurations. -+- build the module by simple "make". -+- you can specify ${KDIR} make variable which points to your kernel -+ source tree. -+- install the files -+ + run "make install" to install the aufs module, or copy the built -+ $PWD/aufs.ko to /lib/modules/... and run depmod -a (or reboot simply). -+ + run "make install_headers" (instead of headers_install) to install -+ the modified aufs header file (you can specify DESTDIR which is -+ 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 aufs6-kbuild.patch, nor copying source files to your -+ kernel source tree. -+ -+Note: The header file aufs_type.h is necessary to build aufs-util -+ as well as "make headers_install" in the kernel source tree. -+ headers_install is subject to be forgotten, but it is essentially -+ necessary, not only for building aufs-util. -+ You may not meet problems without headers_install in some older -+ version though. -+ -+And then, -+- read README in aufs-util, build and install it -+- note that your distribution may contain an obsoleted version of -+ aufs_type.h in /usr/include/linux or something. When you build aufs -+ utilities, make sure that your compiler refers the correct aufs header -+ file which is built by "make headers_install." -+- if you want to use readdir(3) in userspace or pathconf(3) wrapper, -+ then run "make install_ulib" too. And refer to the aufs manual in -+ detail. -+ -+There several other patches in aufs-standalone.git. They are all -+optional. When you meet some problems, they will help you. -+- aufs6-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". -+- vfs-ino.patch -+ Modifies a system global kernel internal function get_next_ino() in -+ order to stop assigning 0 for an inode-number. Not directly related to -+ aufs, but recommended generally. -+- tmpfs-idr.patch -+ Keeps the tmpfs inode number as the lowest value. Effective to reduce -+ the size of aufs XINO files for tmpfs branch. Also it prevents the -+ duplication of inode number, which is important for backup tools and -+ other utilities. When you find aufs XINO files for tmpfs branch -+ growing too much, try this patch. -+- lockdep-debug.patch -+ Similar to some kernel configurations for LOCKDEP (see the top of -+ this section), you will need expand some constants in LOCKDEP for -+ aufs if you enable CONFIG_LOCKDEP. -+ -+ -+4. Usage -+---------------------------------------- -+At first, make sure aufs-util are installed, and please read the aufs -+manual, aufs.5 in aufs-util.git tree. -+$ man -l aufs.5 -+ -+And then, -+$ mkdir /tmp/rw /tmp/aufs -+# mount -t aufs -o br=/tmp/rw:${HOME} none /tmp/aufs -+ -+Here is another example. The result is equivalent. -+# mount -t aufs -o br=/tmp/rw=rw:${HOME}=ro none /tmp/aufs -+ Or -+# mount -t aufs -o br:/tmp/rw none /tmp/aufs -+# mount -o remount,append:${HOME} /tmp/aufs -+ -+Then, you can see whole tree of your home dir through /tmp/aufs. If -+you modify a file under /tmp/aufs, the one on your home directory is -+not affected, instead the same named file will be newly created under -+/tmp/rw. And all of your modification to a file will be applied to -+the one under /tmp/rw. This is called the file based Copy on Write -+(COW) method. -+Aufs mount options are described in aufs.5. -+If you run chroot or something and make your aufs as a root directory, -+then you need to customize the shutdown script. See the aufs manual in -+detail. -+ -+Additionally, there are some sample usages of aufs which are a -+diskless system with network booting, and LiveCD over NFS. -+See sample dir in CVS tree on SourceForge. -+ -+ -+5. Contact -+---------------------------------------- -+When you have any problems or strange behaviour in aufs, please let me -+know with: -+- /proc/mounts (instead of the output of mount(8)) -+- /sys/module/aufs/* -+- /sys/fs/aufs/* (if you have them) -+- /debug/aufs/* (if you have them) -+- linux kernel version -+ if your kernel is not plain, for example modified by distributor, -+ the url where i can download its source is necessary too. -+- aufs version which was printed at loading the module or booting the -+ system, instead of the date you downloaded. -+- configuration (define/undefine CONFIG_AUFS_xxx) -+- kernel configuration or /proc/config.gz (if you have it) -+- LSM (linux security module, if you are using) -+- behaviour which you think to be incorrect -+- actual operation, reproducible one is better -+- mailto: aufs-users at lists.sourceforge.net -+ -+Usually, I don't watch the Public Areas(Bugs, Support Requests, Patches, -+and Feature Requests) on SourceForge. Please join and write to -+aufs-users ML. -+ -+ -+6. Acknowledgements -+---------------------------------------- -+Thanks to everyone who have tried and are using aufs, whoever -+have reported a bug or any feedback. -+ -+Especially donators: -+Tomas Matejicek(slax.org) made a donation (much more than once). -+ Since Apr 2010, Tomas M (the author of Slax and Linux Live -+ scripts) is making "doubling" donations. -+ Unfortunately I cannot list all of the donators, but I really -+ appreciate. -+ It ends Aug 2010, but the ordinary donation URL is still available. -+ -+Dai Itasaka made a donation (2007/8). -+Chuck Smith made a donation (2008/4, 10 and 12). -+Henk Schoneveld made a donation (2008/9). -+Chih-Wei Huang, ASUS, CTC donated Eee PC 4G (2008/10). -+Francois Dupoux made a donation (2008/11). -+Bruno Cesar Ribas and Luis Carlos Erpen de Bona, C3SL serves public -+ aufs2 GIT tree (2009/2). -+William Grant made a donation (2009/3). -+Patrick Lane made a donation (2009/4). -+The Mail Archive (mail-archive.com) made donations (2009/5). -+Nippy Networks (Ed Wildgoose) made a donation (2009/7). -+New Dream Network, LLC (www.dreamhost.com) made a donation (2009/11). -+Pavel Pronskiy made a donation (2011/2). -+Iridium and Inmarsat satellite phone retailer (www.mailasail.com), Nippy -+ Networks (Ed Wildgoose) made a donation for hardware (2011/3). -+Max Lekomcev (DOM-TV project) made a donation (2011/7, 12, 2012/3, 6 and -+11). -+Sam Liddicott made a donation (2011/9). -+Era Scarecrow made a donation (2013/4). -+Bor Ratajc made a donation (2013/4). -+Alessandro Gorreta made a donation (2013/4). -+POIRETTE Marc made a donation (2013/4). -+Alessandro Gorreta made a donation (2013/4). -+lauri kasvandik made a donation (2013/5). -+"pemasu from Finland" made a donation (2013/7). -+The Parted Magic Project made a donation (2013/9 and 11). -+Pavel Barta made a donation (2013/10). -+Nikolay Pertsev made a donation (2014/5). -+James B made a donation (2014/7, 2015/7, and 2021/12). -+Stefano Di Biase made a donation (2014/8). -+Daniel Epellei made a donation (2015/1). -+OmegaPhil made a donation (2016/1, 2018/4). -+Tomasz Szewczyk made a donation (2016/4). -+James Burry made a donation (2016/12). -+Carsten Rose made a donation (2018/9). -+Porteus Kiosk made a donation (2018/10). -+huronOS team: Enya Quetzalli made donations (2022/5, 2023/5, 8 and 2024/8). -+Vasily Mikhaylichenko made a donation (2023/5 and 2024/5). -+ -+Thank you very much. -+Donations are always, including future donations, very important and -+helpful for me to keep on developing aufs. -+ -+ -+7. -+---------------------------------------- -+If you are an experienced user, no explanation is needed. Aufs is -+just a linux filesystem. -+ -+ -+Enjoy! -+ -+# Local variables: ; -+# mode: text; -+# End: ; -diff -Naur null/fs/aufs/aufs.h linux-6.6.63/fs/aufs/aufs.h ---- /dev/null -+++ linux-6.6.63/fs/aufs/aufs.h 2024-12-18 15:12:59.293519613 +0300 -@@ -0,0 +1,62 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * all header files -+ */ -+ -+#ifndef __AUFS_H__ -+#define __AUFS_H__ -+ -+#ifdef __KERNEL__ -+ -+#define AuStub(type, name, body, ...) \ -+ static inline type name(__VA_ARGS__) { body; } -+ -+#define AuStubVoid(name, ...) \ -+ AuStub(void, name, , __VA_ARGS__) -+#define AuStubInt0(name, ...) \ -+ AuStub(int, name, return 0, __VA_ARGS__) -+ -+#include "debug.h" -+ -+#include "branch.h" -+#include "cpup.h" -+#include "dcsub.h" -+#include "dbgaufs.h" -+#include "dentry.h" -+#include "dir.h" -+#include "dirren.h" -+#include "dynop.h" -+#include "file.h" -+#include "fstype.h" -+#include "hbl.h" -+#include "inode.h" -+#include "lcnt.h" -+#include "loop.h" -+#include "module.h" -+#include "opts.h" -+#include "rwsem.h" -+#include "super.h" -+#include "sysaufs.h" -+#include "vfsub.h" -+#include "whout.h" -+#include "wkq.h" -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_H__ */ -diff -Naur null/fs/aufs/branch.c linux-6.6.63/fs/aufs/branch.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/branch.c 2024-12-18 15:12:59.293519613 +0300 -@@ -0,0 +1,1427 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * branch management -+ */ -+ -+#include -+#include -+#include "aufs.h" -+ -+/* -+ * free a single branch -+ */ -+static void au_br_do_free(struct au_branch *br) -+{ -+ int i; -+ struct au_wbr *wbr; -+ struct au_dykey **key; -+ -+ au_hnotify_fin_br(br); -+ /* always, regardless the mount option */ -+ au_dr_hino_free(&br->br_dirren); -+ au_xino_put(br); -+ -+ AuLCntZero(au_lcnt_read(&br->br_nfiles, /*do_rev*/0)); -+ au_lcnt_fin(&br->br_nfiles, /*do_sync*/0); -+ AuLCntZero(au_lcnt_read(&br->br_count, /*do_rev*/0)); -+ au_lcnt_fin(&br->br_count, /*do_sync*/0); -+ -+ wbr = br->br_wbr; -+ if (wbr) { -+ for (i = 0; i < AuBrWh_Last; i++) -+ dput(wbr->wbr_wh[i]); -+ AuDebugOn(atomic_read(&wbr->wbr_wh_running)); -+ AuRwDestroy(&wbr->wbr_wh_rwsem); -+ } -+ -+ if (br->br_fhsm) { -+ au_br_fhsm_fin(br->br_fhsm); -+ au_kfree_try_rcu(br->br_fhsm); -+ } -+ -+ key = br->br_dykey; -+ for (i = 0; i < AuBrDynOp; i++, key++) -+ if (*key) -+ au_dy_put(*key); -+ else -+ break; -+ -+ /* recursive lock, s_umount of branch's */ -+ /* synchronize_rcu(); */ /* why? */ -+ lockdep_off(); -+ path_put(&br->br_path); -+ lockdep_on(); -+ au_kfree_rcu(wbr); -+ au_lcnt_wait_for_fin(&br->br_nfiles); -+ au_lcnt_wait_for_fin(&br->br_count); -+ /* I don't know why, but percpu_refcount requires this */ -+ /* synchronize_rcu(); */ -+ au_kfree_rcu(br); -+} -+ -+/* -+ * frees all branches -+ */ -+void au_br_free(struct au_sbinfo *sbinfo) -+{ -+ aufs_bindex_t bmax; -+ struct au_branch **br; -+ -+ AuRwMustWriteLock(&sbinfo->si_rwsem); -+ -+ bmax = sbinfo->si_bbot + 1; -+ br = sbinfo->si_branch; -+ while (bmax--) -+ au_br_do_free(*br++); -+} -+ -+/* -+ * find the index of a branch which is specified by @br_id. -+ */ -+int au_br_index(struct super_block *sb, aufs_bindex_t br_id) -+{ -+ aufs_bindex_t bindex, bbot; -+ -+ bbot = au_sbbot(sb); -+ for (bindex = 0; bindex <= bbot; bindex++) -+ if (au_sbr_id(sb, bindex) == br_id) -+ return bindex; -+ return -1; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * add a branch -+ */ -+ -+static int test_overlap(struct super_block *sb, struct dentry *h_adding, -+ struct dentry *h_root) -+{ -+ if (unlikely(h_adding == h_root -+ || au_test_loopback_overlap(sb, h_adding))) -+ return 1; -+ if (h_adding->d_sb != h_root->d_sb) -+ return 0; -+ return au_test_subdir(h_adding, h_root) -+ || au_test_subdir(h_root, h_adding); -+} -+ -+/* -+ * returns a newly allocated branch. @new_nbranch is a number of branches -+ * after adding a branch. -+ */ -+static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch, -+ int perm) -+{ -+ struct au_branch *add_branch; -+ struct dentry *root; -+ struct inode *inode; -+ int err; -+ -+ err = -ENOMEM; -+ add_branch = kzalloc(sizeof(*add_branch), GFP_NOFS); -+ if (unlikely(!add_branch)) -+ goto out; -+ add_branch->br_xino = au_xino_alloc(/*nfile*/1); -+ if (unlikely(!add_branch->br_xino)) -+ goto out_br; -+ err = au_hnotify_init_br(add_branch, perm); -+ if (unlikely(err)) -+ goto out_xino; -+ -+ if (au_br_writable(perm)) { -+ /* may be freed separately at changing the branch permission */ -+ add_branch->br_wbr = kzalloc(sizeof(*add_branch->br_wbr), -+ GFP_NOFS); -+ if (unlikely(!add_branch->br_wbr)) -+ goto out_hnotify; -+ } -+ -+ if (au_br_fhsm(perm)) { -+ err = au_fhsm_br_alloc(add_branch); -+ if (unlikely(err)) -+ goto out_wbr; -+ } -+ -+ root = sb->s_root; -+ err = au_sbr_realloc(au_sbi(sb), new_nbranch, /*may_shrink*/0); -+ if (!err) -+ err = au_di_realloc(au_di(root), new_nbranch, /*may_shrink*/0); -+ if (!err) { -+ inode = d_inode(root); -+ err = au_hinode_realloc(au_ii(inode), new_nbranch, -+ /*may_shrink*/0); -+ } -+ if (!err) -+ return add_branch; /* success */ -+ -+out_wbr: -+ au_kfree_rcu(add_branch->br_wbr); -+out_hnotify: -+ au_hnotify_fin_br(add_branch); -+out_xino: -+ au_xino_put(add_branch); -+out_br: -+ au_kfree_rcu(add_branch); -+out: -+ return ERR_PTR(err); -+} -+ -+/* -+ * test if the branch permission is legal or not. -+ */ -+static int test_br(struct inode *inode, int brperm, char *path) -+{ -+ int err; -+ -+ err = (au_br_writable(brperm) && IS_RDONLY(inode)); -+ if (!err) -+ goto out; -+ -+ err = -EINVAL; -+ pr_err("write permission for readonly mount or inode, %s\n", path); -+ -+out: -+ return err; -+} -+ -+/* -+ * returns: -+ * 0: success, the caller will add it -+ * plus: success, it is already unified, the caller should ignore it -+ * minus: error -+ */ -+static int test_add(struct super_block *sb, struct au_opt_add *add, int remount) -+{ -+ int err; -+ aufs_bindex_t bbot, bindex; -+ struct dentry *root, *h_dentry; -+ struct inode *inode, *h_inode; -+ -+ root = sb->s_root; -+ bbot = au_sbbot(sb); -+ if (unlikely(bbot >= 0 -+ && au_find_dbindex(root, add->path.dentry) >= 0)) { -+ err = 1; -+ if (!remount) { -+ err = -EINVAL; -+ pr_err("%s duplicated\n", add->pathname); -+ } -+ goto out; -+ } -+ -+ err = -ENOSPC; /* -E2BIG; */ -+ if (unlikely(AUFS_BRANCH_MAX <= add->bindex -+ || AUFS_BRANCH_MAX - 1 <= bbot)) { -+ pr_err("number of branches exceeded %s\n", add->pathname); -+ goto out; -+ } -+ -+ err = -EDOM; -+ if (unlikely(add->bindex < 0 || bbot + 1 < add->bindex)) { -+ pr_err("bad index %d\n", add->bindex); -+ goto out; -+ } -+ -+ inode = d_inode(add->path.dentry); -+ err = -ENOENT; -+ if (unlikely(!vfsub_inode_nlink(inode, AU_I_UNKNOWN))) { -+ pr_err("no existence %s\n", add->pathname); -+ goto out; -+ } -+ -+ err = -EINVAL; -+ if (unlikely(inode->i_sb == sb)) { -+ pr_err("%s must be outside\n", add->pathname); -+ goto out; -+ } -+ -+ if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) { -+ pr_err("unsupported filesystem, %s (%s)\n", -+ add->pathname, au_sbtype(inode->i_sb)); -+ goto out; -+ } -+ -+ if (unlikely(inode->i_sb->s_stack_depth)) { -+ pr_err("already stacked, %s (%s)\n", -+ add->pathname, au_sbtype(inode->i_sb)); -+ goto out; -+ } -+ -+ err = test_br(d_inode(add->path.dentry), add->perm, add->pathname); -+ if (unlikely(err)) -+ goto out; -+ -+ if (bbot < 0) -+ return 0; /* success */ -+ -+ err = -EINVAL; -+ for (bindex = 0; bindex <= bbot; bindex++) -+ if (unlikely(test_overlap(sb, add->path.dentry, -+ au_h_dptr(root, bindex)))) { -+ pr_err("%s is overlapped\n", add->pathname); -+ goto out; -+ } -+ -+ err = 0; -+ if (au_opt_test(au_mntflags(sb), WARN_PERM)) { -+ 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)) -+ pr_warn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n", -+ add->pathname, -+ i_uid_read(inode), i_gid_read(inode), -+ (inode->i_mode & S_IALLUGO), -+ i_uid_read(h_inode), i_gid_read(h_inode), -+ (h_inode->i_mode & S_IALLUGO)); -+ } -+ -+out: -+ return err; -+} -+ -+/* -+ * initialize or clean the whiteouts for an adding branch -+ */ -+static int au_br_init_wh(struct super_block *sb, struct au_branch *br, -+ int new_perm) -+{ -+ int err, old_perm; -+ aufs_bindex_t bindex; -+ struct inode *h_inode; -+ struct au_wbr *wbr; -+ struct au_hinode *hdir; -+ struct dentry *h_dentry; -+ -+ err = vfsub_mnt_want_write(au_br_mnt(br)); -+ if (unlikely(err)) -+ goto out; -+ -+ wbr = br->br_wbr; -+ old_perm = br->br_perm; -+ br->br_perm = new_perm; -+ hdir = NULL; -+ h_inode = NULL; -+ bindex = au_br_index(sb, br->br_id); -+ if (0 <= bindex) { -+ hdir = au_hi(d_inode(sb->s_root), bindex); -+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT); -+ } else { -+ h_dentry = au_br_dentry(br); -+ h_inode = d_inode(h_dentry); -+ inode_lock_nested(h_inode, AuLsc_I_PARENT); -+ } -+ if (!wbr) -+ err = au_wh_init(br, sb); -+ else { -+ wbr_wh_write_lock(wbr); -+ err = au_wh_init(br, sb); -+ wbr_wh_write_unlock(wbr); -+ } -+ if (hdir) -+ au_hn_inode_unlock(hdir); -+ else -+ inode_unlock(h_inode); -+ vfsub_mnt_drop_write(au_br_mnt(br)); -+ br->br_perm = old_perm; -+ -+ if (!err && wbr && !au_br_writable(new_perm)) { -+ au_kfree_rcu(wbr); -+ br->br_wbr = NULL; -+ } -+ -+out: -+ return err; -+} -+ -+static int au_wbr_init(struct au_branch *br, struct super_block *sb, -+ int perm) -+{ -+ int err; -+ struct kstatfs kst; -+ struct au_wbr *wbr; -+ -+ wbr = br->br_wbr; -+ au_rw_init(&wbr->wbr_wh_rwsem); -+ atomic_set(&wbr->wbr_wh_running, 0); -+ -+ /* -+ * a limit for rmdir/rename a dir -+ * cf. AUFS_MAX_NAMELEN in include/uapi/linux/aufs_type.h -+ */ -+ err = vfs_statfs(&br->br_path, &kst); -+ if (unlikely(err)) -+ goto out; -+ err = -EINVAL; -+ if (kst.f_namelen >= NAME_MAX) -+ err = au_br_init_wh(sb, br, perm); -+ else -+ pr_err("%pd(%s), unsupported namelen %ld\n", -+ au_br_dentry(br), -+ au_sbtype(au_br_dentry(br)->d_sb), kst.f_namelen); -+ -+out: -+ return err; -+} -+ -+/* initialize a new branch */ -+static int au_br_init(struct au_branch *br, struct super_block *sb, -+ struct au_opt_add *add) -+{ -+ int err; -+ struct au_branch *brbase; -+ struct file *xf; -+ struct inode *h_inode; -+ -+ err = 0; -+ br->br_perm = add->perm; -+ br->br_path = add->path; /* set first, path_get() later */ -+ spin_lock_init(&br->br_dykey_lock); -+ au_lcnt_init(&br->br_nfiles, /*release*/NULL); -+ au_lcnt_init(&br->br_count, /*release*/NULL); -+ br->br_id = au_new_br_id(sb); -+ AuDebugOn(br->br_id < 0); -+ -+ /* always, regardless the given option */ -+ err = au_dr_br_init(sb, br, &add->path); -+ if (unlikely(err)) -+ goto out_err; -+ -+ if (au_br_writable(add->perm)) { -+ err = au_wbr_init(br, sb, add->perm); -+ if (unlikely(err)) -+ goto out_err; -+ } -+ -+ if (au_opt_test(au_mntflags(sb), XINO)) { -+ brbase = au_sbr(sb, 0); -+ xf = au_xino_file(brbase->br_xino, /*idx*/-1); -+ AuDebugOn(!xf); -+ h_inode = d_inode(add->path.dentry); -+ err = au_xino_init_br(sb, br, h_inode->i_ino, &xf->f_path); -+ if (unlikely(err)) { -+ AuDebugOn(au_xino_file(br->br_xino, /*idx*/-1)); -+ goto out_err; -+ } -+ } -+ -+ sysaufs_br_init(br); -+ path_get(&br->br_path); -+ goto out; /* success */ -+ -+out_err: -+ memset(&br->br_path, 0, sizeof(br->br_path)); -+out: -+ return err; -+} -+ -+static void au_br_do_add_brp(struct au_sbinfo *sbinfo, aufs_bindex_t bindex, -+ struct au_branch *br, aufs_bindex_t bbot, -+ aufs_bindex_t amount) -+{ -+ struct au_branch **brp; -+ -+ AuRwMustWriteLock(&sbinfo->si_rwsem); -+ -+ brp = sbinfo->si_branch + bindex; -+ memmove(brp + 1, brp, sizeof(*brp) * amount); -+ *brp = br; -+ sbinfo->si_bbot++; -+ if (unlikely(bbot < 0)) -+ sbinfo->si_bbot = 0; -+} -+ -+static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex, -+ aufs_bindex_t bbot, aufs_bindex_t amount) -+{ -+ struct au_hdentry *hdp; -+ -+ AuRwMustWriteLock(&dinfo->di_rwsem); -+ -+ hdp = au_hdentry(dinfo, bindex); -+ memmove(hdp + 1, hdp, sizeof(*hdp) * amount); -+ au_h_dentry_init(hdp); -+ dinfo->di_bbot++; -+ if (unlikely(bbot < 0)) -+ dinfo->di_btop = 0; -+} -+ -+static void au_br_do_add_hip(struct au_iinfo *iinfo, aufs_bindex_t bindex, -+ aufs_bindex_t bbot, aufs_bindex_t amount) -+{ -+ struct au_hinode *hip; -+ -+ AuRwMustWriteLock(&iinfo->ii_rwsem); -+ -+ hip = au_hinode(iinfo, bindex); -+ memmove(hip + 1, hip, sizeof(*hip) * amount); -+ au_hinode_init(hip); -+ iinfo->ii_bbot++; -+ if (unlikely(bbot < 0)) -+ iinfo->ii_btop = 0; -+} -+ -+static void au_br_do_add(struct super_block *sb, struct au_branch *br, -+ aufs_bindex_t bindex) -+{ -+ struct dentry *root, *h_dentry; -+ struct inode *root_inode, *h_inode; -+ aufs_bindex_t bbot, amount; -+ -+ root = sb->s_root; -+ root_inode = d_inode(root); -+ bbot = au_sbbot(sb); -+ amount = bbot + 1 - bindex; -+ h_dentry = au_br_dentry(br); -+ au_sbilist_lock(); -+ au_br_do_add_brp(au_sbi(sb), bindex, br, bbot, amount); -+ au_br_do_add_hdp(au_di(root), bindex, bbot, amount); -+ au_br_do_add_hip(au_ii(root_inode), bindex, bbot, amount); -+ au_set_h_dptr(root, bindex, dget(h_dentry)); -+ h_inode = d_inode(h_dentry); -+ au_set_h_iptr(root_inode, bindex, au_igrab(h_inode), /*flags*/0); -+ au_sbilist_unlock(); -+} -+ -+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount) -+{ -+ int err; -+ aufs_bindex_t bbot, add_bindex; -+ struct dentry *root, *h_dentry; -+ struct inode *root_inode; -+ struct au_branch *add_branch; -+ -+ root = sb->s_root; -+ root_inode = d_inode(root); -+ IMustLock(root_inode); -+ IiMustWriteLock(root_inode); -+ err = test_add(sb, add, remount); -+ if (unlikely(err < 0)) -+ goto out; -+ if (err) { -+ err = 0; -+ goto out; /* success */ -+ } -+ -+ bbot = au_sbbot(sb); -+ add_branch = au_br_alloc(sb, bbot + 2, add->perm); -+ err = PTR_ERR(add_branch); -+ if (IS_ERR(add_branch)) -+ goto out; -+ -+ err = au_br_init(add_branch, sb, add); -+ if (unlikely(err)) { -+ au_br_do_free(add_branch); -+ goto out; -+ } -+ -+ add_bindex = add->bindex; -+ sysaufs_brs_del(sb, add_bindex); /* remove successors */ -+ au_br_do_add(sb, add_branch, add_bindex); -+ sysaufs_brs_add(sb, add_bindex); /* append successors */ -+ dbgaufs_brs_add(sb, add_bindex, /*topdown*/0); /* rename successors */ -+ -+ h_dentry = add->path.dentry; -+ if (!add_bindex) { -+ au_cpup_attr_all(root_inode, /*force*/1); -+ sb->s_maxbytes = h_dentry->d_sb->s_maxbytes; -+ } else -+ au_add_nlink(root_inode, d_inode(h_dentry)); -+ -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static unsigned long long au_farray_cb(struct super_block *sb, void *a, -+ unsigned long long max __maybe_unused, -+ void *arg) -+{ -+ unsigned long long n; -+ struct file **p, *f; -+ struct hlist_bl_head *files; -+ struct hlist_bl_node *pos; -+ struct au_finfo *finfo; -+ -+ n = 0; -+ p = a; -+ files = &au_sbi(sb)->si_files; -+ hlist_bl_lock(files); -+ hlist_bl_for_each_entry(finfo, pos, files, fi_hlist) { -+ f = finfo->fi_file; -+ if (file_count(f) -+ && !special_file(file_inode(f)->i_mode)) { -+ get_file(f); -+ *p++ = f; -+ n++; -+ AuDebugOn(n > max); -+ } -+ } -+ hlist_bl_unlock(files); -+ -+ return n; -+} -+ -+static struct file **au_farray_alloc(struct super_block *sb, -+ unsigned long long *max) -+{ -+ struct au_sbinfo *sbi; -+ -+ sbi = au_sbi(sb); -+ *max = au_lcnt_read(&sbi->si_nfiles, /*do_rev*/1); -+ return au_array_alloc(max, au_farray_cb, sb, /*arg*/NULL); -+} -+ -+static void au_farray_free(struct file **a, unsigned long long max) -+{ -+ unsigned long long ull; -+ -+ for (ull = 0; ull < max; ull++) -+ if (a[ull]) -+ fput(a[ull]); -+ kvfree(a); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * delete a branch -+ */ -+ -+/* to show the line number, do not make it inlined function */ -+#define AuVerbose(do_info, fmt, ...) do { \ -+ if (do_info) \ -+ pr_info(fmt, ##__VA_ARGS__); \ -+} while (0) -+ -+static int au_test_ibusy(struct inode *inode, aufs_bindex_t btop, -+ aufs_bindex_t bbot) -+{ -+ return (inode && !S_ISDIR(inode->i_mode)) || btop == bbot; -+} -+ -+static int au_test_dbusy(struct dentry *dentry, aufs_bindex_t btop, -+ aufs_bindex_t bbot) -+{ -+ return au_test_ibusy(d_inode(dentry), btop, bbot); -+} -+ -+/* -+ * test if the branch is deletable or not. -+ */ -+static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex, -+ unsigned int sigen, const unsigned int verbose) -+{ -+ int err, i, j, ndentry; -+ aufs_bindex_t btop, bbot; -+ struct au_dcsub_pages dpages; -+ struct au_dpage *dpage; -+ struct dentry *d; -+ -+ err = au_dpages_init(&dpages, GFP_NOFS); -+ if (unlikely(err)) -+ goto out; -+ err = au_dcsub_pages(&dpages, root, NULL, NULL); -+ if (unlikely(err)) -+ goto out_dpages; -+ -+ for (i = 0; !err && i < dpages.ndpage; i++) { -+ dpage = dpages.dpages + i; -+ ndentry = dpage->ndentry; -+ for (j = 0; !err && j < ndentry; j++) { -+ d = dpage->dentries[j]; -+ AuDebugOn(au_dcount(d) <= 0); -+ if (!au_digen_test(d, sigen)) { -+ di_read_lock_child(d, AuLock_IR); -+ if (unlikely(au_dbrange_test(d))) { -+ di_read_unlock(d, AuLock_IR); -+ continue; -+ } -+ } else { -+ di_write_lock_child(d); -+ if (unlikely(au_dbrange_test(d))) { -+ di_write_unlock(d); -+ continue; -+ } -+ err = au_reval_dpath(d, sigen); -+ if (!err) -+ di_downgrade_lock(d, AuLock_IR); -+ else { -+ di_write_unlock(d); -+ break; -+ } -+ } -+ -+ /* AuDbgDentry(d); */ -+ btop = au_dbtop(d); -+ bbot = au_dbbot(d); -+ if (btop <= bindex -+ && bindex <= bbot -+ && au_h_dptr(d, bindex) -+ && au_test_dbusy(d, btop, bbot)) { -+ err = -EBUSY; -+ AuVerbose(verbose, "busy %pd\n", d); -+ AuDbgDentry(d); -+ } -+ di_read_unlock(d, AuLock_IR); -+ } -+ } -+ -+out_dpages: -+ au_dpages_free(&dpages); -+out: -+ return err; -+} -+ -+static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex, -+ unsigned int sigen, const unsigned int verbose) -+{ -+ int err; -+ unsigned long long max, ull; -+ struct inode *i, **array; -+ aufs_bindex_t btop, bbot; -+ -+ array = au_iarray_alloc(sb, &max); -+ err = PTR_ERR(array); -+ if (IS_ERR(array)) -+ goto out; -+ -+ err = 0; -+ AuDbg("b%d\n", bindex); -+ for (ull = 0; !err && ull < max; ull++) { -+ i = array[ull]; -+ if (unlikely(!i)) -+ break; -+ if (i->i_ino == AUFS_ROOT_INO) -+ continue; -+ -+ /* AuDbgInode(i); */ -+ if (au_iigen(i, NULL) == sigen) -+ ii_read_lock_child(i); -+ else { -+ ii_write_lock_child(i); -+ err = au_refresh_hinode_self(i); -+ au_iigen_dec(i); -+ if (!err) -+ ii_downgrade_lock(i); -+ else { -+ ii_write_unlock(i); -+ break; -+ } -+ } -+ -+ btop = au_ibtop(i); -+ bbot = au_ibbot(i); -+ if (btop <= bindex -+ && bindex <= bbot -+ && au_h_iptr(i, bindex) -+ && au_test_ibusy(i, btop, bbot)) { -+ err = -EBUSY; -+ AuVerbose(verbose, "busy i%lu\n", i->i_ino); -+ AuDbgInode(i); -+ } -+ ii_read_unlock(i); -+ } -+ au_iarray_free(array, max); -+ -+out: -+ return err; -+} -+ -+static int test_children_busy(struct dentry *root, aufs_bindex_t bindex, -+ const unsigned int verbose) -+{ -+ int err; -+ unsigned int sigen; -+ -+ sigen = au_sigen(root->d_sb); -+ DiMustNoWaiters(root); -+ IiMustNoWaiters(d_inode(root)); -+ di_write_unlock(root); -+ err = test_dentry_busy(root, bindex, sigen, verbose); -+ if (!err) -+ err = test_inode_busy(root->d_sb, bindex, sigen, verbose); -+ di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */ -+ -+ return err; -+} -+ -+static int test_dir_busy(struct file *file, aufs_bindex_t br_id, -+ struct file **to_free, int *idx) -+{ -+ int err; -+ unsigned char matched, root; -+ aufs_bindex_t bindex, bbot; -+ struct au_fidir *fidir; -+ struct au_hfile *hfile; -+ -+ err = 0; -+ root = IS_ROOT(file->f_path.dentry); -+ if (root) { -+ get_file(file); -+ to_free[*idx] = file; -+ (*idx)++; -+ goto out; -+ } -+ -+ matched = 0; -+ fidir = au_fi(file)->fi_hdir; -+ AuDebugOn(!fidir); -+ bbot = au_fbbot_dir(file); -+ for (bindex = au_fbtop(file); bindex <= bbot; bindex++) { -+ hfile = fidir->fd_hfile + bindex; -+ if (!hfile->hf_file) -+ continue; -+ -+ if (hfile->hf_br->br_id == br_id) { -+ matched = 1; -+ break; -+ } -+ } -+ if (matched) -+ err = -EBUSY; -+ -+out: -+ return err; -+} -+ -+static int test_file_busy(struct super_block *sb, aufs_bindex_t br_id, -+ struct file **to_free, int opened) -+{ -+ int err, idx; -+ unsigned long long ull, max; -+ aufs_bindex_t btop; -+ struct file *file, **array; -+ struct dentry *root; -+ struct au_hfile *hfile; -+ -+ array = au_farray_alloc(sb, &max); -+ err = PTR_ERR(array); -+ if (IS_ERR(array)) -+ goto out; -+ -+ err = 0; -+ idx = 0; -+ root = sb->s_root; -+ di_write_unlock(root); -+ for (ull = 0; ull < max; ull++) { -+ file = array[ull]; -+ if (unlikely(!file)) -+ break; -+ -+ /* AuDbg("%pD\n", file); */ -+ fi_read_lock(file); -+ btop = au_fbtop(file); -+ if (!d_is_dir(file->f_path.dentry)) { -+ hfile = &au_fi(file)->fi_htop; -+ if (hfile->hf_br->br_id == br_id) -+ err = -EBUSY; -+ } else -+ err = test_dir_busy(file, br_id, to_free, &idx); -+ fi_read_unlock(file); -+ if (unlikely(err)) -+ break; -+ } -+ di_write_lock_child(root); -+ au_farray_free(array, max); -+ AuDebugOn(idx > opened); -+ -+out: -+ return err; -+} -+ -+static void br_del_file(struct file **to_free, unsigned long long opened, -+ aufs_bindex_t br_id) -+{ -+ unsigned long long ull; -+ aufs_bindex_t bindex, btop, bbot, bfound; -+ struct file *file; -+ struct au_fidir *fidir; -+ struct au_hfile *hfile; -+ -+ for (ull = 0; ull < opened; ull++) { -+ file = to_free[ull]; -+ if (unlikely(!file)) -+ break; -+ -+ /* AuDbg("%pD\n", file); */ -+ AuDebugOn(!d_is_dir(file->f_path.dentry)); -+ bfound = -1; -+ fidir = au_fi(file)->fi_hdir; -+ AuDebugOn(!fidir); -+ fi_write_lock(file); -+ btop = au_fbtop(file); -+ bbot = au_fbbot_dir(file); -+ for (bindex = btop; bindex <= bbot; bindex++) { -+ hfile = fidir->fd_hfile + bindex; -+ if (!hfile->hf_file) -+ continue; -+ -+ if (hfile->hf_br->br_id == br_id) { -+ bfound = bindex; -+ break; -+ } -+ } -+ AuDebugOn(bfound < 0); -+ au_set_h_fptr(file, bfound, NULL); -+ if (bfound == btop) { -+ for (btop++; btop <= bbot; btop++) -+ if (au_hf_dir(file, btop)) { -+ au_set_fbtop(file, btop); -+ break; -+ } -+ } -+ fi_write_unlock(file); -+ } -+} -+ -+static void au_br_do_del_brp(struct au_sbinfo *sbinfo, -+ const aufs_bindex_t bindex, -+ const aufs_bindex_t bbot) -+{ -+ struct au_branch **brp, **p; -+ -+ AuRwMustWriteLock(&sbinfo->si_rwsem); -+ -+ brp = sbinfo->si_branch + bindex; -+ if (bindex < bbot) -+ memmove(brp, brp + 1, sizeof(*brp) * (bbot - bindex)); -+ sbinfo->si_branch[0 + bbot] = NULL; -+ sbinfo->si_bbot--; -+ -+ p = au_krealloc(sbinfo->si_branch, sizeof(*p) * bbot, AuGFP_SBILIST, -+ /*may_shrink*/1); -+ if (p) -+ sbinfo->si_branch = p; -+ /* harmless error */ -+} -+ -+static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex, -+ const aufs_bindex_t bbot) -+{ -+ struct au_hdentry *hdp, *p; -+ -+ AuRwMustWriteLock(&dinfo->di_rwsem); -+ -+ hdp = au_hdentry(dinfo, bindex); -+ if (bindex < bbot) -+ memmove(hdp, hdp + 1, sizeof(*hdp) * (bbot - bindex)); -+ /* au_h_dentry_init(au_hdentry(dinfo, bbot); */ -+ dinfo->di_bbot--; -+ -+ p = au_krealloc(dinfo->di_hdentry, sizeof(*p) * bbot, AuGFP_SBILIST, -+ /*may_shrink*/1); -+ if (p) -+ dinfo->di_hdentry = p; -+ /* harmless error */ -+} -+ -+static void au_br_do_del_hip(struct au_iinfo *iinfo, const aufs_bindex_t bindex, -+ const aufs_bindex_t bbot) -+{ -+ struct au_hinode *hip, *p; -+ -+ AuRwMustWriteLock(&iinfo->ii_rwsem); -+ -+ hip = au_hinode(iinfo, bindex); -+ if (bindex < bbot) -+ memmove(hip, hip + 1, sizeof(*hip) * (bbot - bindex)); -+ /* au_hinode_init(au_hinode(iinfo, bbot)); */ -+ iinfo->ii_bbot--; -+ -+ p = au_krealloc(iinfo->ii_hinode, sizeof(*p) * bbot, AuGFP_SBILIST, -+ /*may_shrink*/1); -+ if (p) -+ iinfo->ii_hinode = p; -+ /* harmless error */ -+} -+ -+static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex, -+ struct au_branch *br) -+{ -+ aufs_bindex_t bbot; -+ struct au_sbinfo *sbinfo; -+ struct dentry *root, *h_root; -+ struct inode *inode, *h_inode; -+ struct au_hinode *hinode; -+ -+ SiMustWriteLock(sb); -+ -+ root = sb->s_root; -+ inode = d_inode(root); -+ sbinfo = au_sbi(sb); -+ bbot = sbinfo->si_bbot; -+ -+ h_root = au_h_dptr(root, bindex); -+ hinode = au_hi(inode, bindex); -+ h_inode = au_igrab(hinode->hi_inode); -+ au_hiput(hinode); -+ -+ au_sbilist_lock(); -+ au_br_do_del_brp(sbinfo, bindex, bbot); -+ au_br_do_del_hdp(au_di(root), bindex, bbot); -+ au_br_do_del_hip(au_ii(inode), bindex, bbot); -+ au_sbilist_unlock(); -+ -+ /* ignore an error */ -+ au_dr_br_fin(sb, br); /* always, regardless the mount option */ -+ -+ dput(h_root); -+ iput(h_inode); -+ au_br_do_free(br); -+} -+ -+static unsigned long long empty_cb(struct super_block *sb, void *array, -+ unsigned long long max, void *arg) -+{ -+ return max; -+} -+ -+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount) -+{ -+ int err, rerr, i; -+ unsigned long long opened; -+ unsigned int mnt_flags; -+ aufs_bindex_t bindex, bbot, br_id; -+ unsigned char do_wh, verbose; -+ struct au_branch *br; -+ struct au_wbr *wbr; -+ struct dentry *root; -+ struct file **to_free; -+ -+ err = 0; -+ opened = 0; -+ to_free = NULL; -+ root = sb->s_root; -+ bindex = au_find_dbindex(root, del->h_path.dentry); -+ if (bindex < 0) { -+ if (remount) -+ goto out; /* success */ -+ err = -ENOENT; -+ pr_err("%s no such branch\n", del->pathname); -+ goto out; -+ } -+ AuDbg("bindex b%d\n", bindex); -+ -+ err = -EBUSY; -+ mnt_flags = au_mntflags(sb); -+ verbose = !!au_opt_test(mnt_flags, VERBOSE); -+ bbot = au_sbbot(sb); -+ if (unlikely(!bbot)) { -+ AuVerbose(verbose, "no more branches left\n"); -+ goto out; -+ } -+ -+ br = au_sbr(sb, bindex); -+ AuDebugOn(!path_equal(&br->br_path, &del->h_path)); -+ if (unlikely(au_lcnt_read(&br->br_count, /*do_rev*/1))) { -+ AuVerbose(verbose, "br %pd2 is busy now\n", del->h_path.dentry); -+ goto out; -+ } -+ -+ br_id = br->br_id; -+ opened = au_lcnt_read(&br->br_nfiles, /*do_rev*/1); -+ if (unlikely(opened)) { -+ to_free = au_array_alloc(&opened, empty_cb, sb, NULL); -+ err = PTR_ERR(to_free); -+ if (IS_ERR(to_free)) -+ goto out; -+ -+ err = test_file_busy(sb, br_id, to_free, opened); -+ if (unlikely(err)) { -+ AuVerbose(verbose, "%llu file(s) opened\n", opened); -+ goto out; -+ } -+ } -+ -+ wbr = br->br_wbr; -+ do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph); -+ if (do_wh) { -+ /* instead of WbrWhMustWriteLock(wbr) */ -+ SiMustWriteLock(sb); -+ for (i = 0; i < AuBrWh_Last; i++) { -+ dput(wbr->wbr_wh[i]); -+ wbr->wbr_wh[i] = NULL; -+ } -+ } -+ -+ err = test_children_busy(root, bindex, verbose); -+ if (unlikely(err)) { -+ if (do_wh) -+ goto out_wh; -+ goto out; -+ } -+ -+ err = 0; -+ if (to_free) { -+ /* -+ * now we confirmed the branch is deletable. -+ * let's free the remaining opened dirs on the branch. -+ */ -+ di_write_unlock(root); -+ br_del_file(to_free, opened, br_id); -+ di_write_lock_child(root); -+ } -+ -+ sysaufs_brs_del(sb, bindex); /* remove successors */ -+ dbgaufs_xino_del(br); /* remove one */ -+ au_br_do_del(sb, bindex, br); -+ sysaufs_brs_add(sb, bindex); /* append successors */ -+ dbgaufs_brs_add(sb, bindex, /*topdown*/1); /* rename successors */ -+ -+ if (!bindex) { -+ au_cpup_attr_all(d_inode(root), /*force*/1); -+ sb->s_maxbytes = au_sbr_sb(sb, 0)->s_maxbytes; -+ } else -+ 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); -+ -+ goto out; /* success */ -+ -+out_wh: -+ /* revert */ -+ rerr = au_br_init_wh(sb, br, br->br_perm); -+ if (rerr) -+ pr_warn("failed re-creating base whiteout, %s. (%d)\n", -+ del->pathname, rerr); -+out: -+ if (to_free) -+ au_farray_free(to_free, opened); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_ibusy(struct super_block *sb, struct aufs_ibusy __user *arg) -+{ -+ int err; -+ aufs_bindex_t btop, bbot; -+ struct aufs_ibusy ibusy; -+ struct inode *inode, *h_inode; -+ -+ err = -EPERM; -+ if (unlikely(!capable(CAP_SYS_ADMIN))) -+ goto out; -+ -+ err = copy_from_user(&ibusy, arg, sizeof(ibusy)); -+ if (!err) -+ /* VERIFY_WRITE */ -+ err = !access_ok(&arg->h_ino, sizeof(arg->h_ino)); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ AuTraceErr(err); -+ goto out; -+ } -+ -+ err = -EINVAL; -+ si_read_lock(sb, AuLock_FLUSH); -+ if (unlikely(ibusy.bindex < 0 || ibusy.bindex > au_sbbot(sb))) -+ goto out_unlock; -+ -+ err = 0; -+ ibusy.h_ino = 0; /* invalid */ -+ inode = ilookup(sb, ibusy.ino); -+ if (!inode -+ || inode->i_ino == AUFS_ROOT_INO -+ || au_is_bad_inode(inode)) -+ goto out_unlock; -+ -+ ii_read_lock_child(inode); -+ btop = au_ibtop(inode); -+ bbot = au_ibbot(inode); -+ if (btop <= ibusy.bindex && ibusy.bindex <= bbot) { -+ h_inode = au_h_iptr(inode, ibusy.bindex); -+ if (h_inode && au_test_ibusy(inode, btop, bbot)) -+ ibusy.h_ino = h_inode->i_ino; -+ } -+ ii_read_unlock(inode); -+ iput(inode); -+ -+out_unlock: -+ si_read_unlock(sb); -+ if (!err) { -+ err = __put_user(ibusy.h_ino, &arg->h_ino); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ AuTraceErr(err); -+ } -+ } -+out: -+ return err; -+} -+ -+long au_ibusy_ioctl(struct file *file, unsigned long arg) -+{ -+ return au_ibusy(file->f_path.dentry->d_sb, (void __user *)arg); -+} -+ -+#ifdef CONFIG_COMPAT -+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg) -+{ -+ return au_ibusy(file->f_path.dentry->d_sb, compat_ptr(arg)); -+} -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * change a branch permission -+ */ -+ -+static void au_warn_ima(void) -+{ -+#ifdef CONFIG_IMA -+ /* since it doesn't support mark_files_ro() */ -+ AuWarn1("RW -> RO makes IMA to produce wrong message\n"); -+#endif -+} -+ -+static int do_need_sigen_inc(int a, int b) -+{ -+ return au_br_whable(a) && !au_br_whable(b); -+} -+ -+static int need_sigen_inc(int old, int new) -+{ -+ return do_need_sigen_inc(old, new) -+ || do_need_sigen_inc(new, old); -+} -+ -+static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ int err, do_warn; -+ unsigned int mnt_flags; -+ unsigned long long ull, max; -+ aufs_bindex_t br_id; -+ unsigned char verbose, writer; -+ struct file *file, *hf, **array; -+ struct au_hfile *hfile; -+ struct inode *h_inode; -+ -+ mnt_flags = au_mntflags(sb); -+ verbose = !!au_opt_test(mnt_flags, VERBOSE); -+ -+ array = au_farray_alloc(sb, &max); -+ err = PTR_ERR(array); -+ if (IS_ERR(array)) -+ goto out; -+ -+ do_warn = 0; -+ br_id = au_sbr_id(sb, bindex); -+ for (ull = 0; ull < max; ull++) { -+ file = array[ull]; -+ if (unlikely(!file)) -+ break; -+ -+ /* AuDbg("%pD\n", file); */ -+ fi_read_lock(file); -+ if (unlikely(au_test_mmapped(file))) { -+ err = -EBUSY; -+ AuVerbose(verbose, "mmapped %pD\n", file); -+ AuDbgFile(file); -+ FiMustNoWaiters(file); -+ fi_read_unlock(file); -+ goto out_array; -+ } -+ -+ hfile = &au_fi(file)->fi_htop; -+ hf = hfile->hf_file; -+ 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)) -+ array[ull] = NULL; -+ else { -+ do_warn = 1; -+ get_file(file); -+ } -+ -+ FiMustNoWaiters(file); -+ fi_read_unlock(file); -+ fput(file); -+ } -+ -+ err = 0; -+ if (do_warn) -+ au_warn_ima(); -+ -+ for (ull = 0; ull < max; ull++) { -+ file = array[ull]; -+ if (!file) -+ continue; -+ -+ /* todo: already flushed? */ -+ /* -+ * fs/super.c:mark_files_ro() is gone, but aufs keeps its -+ * approach which resets f_mode and calls mnt_drop_write() and -+ * file_release_write() for each file, because the branch -+ * attribute in aufs world is totally different from the native -+ * fs rw/ro mode. -+ */ -+ /* fi_read_lock(file); */ -+ hfile = &au_fi(file)->fi_htop; -+ hf = hfile->hf_file; -+ /* fi_read_unlock(file); */ -+ spin_lock(&hf->f_lock); -+ writer = !!(hf->f_mode & FMODE_WRITER); -+ hf->f_mode &= ~(FMODE_WRITE | FMODE_WRITER); -+ spin_unlock(&hf->f_lock); -+ if (writer) { -+ h_inode = file_inode(hf); -+ if (hf->f_mode & FMODE_READ) -+ i_readcount_inc(h_inode); -+ put_write_access(h_inode); -+ __mnt_drop_write(hf->f_path.mnt); -+ } -+ } -+ -+out_array: -+ au_farray_free(array, max); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount, -+ int *do_refresh) -+{ -+ int err, rerr; -+ aufs_bindex_t bindex; -+ struct dentry *root; -+ struct au_branch *br; -+ struct au_br_fhsm *bf; -+ -+ root = sb->s_root; -+ bindex = au_find_dbindex(root, mod->h_root); -+ if (bindex < 0) { -+ if (remount) -+ return 0; /* success */ -+ err = -ENOENT; -+ pr_err("%s no such branch\n", mod->path); -+ goto out; -+ } -+ AuDbg("bindex b%d\n", bindex); -+ -+ err = test_br(d_inode(mod->h_root), mod->perm, mod->path); -+ if (unlikely(err)) -+ goto out; -+ -+ br = au_sbr(sb, bindex); -+ AuDebugOn(mod->h_root != au_br_dentry(br)); -+ if (br->br_perm == mod->perm) -+ return 0; /* success */ -+ -+ /* pre-allocate for non-fhsm --> fhsm */ -+ bf = NULL; -+ if (!au_br_fhsm(br->br_perm) && au_br_fhsm(mod->perm)) { -+ err = au_fhsm_br_alloc(br); -+ if (unlikely(err)) -+ goto out; -+ bf = br->br_fhsm; -+ br->br_fhsm = NULL; -+ } -+ -+ if (au_br_writable(br->br_perm)) { -+ /* remove whiteout base */ -+ err = au_br_init_wh(sb, br, mod->perm); -+ if (unlikely(err)) -+ goto out_bf; -+ -+ if (!au_br_writable(mod->perm)) { -+ /* rw --> ro, file might be mmapped */ -+ DiMustNoWaiters(root); -+ IiMustNoWaiters(d_inode(root)); -+ di_write_unlock(root); -+ err = au_br_mod_files_ro(sb, bindex); -+ /* aufs_write_lock() calls ..._child() */ -+ di_write_lock_child(root); -+ -+ if (unlikely(err)) { -+ rerr = -ENOMEM; -+ br->br_wbr = kzalloc(sizeof(*br->br_wbr), -+ GFP_NOFS); -+ if (br->br_wbr) -+ rerr = au_wbr_init(br, sb, br->br_perm); -+ if (unlikely(rerr)) { -+ AuIOErr("nested error %d (%d)\n", -+ rerr, err); -+ br->br_perm = mod->perm; -+ } -+ } -+ } -+ } else if (au_br_writable(mod->perm)) { -+ /* ro --> rw */ -+ err = -ENOMEM; -+ br->br_wbr = kzalloc(sizeof(*br->br_wbr), GFP_NOFS); -+ if (br->br_wbr) { -+ err = au_wbr_init(br, sb, mod->perm); -+ if (unlikely(err)) { -+ au_kfree_rcu(br->br_wbr); -+ br->br_wbr = NULL; -+ } -+ } -+ } -+ if (unlikely(err)) -+ goto out_bf; -+ -+ if (au_br_fhsm(br->br_perm)) { -+ if (!au_br_fhsm(mod->perm)) { -+ /* fhsm --> non-fhsm */ -+ au_br_fhsm_fin(br->br_fhsm); -+ au_kfree_rcu(br->br_fhsm); -+ br->br_fhsm = NULL; -+ } -+ } else if (au_br_fhsm(mod->perm)) -+ /* non-fhsm --> fhsm */ -+ br->br_fhsm = bf; -+ -+ *do_refresh |= need_sigen_inc(br->br_perm, mod->perm); -+ br->br_perm = mod->perm; -+ goto out; /* success */ -+ -+out_bf: -+ au_kfree_try_rcu(bf); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs) -+{ -+ int err; -+ struct kstatfs kstfs; -+ -+ err = vfs_statfs(&br->br_path, &kstfs); -+ if (!err) { -+ stfs->f_blocks = kstfs.f_blocks; -+ stfs->f_bavail = kstfs.f_bavail; -+ stfs->f_files = kstfs.f_files; -+ stfs->f_ffree = kstfs.f_ffree; -+ } -+ -+ return err; -+} -diff -Naur null/fs/aufs/branch.h linux-6.6.63/fs/aufs/branch.h ---- /dev/null -+++ linux-6.6.63/fs/aufs/branch.h 2024-12-18 15:12:59.293519613 +0300 -@@ -0,0 +1,375 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * branch filesystems and xino for them -+ */ -+ -+#ifndef __AUFS_BRANCH_H__ -+#define __AUFS_BRANCH_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include "dirren.h" -+#include "dynop.h" -+#include "lcnt.h" -+#include "rwsem.h" -+#include "super.h" -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* a xino file */ -+struct au_xino { -+ struct file **xi_file; -+ unsigned int xi_nfile; -+ -+ struct { -+ spinlock_t spin; -+ ino_t *array; -+ int total; -+ /* reserved for future use */ -+ /* unsigned long *bitmap; */ -+ wait_queue_head_t wqh; -+ } xi_nondir; -+ -+ struct mutex xi_mtx; /* protects xi_file array */ -+ struct hlist_bl_head xi_writing; -+ -+ atomic_t xi_truncating; -+ -+ struct kref xi_kref; -+}; -+ -+/* File-based Hierarchical Storage Management */ -+struct au_br_fhsm { -+#ifdef CONFIG_AUFS_FHSM -+ struct mutex bf_lock; -+ unsigned long bf_jiffy; -+ struct aufs_stfs bf_stfs; -+ int bf_readable; -+#endif -+}; -+ -+/* members for writable branch only */ -+enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last}; -+struct au_wbr { -+ struct au_rwsem wbr_wh_rwsem; -+ struct dentry *wbr_wh[AuBrWh_Last]; -+ atomic_t wbr_wh_running; -+#define wbr_whbase wbr_wh[AuBrWh_BASE] /* whiteout base */ -+#define wbr_plink wbr_wh[AuBrWh_PLINK] /* pseudo-link dir */ -+#define wbr_orph wbr_wh[AuBrWh_ORPH] /* dir for orphans */ -+ -+ /* mfs mode */ -+ unsigned long long wbr_bytes; -+}; -+ -+/* ext2 has 3 types of operations at least, ext3 has 4 */ -+#define AuBrDynOp (AuDyLast * 4) -+ -+#ifdef CONFIG_AUFS_HFSNOTIFY -+/* support for asynchronous destruction */ -+struct au_br_hfsnotify { -+ struct fsnotify_group *hfsn_group; -+}; -+#endif -+ -+/* sysfs entries */ -+struct au_brsysfs { -+ char name[16]; -+ struct attribute attr; -+}; -+ -+enum { -+ AuBrSysfs_BR, -+ AuBrSysfs_BRID, -+ AuBrSysfs_Last -+}; -+ -+/* protected by superblock rwsem */ -+struct au_branch { -+ struct au_xino *br_xino; -+ -+ aufs_bindex_t br_id; -+ -+ int br_perm; -+ struct path br_path; -+ spinlock_t br_dykey_lock; -+ struct au_dykey *br_dykey[AuBrDynOp]; -+ au_lcnt_t br_nfiles; /* opened files */ -+ au_lcnt_t br_count; /* in-use for other */ -+ -+ struct au_wbr *br_wbr; -+ struct au_br_fhsm *br_fhsm; -+ -+#ifdef CONFIG_AUFS_HFSNOTIFY -+ struct au_br_hfsnotify *br_hfsn; -+#endif -+ -+#ifdef CONFIG_SYSFS -+ /* entries under sysfs per mount-point */ -+ struct au_brsysfs br_sysfs[AuBrSysfs_Last]; -+#endif -+ -+#ifdef CONFIG_DEBUG_FS -+ struct dentry *br_dbgaufs; /* xino */ -+#endif -+ -+ struct au_dr_br br_dirren; -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline struct vfsmount *au_br_mnt(struct au_branch *br) -+{ -+ return br->br_path.mnt; -+} -+ -+static inline struct dentry *au_br_dentry(struct au_branch *br) -+{ -+ return br->br_path.dentry; -+} -+ -+static inline struct mnt_idmap *au_br_idmap(struct au_branch *br) -+{ -+ return mnt_idmap(br->br_path.mnt); -+} -+ -+static inline struct super_block *au_br_sb(struct au_branch *br) -+{ -+ return au_br_mnt(br)->mnt_sb; -+} -+ -+static inline int au_br_rdonly(struct au_branch *br) -+{ -+ return (sb_rdonly(au_br_sb(br)) -+ || !au_br_writable(br->br_perm)) -+ ? -EROFS : 0; -+} -+ -+static inline int au_br_hnotifyable(int brperm __maybe_unused) -+{ -+#ifdef CONFIG_AUFS_HNOTIFY -+ return !(brperm & AuBrPerm_RR); -+#else -+ return 0; -+#endif -+} -+ -+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 && path_noexec(&br->br_path))) -+ err = -EACCES; -+ -+ return err; -+} -+ -+static inline void au_xino_get(struct au_branch *br) -+{ -+ struct au_xino *xi; -+ -+ xi = br->br_xino; -+ if (xi) -+ kref_get(&xi->xi_kref); -+} -+ -+static inline int au_xino_count(struct au_branch *br) -+{ -+ int v; -+ struct au_xino *xi; -+ -+ v = 0; -+ xi = br->br_xino; -+ if (xi) -+ v = kref_read(&xi->xi_kref); -+ -+ return v; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* branch.c */ -+struct au_sbinfo; -+void au_br_free(struct au_sbinfo *sinfo); -+int au_br_index(struct super_block *sb, aufs_bindex_t br_id); -+struct au_opt_add; -+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount); -+struct au_opt_del; -+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount); -+long au_ibusy_ioctl(struct file *file, unsigned long arg); -+#ifdef CONFIG_COMPAT -+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg); -+#endif -+struct au_opt_mod; -+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount, -+ int *do_refresh); -+struct aufs_stfs; -+int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs); -+ -+/* xino.c */ -+static const loff_t au_loff_max = LLONG_MAX; -+ -+aufs_bindex_t au_xi_root(struct super_block *sb, struct dentry *dentry); -+struct file *au_xino_create(struct super_block *sb, char *fpath, int silent, -+ int wbrtop); -+struct file *au_xino_create2(struct super_block *sb, struct path *base, -+ struct file *copy_src); -+struct au_xi_new { -+ struct au_xino *xi; /* switch between xino and xigen */ -+ int idx; -+ struct path *base; -+ struct file *copy_src; -+}; -+struct file *au_xi_new(struct super_block *sb, struct au_xi_new *xinew); -+ -+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, -+ ino_t *ino); -+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, -+ ino_t ino); -+ssize_t xino_fread(struct file *file, void *buf, size_t size, loff_t *pos); -+ssize_t xino_fwrite(struct file *file, void *buf, size_t size, loff_t *pos); -+ -+int au_xib_trunc(struct super_block *sb); -+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex, int idx_begin); -+ -+struct au_xino *au_xino_alloc(unsigned int nfile); -+int au_xino_put(struct au_branch *br); -+struct file *au_xino_file1(struct au_xino *xi); -+ -+struct au_opt_xino; -+void au_xino_clr(struct super_block *sb); -+int au_xino_set(struct super_block *sb, struct au_opt_xino *xiopt, int remount); -+struct file *au_xino_def(struct super_block *sb); -+int au_xino_init_br(struct super_block *sb, struct au_branch *br, ino_t hino, -+ struct path *base); -+ -+ino_t au_xino_new_ino(struct super_block *sb); -+void au_xino_delete_inode(struct inode *inode, const int unlinked); -+ -+void au_xinondir_leave(struct super_block *sb, aufs_bindex_t bindex, -+ ino_t h_ino, int idx); -+int au_xinondir_enter(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, -+ int *idx); -+ -+int au_xino_path(struct seq_file *seq, struct file *file); -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* @idx is signed to accept -1 meaning the first file */ -+static inline struct file *au_xino_file(struct au_xino *xi, int idx) -+{ -+ struct file *file; -+ -+ file = NULL; -+ if (!xi) -+ goto out; -+ -+ if (idx >= 0) { -+ if (idx < xi->xi_nfile) -+ file = xi->xi_file[idx]; -+ } else -+ file = au_xino_file1(xi); -+ -+out: -+ return file; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* Superblock to branch */ -+static inline -+aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ return au_sbr(sb, bindex)->br_id; -+} -+ -+static inline -+struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ return au_br_mnt(au_sbr(sb, bindex)); -+} -+ -+static inline -+struct mnt_idmap *au_sbr_idmap(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ return au_br_idmap(au_sbr(sb, bindex)); -+} -+ -+static inline -+struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ return au_br_sb(au_sbr(sb, bindex)); -+} -+ -+static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ return au_sbr(sb, bindex)->br_perm; -+} -+ -+static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ return au_br_whable(au_sbr_perm(sb, bindex)); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+#define wbr_wh_read_lock(wbr) au_rw_read_lock(&(wbr)->wbr_wh_rwsem) -+#define wbr_wh_write_lock(wbr) au_rw_write_lock(&(wbr)->wbr_wh_rwsem) -+#define wbr_wh_read_trylock(wbr) au_rw_read_trylock(&(wbr)->wbr_wh_rwsem) -+#define wbr_wh_write_trylock(wbr) au_rw_write_trylock(&(wbr)->wbr_wh_rwsem) -+/* -+#define wbr_wh_read_trylock_nested(wbr) \ -+ au_rw_read_trylock_nested(&(wbr)->wbr_wh_rwsem) -+#define wbr_wh_write_trylock_nested(wbr) \ -+ au_rw_write_trylock_nested(&(wbr)->wbr_wh_rwsem) -+*/ -+ -+#define wbr_wh_read_unlock(wbr) au_rw_read_unlock(&(wbr)->wbr_wh_rwsem) -+#define wbr_wh_write_unlock(wbr) au_rw_write_unlock(&(wbr)->wbr_wh_rwsem) -+#define wbr_wh_downgrade_lock(wbr) au_rw_dgrade_lock(&(wbr)->wbr_wh_rwsem) -+ -+#define WbrWhMustNoWaiters(wbr) AuRwMustNoWaiters(&(wbr)->wbr_wh_rwsem) -+#define WbrWhMustAnyLock(wbr) AuRwMustAnyLock(&(wbr)->wbr_wh_rwsem) -+#define WbrWhMustWriteLock(wbr) AuRwMustWriteLock(&(wbr)->wbr_wh_rwsem) -+ -+/* ---------------------------------------------------------------------- */ -+ -+#ifdef CONFIG_AUFS_FHSM -+static inline void au_br_fhsm_init(struct au_br_fhsm *brfhsm) -+{ -+ mutex_init(&brfhsm->bf_lock); -+ brfhsm->bf_jiffy = 0; -+ brfhsm->bf_readable = 0; -+} -+ -+static inline void au_br_fhsm_fin(struct au_br_fhsm *brfhsm) -+{ -+ mutex_destroy(&brfhsm->bf_lock); -+} -+#else -+AuStubVoid(au_br_fhsm_init, struct au_br_fhsm *brfhsm) -+AuStubVoid(au_br_fhsm_fin, struct au_br_fhsm *brfhsm) -+#endif -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_BRANCH_H__ */ -diff -Naur null/fs/aufs/conf.mk linux-6.6.63/fs/aufs/conf.mk ---- /dev/null -+++ linux-6.6.63/fs/aufs/conf.mk 2024-12-18 15:12:59.293519613 +0300 -@@ -0,0 +1,40 @@ -+# SPDX-License-Identifier: GPL-2.0 -+ -+AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS} -+ -+define AuConf -+ifdef ${1} -+AuConfStr += ${1}=${${1}} -+endif -+endef -+ -+AuConfAll = BRANCH_MAX_127 BRANCH_MAX_511 BRANCH_MAX_1023 BRANCH_MAX_32767 \ -+ SBILIST \ -+ HNOTIFY HFSNOTIFY \ -+ EXPORT INO_T_64 \ -+ XATTR \ -+ FHSM \ -+ RDU \ -+ DIRREN \ -+ SHWH \ -+ BR_RAMFS \ -+ BR_FUSE POLL \ -+ BR_HFSPLUS \ -+ BDEV_LOOP \ -+ DEBUG MAGIC_SYSRQ -+$(foreach i, ${AuConfAll}, \ -+ $(eval $(call AuConf,CONFIG_AUFS_${i}))) -+ -+AuConfName = ${obj}/conf.str -+${AuConfName}.tmp: FORCE -+ @echo ${AuConfStr} | tr ' ' '\n' | sed -e 's/^/"/' -e 's/$$/\\n"/' > $@ -+${AuConfName}: ${AuConfName}.tmp -+ @diff -q $< $@ > /dev/null 2>&1 || { \ -+ echo ' GEN ' $@; \ -+ cp -p $< $@; \ -+ } -+FORCE: -+clean-files += ${AuConfName} ${AuConfName}.tmp -+${obj}/sysfs.o: ${AuConfName} -+ -+-include ${srctree}/${src}/conf_priv.mk -diff -Naur null/fs/aufs/cpup.c linux-6.6.63/fs/aufs/cpup.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/cpup.c 2024-12-18 15:12:59.293519613 +0300 -@@ -0,0 +1,1458 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * copy-up functions, see wbr_policy.c for copy-down -+ */ -+ -+#include -+#include -+#include -+#include "aufs.h" -+ -+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags) -+{ -+ const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE -+ | S_NOATIME | S_NOCMTIME | S_AUTOMOUNT; -+ -+ BUILD_BUG_ON(sizeof(iflags) != sizeof(dst->i_flags)); -+ -+ dst->i_flags |= iflags & ~mask; -+ if (au_test_fs_notime(dst->i_sb)) -+ dst->i_flags |= S_NOATIME | S_NOCMTIME; -+} -+ -+void au_cpup_attr_timesizes(struct inode *inode) -+{ -+ struct inode *h_inode; -+ -+ h_inode = au_h_iptr(inode, au_ibtop(inode)); -+ fsstack_copy_attr_times(inode, h_inode); -+ fsstack_copy_inode_size(inode, h_inode); -+} -+ -+void au_cpup_attr_nlink(struct inode *inode, int force) -+{ -+ struct inode *h_inode; -+ struct super_block *sb; -+ aufs_bindex_t bindex, bbot; -+ -+ sb = inode->i_sb; -+ bindex = au_ibtop(inode); -+ h_inode = au_h_iptr(inode, bindex); -+ if (!force -+ && !S_ISDIR(h_inode->i_mode) -+ && au_opt_test(au_mntflags(sb), PLINK) -+ && au_plink_test(inode)) -+ return; -+ -+ /* -+ * 0 can happen in revalidating. -+ * h_inode->i_mutex may not be held here, but it is harmless since once -+ * i_nlink reaches 0, it will never become positive except O_TMPFILE -+ * case. -+ * todo: O_TMPFILE+linkat(AT_SYMLINK_FOLLOW) bypassing aufs may cause -+ * the incorrect link count. -+ */ -+ vfsub_set_nlink(inode, vfsub_inode_nlink(h_inode, AU_I_BRANCH)); -+ -+ /* -+ * fewer nlink makes find(1) noisy, but larger nlink doesn't. -+ * it may includes whplink directory. -+ */ -+ if (S_ISDIR(h_inode->i_mode)) { -+ bbot = au_ibbot(inode); -+ for (bindex++; bindex <= bbot; bindex++) { -+ h_inode = au_h_iptr(inode, bindex); -+ if (h_inode) -+ au_add_nlink(inode, h_inode); -+ } -+ } -+} -+ -+void au_cpup_attr_changeable(struct inode *inode) -+{ -+ struct inode *h_inode; -+ -+ h_inode = au_h_iptr(inode, au_ibtop(inode)); -+ inode->i_mode = h_inode->i_mode; -+ inode->i_uid = h_inode->i_uid; -+ inode->i_gid = h_inode->i_gid; -+ au_cpup_attr_timesizes(inode); -+ au_cpup_attr_flags(inode, h_inode->i_flags); -+} -+ -+void au_cpup_igen(struct inode *inode, struct inode *h_inode) -+{ -+ struct au_iinfo *iinfo = au_ii(inode); -+ -+ IiMustWriteLock(inode); -+ -+ iinfo->ii_higen = h_inode->i_generation; -+ iinfo->ii_hsb1 = h_inode->i_sb; -+} -+ -+void au_cpup_attr_all(struct inode *inode, int force) -+{ -+ struct inode *h_inode; -+ -+ h_inode = au_h_iptr(inode, au_ibtop(inode)); -+ au_cpup_attr_changeable(inode); -+ au_cpup_attr_nlink(inode, force); -+ inode->i_rdev = h_inode->i_rdev; -+ inode->i_blkbits = h_inode->i_blkbits; -+ au_cpup_igen(inode, h_inode); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */ -+ -+/* keep the timestamps of the parent dir when cpup */ -+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry, -+ struct path *h_path) -+{ -+ struct inode *h_inode; -+ -+ dt->dt_dentry = dentry; -+ dt->dt_h_path = *h_path; -+ h_inode = d_inode(h_path->dentry); -+ dt->dt_atime = h_inode->i_atime; -+ dt->dt_mtime = h_inode->i_mtime; -+ /* smp_mb(); */ -+} -+ -+void au_dtime_revert(struct au_dtime *dt) -+{ -+ struct iattr attr; -+ int err; -+ -+ attr.ia_atime = dt->dt_atime; -+ attr.ia_mtime = dt->dt_mtime; -+ attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET -+ | ATTR_ATIME | ATTR_ATIME_SET; -+ -+ /* no delegation since this is a directory */ -+ err = vfsub_notify_change(&dt->dt_h_path, &attr, /*delegated*/NULL); -+ if (unlikely(err)) -+ pr_warn("restoring timestamps failed(%d). ignored\n", err); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* internal use only */ -+struct au_cpup_reg_attr { -+ int valid; -+ struct kstat st; -+ unsigned int iflags; /* inode->i_flags */ -+}; -+ -+static noinline_for_stack -+int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct path *h_src, -+ 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; -+ struct kstat *h_st; -+ struct au_branch *br; -+ -+ br = au_sbr(dst->d_sb, bindex); -+ h_path.mnt = au_br_mnt(br); -+ h_path.dentry = au_h_dptr(dst, bindex); -+ h_idst = d_inode(h_path.dentry); -+ h_isrc = d_inode(h_src->dentry); -+ ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID -+ | ATTR_ATIME | ATTR_MTIME -+ | ATTR_ATIME_SET | ATTR_MTIME_SET; -+ if (h_src_attr && h_src_attr->valid) { -+ h_st = &h_src_attr->st; -+ ia.ia_uid = h_st->uid; -+ ia.ia_gid = h_st->gid; -+ ia.ia_atime = h_st->atime; -+ ia.ia_mtime = h_st->mtime; -+ if (h_idst->i_mode != h_st->mode -+ && !S_ISLNK(h_idst->i_mode)) { -+ ia.ia_valid |= ATTR_MODE; -+ ia.ia_mode = h_st->mode; -+ } -+ sbits = !!(h_st->mode & (S_ISUID | S_ISGID)); -+ au_cpup_attr_flags(h_idst, h_src_attr->iflags); -+ } else { -+ ia.ia_uid = h_isrc->i_uid; -+ ia.ia_gid = h_isrc->i_gid; -+ ia.ia_atime = h_isrc->i_atime; -+ ia.ia_mtime = h_isrc->i_mtime; -+ if (h_idst->i_mode != h_isrc->i_mode -+ && !S_ISLNK(h_idst->i_mode)) { -+ ia.ia_valid |= ATTR_MODE; -+ ia.ia_mode = h_isrc->i_mode; -+ } -+ sbits = !!(h_isrc->i_mode & (S_ISUID | S_ISGID)); -+ au_cpup_attr_flags(h_idst, h_isrc->i_flags); -+ } -+ /* no delegation since it is just created */ -+ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL); -+ -+ /* is this nfs only? */ -+ if (!err && sbits && au_test_nfs(h_path.dentry->d_sb)) { -+ ia.ia_valid = ATTR_FORCE | ATTR_MODE; -+ ia.ia_mode = h_isrc->i_mode; -+ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL); -+ } -+ -+ icex = br->br_perm & AuBrAttr_ICEX; -+ if (!err) { -+ mnt_flags = au_mntflags(dst->d_sb); -+ verbose = !!au_opt_test(mnt_flags, VERBOSE); -+ err = au_cpup_xattr(&h_path, h_src, icex, verbose); -+ } -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_do_copy_file(struct file *dst, struct file *src, loff_t len, -+ char *buf, unsigned long blksize) -+{ -+ int err; -+ size_t sz, rbytes, wbytes; -+ unsigned char all_zero; -+ char *p, *zp; -+ struct inode *h_inode; -+ /* reduce stack usage */ -+ struct iattr *ia; -+ -+ zp = page_address(ZERO_PAGE(0)); -+ if (unlikely(!zp)) -+ return -ENOMEM; /* possible? */ -+ -+ err = 0; -+ all_zero = 0; -+ while (len) { -+ AuDbg("len %lld\n", len); -+ sz = blksize; -+ if (len < blksize) -+ sz = len; -+ -+ rbytes = 0; -+ /* todo: signal_pending? */ -+ while (!rbytes || err == -EAGAIN || err == -EINTR) { -+ rbytes = vfsub_read_k(src, buf, sz, &src->f_pos); -+ err = rbytes; -+ } -+ if (unlikely(err < 0)) -+ break; -+ -+ all_zero = 0; -+ if (len >= rbytes && rbytes == blksize) -+ all_zero = !memcmp(buf, zp, rbytes); -+ if (!all_zero) { -+ wbytes = rbytes; -+ p = buf; -+ while (wbytes) { -+ size_t b; -+ -+ b = vfsub_write_k(dst, p, wbytes, &dst->f_pos); -+ err = b; -+ /* todo: signal_pending? */ -+ if (unlikely(err == -EAGAIN || err == -EINTR)) -+ continue; -+ if (unlikely(err < 0)) -+ break; -+ wbytes -= b; -+ p += b; -+ } -+ if (unlikely(err < 0)) -+ break; -+ } else { -+ loff_t res; -+ -+ AuLabel(hole); -+ res = vfsub_llseek(dst, rbytes, SEEK_CUR); -+ err = res; -+ if (unlikely(res < 0)) -+ break; -+ } -+ len -= rbytes; -+ err = 0; -+ } -+ -+ /* the last block may be a hole */ -+ if (!err && all_zero) { -+ AuLabel(last hole); -+ -+ err = 1; -+ if (au_test_nfs(dst->f_path.dentry->d_sb)) { -+ /* nfs requires this step to make last hole */ -+ /* is this only nfs? */ -+ do { -+ /* todo: signal_pending? */ -+ err = vfsub_write_k(dst, "\0", 1, &dst->f_pos); -+ } while (err == -EAGAIN || err == -EINTR); -+ if (err == 1) -+ dst->f_pos--; -+ } -+ -+ if (err == 1) { -+ ia = (void *)buf; -+ ia->ia_size = dst->f_pos; -+ ia->ia_valid = ATTR_SIZE | ATTR_FILE; -+ ia->ia_file = dst; -+ h_inode = file_inode(dst); -+ inode_lock_nested(h_inode, AuLsc_I_CHILD2); -+ /* no delegation since it is just created */ -+ err = vfsub_notify_change(&dst->f_path, ia, -+ /*delegated*/NULL); -+ inode_unlock(h_inode); -+ } -+ } -+ -+ return err; -+} -+ -+int au_copy_file(struct file *dst, struct file *src, loff_t len) -+{ -+ int err; -+ unsigned long blksize; -+ unsigned char do_kfree; -+ char *buf; -+ struct super_block *h_sb; -+ -+ err = -ENOMEM; -+ h_sb = file_inode(dst)->i_sb; -+ blksize = h_sb->s_blocksize; -+ if (!blksize || PAGE_SIZE < blksize) -+ blksize = PAGE_SIZE; -+ AuDbg("blksize %lu\n", blksize); -+ do_kfree = (blksize != PAGE_SIZE && blksize >= sizeof(struct iattr *)); -+ if (do_kfree) -+ buf = kmalloc(blksize, GFP_NOFS); -+ else -+ buf = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!buf)) -+ goto out; -+ -+ if (len > (1 << 22)) -+ AuDbg("copying a large file %lld\n", (long long)len); -+ -+ src->f_pos = 0; -+ dst->f_pos = 0; -+ err = au_do_copy_file(dst, src, len, buf, blksize); -+ if (do_kfree) { -+ AuDebugOn(!au_kfree_do_sz_test(blksize)); -+ au_kfree_do_rcu(buf); -+ } else -+ free_page((unsigned long)buf); -+ -+out: -+ return err; -+} -+ -+static int au_do_copy(struct file *dst, struct file *src, loff_t len) -+{ -+ int err; -+ struct super_block *h_src_sb; -+ struct inode *h_src_inode; -+ -+ h_src_inode = file_inode(src); -+ h_src_sb = h_src_inode->i_sb; -+ -+ /* XFS acquires inode_lock */ -+ if (!au_test_xfs(h_src_sb)) -+ err = au_copy_file(dst, src, len); -+ else { -+ inode_unlock_shared(h_src_inode); -+ err = au_copy_file(dst, src, len); -+ inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD); -+ } -+ -+ return err; -+} -+ -+static int au_clone_or_copy(struct file *dst, struct file *src, loff_t len) -+{ -+ int err; -+ loff_t lo; -+ struct super_block *h_src_sb; -+ struct inode *h_src_inode; -+ -+ h_src_inode = file_inode(src); -+ h_src_sb = h_src_inode->i_sb; -+ if (h_src_sb != file_inode(dst)->i_sb -+ || !dst->f_op->remap_file_range) { -+ err = au_do_copy(dst, src, len); -+ goto out; -+ } -+ -+ if (!au_test_nfs(h_src_sb)) { -+ inode_unlock_shared(h_src_inode); -+ lo = vfsub_clone_file_range(src, dst, len); -+ inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD); -+ } else -+ lo = vfsub_clone_file_range(src, dst, len); -+ if (lo == len) { -+ err = 0; -+ goto out; /* success */ -+ } else if (lo >= 0) -+ /* todo: possible? */ -+ /* paritially succeeded */ -+ AuDbg("lo %lld, len %lld. Retrying.\n", lo, len); -+ else if (lo != -EOPNOTSUPP) { -+ /* older XFS has a condition in cloning */ -+ err = lo; -+ goto out; -+ } -+ -+ /* the backend fs on NFS may not support cloning */ -+ err = au_do_copy(dst, src, len); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* -+ * to support a sparse file which is opened with O_APPEND, -+ * we need to close the file. -+ */ -+static int au_cp_regular(struct au_cp_generic *cpg) -+{ -+ int err, i; -+ enum { SRC, DST }; -+ struct { -+ aufs_bindex_t bindex; -+ unsigned int flags; -+ struct dentry *dentry; -+ int force_wr; -+ struct file *file; -+ } *f, file[] = { -+ { -+ .bindex = cpg->bsrc, -+ .flags = O_RDONLY | O_NOATIME | O_LARGEFILE, -+ }, -+ { -+ .bindex = cpg->bdst, -+ .flags = O_WRONLY | O_NOATIME | O_LARGEFILE, -+ .force_wr = !!au_ftest_cpup(cpg->flags, RWDST), -+ } -+ }; -+ struct au_branch *br; -+ struct super_block *sb, *h_src_sb; -+ struct inode *h_src_inode; -+ struct task_struct *tsk = current; -+ -+ /* bsrc branch can be ro/rw. */ -+ sb = cpg->dentry->d_sb; -+ f = file; -+ for (i = 0; i < 2; i++, f++) { -+ f->dentry = au_h_dptr(cpg->dentry, f->bindex); -+ f->file = au_h_open(cpg->dentry, f->bindex, f->flags, -+ /*file*/NULL, f->force_wr); -+ if (IS_ERR(f->file)) { -+ err = PTR_ERR(f->file); -+ if (i == SRC) -+ goto out; -+ else -+ goto out_src; -+ } -+ } -+ -+ /* try stopping to update while we copyup */ -+ h_src_inode = d_inode(file[SRC].dentry); -+ h_src_sb = h_src_inode->i_sb; -+ if (!au_test_nfs(h_src_sb)) -+ IMustLock(h_src_inode); -+ err = au_clone_or_copy(file[DST].file, file[SRC].file, cpg->len); -+ -+ /* i wonder if we had O_NO_DELAY_FPUT flag */ -+ if (tsk->flags & PF_KTHREAD) -+ __fput_sync(file[DST].file); -+ else { -+ /* it happened actually */ -+ fput(file[DST].file); -+ /* -+ * too bad. -+ * we have to call both since we don't know which place the file -+ * was added to. -+ */ -+ task_work_run(); -+ flush_delayed_fput(); -+ } -+ br = au_sbr(sb, file[DST].bindex); -+ au_lcnt_dec(&br->br_nfiles); -+ -+out_src: -+ fput(file[SRC].file); -+ br = au_sbr(sb, file[SRC].bindex); -+ au_lcnt_dec(&br->br_nfiles); -+out: -+ return err; -+} -+ -+static int au_do_cpup_regular(struct au_cp_generic *cpg, -+ struct au_cpup_reg_attr *h_src_attr) -+{ -+ int err, rerr; -+ loff_t l; -+ struct path h_path; -+ struct inode *h_src_inode, *h_dst_inode; -+ -+ err = 0; -+ 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; -+ if (cpg->len) { -+ /* try stopping to update while we are referencing */ -+ inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD); -+ au_pin_hdir_unlock(cpg->pin); -+ -+ 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; -+ if (!au_test_nfs(h_src_inode->i_sb)) -+ err = vfsub_getattr(&h_path, &h_src_attr->st); -+ else { -+ inode_unlock_shared(h_src_inode); -+ err = vfsub_getattr(&h_path, &h_src_attr->st); -+ inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD); -+ } -+ if (unlikely(err)) { -+ inode_unlock_shared(h_src_inode); -+ goto out; -+ } -+ h_src_attr->valid = 1; -+ if (!au_test_fs_unlock_for_open(h_src_inode->i_sb)) { -+ err = au_cp_regular(cpg); -+ inode_unlock_shared(h_src_inode); -+ } else { -+ inode_unlock_shared(h_src_inode); -+ err = au_cp_regular(cpg); -+ } -+ rerr = au_pin_hdir_relock(cpg->pin); -+ if (!err && rerr) -+ err = rerr; -+ } -+ if (!err && (h_src_inode->i_state & I_LINKABLE)) { -+ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bdst); -+ 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); -+ } -+ -+out: -+ return err; -+} -+ -+static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src, -+ struct inode *h_dir) -+{ -+ int err; -+ DEFINE_DELAYED_CALL(done); -+ const char *sym; -+ -+ sym = vfs_get_link(h_src, &done); -+ err = PTR_ERR(sym); -+ if (IS_ERR(sym)) -+ goto out; -+ -+ err = vfsub_symlink(h_dir, h_path, sym); -+ -+out: -+ do_delayed_call(&done); -+ return err; -+} -+ -+/* -+ * regardless 'acl' option, reset all ACL. -+ * All ACL will be copied up later from the original entry on the lower branch. -+ */ -+static int au_reset_acl(struct path *h_path, umode_t mode) -+{ -+ int err; -+ struct dentry *h_dentry; -+ /* struct inode *h_inode; */ -+ struct mnt_idmap *h_idmap; -+ -+ h_idmap = mnt_idmap(h_path->mnt); -+ h_dentry = h_path->dentry; -+ /* h_inode = d_inode(h_dentry); */ -+ /* forget_all_cached_acls(h_inode)); */ -+ err = vfsub_remove_acl(h_idmap, h_dentry, XATTR_NAME_POSIX_ACL_ACCESS); -+ AuTraceErr(err); -+ if (err == -EOPNOTSUPP) -+ err = 0; -+ if (!err) -+ err = vfsub_acl_chmod(h_idmap, h_dentry, mode); -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_do_cpup_dir(struct au_cp_generic *cpg, struct dentry *dst_parent, -+ struct inode *h_dir, struct path *h_path) -+{ -+ int err; -+ struct inode *dir, *inode; -+ struct mnt_idmap *h_idmap; -+ -+ h_idmap = mnt_idmap(h_path->mnt); -+ err = vfsub_remove_acl(h_idmap, h_path->dentry, -+ XATTR_NAME_POSIX_ACL_DEFAULT); -+ AuTraceErr(err); -+ if (err == -EOPNOTSUPP) -+ err = 0; -+ if (unlikely(err)) -+ goto out; -+ -+ /* -+ * strange behaviour from the users view, -+ * particularly setattr case -+ */ -+ dir = d_inode(dst_parent); -+ if (au_ibtop(dir) == cpg->bdst) -+ au_cpup_attr_nlink(dir, /*force*/1); -+ inode = d_inode(cpg->dentry); -+ au_cpup_attr_nlink(inode, /*force*/1); -+ -+out: -+ return err; -+} -+ -+static noinline_for_stack -+int cpup_entry(struct au_cp_generic *cpg, struct dentry *dst_parent, -+ struct au_cpup_reg_attr *h_src_attr) -+{ -+ int err; -+ umode_t mode; -+ unsigned int mnt_flags; -+ unsigned char isdir, isreg, force; -+ const unsigned char do_dt = !!au_ftest_cpup(cpg->flags, DTIME); -+ struct au_dtime dt; -+ struct path h_path; -+ struct dentry *h_src, *h_dst, *h_parent; -+ struct inode *h_inode, *h_dir; -+ struct super_block *sb; -+ -+ /* bsrc branch can be ro/rw. */ -+ h_src = au_h_dptr(cpg->dentry, 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); -+ if (au_ftest_cpup(cpg->flags, RENAME)) -+ 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 = d_inode(h_parent); -+ IMustLock(h_dir); -+ AuDebugOn(h_parent != h_dst->d_parent); -+ -+ sb = cpg->dentry->d_sb; -+ h_path.mnt = au_sbr_mnt(sb, cpg->bdst); -+ if (do_dt) { -+ h_path.dentry = h_parent; -+ au_dtime_store(&dt, dst_parent, &h_path); -+ } -+ h_path.dentry = h_dst; -+ -+ isreg = 0; -+ isdir = 0; -+ mode = h_inode->i_mode; -+ switch (mode & S_IFMT) { -+ case S_IFREG: -+ isreg = 1; -+ err = vfsub_create(h_dir, &h_path, 0600, /*want_excl*/true); -+ if (!err) -+ err = au_do_cpup_regular(cpg, h_src_attr); -+ break; -+ case S_IFDIR: -+ isdir = 1; -+ err = vfsub_mkdir(h_dir, &h_path, mode); -+ if (!err) -+ err = au_do_cpup_dir(cpg, dst_parent, h_dir, &h_path); -+ break; -+ case S_IFLNK: -+ err = au_do_cpup_symlink(&h_path, h_src, h_dir); -+ break; -+ case S_IFCHR: -+ case S_IFBLK: -+ AuDebugOn(!capable(CAP_MKNOD)); -+ fallthrough; -+ case S_IFIFO: -+ case S_IFSOCK: -+ err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev); -+ break; -+ default: -+ AuIOErr("Unknown inode type 0%o\n", mode); -+ err = -EIO; -+ } -+ if (!err) -+ err = au_reset_acl(&h_path, mode); -+ -+ mnt_flags = au_mntflags(sb); -+ if (!au_opt_test(mnt_flags, UDBA_NONE) -+ && !isdir -+ && au_opt_test(mnt_flags, XINO) -+ && (vfsub_inode_nlink(h_inode, AU_I_BRANCH) == 1 -+ || (h_inode->i_state & I_LINKABLE)) -+ /* todo: unnecessary? */ -+ /* && 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); -+ /* ignore this error */ -+ -+ if (!err) { -+ force = 0; -+ if (isreg) { -+ force = !!cpg->len; -+ if (cpg->len == -1) -+ force = !!i_size_read(h_inode); -+ } -+ au_fhsm_wrote(sb, cpg->bdst, force); -+ } -+ -+ if (do_dt) -+ au_dtime_revert(&dt); -+ return err; -+} -+ -+static int au_do_ren_after_cpup(struct au_cp_generic *cpg, struct path *h_path) -+{ -+ int err; -+ struct dentry *dentry, *h_dentry, *h_parent, *parent; -+ struct path h_ppath; -+ struct inode *h_dir; -+ aufs_bindex_t bdst; -+ -+ dentry = cpg->dentry; -+ bdst = cpg->bdst; -+ h_ppath.mnt = au_sbr_mnt(dentry->d_sb, bdst); -+ h_dentry = au_h_dptr(dentry, bdst); -+ if (!au_ftest_cpup(cpg->flags, OVERWRITE)) { -+ dget(h_dentry); -+ au_set_h_dptr(dentry, bdst, NULL); -+ err = au_lkup_neg(dentry, bdst, /*wh*/0); -+ if (!err) -+ h_path->dentry = dget(au_h_dptr(dentry, bdst)); -+ au_set_h_dptr(dentry, bdst, h_dentry); -+ } else { -+ err = 0; -+ parent = dget_parent(dentry); -+ h_ppath.dentry = au_h_dptr(parent, bdst); -+ dput(parent); -+ h_path->dentry = vfsub_lkup_one(&dentry->d_name, &h_ppath); -+ if (IS_ERR(h_path->dentry)) -+ err = PTR_ERR(h_path->dentry); -+ } -+ if (unlikely(err)) -+ goto out; -+ -+ h_parent = h_dentry->d_parent; /* dir inode is locked */ -+ 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 */ -+ err = vfsub_rename(h_dir, h_dentry, h_dir, h_path, /*delegated*/NULL, -+ /*flags*/0); -+ dput(h_path->dentry); -+ -+out: -+ return err; -+} -+ -+/* -+ * copyup the @dentry from @bsrc to @bdst. -+ * the caller must set the both of lower dentries. -+ * @len is for truncating when it is -1 copyup the entire file. -+ * in link/rename cases, @dst_parent may be different from the real one. -+ * basic->bsrc can be larger than basic->bdst. -+ * aufs doesn't touch the credential so -+ * security_inode_copy_up{,_xattr}() are unnecessary. -+ */ -+static int au_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent) -+{ -+ int err, rerr; -+ aufs_bindex_t old_ibtop; -+ unsigned char isdir, plink; -+ struct dentry *h_src, *h_dst, *h_parent; -+ struct inode *dst_inode, *h_dir, *inode, *delegated, *src_inode; -+ struct super_block *sb; -+ struct au_branch *br; -+ struct path h_src_path; -+ /* to reduce stack size */ -+ struct { -+ struct au_dtime dt; -+ struct path h_path; -+ struct au_cpup_reg_attr h_src_attr; -+ } *a; -+ -+ err = -ENOMEM; -+ a = kmalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ a->h_src_attr.valid = 0; -+ -+ sb = cpg->dentry->d_sb; -+ br = au_sbr(sb, cpg->bdst); -+ 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 = d_inode(h_parent); -+ IMustLock(h_dir); -+ -+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc); -+ inode = d_inode(cpg->dentry); -+ -+ if (!dst_parent) -+ dst_parent = dget_parent(cpg->dentry); -+ else -+ dget(dst_parent); -+ -+ plink = !!au_opt_test(au_mntflags(sb), PLINK); -+ dst_inode = au_h_iptr(inode, cpg->bdst); -+ if (dst_inode) { -+ if (unlikely(!plink)) { -+ err = -EIO; -+ AuIOErr("hi%lu(i%lu) exists on b%d " -+ "but plink is disabled\n", -+ dst_inode->i_ino, inode->i_ino, cpg->bdst); -+ goto out_parent; -+ } -+ -+ if (vfsub_inode_nlink(dst_inode, AU_I_BRANCH)) { -+ const int do_dt = au_ftest_cpup(cpg->flags, DTIME); -+ -+ h_src = au_plink_lkup(inode, cpg->bdst); -+ err = PTR_ERR(h_src); -+ if (IS_ERR(h_src)) -+ goto out_parent; -+ if (unlikely(d_is_negative(h_src))) { -+ err = -EIO; -+ AuIOErr("i%lu exists on b%d " -+ "but not pseudo-linked\n", -+ inode->i_ino, cpg->bdst); -+ dput(h_src); -+ goto out_parent; -+ } -+ -+ if (do_dt) { -+ a->h_path.dentry = h_parent; -+ au_dtime_store(&a->dt, dst_parent, &a->h_path); -+ } -+ -+ a->h_path.dentry = h_dst; -+ delegated = NULL; -+ err = vfsub_link(h_src, h_dir, &a->h_path, &delegated); -+ if (!err && au_ftest_cpup(cpg->flags, RENAME)) -+ err = au_do_ren_after_cpup(cpg, &a->h_path); -+ if (do_dt) -+ au_dtime_revert(&a->dt); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal link\n"); -+ iput(delegated); -+ } -+ dput(h_src); -+ goto out_parent; -+ } else -+ /* todo: cpup_wh_file? */ -+ /* udba work */ -+ au_update_ibrange(inode, /*do_put_zero*/1); -+ } -+ -+ isdir = S_ISDIR(inode->i_mode); -+ old_ibtop = au_ibtop(inode); -+ err = cpup_entry(cpg, dst_parent, &a->h_src_attr); -+ if (unlikely(err)) -+ goto out_rev; -+ dst_inode = d_inode(h_dst); -+ inode_lock_nested(dst_inode, AuLsc_I_CHILD2); -+ /* todo: necessary? */ -+ /* au_pin_hdir_unlock(cpg->pin); */ -+ -+ h_src_path.dentry = h_src; -+ h_src_path.mnt = au_sbr_mnt(sb, cpg->bsrc); -+ err = cpup_iattr(cpg->dentry, cpg->bdst, &h_src_path, &a->h_src_attr); -+ if (unlikely(err)) { -+ /* todo: necessary? */ -+ /* au_pin_hdir_relock(cpg->pin); */ /* ignore an error */ -+ inode_unlock(dst_inode); -+ goto out_rev; -+ } -+ -+ if (cpg->bdst < old_ibtop) { -+ if (S_ISREG(inode->i_mode)) { -+ err = au_dy_iaop(inode, cpg->bdst, dst_inode); -+ if (unlikely(err)) { -+ /* ignore an error */ -+ /* au_pin_hdir_relock(cpg->pin); */ -+ inode_unlock(dst_inode); -+ goto out_rev; -+ } -+ } -+ au_set_ibtop(inode, cpg->bdst); -+ } else -+ au_set_ibbot(inode, cpg->bdst); -+ au_set_h_iptr(inode, cpg->bdst, au_igrab(dst_inode), -+ au_hi_flags(inode, isdir)); -+ -+ /* todo: necessary? */ -+ /* err = au_pin_hdir_relock(cpg->pin); */ -+ inode_unlock(dst_inode); -+ if (unlikely(err)) -+ goto out_rev; -+ -+ src_inode = d_inode(h_src); -+ if (!isdir -+ && (vfsub_inode_nlink(src_inode, AU_I_BRANCH) > 1 -+ || src_inode->i_state & I_LINKABLE) -+ && plink) -+ au_plink_append(inode, cpg->bdst, h_dst); -+ -+ if (au_ftest_cpup(cpg->flags, RENAME)) { -+ a->h_path.dentry = h_dst; -+ err = au_do_ren_after_cpup(cpg, &a->h_path); -+ } -+ if (!err) -+ goto out_parent; /* success */ -+ -+ /* revert */ -+out_rev: -+ a->h_path.dentry = h_parent; -+ au_dtime_store(&a->dt, dst_parent, &a->h_path); -+ a->h_path.dentry = h_dst; -+ rerr = 0; -+ if (d_is_positive(h_dst)) { -+ if (!isdir) { -+ /* no delegation since it is just created */ -+ rerr = vfsub_unlink(h_dir, &a->h_path, -+ /*delegated*/NULL, /*force*/0); -+ } else -+ rerr = vfsub_rmdir(h_dir, &a->h_path); -+ } -+ au_dtime_revert(&a->dt); -+ if (rerr) { -+ AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr); -+ err = -EIO; -+ } -+out_parent: -+ dput(dst_parent); -+ au_kfree_rcu(a); -+out: -+ return err; -+} -+ -+#if 0 /* reserved */ -+struct au_cpup_single_args { -+ int *errp; -+ struct au_cp_generic *cpg; -+ struct dentry *dst_parent; -+}; -+ -+static void au_call_cpup_single(void *args) -+{ -+ struct au_cpup_single_args *a = args; -+ -+ au_pin_hdir_acquire_nest(a->cpg->pin); -+ *a->errp = au_cpup_single(a->cpg, a->dst_parent); -+ au_pin_hdir_release(a->cpg->pin); -+} -+#endif -+ -+/* -+ * prevent SIGXFSZ in copy-up. -+ * testing CAP_MKNOD is for generic fs, -+ * but CAP_FSETID is for xfs only, currently. -+ */ -+static int au_cpup_sio_test(struct au_pin *pin, umode_t mode) -+{ -+ int do_sio; -+ struct super_block *sb; -+ struct inode *h_dir; -+ -+ do_sio = 0; -+ sb = au_pinned_parent(pin)->d_sb; -+ if (!au_wkq_test() -+ && (!au_sbi(sb)->si_plink_maint_pid -+ || au_plink_maint(sb, AuLock_NOPLM))) { -+ switch (mode & S_IFMT) { -+ case S_IFREG: -+ /* no condition about RLIMIT_FSIZE and the file size */ -+ do_sio = 1; -+ break; -+ case S_IFCHR: -+ case S_IFBLK: -+ do_sio = !capable(CAP_MKNOD); -+ break; -+ } -+ if (!do_sio) -+ do_sio = ((mode & (S_ISUID | S_ISGID)) -+ && !capable(CAP_FSETID)); -+ /* this workaround may be removed in the future */ -+ if (!do_sio) { -+ h_dir = au_pinned_h_dir(pin); -+ do_sio = h_dir->i_mode & S_ISVTX; -+ } -+ } -+ -+ return do_sio; -+} -+ -+#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, d_inode(h_dentry)->i_mode)) -+ err = au_cpup_single(cpg, dst_parent); -+ else { -+ struct au_cpup_single_args args = { -+ .errp = &err, -+ .cpg = cpg, -+ .dst_parent = dst_parent -+ }; -+ wkq_err = au_wkq_wait(au_call_cpup_single, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } -+ -+ return err; -+} -+#endif -+ -+/* -+ * copyup the @dentry from the first active lower branch to @bdst, -+ * using au_cpup_single(). -+ */ -+static int au_cpup_simple(struct au_cp_generic *cpg) -+{ -+ int err; -+ unsigned int flags_orig; -+ struct dentry *dentry; -+ -+ AuDebugOn(cpg->bsrc < 0); -+ -+ dentry = cpg->dentry; -+ DiMustWriteLock(dentry); -+ -+ err = au_lkup_neg(dentry, cpg->bdst, /*wh*/1); -+ if (!err) { -+ flags_orig = cpg->flags; -+ au_fset_cpup(cpg->flags, RENAME); -+ err = au_cpup_single(cpg, NULL); -+ cpg->flags = flags_orig; -+ if (!err) -+ return 0; /* success */ -+ -+ /* revert */ -+ au_set_h_dptr(dentry, cpg->bdst, NULL); -+ au_set_dbtop(dentry, cpg->bsrc); -+ } -+ -+ return err; -+} -+ -+struct au_cpup_simple_args { -+ int *errp; -+ struct au_cp_generic *cpg; -+}; -+ -+static void au_call_cpup_simple(void *args) -+{ -+ struct au_cpup_simple_args *a = args; -+ -+ au_pin_hdir_acquire_nest(a->cpg->pin); -+ *a->errp = au_cpup_simple(a->cpg); -+ au_pin_hdir_release(a->cpg->pin); -+} -+ -+static int au_do_sio_cpup_simple(struct au_cp_generic *cpg) -+{ -+ int err, wkq_err; -+ struct dentry *dentry, *parent; -+ struct file *h_file; -+ struct inode *h_dir; -+ struct mnt_idmap *h_idmap; -+ -+ dentry = cpg->dentry; -+ h_file = NULL; -+ if (au_ftest_cpup(cpg->flags, HOPEN)) { -+ AuDebugOn(cpg->bsrc < 0); -+ h_file = au_h_open_pre(dentry, cpg->bsrc, /*force_wr*/0); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ } -+ -+ parent = dget_parent(dentry); -+ h_dir = au_h_iptr(d_inode(parent), cpg->bdst); -+ h_idmap = au_sbr_idmap(dentry->d_sb, cpg->bdst); -+ if (!au_test_h_perm_sio(h_idmap, h_dir, MAY_EXEC | MAY_WRITE) -+ && !au_cpup_sio_test(cpg->pin, d_inode(dentry)->i_mode)) -+ err = au_cpup_simple(cpg); -+ else { -+ struct au_cpup_simple_args args = { -+ .errp = &err, -+ .cpg = cpg -+ }; -+ wkq_err = au_wkq_wait(au_call_cpup_simple, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } -+ -+ dput(parent); -+ if (h_file) -+ au_h_open_post(dentry, cpg->bsrc, h_file); -+ -+out: -+ return err; -+} -+ -+int au_sio_cpup_simple(struct au_cp_generic *cpg) -+{ -+ aufs_bindex_t bsrc, bbot; -+ struct dentry *dentry, *h_dentry; -+ -+ if (cpg->bsrc < 0) { -+ dentry = cpg->dentry; -+ bbot = au_dbbot(dentry); -+ for (bsrc = cpg->bdst + 1; bsrc <= bbot; bsrc++) { -+ h_dentry = au_h_dptr(dentry, bsrc); -+ if (h_dentry) { -+ AuDebugOn(d_is_negative(h_dentry)); -+ break; -+ } -+ } -+ AuDebugOn(bsrc > bbot); -+ cpg->bsrc = bsrc; -+ } -+ AuDebugOn(cpg->bsrc <= cpg->bdst); -+ return au_do_sio_cpup_simple(cpg); -+} -+ -+int au_sio_cpdown_simple(struct au_cp_generic *cpg) -+{ -+ AuDebugOn(cpg->bdst <= cpg->bsrc); -+ return au_do_sio_cpup_simple(cpg); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * copyup the deleted file for writing. -+ */ -+static int au_do_cpup_wh(struct au_cp_generic *cpg, struct dentry *wh_dentry, -+ struct file *file) -+{ -+ int err; -+ unsigned int flags_orig; -+ aufs_bindex_t bsrc_orig; -+ struct au_dinfo *dinfo; -+ struct { -+ struct au_hdentry *hd; -+ struct dentry *h_dentry; -+ } hdst, hsrc; -+ -+ dinfo = au_di(cpg->dentry); -+ AuRwMustWriteLock(&dinfo->di_rwsem); -+ -+ bsrc_orig = cpg->bsrc; -+ cpg->bsrc = dinfo->di_btop; -+ hdst.hd = au_hdentry(dinfo, cpg->bdst); -+ hdst.h_dentry = hdst.hd->hd_dentry; -+ hdst.hd->hd_dentry = wh_dentry; -+ dinfo->di_btop = cpg->bdst; -+ -+ hsrc.h_dentry = NULL; -+ if (file) { -+ hsrc.hd = au_hdentry(dinfo, cpg->bsrc); -+ hsrc.h_dentry = hsrc.hd->hd_dentry; -+ hsrc.hd->hd_dentry = au_hf_top(file)->f_path.dentry; -+ } -+ flags_orig = cpg->flags; -+ cpg->flags = !AuCpup_DTIME; -+ err = au_cpup_single(cpg, /*h_parent*/NULL); -+ cpg->flags = flags_orig; -+ if (file) { -+ if (!err) -+ err = au_reopen_nondir(file); -+ hsrc.hd->hd_dentry = hsrc.h_dentry; -+ } -+ hdst.hd->hd_dentry = hdst.h_dentry; -+ dinfo->di_btop = cpg->bsrc; -+ cpg->bsrc = bsrc_orig; -+ -+ return err; -+} -+ -+static int au_cpup_wh(struct au_cp_generic *cpg, struct file *file) -+{ -+ int err; -+ aufs_bindex_t bdst; -+ struct au_dtime dt; -+ struct dentry *dentry, *parent, *h_parent, *wh_dentry; -+ struct au_branch *br; -+ struct path h_path; -+ -+ dentry = cpg->dentry; -+ bdst = cpg->bdst; -+ br = au_sbr(dentry->d_sb, bdst); -+ parent = dget_parent(dentry); -+ h_parent = au_h_dptr(parent, bdst); -+ wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name); -+ err = PTR_ERR(wh_dentry); -+ if (IS_ERR(wh_dentry)) -+ goto out; -+ -+ h_path.dentry = h_parent; -+ h_path.mnt = au_br_mnt(br); -+ au_dtime_store(&dt, parent, &h_path); -+ err = au_do_cpup_wh(cpg, wh_dentry, file); -+ if (unlikely(err)) -+ goto out_wh; -+ -+ dget(wh_dentry); -+ h_path.dentry = wh_dentry; -+ if (!d_is_dir(wh_dentry)) { -+ /* no delegation since it is just created */ -+ err = vfsub_unlink(d_inode(h_parent), &h_path, -+ /*delegated*/NULL, /*force*/0); -+ } else -+ 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(d_inode(dentry), bdst, wh_dentry); -+ -+out_wh: -+ dput(wh_dentry); -+out: -+ dput(parent); -+ return err; -+} -+ -+struct au_cpup_wh_args { -+ int *errp; -+ struct au_cp_generic *cpg; -+ struct file *file; -+}; -+ -+static void au_call_cpup_wh(void *args) -+{ -+ struct au_cpup_wh_args *a = args; -+ -+ au_pin_hdir_acquire_nest(a->cpg->pin); -+ *a->errp = au_cpup_wh(a->cpg, a->file); -+ au_pin_hdir_release(a->cpg->pin); -+} -+ -+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file) -+{ -+ int err, wkq_err; -+ aufs_bindex_t bdst; -+ struct dentry *dentry, *parent, *h_orph, *h_parent; -+ struct inode *dir, *h_dir, *h_tmpdir; -+ struct au_wbr *wbr; -+ struct au_pin wh_pin, *pin_orig; -+ struct mnt_idmap *h_idmap; -+ -+ dentry = cpg->dentry; -+ bdst = cpg->bdst; -+ parent = dget_parent(dentry); -+ dir = d_inode(parent); -+ h_orph = NULL; -+ h_parent = NULL; -+ h_dir = au_igrab(au_h_iptr(dir, bdst)); -+ h_tmpdir = h_dir; -+ pin_orig = NULL; -+ if (!vfsub_inode_nlink(h_dir, AU_I_BRANCH)) { -+ wbr = au_sbr(dentry->d_sb, bdst)->br_wbr; -+ h_orph = wbr->wbr_orph; -+ -+ h_parent = dget(au_h_dptr(parent, bdst)); -+ au_set_h_dptr(parent, bdst, dget(h_orph)); -+ h_tmpdir = d_inode(h_orph); -+ au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0); -+ -+ inode_lock_nested(h_tmpdir, AuLsc_I_PARENT3); -+ /* todo: au_h_open_pre()? */ -+ -+ pin_orig = cpg->pin; -+ au_pin_init(&wh_pin, dentry, bdst, AuLsc_DI_PARENT, -+ AuLsc_I_PARENT3, cpg->pin->udba, AuPin_DI_LOCKED); -+ cpg->pin = &wh_pin; -+ } -+ -+ h_idmap = au_sbr_idmap(dentry->d_sb, bdst); -+ if (!au_test_h_perm_sio(h_idmap, h_tmpdir, MAY_EXEC | MAY_WRITE) -+ && !au_cpup_sio_test(cpg->pin, d_inode(dentry)->i_mode)) -+ err = au_cpup_wh(cpg, file); -+ else { -+ struct au_cpup_wh_args args = { -+ .errp = &err, -+ .cpg = cpg, -+ .file = file -+ }; -+ wkq_err = au_wkq_wait(au_call_cpup_wh, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } -+ -+ if (h_orph) { -+ inode_unlock(h_tmpdir); -+ /* todo: au_h_open_post()? */ -+ au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0); -+ au_set_h_dptr(parent, bdst, h_parent); -+ AuDebugOn(!pin_orig); -+ cpg->pin = pin_orig; -+ } -+ iput(h_dir); -+ dput(parent); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * generic routine for both of copy-up and copy-down. -+ */ -+/* cf. revalidate function in file.c */ -+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst, -+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst, -+ struct au_pin *pin, -+ struct dentry *h_parent, void *arg), -+ void *arg) -+{ -+ int err; -+ struct au_pin pin; -+ struct dentry *d, *parent, *h_parent, *real_parent, *h_dentry; -+ -+ err = 0; -+ parent = dget_parent(dentry); -+ if (IS_ROOT(parent)) -+ goto out; -+ -+ au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2, -+ au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE); -+ -+ /* do not use au_dpage */ -+ real_parent = parent; -+ while (1) { -+ dput(parent); -+ parent = dget_parent(dentry); -+ h_parent = au_h_dptr(parent, bdst); -+ if (h_parent) -+ goto out; /* success */ -+ -+ /* find top dir which is necessary to cpup */ -+ do { -+ d = parent; -+ dput(parent); -+ parent = dget_parent(d); -+ di_read_lock_parent3(parent, !AuLock_IR); -+ h_parent = au_h_dptr(parent, bdst); -+ di_read_unlock(parent, !AuLock_IR); -+ } while (!h_parent); -+ -+ if (d != real_parent) -+ di_write_lock_child3(d); -+ -+ /* somebody else might create while we were sleeping */ -+ h_dentry = au_h_dptr(d, bdst); -+ if (!h_dentry || d_is_negative(h_dentry)) { -+ if (h_dentry) -+ au_update_dbtop(d); -+ -+ au_pin_set_dentry(&pin, d); -+ err = au_do_pin(&pin); -+ if (!err) { -+ err = cp(d, bdst, &pin, h_parent, arg); -+ au_unpin(&pin); -+ } -+ } -+ -+ if (d != real_parent) -+ di_write_unlock(d); -+ if (unlikely(err)) -+ break; -+ } -+ -+out: -+ dput(parent); -+ return err; -+} -+ -+static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst, -+ struct au_pin *pin, -+ struct dentry *h_parent __maybe_unused, -+ void *arg __maybe_unused) -+{ -+ struct au_cp_generic cpg = { -+ .dentry = dentry, -+ .bdst = bdst, -+ .bsrc = -1, -+ .len = 0, -+ .pin = pin, -+ .flags = AuCpup_DTIME -+ }; -+ return au_sio_cpup_simple(&cpg); -+} -+ -+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst) -+{ -+ return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL); -+} -+ -+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst) -+{ -+ int err; -+ struct dentry *parent; -+ struct inode *dir; -+ -+ parent = dget_parent(dentry); -+ dir = d_inode(parent); -+ err = 0; -+ if (au_h_iptr(dir, bdst)) -+ goto out; -+ -+ di_read_unlock(parent, AuLock_IR); -+ di_write_lock_parent(parent); -+ /* someone else might change our inode while we were sleeping */ -+ if (!au_h_iptr(dir, bdst)) -+ err = au_cpup_dirs(dentry, bdst); -+ di_downgrade_lock(parent, AuLock_IR); -+ -+out: -+ dput(parent); -+ return err; -+} -diff -Naur null/fs/aufs/cpup.h linux-6.6.63/fs/aufs/cpup.h ---- /dev/null -+++ linux-6.6.63/fs/aufs/cpup.h 2024-12-18 15:12:59.293519613 +0300 -@@ -0,0 +1,100 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * copy-up/down functions -+ */ -+ -+#ifndef __AUFS_CPUP_H__ -+#define __AUFS_CPUP_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+ -+struct inode; -+struct file; -+struct au_pin; -+ -+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags); -+void au_cpup_attr_timesizes(struct inode *inode); -+void au_cpup_attr_nlink(struct inode *inode, int force); -+void au_cpup_attr_changeable(struct inode *inode); -+void au_cpup_igen(struct inode *inode, struct inode *h_inode); -+void au_cpup_attr_all(struct inode *inode, int force); -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_cp_generic { -+ struct dentry *dentry; -+ aufs_bindex_t bdst, bsrc; -+ loff_t len; -+ struct au_pin *pin; -+ unsigned int flags; -+}; -+ -+/* cpup flags */ -+#define AuCpup_DTIME 1 /* do dtime_store/revert */ -+#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino, -+ for link(2) */ -+#define AuCpup_RENAME (1 << 2) /* rename after cpup */ -+#define AuCpup_HOPEN (1 << 3) /* call h_open_pre/post() in -+ cpup */ -+#define AuCpup_OVERWRITE (1 << 4) /* allow overwriting the -+ existing entry */ -+#define AuCpup_RWDST (1 << 5) /* force write target even if -+ the branch is marked as RO */ -+ -+#ifndef CONFIG_AUFS_BR_HFSPLUS -+#undef AuCpup_HOPEN -+#define AuCpup_HOPEN 0 -+#endif -+ -+#define au_ftest_cpup(flags, name) ((flags) & AuCpup_##name) -+#define au_fset_cpup(flags, name) \ -+ do { (flags) |= AuCpup_##name; } while (0) -+#define au_fclr_cpup(flags, name) \ -+ do { (flags) &= ~AuCpup_##name; } while (0) -+ -+int au_copy_file(struct file *dst, struct file *src, loff_t len); -+int au_sio_cpup_simple(struct au_cp_generic *cpg); -+int au_sio_cpdown_simple(struct au_cp_generic *cpg); -+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file); -+ -+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst, -+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst, -+ struct au_pin *pin, -+ struct dentry *h_parent, void *arg), -+ void *arg); -+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst); -+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst); -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* keep timestamps when copyup */ -+struct au_dtime { -+ struct dentry *dt_dentry; -+ struct path dt_h_path; -+ struct timespec64 dt_atime, dt_mtime; -+}; -+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry, -+ struct path *h_path); -+void au_dtime_revert(struct au_dtime *dt); -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_CPUP_H__ */ -diff -Naur null/fs/aufs/dbgaufs.c linux-6.6.63/fs/aufs/dbgaufs.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/dbgaufs.c 2024-12-18 15:12:59.293519613 +0300 -@@ -0,0 +1,526 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * debugfs interface -+ */ -+ -+#include -+#include "aufs.h" -+ -+#ifndef CONFIG_SYSFS -+#error DEBUG_FS depends upon SYSFS -+#endif -+ -+static struct dentry *dbgaufs; -+static const mode_t dbgaufs_mode = 0444; -+ -+/* 20 is max digits length of ulong 64 */ -+struct dbgaufs_arg { -+ int n; -+ char a[20 * 4]; -+}; -+ -+/* -+ * common function for all XINO files -+ */ -+static int dbgaufs_xi_release(struct inode *inode __maybe_unused, -+ struct file *file) -+{ -+ void *p; -+ -+ p = file->private_data; -+ if (p) { -+ /* this is struct dbgaufs_arg */ -+ AuDebugOn(!au_kfree_sz_test(p)); -+ au_kfree_do_rcu(p); -+ } -+ return 0; -+} -+ -+static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt, -+ int cnt) -+{ -+ int err; -+ struct kstat st; -+ struct dbgaufs_arg *p; -+ -+ err = -ENOMEM; -+ p = kmalloc(sizeof(*p), GFP_NOFS); -+ if (unlikely(!p)) -+ goto out; -+ -+ err = 0; -+ p->n = 0; -+ file->private_data = p; -+ if (!xf) -+ goto out; -+ -+ err = vfsub_getattr(&xf->f_path, &st); -+ if (!err) { -+ if (do_fcnt) -+ p->n = snprintf -+ (p->a, sizeof(p->a), "%d, %llux%u %lld\n", -+ cnt, st.blocks, st.blksize, -+ (long long)st.size); -+ else -+ p->n = snprintf(p->a, sizeof(p->a), "%llux%u %lld\n", -+ st.blocks, st.blksize, -+ (long long)st.size); -+ AuDebugOn(p->n >= sizeof(p->a)); -+ } else { -+ p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err); -+ err = 0; -+ } -+ -+out: -+ return err; -+} -+ -+static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf, -+ size_t count, loff_t *ppos) -+{ -+ struct dbgaufs_arg *p; -+ -+ p = file->private_data; -+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct dbgaufs_plink_arg { -+ int n; -+ char a[]; -+}; -+ -+static int dbgaufs_plink_release(struct inode *inode __maybe_unused, -+ struct file *file) -+{ -+ free_page((unsigned long)file->private_data); -+ return 0; -+} -+ -+static int dbgaufs_plink_open(struct inode *inode, struct file *file) -+{ -+ int err, i, limit; -+ unsigned long n, sum; -+ struct dbgaufs_plink_arg *p; -+ struct au_sbinfo *sbinfo; -+ struct super_block *sb; -+ struct hlist_bl_head *hbl; -+ -+ err = -ENOMEM; -+ p = (void *)get_zeroed_page(GFP_NOFS); -+ if (unlikely(!p)) -+ goto out; -+ -+ err = -EFBIG; -+ sbinfo = inode->i_private; -+ sb = sbinfo->si_sb; -+ si_noflush_read_lock(sb); -+ if (au_opt_test(au_mntflags(sb), PLINK)) { -+ limit = PAGE_SIZE - sizeof(p->n); -+ -+ /* the number of buckets */ -+ n = snprintf(p->a + p->n, limit, "%d\n", AuPlink_NHASH); -+ p->n += n; -+ limit -= n; -+ -+ sum = 0; -+ for (i = 0, hbl = sbinfo->si_plink; i < AuPlink_NHASH; -+ i++, hbl++) { -+ n = au_hbl_count(hbl); -+ sum += n; -+ -+ n = snprintf(p->a + p->n, limit, "%lu ", n); -+ p->n += n; -+ limit -= n; -+ if (unlikely(limit <= 0)) -+ goto out_free; -+ } -+ p->a[p->n - 1] = '\n'; -+ -+ /* the sum of plinks */ -+ n = snprintf(p->a + p->n, limit, "%lu\n", sum); -+ p->n += n; -+ limit -= n; -+ if (unlikely(limit <= 0)) -+ goto out_free; -+ } else { -+#define str "1\n0\n0\n" -+ p->n = sizeof(str) - 1; -+ strscpy(p->a, str, sizeof(str)); -+#undef str -+ } -+ si_read_unlock(sb); -+ -+ err = 0; -+ file->private_data = p; -+ goto out; /* success */ -+ -+out_free: -+ free_page((unsigned long)p); -+out: -+ return err; -+} -+ -+static ssize_t dbgaufs_plink_read(struct file *file, char __user *buf, -+ size_t count, loff_t *ppos) -+{ -+ struct dbgaufs_plink_arg *p; -+ -+ p = file->private_data; -+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n); -+} -+ -+static const struct file_operations dbgaufs_plink_fop = { -+ .owner = THIS_MODULE, -+ .open = dbgaufs_plink_open, -+ .release = dbgaufs_plink_release, -+ .read = dbgaufs_plink_read -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int dbgaufs_xib_open(struct inode *inode, struct file *file) -+{ -+ int err; -+ struct au_sbinfo *sbinfo; -+ struct super_block *sb; -+ -+ sbinfo = inode->i_private; -+ sb = sbinfo->si_sb; -+ si_noflush_read_lock(sb); -+ err = dbgaufs_xi_open(sbinfo->si_xib, file, /*do_fcnt*/0, /*cnt*/0); -+ si_read_unlock(sb); -+ return err; -+} -+ -+static const struct file_operations dbgaufs_xib_fop = { -+ .owner = THIS_MODULE, -+ .open = dbgaufs_xib_open, -+ .release = dbgaufs_xi_release, -+ .read = dbgaufs_xi_read -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+#define DbgaufsXi_PREFIX "xi" -+ -+static int dbgaufs_xino_open(struct inode *inode, struct file *file) -+{ -+ int err, idx; -+ long l; -+ aufs_bindex_t bindex; -+ char *p, a[sizeof(DbgaufsXi_PREFIX) + 8]; -+ struct au_sbinfo *sbinfo; -+ struct super_block *sb; -+ struct au_xino *xi; -+ struct file *xf; -+ struct qstr *name; -+ struct au_branch *br; -+ -+ err = -ENOENT; -+ name = &file->f_path.dentry->d_name; -+ if (unlikely(name->len < sizeof(DbgaufsXi_PREFIX) -+ || memcmp(name->name, DbgaufsXi_PREFIX, -+ sizeof(DbgaufsXi_PREFIX) - 1))) -+ goto out; -+ -+ AuDebugOn(name->len >= sizeof(a)); -+ memcpy(a, name->name, name->len); -+ a[name->len] = '\0'; -+ p = strchr(a, '-'); -+ if (p) -+ *p = '\0'; -+ err = kstrtol(a + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l); -+ if (unlikely(err)) -+ goto out; -+ bindex = l; -+ idx = 0; -+ if (p) { -+ err = kstrtol(p + 1, 10, &l); -+ if (unlikely(err)) -+ goto out; -+ idx = l; -+ } -+ -+ err = -ENOENT; -+ sbinfo = inode->i_private; -+ sb = sbinfo->si_sb; -+ si_noflush_read_lock(sb); -+ if (unlikely(bindex < 0 || bindex > au_sbbot(sb))) -+ goto out_si; -+ br = au_sbr(sb, bindex); -+ xi = br->br_xino; -+ if (unlikely(idx >= xi->xi_nfile)) -+ goto out_si; -+ xf = au_xino_file(xi, idx); -+ if (xf) -+ err = dbgaufs_xi_open(xf, file, /*do_fcnt*/1, -+ au_xino_count(br)); -+ -+out_si: -+ si_read_unlock(sb); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static const struct file_operations dbgaufs_xino_fop = { -+ .owner = THIS_MODULE, -+ .open = dbgaufs_xino_open, -+ .release = dbgaufs_xi_release, -+ .read = dbgaufs_xi_read -+}; -+ -+void dbgaufs_xino_del(struct au_branch *br) -+{ -+ struct dentry *dbgaufs; -+ -+ dbgaufs = br->br_dbgaufs; -+ if (!dbgaufs) -+ return; -+ -+ br->br_dbgaufs = NULL; -+ /* debugfs acquires the parent i_mutex */ -+ lockdep_off(); -+ debugfs_remove(dbgaufs); -+ lockdep_on(); -+} -+ -+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ aufs_bindex_t bbot; -+ struct au_branch *br; -+ -+ if (!au_sbi(sb)->si_dbgaufs) -+ return; -+ -+ bbot = au_sbbot(sb); -+ for (; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ dbgaufs_xino_del(br); -+ } -+} -+ -+static void dbgaufs_br_do_add(struct super_block *sb, aufs_bindex_t bindex, -+ unsigned int idx, struct dentry *parent, -+ struct au_sbinfo *sbinfo) -+{ -+ struct au_branch *br; -+ struct dentry *d; -+ /* "xi" bindex(5) "-" idx(2) NULL */ -+ char name[sizeof(DbgaufsXi_PREFIX) + 8]; -+ -+ if (!idx) -+ snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d", bindex); -+ else -+ snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d-%u", -+ bindex, idx); -+ br = au_sbr(sb, bindex); -+ if (br->br_dbgaufs) { -+ struct qstr qstr = QSTR_INIT(name, strlen(name)); -+ -+ if (!au_qstreq(&br->br_dbgaufs->d_name, &qstr)) { -+ /* debugfs acquires the parent i_mutex */ -+ lockdep_off(); -+ d = debugfs_rename(parent, br->br_dbgaufs, parent, -+ name); -+ lockdep_on(); -+ if (unlikely(!d)) -+ pr_warn("failed renaming %pd/%s, ignored.\n", -+ parent, name); -+ } -+ } else { -+ lockdep_off(); -+ br->br_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent, -+ sbinfo, &dbgaufs_xino_fop); -+ lockdep_on(); -+ if (unlikely(!br->br_dbgaufs)) -+ pr_warn("failed creating %pd/%s, ignored.\n", -+ parent, name); -+ } -+} -+ -+static void dbgaufs_br_add(struct super_block *sb, aufs_bindex_t bindex, -+ struct dentry *parent, struct au_sbinfo *sbinfo) -+{ -+ struct au_branch *br; -+ struct au_xino *xi; -+ unsigned int u; -+ -+ br = au_sbr(sb, bindex); -+ xi = br->br_xino; -+ for (u = 0; u < xi->xi_nfile; u++) -+ dbgaufs_br_do_add(sb, bindex, u, parent, sbinfo); -+} -+ -+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex, int topdown) -+{ -+ struct au_sbinfo *sbinfo; -+ struct dentry *parent; -+ aufs_bindex_t bbot; -+ -+ if (!au_opt_test(au_mntflags(sb), XINO)) -+ return; -+ -+ sbinfo = au_sbi(sb); -+ parent = sbinfo->si_dbgaufs; -+ if (!parent) -+ return; -+ -+ bbot = au_sbbot(sb); -+ if (topdown) -+ for (; bindex <= bbot; bindex++) -+ dbgaufs_br_add(sb, bindex, parent, sbinfo); -+ else -+ for (; bbot >= bindex; bbot--) -+ dbgaufs_br_add(sb, bbot, parent, sbinfo); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+#ifdef CONFIG_AUFS_EXPORT -+static int dbgaufs_xigen_open(struct inode *inode, struct file *file) -+{ -+ int err; -+ struct au_sbinfo *sbinfo; -+ struct super_block *sb; -+ -+ sbinfo = inode->i_private; -+ sb = sbinfo->si_sb; -+ si_noflush_read_lock(sb); -+ err = dbgaufs_xi_open(sbinfo->si_xigen, file, /*do_fcnt*/0, /*cnt*/0); -+ si_read_unlock(sb); -+ return err; -+} -+ -+static const struct file_operations dbgaufs_xigen_fop = { -+ .owner = THIS_MODULE, -+ .open = dbgaufs_xigen_open, -+ .release = dbgaufs_xi_release, -+ .read = dbgaufs_xi_read -+}; -+ -+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo) -+{ -+ int err; -+ -+ /* -+ * This function is a dynamic '__init' function actually, -+ * so the tiny check for si_rwsem is unnecessary. -+ */ -+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */ -+ -+ err = -EIO; -+ sbinfo->si_dbgaufs_xigen = debugfs_create_file -+ ("xigen", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo, -+ &dbgaufs_xigen_fop); -+ if (sbinfo->si_dbgaufs_xigen) -+ err = 0; -+ -+ return err; -+} -+#else -+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo) -+{ -+ return 0; -+} -+#endif /* CONFIG_AUFS_EXPORT */ -+ -+/* ---------------------------------------------------------------------- */ -+ -+void dbgaufs_si_fin(struct au_sbinfo *sbinfo) -+{ -+ /* -+ * This function is a dynamic '__fin' function actually, -+ * so the tiny check for si_rwsem is unnecessary. -+ */ -+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */ -+ -+ debugfs_remove_recursive(sbinfo->si_dbgaufs); -+ sbinfo->si_dbgaufs = NULL; -+} -+ -+int dbgaufs_si_init(struct au_sbinfo *sbinfo) -+{ -+ int err; -+ char name[SysaufsSiNameLen]; -+ -+ /* -+ * This function is a dynamic '__init' function actually, -+ * so the tiny check for si_rwsem is unnecessary. -+ */ -+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */ -+ -+ err = -ENOENT; -+ if (!dbgaufs) { -+ AuErr1("/debug/aufs is uninitialized\n"); -+ goto out; -+ } -+ -+ err = -EIO; -+ sysaufs_name(sbinfo, name); -+ sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs); -+ if (unlikely(!sbinfo->si_dbgaufs)) -+ goto out; -+ -+ /* regardless plink/noplink option */ -+ sbinfo->si_dbgaufs_plink = debugfs_create_file -+ ("plink", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo, -+ &dbgaufs_plink_fop); -+ if (unlikely(!sbinfo->si_dbgaufs_plink)) -+ goto out_dir; -+ -+ /* regardless xino/noxino option */ -+ sbinfo->si_dbgaufs_xib = debugfs_create_file -+ ("xib", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo, -+ &dbgaufs_xib_fop); -+ if (unlikely(!sbinfo->si_dbgaufs_xib)) -+ goto out_dir; -+ -+ err = dbgaufs_xigen_init(sbinfo); -+ if (!err) -+ goto out; /* success */ -+ -+out_dir: -+ dbgaufs_si_fin(sbinfo); -+out: -+ if (unlikely(err)) -+ pr_err("debugfs/aufs failed\n"); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void dbgaufs_fin(void) -+{ -+ debugfs_remove(dbgaufs); -+} -+ -+int __init dbgaufs_init(void) -+{ -+ int err; -+ -+ err = -EIO; -+ dbgaufs = debugfs_create_dir(AUFS_NAME, NULL); -+ if (dbgaufs) -+ err = 0; -+ return err; -+} -diff -Naur null/fs/aufs/dbgaufs.h linux-6.6.63/fs/aufs/dbgaufs.h ---- /dev/null -+++ linux-6.6.63/fs/aufs/dbgaufs.h 2024-12-18 15:12:59.294519601 +0300 -@@ -0,0 +1,53 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * debugfs interface -+ */ -+ -+#ifndef __DBGAUFS_H__ -+#define __DBGAUFS_H__ -+ -+#ifdef __KERNEL__ -+ -+struct super_block; -+struct au_sbinfo; -+struct au_branch; -+ -+#ifdef CONFIG_DEBUG_FS -+/* dbgaufs.c */ -+void dbgaufs_xino_del(struct au_branch *br); -+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex); -+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex, int topdown); -+void dbgaufs_si_fin(struct au_sbinfo *sbinfo); -+int dbgaufs_si_init(struct au_sbinfo *sbinfo); -+void dbgaufs_fin(void); -+int __init dbgaufs_init(void); -+#else -+AuStubVoid(dbgaufs_xino_del, struct au_branch *br) -+AuStubVoid(dbgaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex) -+AuStubVoid(dbgaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex, -+ int topdown) -+AuStubVoid(dbgaufs_si_fin, struct au_sbinfo *sbinfo) -+AuStubInt0(dbgaufs_si_init, struct au_sbinfo *sbinfo) -+AuStubVoid(dbgaufs_fin, void) -+AuStubInt0(__init dbgaufs_init, void) -+#endif /* CONFIG_DEBUG_FS */ -+ -+#endif /* __KERNEL__ */ -+#endif /* __DBGAUFS_H__ */ -diff -Naur null/fs/aufs/dcsub.c linux-6.6.63/fs/aufs/dcsub.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/dcsub.c 2024-12-18 15:12:59.294519601 +0300 -@@ -0,0 +1,225 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * sub-routines for dentry cache -+ */ -+ -+#include "aufs.h" -+ -+static void au_dpage_free(struct au_dpage *dpage) -+{ -+ int i; -+ struct dentry **p; -+ -+ p = dpage->dentries; -+ for (i = 0; i < dpage->ndentry; i++) -+ dput(*p++); -+ free_page((unsigned long)dpage->dentries); -+} -+ -+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp) -+{ -+ int err; -+ void *p; -+ -+ err = -ENOMEM; -+ dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp); -+ if (unlikely(!dpages->dpages)) -+ goto out; -+ -+ p = (void *)__get_free_page(gfp); -+ if (unlikely(!p)) -+ goto out_dpages; -+ -+ dpages->dpages[0].ndentry = 0; -+ dpages->dpages[0].dentries = p; -+ dpages->ndpage = 1; -+ return 0; /* success */ -+ -+out_dpages: -+ au_kfree_try_rcu(dpages->dpages); -+out: -+ return err; -+} -+ -+void au_dpages_free(struct au_dcsub_pages *dpages) -+{ -+ int i; -+ struct au_dpage *p; -+ -+ p = dpages->dpages; -+ for (i = 0; i < dpages->ndpage; i++) -+ au_dpage_free(p++); -+ au_kfree_try_rcu(dpages->dpages); -+} -+ -+static int au_dpages_append(struct au_dcsub_pages *dpages, -+ struct dentry *dentry, gfp_t gfp) -+{ -+ int err, sz; -+ struct au_dpage *dpage; -+ void *p; -+ -+ dpage = dpages->dpages + dpages->ndpage - 1; -+ sz = PAGE_SIZE / sizeof(dentry); -+ if (unlikely(dpage->ndentry >= sz)) { -+ AuLabel(new dpage); -+ err = -ENOMEM; -+ sz = dpages->ndpage * sizeof(*dpages->dpages); -+ p = au_kzrealloc(dpages->dpages, sz, -+ sz + sizeof(*dpages->dpages), gfp, -+ /*may_shrink*/0); -+ if (unlikely(!p)) -+ goto out; -+ -+ dpages->dpages = p; -+ dpage = dpages->dpages + dpages->ndpage; -+ p = (void *)__get_free_page(gfp); -+ if (unlikely(!p)) -+ goto out; -+ -+ dpage->ndentry = 0; -+ dpage->dentries = p; -+ dpages->ndpage++; -+ } -+ -+ AuDebugOn(au_dcount(dentry) <= 0); -+ dpage->dentries[dpage->ndentry++] = dget_dlock(dentry); -+ return 0; /* success */ -+ -+out: -+ return err; -+} -+ -+/* todo: BAD approach */ -+/* copied from linux/fs/dcache.c */ -+enum d_walk_ret { -+ D_WALK_CONTINUE, -+ D_WALK_QUIT, -+ D_WALK_NORETRY, -+ D_WALK_SKIP, -+}; -+ -+extern void d_walk(struct dentry *parent, void *data, -+ enum d_walk_ret (*enter)(void *, struct dentry *)); -+ -+struct ac_dpages_arg { -+ int err; -+ struct au_dcsub_pages *dpages; -+ struct super_block *sb; -+ au_dpages_test test; -+ void *arg; -+}; -+ -+static enum d_walk_ret au_call_dpages_append(void *_arg, struct dentry *dentry) -+{ -+ enum d_walk_ret ret; -+ struct ac_dpages_arg *arg = _arg; -+ -+ ret = D_WALK_CONTINUE; -+ if (dentry->d_sb == arg->sb -+ && !IS_ROOT(dentry) -+ && au_dcount(dentry) > 0 -+ && au_di(dentry) -+ && (!arg->test || arg->test(dentry, arg->arg))) { -+ arg->err = au_dpages_append(arg->dpages, dentry, GFP_ATOMIC); -+ if (unlikely(arg->err)) -+ ret = D_WALK_QUIT; -+ } -+ -+ return ret; -+} -+ -+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root, -+ au_dpages_test test, void *arg) -+{ -+ struct ac_dpages_arg args = { -+ .err = 0, -+ .dpages = dpages, -+ .sb = root->d_sb, -+ .test = test, -+ .arg = arg -+ }; -+ -+ d_walk(root, &args, au_call_dpages_append); -+ -+ return args.err; -+} -+ -+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry, -+ int do_include, au_dpages_test test, void *arg) -+{ -+ int err; -+ -+ err = 0; -+ write_seqlock(&rename_lock); -+ spin_lock(&dentry->d_lock); -+ if (do_include -+ && au_dcount(dentry) > 0 -+ && (!test || test(dentry, arg))) -+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC); -+ spin_unlock(&dentry->d_lock); -+ if (unlikely(err)) -+ goto out; -+ -+ /* -+ * RCU for vfsmount is unnecessary since this is a traverse in a single -+ * mount -+ */ -+ while (!IS_ROOT(dentry)) { -+ dentry = dentry->d_parent; /* rename_lock is locked */ -+ spin_lock(&dentry->d_lock); -+ if (au_dcount(dentry) > 0 -+ && (!test || test(dentry, arg))) -+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC); -+ spin_unlock(&dentry->d_lock); -+ if (unlikely(err)) -+ break; -+ } -+ -+out: -+ write_sequnlock(&rename_lock); -+ return err; -+} -+ -+static inline int au_dcsub_dpages_aufs(struct dentry *dentry, void *arg) -+{ -+ return au_di(dentry) && dentry->d_sb == arg; -+} -+ -+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages, -+ struct dentry *dentry, int do_include) -+{ -+ return au_dcsub_pages_rev(dpages, dentry, do_include, -+ au_dcsub_dpages_aufs, dentry->d_sb); -+} -+ -+int au_test_subdir(struct dentry *d1, struct dentry *d2) -+{ -+ struct path path[2] = { -+ { -+ .dentry = d1 -+ }, -+ { -+ .dentry = d2 -+ } -+ }; -+ -+ return path_is_under(path + 0, path + 1); -+} -diff -Naur null/fs/aufs/dcsub.h linux-6.6.63/fs/aufs/dcsub.h ---- /dev/null -+++ linux-6.6.63/fs/aufs/dcsub.h 2024-12-18 15:12:59.294519601 +0300 -@@ -0,0 +1,139 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * sub-routines for dentry cache -+ */ -+ -+#ifndef __AUFS_DCSUB_H__ -+#define __AUFS_DCSUB_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+#include "vfsub.h" -+ -+struct au_dpage { -+ int ndentry; -+ struct dentry **dentries; -+}; -+ -+struct au_dcsub_pages { -+ int ndpage; -+ struct au_dpage *dpages; -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* dcsub.c */ -+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp); -+void au_dpages_free(struct au_dcsub_pages *dpages); -+typedef int (*au_dpages_test)(struct dentry *dentry, void *arg); -+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root, -+ au_dpages_test test, void *arg); -+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry, -+ int do_include, au_dpages_test test, void *arg); -+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages, -+ struct dentry *dentry, int do_include); -+int au_test_subdir(struct dentry *d1, struct dentry *d2); -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * todo: in linux-3.13, several similar (but faster) helpers are added to -+ * include/linux/dcache.h. Try them (in the future). -+ */ -+ -+static inline int au_d_hashed_positive(struct dentry *d) -+{ -+ int err; -+ struct inode *inode = d_inode(d); -+ -+ err = 0; -+ if (unlikely(d_unhashed(d) -+ || d_is_negative(d) -+ /* to support both aufs and branches */ -+ || !vfsub_inode_nlink(inode, AU_I_UNKNOWN))) -+ err = -ENOENT; -+ return err; -+} -+ -+static inline int au_d_linkable(struct dentry *d) -+{ -+ int err; -+ struct inode *inode = d_inode(d); -+ -+ err = au_d_hashed_positive(d); -+ if (err -+ && d_is_positive(d) -+ && (inode->i_state & I_LINKABLE)) -+ err = 0; -+ return err; -+} -+ -+static inline int au_d_alive(struct dentry *d) -+{ -+ int err; -+ struct inode *inode; -+ -+ err = 0; -+ if (!IS_ROOT(d)) -+ err = au_d_hashed_positive(d); -+ else { -+ inode = d_inode(d); -+ if (unlikely(d_unlinked(d) -+ || d_is_negative(d) -+ || !vfsub_inode_nlink(inode, AU_I_UNKNOWN))) -+ err = -ENOENT; -+ } -+ return err; -+} -+ -+static inline int au_alive_dir(struct dentry *d) -+{ -+ int err; -+ -+ err = au_d_alive(d); -+ if (unlikely(err || IS_DEADDIR(d_inode(d)))) -+ err = -ENOENT; -+ return err; -+} -+ -+static inline int au_qstreq(struct qstr *a, struct qstr *b) -+{ -+ return a->len == b->len -+ && !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); -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_DCSUB_H__ */ -diff -Naur null/fs/aufs/debug.c linux-6.6.63/fs/aufs/debug.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/debug.c 2024-12-18 15:12:59.294519601 +0300 -@@ -0,0 +1,449 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * debug print functions -+ */ -+ -+#include -+#include "aufs.h" -+ -+/* Returns 0, or -errno. arg is in kp->arg. */ -+static int param_atomic_t_set(const char *val, const struct kernel_param *kp) -+{ -+ int err, n; -+ -+ err = kstrtoint(val, 0, &n); -+ if (!err) { -+ if (n > 0) -+ au_debug_on(); -+ else -+ au_debug_off(); -+ } -+ return err; -+} -+ -+/* Returns length written or -errno. Buffer is 4k (ie. be short!) */ -+static int param_atomic_t_get(char *buffer, const struct kernel_param *kp) -+{ -+ atomic_t *a; -+ -+ a = kp->arg; -+ return sprintf(buffer, "%d", atomic_read(a)); -+} -+ -+static const struct kernel_param_ops param_ops_atomic_t = { -+ .set = param_atomic_t_set, -+ .get = param_atomic_t_get -+ /* void (*free)(void *arg) */ -+}; -+ -+atomic_t aufs_debug = ATOMIC_INIT(0); -+MODULE_PARM_DESC(debug, "debug print"); -+module_param_named(debug, aufs_debug, atomic_t, 0664); -+ -+DEFINE_MUTEX(au_dbg_mtx); /* just to serialize the dbg msgs */ -+char *au_plevel = KERN_DEBUG; -+#define dpri(fmt, ...) do { \ -+ if ((au_plevel \ -+ && strcmp(au_plevel, KERN_DEBUG)) \ -+ || au_debug_test()) \ -+ printk("%s" fmt, au_plevel, ##__VA_ARGS__); \ -+} while (0) -+ -+/* ---------------------------------------------------------------------- */ -+ -+void au_dpri_whlist(struct au_nhash *whlist) -+{ -+ unsigned long ul, n; -+ struct hlist_head *head; -+ struct au_vdir_wh *pos; -+ -+ n = whlist->nh_num; -+ head = whlist->nh_head; -+ for (ul = 0; ul < n; ul++) { -+ hlist_for_each_entry(pos, head, wh_hash) -+ dpri("b%d, %.*s, %d\n", -+ pos->wh_bindex, -+ pos->wh_str.len, pos->wh_str.name, -+ pos->wh_str.len); -+ head++; -+ } -+} -+ -+void au_dpri_vdir(struct au_vdir *vdir) -+{ -+ unsigned long ul; -+ union au_vdir_deblk_p p; -+ unsigned char *o; -+ -+ if (!vdir || IS_ERR(vdir)) { -+ dpri("err %ld\n", PTR_ERR(vdir)); -+ return; -+ } -+ -+ dpri("deblk %u, nblk %lu, deblk %p, last{%lu, %p}, ver %llu\n", -+ vdir->vd_deblk_sz, vdir->vd_nblk, vdir->vd_deblk, -+ vdir->vd_last.ul, vdir->vd_last.p.deblk, vdir->vd_version); -+ for (ul = 0; ul < vdir->vd_nblk; ul++) { -+ p.deblk = vdir->vd_deblk[ul]; -+ o = p.deblk; -+ dpri("[%lu]: %p\n", ul, o); -+ } -+} -+ -+static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode, int hn, -+ struct dentry *wh) -+{ -+ char *n = NULL; -+ int l = 0; -+ struct timespec64 ctime; -+ -+ if (!inode || IS_ERR(inode)) { -+ dpri("i%d: err %ld\n", bindex, PTR_ERR(inode)); -+ return -1; -+ } -+ -+ /* the type of i_blocks depends upon CONFIG_LBDAF */ -+ BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long) -+ && sizeof(inode->i_blocks) != sizeof(u64)); -+ if (wh) { -+ n = (void *)wh->d_name.name; -+ l = wh->d_name.len; -+ } -+ -+ ctime = inode_get_ctime(inode); -+ dpri("i%d: %p, i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu," -+ " acl %p, def_acl %p," -+ " hn %d, ct %lld, np %lu, st 0x%lx, f 0x%x, v %llu, g %x%s%.*s\n", -+ bindex, inode, -+ inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??", -+ atomic_read(&inode->i_count), -+ vfsub_inode_nlink(inode, AU_I_UNKNOWN), inode->i_mode, -+ i_size_read(inode), (unsigned long long)inode->i_blocks, -+ inode->i_acl, inode->i_default_acl, -+ hn, (long long)timespec64_to_ns(&ctime) & 0x0ffff, -+ inode->i_mapping ? inode->i_mapping->nrpages : 0, -+ inode->i_state, inode->i_flags, inode_peek_iversion(inode), -+ inode->i_generation, -+ l ? ", wh " : "", l, n); -+ return 0; -+} -+ -+void au_dpri_inode(struct inode *inode) -+{ -+ struct au_iinfo *iinfo; -+ struct au_hinode *hi; -+ aufs_bindex_t bindex; -+ int err, hn; -+ -+ err = do_pri_inode(-1, inode, -1, NULL); -+ if (err || !au_test_aufs(inode->i_sb) || au_is_bad_inode(inode)) -+ return; -+ -+ iinfo = au_ii(inode); -+ dpri("i-1: btop %d, bbot %d, gen %d\n", -+ iinfo->ii_btop, iinfo->ii_bbot, au_iigen(inode, NULL)); -+ if (iinfo->ii_btop < 0) -+ return; -+ hn = 0; -+ for (bindex = iinfo->ii_btop; bindex <= iinfo->ii_bbot; bindex++) { -+ hi = au_hinode(iinfo, bindex); -+ hn = !!au_hn(hi); -+ do_pri_inode(bindex, hi->hi_inode, hn, hi->hi_whdentry); -+ } -+} -+ -+void au_dpri_dalias(struct inode *inode) -+{ -+ struct dentry *d; -+ -+ spin_lock(&inode->i_lock); -+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) -+ au_dpri_dentry(d); -+ spin_unlock(&inode->i_lock); -+} -+ -+static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry) -+{ -+ struct dentry *wh = NULL; -+ int hn; -+ struct inode *inode; -+ struct au_iinfo *iinfo; -+ struct au_hinode *hi; -+ -+ if (!dentry || IS_ERR(dentry)) { -+ dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry)); -+ return -1; -+ } -+ /* do not call dget_parent() here */ -+ /* note: access d_xxx without d_lock */ -+ dpri("d%d: %p, %pd2?, %s, cnt %d, flags 0x%x, %shashed\n", -+ bindex, dentry, dentry, -+ dentry->d_sb ? au_sbtype(dentry->d_sb) : "??", -+ au_dcount(dentry), dentry->d_flags, -+ d_unhashed(dentry) ? "un" : ""); -+ hn = -1; -+ inode = NULL; -+ if (d_is_positive(dentry)) -+ inode = d_inode(dentry); -+ if (inode -+ && au_test_aufs(dentry->d_sb) -+ && bindex >= 0 -+ && !au_is_bad_inode(inode)) { -+ iinfo = au_ii(inode); -+ hi = au_hinode(iinfo, bindex); -+ hn = !!au_hn(hi); -+ wh = hi->hi_whdentry; -+ } -+ do_pri_inode(bindex, inode, hn, wh); -+ return 0; -+} -+ -+void au_dpri_dentry(struct dentry *dentry) -+{ -+ struct au_dinfo *dinfo; -+ aufs_bindex_t bindex; -+ int err; -+ -+ err = do_pri_dentry(-1, dentry); -+ if (err || !au_test_aufs(dentry->d_sb)) -+ return; -+ -+ dinfo = au_di(dentry); -+ if (!dinfo) -+ return; -+ dpri("d-1: btop %d, bbot %d, bwh %d, bdiropq %d, gen %d, tmp %d\n", -+ dinfo->di_btop, dinfo->di_bbot, -+ dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry), -+ dinfo->di_tmpfile); -+ if (dinfo->di_btop < 0) -+ return; -+ for (bindex = dinfo->di_btop; bindex <= dinfo->di_bbot; bindex++) -+ do_pri_dentry(bindex, au_hdentry(dinfo, bindex)->hd_dentry); -+} -+ -+static int do_pri_file(aufs_bindex_t bindex, struct file *file) -+{ -+ char a[32]; -+ -+ if (!file || IS_ERR(file)) { -+ dpri("f%d: err %ld\n", bindex, PTR_ERR(file)); -+ return -1; -+ } -+ a[0] = 0; -+ if (bindex < 0 -+ && !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", -+ au_figen(file), atomic_read(&au_fi(file)->fi_mmapped)); -+ dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, v %llu, pos %llu%s\n", -+ bindex, file->f_mode, file->f_flags, (long)file_count(file), -+ file->f_version, file->f_pos, a); -+ if (!IS_ERR_OR_NULL(file->f_path.dentry)) -+ do_pri_dentry(bindex, file->f_path.dentry); -+ return 0; -+} -+ -+void au_dpri_file(struct file *file) -+{ -+ struct au_finfo *finfo; -+ struct au_fidir *fidir; -+ struct au_hfile *hfile; -+ aufs_bindex_t bindex; -+ int err; -+ -+ err = do_pri_file(-1, file); -+ if (err -+ || IS_ERR_OR_NULL(file->f_path.dentry) -+ || !au_test_aufs(file->f_path.dentry->d_sb)) -+ return; -+ -+ finfo = au_fi(file); -+ if (!finfo) -+ return; -+ if (finfo->fi_btop < 0) -+ return; -+ fidir = finfo->fi_hdir; -+ if (!fidir) -+ do_pri_file(finfo->fi_btop, finfo->fi_htop.hf_file); -+ else -+ for (bindex = finfo->fi_btop; -+ bindex >= 0 && bindex <= fidir->fd_bbot; -+ bindex++) { -+ hfile = fidir->fd_hfile + bindex; -+ do_pri_file(bindex, hfile ? hfile->hf_file : NULL); -+ } -+} -+ -+static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br) -+{ -+ struct vfsmount *mnt; -+ struct super_block *sb; -+ -+ if (!br || IS_ERR(br)) -+ goto out; -+ mnt = au_br_mnt(br); -+ if (!mnt || IS_ERR(mnt)) -+ goto out; -+ sb = mnt->mnt_sb; -+ if (!sb || IS_ERR(sb)) -+ goto out; -+ -+ dpri("s%d: {perm 0x%x, id %d, wbr %p}, " -+ "%s, dev 0x%02x%02x, flags 0x%lx, cnt %d, active %d, " -+ "xino %d\n", -+ bindex, br->br_perm, br->br_id, br->br_wbr, -+ au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev), -+ sb->s_flags, sb->s_count, -+ atomic_read(&sb->s_active), -+ !!au_xino_file(br->br_xino, /*idx*/-1)); -+ return 0; -+ -+out: -+ dpri("s%d: err %ld\n", bindex, PTR_ERR(br)); -+ return -1; -+} -+ -+void au_dpri_sb(struct super_block *sb) -+{ -+ struct au_sbinfo *sbinfo; -+ aufs_bindex_t bindex; -+ int err; -+ /* to reduce stack size */ -+ struct { -+ struct vfsmount mnt; -+ struct au_branch fake; -+ } *a; -+ -+ /* this function can be called from magic sysrq */ -+ a = kzalloc(sizeof(*a), GFP_ATOMIC); -+ if (unlikely(!a)) { -+ dpri("no memory\n"); -+ return; -+ } -+ -+ a->mnt.mnt_sb = sb; -+ a->fake.br_path.mnt = &a->mnt; -+ err = do_pri_br(-1, &a->fake); -+ au_kfree_rcu(a); -+ dpri("dev 0x%x\n", sb->s_dev); -+ if (err || !au_test_aufs(sb)) -+ return; -+ -+ sbinfo = au_sbi(sb); -+ if (!sbinfo) -+ return; -+ dpri("nw %d, gen %u, kobj %d\n", -+ atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation, -+ kref_read(&sbinfo->si_kobj.kref)); -+ for (bindex = 0; bindex <= sbinfo->si_bbot; bindex++) -+ do_pri_br(bindex, sbinfo->si_branch[0 + bindex]); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line) -+{ -+ struct inode *h_inode, *inode = d_inode(dentry); -+ struct dentry *h_dentry; -+ aufs_bindex_t bindex, bbot, bi; -+ -+ if (!inode /* || au_di(dentry)->di_lsc == AuLsc_DI_TMP */) -+ return; -+ -+ bbot = au_dbbot(dentry); -+ bi = au_ibbot(inode); -+ if (bi < bbot) -+ bbot = bi; -+ bindex = au_dbtop(dentry); -+ bi = au_ibtop(inode); -+ if (bi > bindex) -+ bindex = bi; -+ -+ for (; bindex <= bbot; bindex++) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (!h_dentry) -+ continue; -+ h_inode = au_h_iptr(inode, bindex); -+ if (unlikely(h_inode != d_inode(h_dentry))) { -+ au_debug_on(); -+ AuDbg("b%d, %s:%d\n", bindex, func, line); -+ AuDbgDentry(dentry); -+ AuDbgInode(inode); -+ au_debug_off(); -+ if (au_test_fuse(h_inode->i_sb)) -+ WARN_ON_ONCE(1); -+ else -+ BUG(); -+ } -+ } -+} -+ -+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen) -+{ -+ int err, i, j; -+ struct au_dcsub_pages dpages; -+ struct au_dpage *dpage; -+ struct dentry **dentries; -+ -+ err = au_dpages_init(&dpages, GFP_NOFS); -+ AuDebugOn(err); -+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/1); -+ AuDebugOn(err); -+ for (i = dpages.ndpage - 1; !err && i >= 0; i--) { -+ dpage = dpages.dpages + i; -+ dentries = dpage->dentries; -+ for (j = dpage->ndentry - 1; !err && j >= 0; j--) -+ AuDebugOn(au_digen_test(dentries[j], sigen)); -+ } -+ au_dpages_free(&dpages); -+} -+ -+void au_dbg_verify_kthread(void) -+{ -+ if (au_wkq_test()) { -+ au_dbg_blocked(); -+ /* -+ * It may be recursive, but udba=notify between two aufs mounts, -+ * where a single ro branch is shared, is not a problem. -+ */ -+ /* WARN_ON(1); */ -+ } -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int __init au_debug_init(void) -+{ -+ aufs_bindex_t bindex; -+ struct au_vdir_destr destr; -+ -+ bindex = -1; -+ AuDebugOn(bindex >= 0); -+ -+ destr.len = -1; -+ AuDebugOn(destr.len < NAME_MAX); -+ -+#ifdef CONFIG_4KSTACKS -+ pr_warn("CONFIG_4KSTACKS is defined.\n"); -+#endif -+ -+ return 0; -+} -diff -Naur null/fs/aufs/debug.h linux-6.6.63/fs/aufs/debug.h ---- /dev/null -+++ linux-6.6.63/fs/aufs/debug.h 2024-12-18 15:12:59.294519601 +0300 -@@ -0,0 +1,226 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * debug print functions -+ */ -+ -+#ifndef __AUFS_DEBUG_H__ -+#define __AUFS_DEBUG_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_AUFS_DEBUG -+#define AuDebugOn(a) BUG_ON(a) -+ -+/* module parameter */ -+extern atomic_t aufs_debug; -+static inline void au_debug_on(void) -+{ -+ atomic_inc(&aufs_debug); -+} -+static inline void au_debug_off(void) -+{ -+ atomic_dec_if_positive(&aufs_debug); -+} -+ -+static inline int au_debug_test(void) -+{ -+ return atomic_read(&aufs_debug) > 0; -+} -+#else -+AuStubVoid(AuDebugOn, bool expr __maybe_unused) -+AuStubVoid(au_debug_on, void) -+AuStubVoid(au_debug_off, void) -+AuStubInt0(au_debug_test, void) -+#endif /* CONFIG_AUFS_DEBUG */ -+ -+#define param_check_atomic_t(name, p) __param_check(name, p, atomic_t) -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* debug print */ -+ -+#define AuDbg(fmt, ...) do { \ -+ if (au_debug_test()) \ -+ pr_debug("DEBUG: " fmt, ##__VA_ARGS__); \ -+} while (0) -+#define AuLabel(l) AuDbg(#l "\n") -+#define AuIOErr(fmt, ...) pr_err("I/O Error, " fmt, ##__VA_ARGS__) -+#define AuWarn1(fmt, ...) do { \ -+ static unsigned char _c; \ -+ if (!_c++) \ -+ pr_warn(fmt, ##__VA_ARGS__); \ -+} while (0) -+ -+#define AuErr1(fmt, ...) do { \ -+ static unsigned char _c; \ -+ if (!_c++) \ -+ pr_err(fmt, ##__VA_ARGS__); \ -+} while (0) -+ -+#define AuIOErr1(fmt, ...) do { \ -+ static unsigned char _c; \ -+ if (!_c++) \ -+ AuIOErr(fmt, ##__VA_ARGS__); \ -+} while (0) -+ -+#define AuUnsupportMsg "This operation is not supported." \ -+ " Please report this application to aufs-users ML." -+#define AuUnsupport(fmt, ...) do { \ -+ pr_err(AuUnsupportMsg "\n" fmt, ##__VA_ARGS__); \ -+ dump_stack(); \ -+} while (0) -+ -+#define AuTraceErr(e) do { \ -+ if (unlikely((e) < 0)) \ -+ AuDbg("err %d\n", (int)(e)); \ -+} while (0) -+ -+#define AuTraceErrPtr(p) do { \ -+ if (IS_ERR(p)) \ -+ AuDbg("err %ld\n", PTR_ERR(p)); \ -+} while (0) -+ -+/* dirty macros for debug print, use with "%.*s" and caution */ -+#define AuLNPair(qstr) (qstr)->len, (qstr)->name -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct dentry; -+struct inode; -+struct au_nhash; -+struct au_vdir; -+#ifdef CONFIG_AUFS_DEBUG -+extern struct mutex au_dbg_mtx; -+extern char *au_plevel; -+void au_dpri_whlist(struct au_nhash *whlist); -+void au_dpri_vdir(struct au_vdir *vdir); -+void au_dpri_inode(struct inode *inode); -+void au_dpri_dalias(struct inode *inode); -+void au_dpri_dentry(struct dentry *dentry); -+struct file; -+void au_dpri_file(struct file *filp); -+struct super_block; -+void au_dpri_sb(struct super_block *sb); -+ -+#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_gen(struct dentry *parent, unsigned int sigen); -+void au_dbg_verify_kthread(void); -+ -+int __init au_debug_init(void); -+ -+#define AuDbgWhlist(w) do { \ -+ mutex_lock(&au_dbg_mtx); \ -+ AuDbg(#w "\n"); \ -+ au_dpri_whlist(w); \ -+ mutex_unlock(&au_dbg_mtx); \ -+} while (0) -+ -+#define AuDbgVdir(v) do { \ -+ mutex_lock(&au_dbg_mtx); \ -+ AuDbg(#v "\n"); \ -+ au_dpri_vdir(v); \ -+ mutex_unlock(&au_dbg_mtx); \ -+} while (0) -+ -+#define AuDbgInode(i) do { \ -+ mutex_lock(&au_dbg_mtx); \ -+ AuDbg(#i "\n"); \ -+ au_dpri_inode(i); \ -+ mutex_unlock(&au_dbg_mtx); \ -+} while (0) -+ -+#define AuDbgDAlias(i) do { \ -+ mutex_lock(&au_dbg_mtx); \ -+ AuDbg(#i "\n"); \ -+ au_dpri_dalias(i); \ -+ mutex_unlock(&au_dbg_mtx); \ -+} while (0) -+ -+#define AuDbgDentry(d) do { \ -+ mutex_lock(&au_dbg_mtx); \ -+ AuDbg(#d "\n"); \ -+ au_dpri_dentry(d); \ -+ mutex_unlock(&au_dbg_mtx); \ -+} while (0) -+ -+#define AuDbgFile(f) do { \ -+ mutex_lock(&au_dbg_mtx); \ -+ AuDbg(#f "\n"); \ -+ au_dpri_file(f); \ -+ mutex_unlock(&au_dbg_mtx); \ -+} while (0) -+ -+#define AuDbgSb(sb) do { \ -+ mutex_lock(&au_dbg_mtx); \ -+ AuDbg(#sb "\n"); \ -+ au_dpri_sb(sb); \ -+ mutex_unlock(&au_dbg_mtx); \ -+} while (0) -+ -+#define AuDbgSym(addr) do { \ -+ char sym[KSYM_SYMBOL_LEN]; \ -+ sprint_symbol(sym, (unsigned long)addr); \ -+ AuDbg("%s\n", sym); \ -+} while (0) -+#else -+AuStubVoid(au_dbg_verify_dinode, struct dentry *dentry) -+AuStubVoid(au_dbg_verify_gen, struct dentry *parent, unsigned int sigen) -+AuStubVoid(au_dbg_verify_kthread, void) -+AuStubInt0(__init au_debug_init, void) -+ -+AuStubVoid(AuDbgWhlist, struct au_nhash *whlist) -+AuStubVoid(AuDbgVdir, struct au_vdir *vdir) -+AuStubVoid(AuDbgInode, struct inode *inode) -+AuStubVoid(AuDbgDAlias, struct inode *inode) -+AuStubVoid(AuDbgDentry, struct dentry *dentry) -+AuStubVoid(AuDbgFile, struct file *filp) -+AuStubVoid(AuDbgSb, struct super_block *sb) -+AuStubVoid(AuDbgSym, void *addr) -+#endif /* CONFIG_AUFS_DEBUG */ -+ -+/* ---------------------------------------------------------------------- */ -+ -+#ifdef CONFIG_AUFS_MAGIC_SYSRQ -+int __init au_sysrq_init(void); -+void au_sysrq_fin(void); -+ -+#ifdef CONFIG_HW_CONSOLE -+#define au_dbg_blocked() do { \ -+ WARN_ON(1); \ -+ handle_sysrq('w'); \ -+} while (0) -+#else -+AuStubVoid(au_dbg_blocked, void) -+#endif -+ -+#else -+AuStubInt0(__init au_sysrq_init, void) -+AuStubVoid(au_sysrq_fin, void) -+AuStubVoid(au_dbg_blocked, void) -+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */ -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_DEBUG_H__ */ -diff -Naur null/fs/aufs/dentry.c linux-6.6.63/fs/aufs/dentry.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/dentry.c 2024-12-18 15:12:59.294519601 +0300 -@@ -0,0 +1,1176 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * lookup and dentry operations -+ */ -+ -+#include -+#include "aufs.h" -+ -+/* -+ * returns positive/negative dentry, NULL or an error. -+ * NULL means whiteout-ed or not-found. -+ */ -+static struct dentry* -+au_do_lookup(struct dentry *h_parent, struct dentry *dentry, -+ aufs_bindex_t bindex, struct au_do_lookup_args *args) -+{ -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ struct au_branch *br; -+ struct mnt_idmap *h_idmap; -+ struct path h_path; -+ int wh_found, opq; -+ unsigned char wh_able; -+ const unsigned char allow_neg = !!au_ftest_lkup(args->flags, ALLOW_NEG); -+ const unsigned char ignore_perm = !!au_ftest_lkup(args->flags, -+ IGNORE_PERM); -+ -+ wh_found = 0; -+ br = au_sbr(dentry->d_sb, bindex); -+ h_path.dentry = h_parent; -+ h_path.mnt = au_br_mnt(br); -+ h_idmap = au_br_idmap(br); -+ wh_able = !!au_br_whable(br->br_perm); -+ if (wh_able) -+ wh_found = au_wh_test(h_idmap, &h_path, &args->whname, -+ ignore_perm); -+ h_dentry = ERR_PTR(wh_found); -+ if (!wh_found) -+ goto real_lookup; -+ if (unlikely(wh_found < 0)) -+ goto out; -+ -+ /* We found a whiteout */ -+ /* au_set_dbbot(dentry, bindex); */ -+ au_set_dbwh(dentry, bindex); -+ if (!allow_neg) -+ return NULL; /* success */ -+ -+real_lookup: -+ if (!ignore_perm) -+ h_dentry = vfsub_lkup_one(args->name, &h_path); -+ else -+ h_dentry = au_sio_lkup_one(h_idmap, args->name, &h_path); -+ if (IS_ERR(h_dentry)) { -+ if (PTR_ERR(h_dentry) == -ENAMETOOLONG -+ && !allow_neg) -+ h_dentry = NULL; -+ goto out; -+ } -+ -+ h_inode = d_inode(h_dentry); -+ if (d_is_negative(h_dentry)) { -+ if (!allow_neg) -+ goto out_neg; -+ } else if (wh_found -+ || (args->type && args->type != (h_inode->i_mode & S_IFMT))) -+ goto out_neg; -+ else if (au_ftest_lkup(args->flags, DIRREN) -+ /* && h_inode */ -+ && !au_dr_lkup_h_ino(args, bindex, h_inode->i_ino)) { -+ AuDbg("b%d %pd ignored hi%llu\n", bindex, h_dentry, -+ (unsigned long long)h_inode->i_ino); -+ goto out_neg; -+ } -+ -+ if (au_dbbot(dentry) <= bindex) -+ au_set_dbbot(dentry, bindex); -+ if (au_dbtop(dentry) < 0 || bindex < au_dbtop(dentry)) -+ au_set_dbtop(dentry, bindex); -+ au_set_h_dptr(dentry, bindex, h_dentry); -+ -+ if (!d_is_dir(h_dentry) -+ || !wh_able -+ || (d_really_is_positive(dentry) && !d_is_dir(dentry))) -+ goto out; /* success */ -+ -+ h_path.dentry = h_dentry; -+ inode_lock_shared_nested(h_inode, AuLsc_I_CHILD); -+ opq = au_diropq_test(h_idmap, &h_path); -+ inode_unlock_shared(h_inode); -+ if (opq > 0) -+ au_set_dbdiropq(dentry, bindex); -+ else if (unlikely(opq < 0)) { -+ au_set_h_dptr(dentry, bindex, NULL); -+ h_dentry = ERR_PTR(opq); -+ } -+ goto out; -+ -+out_neg: -+ dput(h_dentry); -+ h_dentry = NULL; -+out: -+ return h_dentry; -+} -+ -+static int au_test_shwh(struct super_block *sb, const struct qstr *name) -+{ -+ if (unlikely(!au_opt_test(au_mntflags(sb), SHWH) -+ && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))) -+ return -EPERM; -+ return 0; -+} -+ -+/* -+ * returns the number of lower positive dentries, -+ * otherwise an error. -+ * can be called at unlinking with @type is zero. -+ */ -+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t btop, -+ unsigned int flags) -+{ -+ int npositive, err; -+ aufs_bindex_t bindex, btail, bdiropq; -+ unsigned char isdir, dirperm1, dirren; -+ struct au_do_lookup_args args = { -+ .flags = flags, -+ .name = &dentry->d_name -+ }; -+ struct dentry *parent; -+ struct super_block *sb; -+ -+ sb = dentry->d_sb; -+ err = au_test_shwh(sb, args.name); -+ if (unlikely(err)) -+ goto out; -+ -+ err = au_wh_name_alloc(&args.whname, args.name); -+ if (unlikely(err)) -+ goto out; -+ -+ isdir = !!d_is_dir(dentry); -+ dirperm1 = !!au_opt_test(au_mntflags(sb), DIRPERM1); -+ dirren = !!au_opt_test(au_mntflags(sb), DIRREN); -+ if (dirren) -+ au_fset_lkup(args.flags, DIRREN); -+ -+ npositive = 0; -+ parent = dget_parent(dentry); -+ btail = au_dbtaildir(parent); -+ for (bindex = btop; bindex <= btail; bindex++) { -+ struct dentry *h_parent, *h_dentry; -+ struct inode *h_inode, *h_dir; -+ struct au_branch *br; -+ -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (h_dentry) { -+ if (d_is_positive(h_dentry)) -+ npositive++; -+ break; -+ } -+ h_parent = au_h_dptr(parent, bindex); -+ if (!h_parent || !d_is_dir(h_parent)) -+ continue; -+ -+ if (dirren) { -+ /* if the inum matches, then use the prepared name */ -+ err = au_dr_lkup_name(&args, bindex); -+ if (unlikely(err)) -+ goto out_parent; -+ } -+ -+ h_dir = d_inode(h_parent); -+ inode_lock_shared_nested(h_dir, AuLsc_I_PARENT); -+ h_dentry = au_do_lookup(h_parent, dentry, bindex, &args); -+ inode_unlock_shared(h_dir); -+ err = PTR_ERR(h_dentry); -+ if (IS_ERR(h_dentry)) -+ goto out_parent; -+ if (h_dentry) -+ au_fclr_lkup(args.flags, ALLOW_NEG); -+ if (dirperm1) -+ au_fset_lkup(args.flags, IGNORE_PERM); -+ -+ if (au_dbwh(dentry) == bindex) -+ break; -+ if (!h_dentry) -+ continue; -+ 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; -+ if (args.type != S_IFDIR) -+ break; -+ else if (isdir) { -+ /* the type of lower may be different */ -+ bdiropq = au_dbdiropq(dentry); -+ if (bdiropq >= 0 && bdiropq <= bindex) -+ break; -+ } -+ br = au_sbr(sb, bindex); -+ if (dirren -+ && au_dr_hino_test_add(&br->br_dirren, h_inode->i_ino, -+ /*add_ent*/NULL)) { -+ /* prepare next name to lookup */ -+ err = au_dr_lkup(&args, dentry, bindex); -+ if (unlikely(err)) -+ goto out_parent; -+ } -+ } -+ -+ if (npositive) { -+ AuLabel(positive); -+ au_update_dbtop(dentry); -+ } -+ err = npositive; -+ if (unlikely(!au_opt_test(au_mntflags(sb), UDBA_NONE) -+ && au_dbtop(dentry) < 0)) { -+ err = -EIO; -+ AuIOErr("both of real entry and whiteout found, %pd, err %d\n", -+ dentry, err); -+ } -+ -+out_parent: -+ dput(parent); -+ au_kfree_try_rcu(args.whname.name); -+ if (dirren) -+ au_dr_lkup_fin(&args); -+out: -+ return err; -+} -+ -+struct dentry *au_sio_lkup_one(struct mnt_idmap *idmap, struct qstr *name, -+ struct path *ppath) -+{ -+ struct dentry *dentry; -+ int wkq_err; -+ -+ if (!au_test_h_perm_sio(idmap, d_inode(ppath->dentry), MAY_EXEC)) -+ dentry = vfsub_lkup_one(name, ppath); -+ else { -+ struct vfsub_lkup_one_args args = { -+ .errp = &dentry, -+ .name = name, -+ .ppath = ppath -+ }; -+ -+ wkq_err = au_wkq_wait(vfsub_call_lkup_one, &args); -+ if (unlikely(wkq_err)) -+ dentry = ERR_PTR(wkq_err); -+ } -+ -+ return dentry; -+} -+ -+/* -+ * lookup @dentry on @bindex which should be negative. -+ */ -+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh) -+{ -+ int err; -+ struct dentry *parent, *h_dentry; -+ struct au_branch *br; -+ struct mnt_idmap *h_idmap; -+ struct path h_ppath; -+ -+ parent = dget_parent(dentry); -+ br = au_sbr(dentry->d_sb, bindex); -+ h_ppath.dentry = au_h_dptr(parent, bindex); -+ h_ppath.mnt = au_br_mnt(br); -+ h_idmap = au_br_idmap(br); -+ if (wh) -+ h_dentry = au_whtmp_lkup(h_ppath.dentry, br, &dentry->d_name); -+ else -+ h_dentry = au_sio_lkup_one(h_idmap, &dentry->d_name, &h_ppath); -+ err = PTR_ERR(h_dentry); -+ if (IS_ERR(h_dentry)) -+ goto out; -+ if (unlikely(d_is_positive(h_dentry))) { -+ err = -EIO; -+ AuIOErr("%pd should be negative on b%d.\n", h_dentry, bindex); -+ dput(h_dentry); -+ goto out; -+ } -+ -+ err = 0; -+ if (bindex < au_dbtop(dentry)) -+ au_set_dbtop(dentry, bindex); -+ if (au_dbbot(dentry) < bindex) -+ au_set_dbbot(dentry, bindex); -+ au_set_h_dptr(dentry, bindex, h_dentry); -+ -+out: -+ dput(parent); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* subset of struct inode */ -+struct au_iattr { -+ unsigned long i_ino; -+ /* unsigned int i_nlink; */ -+ kuid_t i_uid; -+ kgid_t i_gid; -+ u64 i_version; -+/* -+ loff_t i_size; -+ blkcnt_t i_blocks; -+*/ -+ umode_t i_mode; -+}; -+ -+static void au_iattr_save(struct au_iattr *ia, struct inode *h_inode) -+{ -+ ia->i_ino = h_inode->i_ino; -+ /* ia->i_nlink = h_inode->i_nlink; */ -+ ia->i_uid = h_inode->i_uid; -+ ia->i_gid = h_inode->i_gid; -+ ia->i_version = inode_query_iversion(h_inode); -+/* -+ ia->i_size = h_inode->i_size; -+ ia->i_blocks = h_inode->i_blocks; -+*/ -+ ia->i_mode = (h_inode->i_mode & S_IFMT); -+} -+ -+static int au_iattr_test(struct au_iattr *ia, struct inode *h_inode) -+{ -+ return ia->i_ino != h_inode->i_ino -+ /* || ia->i_nlink != h_inode->i_nlink */ -+ || !uid_eq(ia->i_uid, h_inode->i_uid) -+ || !gid_eq(ia->i_gid, h_inode->i_gid) -+ || !inode_eq_iversion(h_inode, ia->i_version) -+/* -+ || ia->i_size != h_inode->i_size -+ || ia->i_blocks != h_inode->i_blocks -+*/ -+ || ia->i_mode != (h_inode->i_mode & S_IFMT); -+} -+ -+static int au_h_verify_dentry(struct dentry *h_dentry, struct dentry *h_parent, -+ struct au_branch *br) -+{ -+ int err; -+ struct au_iattr ia; -+ struct inode *h_inode; -+ struct dentry *h_d; -+ struct super_block *h_sb; -+ struct path h_ppath; -+ -+ err = 0; -+ memset(&ia, -1, sizeof(ia)); -+ h_sb = h_dentry->d_sb; -+ 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)) -+ /* nfs d_revalidate may return 0 for negative dentry */ -+ /* fuse d_revalidate always return 0 for negative dentry */ -+ goto out; -+ -+ /* main purpose is namei.c:cached_lookup() and d_revalidate */ -+ h_ppath.dentry = h_parent; -+ h_ppath.mnt = au_br_mnt(br); -+ h_d = vfsub_lkup_one(&h_dentry->d_name, &h_ppath); -+ err = PTR_ERR(h_d); -+ if (IS_ERR(h_d)) -+ goto out; -+ -+ err = 0; -+ if (unlikely(h_d != h_dentry -+ || d_inode(h_d) != h_inode -+ || (h_inode && au_iattr_test(&ia, h_inode)))) -+ err = au_busy_or_stale(); -+ dput(h_d); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir, -+ struct dentry *h_parent, struct au_branch *br) -+{ -+ int err; -+ -+ err = 0; -+ if (udba == AuOpt_UDBA_REVAL -+ && !au_test_fs_remote(h_dentry->d_sb)) { -+ IMustLock(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); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_do_refresh_hdentry(struct dentry *dentry, struct dentry *parent) -+{ -+ int err; -+ aufs_bindex_t new_bindex, bindex, bbot, bwh, bdiropq; -+ struct au_hdentry tmp, *p, *q; -+ struct au_dinfo *dinfo; -+ struct super_block *sb; -+ -+ DiMustWriteLock(dentry); -+ -+ sb = dentry->d_sb; -+ dinfo = au_di(dentry); -+ bbot = dinfo->di_bbot; -+ bwh = dinfo->di_bwh; -+ bdiropq = dinfo->di_bdiropq; -+ bindex = dinfo->di_btop; -+ p = au_hdentry(dinfo, bindex); -+ for (; bindex <= bbot; bindex++, p++) { -+ if (!p->hd_dentry) -+ continue; -+ -+ new_bindex = au_br_index(sb, p->hd_id); -+ if (new_bindex == bindex) -+ continue; -+ -+ if (dinfo->di_bwh == bindex) -+ bwh = new_bindex; -+ if (dinfo->di_bdiropq == bindex) -+ bdiropq = new_bindex; -+ if (new_bindex < 0) { -+ au_hdput(p); -+ p->hd_dentry = NULL; -+ continue; -+ } -+ -+ /* swap two lower dentries, and loop again */ -+ q = au_hdentry(dinfo, new_bindex); -+ tmp = *q; -+ *q = *p; -+ *p = tmp; -+ if (tmp.hd_dentry) { -+ bindex--; -+ p--; -+ } -+ } -+ -+ dinfo->di_bwh = -1; -+ if (bwh >= 0 && bwh <= au_sbbot(sb) && au_sbr_whable(sb, bwh)) -+ dinfo->di_bwh = bwh; -+ -+ dinfo->di_bdiropq = -1; -+ if (bdiropq >= 0 -+ && bdiropq <= au_sbbot(sb) -+ && au_sbr_whable(sb, bdiropq)) -+ dinfo->di_bdiropq = bdiropq; -+ -+ err = -EIO; -+ dinfo->di_btop = -1; -+ dinfo->di_bbot = -1; -+ bbot = au_dbbot(parent); -+ bindex = 0; -+ p = au_hdentry(dinfo, bindex); -+ for (; bindex <= bbot; bindex++, p++) -+ if (p->hd_dentry) { -+ dinfo->di_btop = bindex; -+ break; -+ } -+ -+ if (dinfo->di_btop >= 0) { -+ bindex = bbot; -+ p = au_hdentry(dinfo, bindex); -+ for (; bindex >= 0; bindex--, p--) -+ if (p->hd_dentry) { -+ dinfo->di_bbot = bindex; -+ err = 0; -+ break; -+ } -+ } -+ -+ return err; -+} -+ -+static void au_do_hide(struct dentry *dentry) -+{ -+ struct inode *inode; -+ -+ if (d_really_is_positive(dentry)) { -+ inode = d_inode(dentry); -+ if (!d_is_dir(dentry)) { -+ if (vfsub_inode_nlink(inode, AU_I_AUFS) -+ && !d_unhashed(dentry)) -+ vfsub_drop_nlink(inode); -+ } else { -+ vfsub_clear_nlink(inode); -+ /* stop next lookup */ -+ inode->i_flags |= S_DEAD; -+ } -+ smp_mb(); /* necessary? */ -+ } -+ d_drop(dentry); -+} -+ -+static int au_hide_children(struct dentry *parent) -+{ -+ int err, i, j, ndentry; -+ struct au_dcsub_pages dpages; -+ struct au_dpage *dpage; -+ struct dentry *dentry; -+ -+ err = au_dpages_init(&dpages, GFP_NOFS); -+ if (unlikely(err)) -+ goto out; -+ err = au_dcsub_pages(&dpages, parent, NULL, NULL); -+ if (unlikely(err)) -+ goto out_dpages; -+ -+ /* in reverse order */ -+ for (i = dpages.ndpage - 1; i >= 0; i--) { -+ dpage = dpages.dpages + i; -+ ndentry = dpage->ndentry; -+ for (j = ndentry - 1; j >= 0; j--) { -+ dentry = dpage->dentries[j]; -+ if (dentry != parent) -+ au_do_hide(dentry); -+ } -+ } -+ -+out_dpages: -+ au_dpages_free(&dpages); -+out: -+ return err; -+} -+ -+static void au_hide(struct dentry *dentry) -+{ -+ int err; -+ -+ AuDbgDentry(dentry); -+ if (d_is_dir(dentry)) { -+ /* shrink_dcache_parent(dentry); */ -+ err = au_hide_children(dentry); -+ if (unlikely(err)) -+ AuIOErr("%pd, failed hiding children, ignored %d\n", -+ dentry, err); -+ } -+ au_do_hide(dentry); -+} -+ -+/* -+ * By adding a dirty branch, a cached dentry may be affected in various ways. -+ * -+ * a dirty branch is added -+ * - on the top of layers -+ * - in the middle of layers -+ * - to the bottom of layers -+ * -+ * on the added branch there exists -+ * - a whiteout -+ * - a diropq -+ * - a same named entry -+ * + exist -+ * * negative --> positive -+ * * positive --> positive -+ * - type is unchanged -+ * - type is changed -+ * + doesn't exist -+ * * negative --> negative -+ * * positive --> negative (rejected by au_br_del() for non-dir case) -+ * - none -+ */ -+static int au_refresh_by_dinfo(struct dentry *dentry, struct au_dinfo *dinfo, -+ struct au_dinfo *tmp) -+{ -+ int err; -+ aufs_bindex_t bindex, bbot; -+ struct { -+ struct dentry *dentry; -+ struct inode *inode; -+ mode_t mode; -+ } orig_h, tmp_h = { -+ .dentry = NULL -+ }; -+ struct au_hdentry *hd; -+ struct inode *inode, *h_inode; -+ struct dentry *h_dentry; -+ -+ err = 0; -+ AuDebugOn(dinfo->di_btop < 0); -+ orig_h.mode = 0; -+ orig_h.dentry = au_hdentry(dinfo, dinfo->di_btop)->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; -+ } -+ if (tmp->di_btop >= 0) { -+ tmp_h.dentry = au_hdentry(tmp, tmp->di_btop)->hd_dentry; -+ 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 = NULL; -+ if (d_really_is_positive(dentry)) -+ inode = d_inode(dentry); -+ if (!orig_h.inode) { -+ AuDbg("negative originally\n"); -+ if (inode) { -+ au_hide(dentry); -+ goto out; -+ } -+ AuDebugOn(inode); -+ AuDebugOn(dinfo->di_btop != dinfo->di_bbot); -+ AuDebugOn(dinfo->di_bdiropq != -1); -+ -+ if (!tmp_h.inode) { -+ AuDbg("negative --> negative\n"); -+ /* should have only one negative lower */ -+ if (tmp->di_btop >= 0 -+ && tmp->di_btop < dinfo->di_btop) { -+ AuDebugOn(tmp->di_btop != tmp->di_bbot); -+ AuDebugOn(dinfo->di_btop != dinfo->di_bbot); -+ au_set_h_dptr(dentry, dinfo->di_btop, NULL); -+ au_di_cp(dinfo, tmp); -+ hd = au_hdentry(tmp, tmp->di_btop); -+ au_set_h_dptr(dentry, tmp->di_btop, -+ dget(hd->hd_dentry)); -+ } -+ au_dbg_verify_dinode(dentry); -+ } else { -+ AuDbg("negative --> positive\n"); -+ /* -+ * similar to the behaviour of creating with bypassing -+ * aufs. -+ * unhash it in order to force an error in the -+ * succeeding create operation. -+ * we should not set S_DEAD here. -+ */ -+ d_drop(dentry); -+ /* au_di_swap(tmp, dinfo); */ -+ au_dbg_verify_dinode(dentry); -+ } -+ } else { -+ AuDbg("positive originally\n"); -+ /* inode may be NULL */ -+ AuDebugOn(inode && (inode->i_mode & S_IFMT) != orig_h.mode); -+ if (!tmp_h.inode) { -+ AuDbg("positive --> negative\n"); -+ /* or bypassing aufs */ -+ au_hide(dentry); -+ if (tmp->di_bwh >= 0 && tmp->di_bwh <= dinfo->di_btop) -+ dinfo->di_bwh = tmp->di_bwh; -+ if (inode) -+ err = au_refresh_hinode_self(inode); -+ au_dbg_verify_dinode(dentry); -+ } else if (orig_h.mode == tmp_h.mode) { -+ AuDbg("positive --> positive, same type\n"); -+ if (!S_ISDIR(orig_h.mode) -+ && dinfo->di_btop > tmp->di_btop) { -+ /* -+ * similar to the behaviour of removing and -+ * creating. -+ */ -+ au_hide(dentry); -+ if (inode) -+ err = au_refresh_hinode_self(inode); -+ au_dbg_verify_dinode(dentry); -+ } else { -+ /* fill empty slots */ -+ if (dinfo->di_btop > tmp->di_btop) -+ dinfo->di_btop = tmp->di_btop; -+ if (dinfo->di_bbot < tmp->di_bbot) -+ dinfo->di_bbot = tmp->di_bbot; -+ dinfo->di_bwh = tmp->di_bwh; -+ dinfo->di_bdiropq = tmp->di_bdiropq; -+ bbot = dinfo->di_bbot; -+ bindex = tmp->di_btop; -+ hd = au_hdentry(tmp, bindex); -+ for (; bindex <= bbot; bindex++, hd++) { -+ if (au_h_dptr(dentry, bindex)) -+ continue; -+ h_dentry = hd->hd_dentry; -+ if (!h_dentry) -+ continue; -+ AuDebugOn(d_is_negative(h_dentry)); -+ h_inode = d_inode(h_dentry); -+ AuDebugOn(orig_h.mode -+ != (h_inode->i_mode -+ & S_IFMT)); -+ au_set_h_dptr(dentry, bindex, -+ dget(h_dentry)); -+ } -+ if (inode) -+ err = au_refresh_hinode(inode, dentry); -+ au_dbg_verify_dinode(dentry); -+ } -+ } else { -+ AuDbg("positive --> positive, different type\n"); -+ /* similar to the behaviour of removing and creating */ -+ au_hide(dentry); -+ if (inode) -+ err = au_refresh_hinode_self(inode); -+ au_dbg_verify_dinode(dentry); -+ } -+ } -+ -+out: -+ return err; -+} -+ -+void au_refresh_dop(struct dentry *dentry, int force_reval) -+{ -+ const struct dentry_operations *dop -+ = force_reval ? &aufs_dop : dentry->d_sb->s_d_op; -+ static const unsigned int mask -+ = DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE; -+ -+ BUILD_BUG_ON(sizeof(mask) != sizeof(dentry->d_flags)); -+ -+ if (dentry->d_op == dop) -+ return; -+ -+ AuDbg("%pd\n", dentry); -+ spin_lock(&dentry->d_lock); -+ if (dop == &aufs_dop) -+ dentry->d_flags |= mask; -+ else -+ dentry->d_flags &= ~mask; -+ dentry->d_op = dop; -+ spin_unlock(&dentry->d_lock); -+} -+ -+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent) -+{ -+ int err, ebrange, nbr; -+ unsigned int sigen; -+ struct au_dinfo *dinfo, *tmp; -+ struct super_block *sb; -+ struct inode *inode; -+ -+ DiMustWriteLock(dentry); -+ AuDebugOn(IS_ROOT(dentry)); -+ AuDebugOn(d_really_is_negative(parent)); -+ -+ sb = dentry->d_sb; -+ sigen = au_sigen(sb); -+ err = au_digen_test(parent, sigen); -+ if (unlikely(err)) -+ goto out; -+ -+ nbr = au_sbbot(sb) + 1; -+ dinfo = au_di(dentry); -+ err = au_di_realloc(dinfo, nbr, /*may_shrink*/0); -+ if (unlikely(err)) -+ goto out; -+ ebrange = au_dbrange_test(dentry); -+ if (!ebrange) -+ ebrange = au_do_refresh_hdentry(dentry, parent); -+ -+ if (d_unhashed(dentry) || ebrange /* || dinfo->di_tmpfile */) { -+ AuDebugOn(au_dbtop(dentry) < 0 && au_dbbot(dentry) >= 0); -+ 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 */ -+ goto out; -+ } -+ -+ /* temporary dinfo */ -+ AuDbgDentry(dentry); -+ err = -ENOMEM; -+ tmp = au_di_alloc(sb, AuLsc_DI_TMP); -+ if (unlikely(!tmp)) -+ goto out; -+ au_di_swap(tmp, dinfo); -+ /* returns the number of positive dentries */ -+ /* -+ * if current working dir is removed, it returns an error. -+ * but the dentry is legal. -+ */ -+ err = au_lkup_dentry(dentry, /*btop*/0, AuLkup_ALLOW_NEG); -+ AuDbgDentry(dentry); -+ au_di_swap(tmp, dinfo); -+ if (err == -ENOENT) -+ err = 0; -+ if (err >= 0) { -+ /* compare/refresh by dinfo */ -+ AuDbgDentry(dentry); -+ err = au_refresh_by_dinfo(dentry, dinfo, tmp); -+ au_dbg_verify_dinode(dentry); -+ AuTraceErr(err); -+ } -+ au_di_realloc(dinfo, nbr, /*may_shrink*/1); /* harmless if err */ -+ au_rw_write_unlock(&tmp->di_rwsem); -+ au_di_free(tmp); -+ if (unlikely(err)) -+ goto out; -+ -+out_dgen: -+ au_update_digen(dentry); -+out: -+ if (unlikely(err && !(dentry->d_flags & DCACHE_NFSFS_RENAMED))) { -+ AuIOErr("failed refreshing %pd, %d\n", dentry, err); -+ AuDbgDentry(dentry); -+ } -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_do_h_d_reval(struct dentry *h_dentry, unsigned int flags, -+ struct dentry *dentry, aufs_bindex_t bindex) -+{ -+ int err, valid; -+ -+ err = 0; -+ if (!(h_dentry->d_flags & DCACHE_OP_REVALIDATE)) -+ goto out; -+ -+ AuDbg("b%d\n", bindex); -+ /* -+ * gave up supporting LOOKUP_CREATE/OPEN for lower fs, -+ * due to whiteout and branch permission. -+ */ -+ flags &= ~(/*LOOKUP_PARENT |*/ LOOKUP_OPEN | LOOKUP_CREATE -+ | LOOKUP_FOLLOW | LOOKUP_EXCL); -+ /* it may return tri-state */ -+ valid = h_dentry->d_op->d_revalidate(h_dentry, flags); -+ -+ if (unlikely(valid < 0)) -+ err = valid; -+ else if (!valid) -+ err = -EINVAL; -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* todo: remove this */ -+static int h_d_revalidate(struct dentry *dentry, struct inode *inode, -+ unsigned int flags, int do_udba, int dirren) -+{ -+ int err; -+ umode_t mode, h_mode; -+ aufs_bindex_t bindex, btail, btop, ibs, ibe, bwh; -+ unsigned char plus, unhashed, is_root, h_plus, h_nfs, tmpfile; -+ struct inode *h_inode, *h_cached_inode; -+ struct dentry *h_dentry; -+ struct qstr *name, *h_name; -+ -+ err = 0; -+ plus = 0; -+ mode = 0; -+ ibs = -1; -+ ibe = -1; -+ unhashed = !!d_unhashed(dentry); -+ is_root = !!IS_ROOT(dentry); -+ name = &dentry->d_name; -+ tmpfile = au_di(dentry)->di_tmpfile; -+ -+ /* -+ * Theoretically, REVAL test should be unnecessary in case of -+ * {FS,I}NOTIFY. -+ * But {fs,i}notify doesn't fire some necessary events, -+ * IN_ATTRIB for atime/nlink/pageio -+ * Let's do REVAL test too. -+ */ -+ if (do_udba && inode) { -+ mode = (inode->i_mode & S_IFMT); -+ plus = (vfsub_inode_nlink(inode, AU_I_AUFS) > 0); -+ ibs = au_ibtop(inode); -+ ibe = au_ibbot(inode); -+ } -+ -+ btop = au_dbtop(dentry); -+ bwh = au_dbwh(dentry); -+ if (0 <= bwh && bwh < btop) -+ btop = bwh; -+ btail = btop; -+ if (inode && S_ISDIR(inode->i_mode)) -+ btail = au_dbtaildir(dentry); -+ for (bindex = btop; bindex <= btail; bindex++) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (!h_dentry -+ && (bindex == bwh && inode)) -+ h_dentry = au_hi_wh(inode, bindex); -+ if (!h_dentry) -+ continue; -+ -+ AuDbg("b%d, %pd\n", bindex, h_dentry); -+ h_nfs = !!au_test_nfs(h_dentry->d_sb); -+ spin_lock(&h_dentry->d_lock); -+ h_name = &h_dentry->d_name; -+ if (unlikely(do_udba -+ && bindex != bwh -+ && !is_root -+ && ((!h_nfs -+ && (unhashed != !!d_unhashed(h_dentry) -+ || (!tmpfile && !dirren -+ && !au_qstreq(name, h_name)) -+ )) -+ || (h_nfs -+ && !(flags & LOOKUP_OPEN) -+ && (h_dentry->d_flags -+ & DCACHE_NFSFS_RENAMED))) -+ )) { -+ int h_unhashed; -+ -+ h_unhashed = d_unhashed(h_dentry); -+ spin_unlock(&h_dentry->d_lock); -+ AuDbg("unhash 0x%x 0x%x, %pd %pd\n", -+ unhashed, h_unhashed, dentry, h_dentry); -+ goto err; -+ } -+ spin_unlock(&h_dentry->d_lock); -+ -+ err = au_do_h_d_reval(h_dentry, flags, dentry, bindex); -+ if (unlikely(err)) -+ /* do not goto err, to keep the errno */ -+ break; -+ -+ /* todo: plink too? */ -+ if (!do_udba) -+ continue; -+ -+ /* UDBA tests */ -+ 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; -+ if (h_inode && bindex != bwh) { -+ h_mode = (h_inode->i_mode & S_IFMT); -+ h_plus = (vfsub_inode_nlink(h_inode, AU_I_BRANCH) > 0); -+ } -+ if (inode && ibs <= bindex && bindex <= ibe) -+ h_cached_inode = au_h_iptr(inode, bindex); -+ -+ if (!h_nfs) { -+ if (unlikely(plus != h_plus && !tmpfile)) -+ goto err; -+ } else { -+ if (unlikely(!(h_dentry->d_flags & DCACHE_NFSFS_RENAMED) -+ && !is_root -+ && !IS_ROOT(h_dentry) -+ && unhashed != d_unhashed(h_dentry))) -+ goto err; -+ } -+ if (unlikely(mode != h_mode -+ || h_cached_inode != h_inode)) -+ goto err; -+ continue; -+ -+err: -+ err = -EINVAL; -+ break; -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+/* todo: consolidate with do_refresh() and au_reval_for_attr() */ -+static int simple_reval_dpath(struct dentry *dentry, unsigned int sigen) -+{ -+ int err; -+ struct dentry *parent; -+ -+ if (!au_digen_test(dentry, sigen)) -+ return 0; -+ -+ parent = dget_parent(dentry); -+ di_read_lock_parent(parent, AuLock_IR); -+ AuDebugOn(au_digen_test(parent, sigen)); -+ au_dbg_verify_gen(parent, sigen); -+ err = au_refresh_dentry(dentry, parent); -+ di_read_unlock(parent, AuLock_IR); -+ dput(parent); -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_reval_dpath(struct dentry *dentry, unsigned int sigen) -+{ -+ int err; -+ struct dentry *d, *parent; -+ -+ if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR)) -+ return simple_reval_dpath(dentry, sigen); -+ -+ /* slow loop, keep it simple and stupid */ -+ /* cf: au_cpup_dirs() */ -+ err = 0; -+ parent = NULL; -+ while (au_digen_test(dentry, sigen)) { -+ d = dentry; -+ while (1) { -+ dput(parent); -+ parent = dget_parent(d); -+ if (!au_digen_test(parent, sigen)) -+ break; -+ d = parent; -+ } -+ -+ if (d != dentry) -+ di_write_lock_child2(d); -+ -+ /* someone might update our dentry while we were sleeping */ -+ if (au_digen_test(d, sigen)) { -+ /* -+ * todo: consolidate with simple_reval_dpath(), -+ * do_refresh() and au_reval_for_attr(). -+ */ -+ di_read_lock_parent(parent, AuLock_IR); -+ err = au_refresh_dentry(d, parent); -+ di_read_unlock(parent, AuLock_IR); -+ } -+ -+ if (d != dentry) -+ di_write_unlock(d); -+ dput(parent); -+ if (unlikely(err)) -+ break; -+ } -+ -+ return err; -+} -+ -+/* -+ * if valid returns 1, otherwise 0. -+ */ -+static int aufs_d_revalidate(struct dentry *dentry, unsigned int flags) -+{ -+ int valid, err; -+ unsigned int sigen; -+ unsigned char do_udba, dirren; -+ struct super_block *sb; -+ struct inode *inode; -+ -+ /* todo: support rcu-walk? */ -+ if (flags & LOOKUP_RCU) -+ return -ECHILD; -+ -+ valid = 0; -+ if (unlikely(!au_di(dentry))) -+ goto out; -+ -+ valid = 1; -+ sb = dentry->d_sb; -+ /* -+ * todo: very ugly -+ * i_mutex of parent dir may be held, -+ * but we should not return 'invalid' due to busy. -+ */ -+ err = aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW | AuLock_NOPLM); -+ if (unlikely(err)) { -+ valid = err; -+ AuTraceErr(err); -+ goto out; -+ } -+ inode = NULL; -+ if (d_really_is_positive(dentry)) -+ inode = d_inode(dentry); -+ if (unlikely(inode && au_is_bad_inode(inode))) { -+ err = -EINVAL; -+ AuTraceErr(err); -+ goto out_dgrade; -+ } -+ if (unlikely(au_dbrange_test(dentry))) { -+ err = -EINVAL; -+ AuTraceErr(err); -+ goto out_dgrade; -+ } -+ -+ sigen = au_sigen(sb); -+ if (au_digen_test(dentry, sigen)) { -+ AuDebugOn(IS_ROOT(dentry)); -+ err = au_reval_dpath(dentry, sigen); -+ if (unlikely(err)) { -+ AuTraceErr(err); -+ goto out_dgrade; -+ } -+ } -+ di_downgrade_lock(dentry, AuLock_IR); -+ -+ err = -EINVAL; -+ if (!(flags & (LOOKUP_OPEN | LOOKUP_EMPTY)) -+ && inode -+ && !(inode->i_state && I_LINKABLE) -+ && (IS_DEADDIR(inode) || !vfsub_inode_nlink(inode, AU_I_AUFS))) { -+ AuTraceErr(err); -+ goto out_inval; -+ } -+ -+ do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE); -+ if (do_udba && inode) { -+ aufs_bindex_t btop = au_ibtop(inode); -+ struct inode *h_inode; -+ -+ if (btop >= 0) { -+ h_inode = au_h_iptr(inode, btop); -+ if (h_inode && au_test_higen(inode, h_inode)) { -+ AuTraceErr(err); -+ goto out_inval; -+ } -+ } -+ } -+ -+ dirren = !!au_opt_test(au_mntflags(sb), DIRREN); -+ err = h_d_revalidate(dentry, inode, flags, do_udba, dirren); -+ if (unlikely(!err && do_udba && au_dbtop(dentry) < 0)) { -+ err = -EIO; -+ AuDbg("both of real entry and whiteout found, %p, err %d\n", -+ dentry, err); -+ } -+ goto out_inval; -+ -+out_dgrade: -+ di_downgrade_lock(dentry, AuLock_IR); -+out_inval: -+ aufs_read_unlock(dentry, AuLock_IR); -+ AuTraceErr(err); -+ valid = !err; -+out: -+ if (!valid) { -+ AuDbg("%pd invalid, %d\n", dentry, valid); -+ d_drop(dentry); -+ } -+ return valid; -+} -+ -+static void aufs_d_release(struct dentry *dentry) -+{ -+ if (au_di(dentry)) { -+ au_di_fin(dentry); -+ au_hn_di_reinit(dentry); -+ } -+} -+ -+const struct dentry_operations aufs_dop = { -+ .d_revalidate = aufs_d_revalidate, -+ .d_weak_revalidate = aufs_d_revalidate, -+ .d_release = aufs_d_release -+}; -+ -+/* aufs_dop without d_revalidate */ -+const struct dentry_operations aufs_dop_noreval = { -+ .d_release = aufs_d_release -+}; -diff -Naur null/fs/aufs/dentry.h linux-6.6.63/fs/aufs/dentry.h ---- /dev/null -+++ linux-6.6.63/fs/aufs/dentry.h 2024-12-18 15:12:59.294519601 +0300 -@@ -0,0 +1,270 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * lookup and dentry operations -+ */ -+ -+#ifndef __AUFS_DENTRY_H__ -+#define __AUFS_DENTRY_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include "dirren.h" -+#include "rwsem.h" -+ -+struct au_hdentry { -+ struct dentry *hd_dentry; -+ aufs_bindex_t hd_id; -+}; -+ -+struct au_dinfo { -+ atomic_t di_generation; -+ -+ struct au_rwsem di_rwsem; -+ aufs_bindex_t di_btop, di_bbot, di_bwh, di_bdiropq; -+ unsigned char di_tmpfile; /* to allow the different name */ -+ struct au_hdentry *di_hdentry; -+ struct file *di_htmpfile; -+ struct rcu_head rcu; -+} ____cacheline_aligned_in_smp; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* flags for au_lkup_dentry() */ -+#define AuLkup_ALLOW_NEG 1 -+#define AuLkup_IGNORE_PERM (1 << 1) -+#define AuLkup_DIRREN (1 << 2) -+#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name) -+#define au_fset_lkup(flags, name) \ -+ do { (flags) |= AuLkup_##name; } while (0) -+#define au_fclr_lkup(flags, name) \ -+ do { (flags) &= ~AuLkup_##name; } while (0) -+ -+#ifndef CONFIG_AUFS_DIRREN -+#undef AuLkup_DIRREN -+#define AuLkup_DIRREN 0 -+#endif -+ -+struct au_do_lookup_args { -+ unsigned int flags; -+ mode_t type; -+ struct qstr whname, *name; -+ struct au_dr_lookup dirren; -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* dentry.c */ -+extern const struct dentry_operations aufs_dop, aufs_dop_noreval; -+struct au_branch; -+struct dentry *au_sio_lkup_one(struct mnt_idmap *idmap, struct qstr *name, -+ struct path *ppath); -+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir, -+ struct dentry *h_parent, struct au_branch *br); -+ -+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t btop, -+ unsigned int flags); -+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh); -+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent); -+int au_reval_dpath(struct dentry *dentry, unsigned int sigen); -+void au_refresh_dop(struct dentry *dentry, int force_reval); -+ -+/* dinfo.c */ -+void au_di_init_once(void *_di); -+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc); -+void au_di_free(struct au_dinfo *dinfo); -+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b); -+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src); -+int au_di_init(struct dentry *dentry); -+void au_di_fin(struct dentry *dentry); -+int au_di_realloc(struct au_dinfo *dinfo, int nbr, int may_shrink); -+ -+void di_read_lock(struct dentry *d, int flags, unsigned int lsc); -+void di_read_unlock(struct dentry *d, int flags); -+void di_downgrade_lock(struct dentry *d, int flags); -+void di_write_lock(struct dentry *d, unsigned int lsc); -+void di_write_unlock(struct dentry *d); -+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir); -+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir); -+void di_write_unlock2(struct dentry *d1, struct dentry *d2); -+ -+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex); -+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex); -+aufs_bindex_t au_dbtail(struct dentry *dentry); -+aufs_bindex_t au_dbtaildir(struct dentry *dentry); -+ -+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex, -+ struct dentry *h_dentry); -+int au_digen_test(struct dentry *dentry, unsigned int sigen); -+int au_dbrange_test(struct dentry *dentry); -+void au_update_digen(struct dentry *dentry); -+void au_update_dbrange(struct dentry *dentry, int do_put_zero); -+void au_update_dbtop(struct dentry *dentry); -+void au_update_dbbot(struct dentry *dentry); -+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry); -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline struct au_dinfo *au_di(struct dentry *dentry) -+{ -+ return dentry->d_fsdata; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* lock subclass for dinfo */ -+enum { -+ AuLsc_DI_CHILD, /* child first */ -+ AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hnotify */ -+ AuLsc_DI_CHILD3, /* copyup dirs */ -+ AuLsc_DI_PARENT, -+ AuLsc_DI_PARENT2, -+ AuLsc_DI_PARENT3, -+ AuLsc_DI_TMP /* temp for replacing dinfo */ -+}; -+ -+/* -+ * di_read_lock_child, di_write_lock_child, -+ * di_read_lock_child2, di_write_lock_child2, -+ * di_read_lock_child3, di_write_lock_child3, -+ * di_read_lock_parent, di_write_lock_parent, -+ * di_read_lock_parent2, di_write_lock_parent2, -+ * di_read_lock_parent3, di_write_lock_parent3, -+ */ -+#define AuReadLockFunc(name, lsc) \ -+static inline void di_read_lock_##name(struct dentry *d, int flags) \ -+{ di_read_lock(d, flags, AuLsc_DI_##lsc); } -+ -+#define AuWriteLockFunc(name, lsc) \ -+static inline void di_write_lock_##name(struct dentry *d) \ -+{ di_write_lock(d, AuLsc_DI_##lsc); } -+ -+#define AuRWLockFuncs(name, lsc) \ -+ AuReadLockFunc(name, lsc) \ -+ AuWriteLockFunc(name, lsc) -+ -+AuRWLockFuncs(child, CHILD); -+AuRWLockFuncs(child2, CHILD2); -+AuRWLockFuncs(child3, CHILD3); -+AuRWLockFuncs(parent, PARENT); -+AuRWLockFuncs(parent2, PARENT2); -+AuRWLockFuncs(parent3, PARENT3); -+ -+#undef AuReadLockFunc -+#undef AuWriteLockFunc -+#undef AuRWLockFuncs -+ -+#define DiMustNoWaiters(d) AuRwMustNoWaiters(&au_di(d)->di_rwsem) -+#define DiMustAnyLock(d) AuRwMustAnyLock(&au_di(d)->di_rwsem) -+#define DiMustWriteLock(d) AuRwMustWriteLock(&au_di(d)->di_rwsem) -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* todo: memory barrier? */ -+static inline unsigned int au_digen(struct dentry *d) -+{ -+ return atomic_read(&au_di(d)->di_generation); -+} -+ -+static inline void au_h_dentry_init(struct au_hdentry *hdentry) -+{ -+ hdentry->hd_dentry = NULL; -+} -+ -+static inline struct au_hdentry *au_hdentry(struct au_dinfo *di, -+ aufs_bindex_t bindex) -+{ -+ return di->di_hdentry + bindex; -+} -+ -+static inline void au_hdput(struct au_hdentry *hd) -+{ -+ if (hd) -+ dput(hd->hd_dentry); -+} -+ -+static inline aufs_bindex_t au_dbtop(struct dentry *dentry) -+{ -+ DiMustAnyLock(dentry); -+ return au_di(dentry)->di_btop; -+} -+ -+static inline aufs_bindex_t au_dbbot(struct dentry *dentry) -+{ -+ DiMustAnyLock(dentry); -+ return au_di(dentry)->di_bbot; -+} -+ -+static inline aufs_bindex_t au_dbwh(struct dentry *dentry) -+{ -+ DiMustAnyLock(dentry); -+ return au_di(dentry)->di_bwh; -+} -+ -+static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry) -+{ -+ DiMustAnyLock(dentry); -+ return au_di(dentry)->di_bdiropq; -+} -+ -+/* todo: hard/soft set? */ -+static inline void au_set_dbtop(struct dentry *dentry, aufs_bindex_t bindex) -+{ -+ DiMustWriteLock(dentry); -+ au_di(dentry)->di_btop = bindex; -+} -+ -+static inline void au_set_dbbot(struct dentry *dentry, aufs_bindex_t bindex) -+{ -+ DiMustWriteLock(dentry); -+ au_di(dentry)->di_bbot = bindex; -+} -+ -+static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex) -+{ -+ DiMustWriteLock(dentry); -+ /* dbwh can be outside of btop - bbot range */ -+ au_di(dentry)->di_bwh = bindex; -+} -+ -+static inline void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex) -+{ -+ DiMustWriteLock(dentry); -+ au_di(dentry)->di_bdiropq = bindex; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+#ifdef CONFIG_AUFS_HNOTIFY -+static inline void au_digen_dec(struct dentry *d) -+{ -+ atomic_dec(&au_di(d)->di_generation); -+} -+ -+static inline void au_hn_di_reinit(struct dentry *dentry) -+{ -+ dentry->d_fsdata = NULL; -+} -+#else -+AuStubVoid(au_hn_di_reinit, struct dentry *dentry __maybe_unused) -+#endif /* CONFIG_AUFS_HNOTIFY */ -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_DENTRY_H__ */ -diff -Naur null/fs/aufs/dinfo.c linux-6.6.63/fs/aufs/dinfo.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/dinfo.c 2024-12-18 15:12:59.294519601 +0300 -@@ -0,0 +1,555 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * dentry private data -+ */ -+ -+#include "aufs.h" -+ -+void au_di_init_once(void *_dinfo) -+{ -+ struct au_dinfo *dinfo = _dinfo; -+ -+ au_rw_init(&dinfo->di_rwsem); -+} -+ -+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc) -+{ -+ struct au_dinfo *dinfo; -+ int nbr, i; -+ -+ dinfo = au_cache_alloc_dinfo(); -+ if (unlikely(!dinfo)) -+ goto out; -+ -+ nbr = au_sbbot(sb) + 1; -+ if (nbr <= 0) -+ nbr = 1; -+ dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS); -+ if (dinfo->di_hdentry) { -+ au_rw_write_lock_nested(&dinfo->di_rwsem, lsc); -+ dinfo->di_btop = -1; -+ dinfo->di_bbot = -1; -+ dinfo->di_bwh = -1; -+ dinfo->di_bdiropq = -1; -+ dinfo->di_tmpfile = 0; -+ for (i = 0; i < nbr; i++) -+ dinfo->di_hdentry[i].hd_id = -1; -+ dinfo->di_htmpfile = NULL; -+ goto out; -+ } -+ -+ au_cache_free_dinfo(dinfo); -+ dinfo = NULL; -+ -+out: -+ return dinfo; -+} -+ -+void au_di_free(struct au_dinfo *dinfo) -+{ -+ struct au_hdentry *p; -+ aufs_bindex_t bbot, bindex; -+ -+ /* dentry may not be revalidated */ -+ bindex = dinfo->di_btop; -+ if (bindex >= 0) { -+ bbot = dinfo->di_bbot; -+ p = au_hdentry(dinfo, bindex); -+ while (bindex++ <= bbot) -+ au_hdput(p++); -+ } -+ au_kfree_try_rcu(dinfo->di_hdentry); -+ au_cache_free_dinfo(dinfo); -+} -+ -+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b) -+{ -+ struct au_hdentry *p; -+ aufs_bindex_t bi; -+ -+ AuRwMustWriteLock(&a->di_rwsem); -+ AuRwMustWriteLock(&b->di_rwsem); -+ -+#define DiSwap(v, name) \ -+ do { \ -+ v = a->di_##name; \ -+ a->di_##name = b->di_##name; \ -+ b->di_##name = v; \ -+ } while (0) -+ -+ DiSwap(p, hdentry); -+ DiSwap(bi, btop); -+ DiSwap(bi, bbot); -+ DiSwap(bi, bwh); -+ DiSwap(bi, bdiropq); -+ /* smp_mb(); */ -+ -+#undef DiSwap -+} -+ -+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src) -+{ -+ AuRwMustWriteLock(&dst->di_rwsem); -+ AuRwMustWriteLock(&src->di_rwsem); -+ -+ dst->di_btop = src->di_btop; -+ dst->di_bbot = src->di_bbot; -+ dst->di_bwh = src->di_bwh; -+ dst->di_bdiropq = src->di_bdiropq; -+ /* smp_mb(); */ -+} -+ -+int au_di_init(struct dentry *dentry) -+{ -+ int err; -+ struct super_block *sb; -+ struct au_dinfo *dinfo; -+ -+ err = 0; -+ sb = dentry->d_sb; -+ dinfo = au_di_alloc(sb, AuLsc_DI_CHILD); -+ if (dinfo) { -+ atomic_set(&dinfo->di_generation, au_sigen(sb)); -+ /* smp_mb(); */ /* atomic_set */ -+ dentry->d_fsdata = dinfo; -+ } else -+ err = -ENOMEM; -+ -+ return err; -+} -+ -+void au_di_fin(struct dentry *dentry) -+{ -+ struct au_dinfo *dinfo; -+ -+ dinfo = au_di(dentry); -+ AuRwDestroy(&dinfo->di_rwsem); -+ au_di_free(dinfo); -+} -+ -+int au_di_realloc(struct au_dinfo *dinfo, int nbr, int may_shrink) -+{ -+ int err, sz; -+ struct au_hdentry *hdp; -+ -+ AuRwMustWriteLock(&dinfo->di_rwsem); -+ -+ err = -ENOMEM; -+ sz = sizeof(*hdp) * (dinfo->di_bbot + 1); -+ if (!sz) -+ sz = sizeof(*hdp); -+ hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS, -+ may_shrink); -+ if (hdp) { -+ dinfo->di_hdentry = hdp; -+ err = 0; -+ } -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void do_ii_write_lock(struct inode *inode, unsigned int lsc) -+{ -+ switch (lsc) { -+ case AuLsc_DI_CHILD: -+ ii_write_lock_child(inode); -+ break; -+ case AuLsc_DI_CHILD2: -+ ii_write_lock_child2(inode); -+ break; -+ case AuLsc_DI_CHILD3: -+ ii_write_lock_child3(inode); -+ break; -+ case AuLsc_DI_PARENT: -+ ii_write_lock_parent(inode); -+ break; -+ case AuLsc_DI_PARENT2: -+ ii_write_lock_parent2(inode); -+ break; -+ case AuLsc_DI_PARENT3: -+ ii_write_lock_parent3(inode); -+ break; -+ default: -+ BUG(); -+ } -+} -+ -+static void do_ii_read_lock(struct inode *inode, unsigned int lsc) -+{ -+ switch (lsc) { -+ case AuLsc_DI_CHILD: -+ ii_read_lock_child(inode); -+ break; -+ case AuLsc_DI_CHILD2: -+ ii_read_lock_child2(inode); -+ break; -+ case AuLsc_DI_CHILD3: -+ ii_read_lock_child3(inode); -+ break; -+ case AuLsc_DI_PARENT: -+ ii_read_lock_parent(inode); -+ break; -+ case AuLsc_DI_PARENT2: -+ ii_read_lock_parent2(inode); -+ break; -+ case AuLsc_DI_PARENT3: -+ ii_read_lock_parent3(inode); -+ break; -+ default: -+ BUG(); -+ } -+} -+ -+void di_read_lock(struct dentry *d, int flags, unsigned int lsc) -+{ -+ struct inode *inode; -+ -+ au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc); -+ if (d_really_is_positive(d)) { -+ inode = d_inode(d); -+ if (au_ftest_lock(flags, IW)) -+ do_ii_write_lock(inode, lsc); -+ else if (au_ftest_lock(flags, IR)) -+ do_ii_read_lock(inode, lsc); -+ } -+} -+ -+void di_read_unlock(struct dentry *d, int flags) -+{ -+ 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(inode); -+ } else if (au_ftest_lock(flags, IR)) { -+ au_dbg_verify_dinode(d); -+ ii_read_unlock(inode); -+ } -+ } -+ au_rw_read_unlock(&au_di(d)->di_rwsem); -+} -+ -+void di_downgrade_lock(struct dentry *d, int flags) -+{ -+ 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_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_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 -+ || d_inode(d1) == d_inode(d2) -+ || d1->d_sb != d2->d_sb); -+ -+ if ((isdir && au_test_subdir(d1, d2)) -+ || d1 < d2) { -+ di_write_lock_child(d1); -+ di_write_lock_child2(d2); -+ } else { -+ di_write_lock_child(d2); -+ di_write_lock_child2(d1); -+ } -+} -+ -+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir) -+{ -+ AuDebugOn(d1 == d2 -+ || d_inode(d1) == d_inode(d2) -+ || d1->d_sb != d2->d_sb); -+ -+ if ((isdir && au_test_subdir(d1, d2)) -+ || d1 < d2) { -+ di_write_lock_parent(d1); -+ di_write_lock_parent2(d2); -+ } else { -+ di_write_lock_parent(d2); -+ di_write_lock_parent2(d1); -+ } -+} -+ -+void di_write_unlock2(struct dentry *d1, struct dentry *d2) -+{ -+ di_write_unlock(d1); -+ if (d_inode(d1) == d_inode(d2)) -+ au_rw_write_unlock(&au_di(d2)->di_rwsem); -+ else -+ di_write_unlock(d2); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex) -+{ -+ struct dentry *d; -+ -+ DiMustAnyLock(dentry); -+ -+ if (au_dbtop(dentry) < 0 || bindex < au_dbtop(dentry)) -+ return NULL; -+ AuDebugOn(bindex < 0); -+ d = au_hdentry(au_di(dentry), bindex)->hd_dentry; -+ AuDebugOn(d && au_dcount(d) <= 0); -+ return d; -+} -+ -+/* -+ * extended version of au_h_dptr(). -+ * returns a hashed and positive (or linkable) h_dentry in bindex, NULL, or -+ * error. -+ */ -+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex) -+{ -+ struct dentry *h_dentry; -+ struct inode *inode, *h_inode; -+ -+ AuDebugOn(d_really_is_negative(dentry)); -+ -+ h_dentry = NULL; -+ if (au_dbtop(dentry) <= bindex -+ && bindex <= au_dbbot(dentry)) -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (h_dentry && !au_d_linkable(h_dentry)) { -+ dget(h_dentry); -+ goto out; /* success */ -+ } -+ -+ inode = d_inode(dentry); -+ AuDebugOn(bindex < au_ibtop(inode)); -+ AuDebugOn(au_ibbot(inode) < bindex); -+ h_inode = au_h_iptr(inode, bindex); -+ h_dentry = d_find_alias(h_inode); -+ if (h_dentry) { -+ if (!IS_ERR(h_dentry)) { -+ if (!au_d_linkable(h_dentry)) -+ goto out; /* success */ -+ dput(h_dentry); -+ } else -+ goto out; -+ } -+ -+ if (au_opt_test(au_mntflags(dentry->d_sb), PLINK)) { -+ h_dentry = au_plink_lkup(inode, bindex); -+ AuDebugOn(!h_dentry); -+ if (!IS_ERR(h_dentry)) { -+ if (!au_d_hashed_positive(h_dentry)) -+ goto out; /* success */ -+ dput(h_dentry); -+ h_dentry = NULL; -+ } -+ } -+ -+out: -+ AuDbgDentry(h_dentry); -+ return h_dentry; -+} -+ -+aufs_bindex_t au_dbtail(struct dentry *dentry) -+{ -+ aufs_bindex_t bbot, bwh; -+ -+ bbot = au_dbbot(dentry); -+ if (0 <= bbot) { -+ bwh = au_dbwh(dentry); -+ if (!bwh) -+ return bwh; -+ if (0 < bwh && bwh < bbot) -+ return bwh - 1; -+ } -+ return bbot; -+} -+ -+aufs_bindex_t au_dbtaildir(struct dentry *dentry) -+{ -+ aufs_bindex_t bbot, bopq; -+ -+ bbot = au_dbtail(dentry); -+ if (0 <= bbot) { -+ bopq = au_dbdiropq(dentry); -+ if (0 <= bopq && bopq < bbot) -+ bbot = bopq; -+ } -+ return bbot; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex, -+ struct dentry *h_dentry) -+{ -+ struct au_dinfo *dinfo; -+ struct au_hdentry *hd; -+ struct au_branch *br; -+ -+ DiMustWriteLock(dentry); -+ -+ dinfo = au_di(dentry); -+ hd = au_hdentry(dinfo, bindex); -+ au_hdput(hd); -+ hd->hd_dentry = h_dentry; -+ if (h_dentry) { -+ br = au_sbr(dentry->d_sb, bindex); -+ hd->hd_id = br->br_id; -+ } -+} -+ -+int au_dbrange_test(struct dentry *dentry) -+{ -+ int err; -+ aufs_bindex_t btop, bbot; -+ -+ err = 0; -+ btop = au_dbtop(dentry); -+ bbot = au_dbbot(dentry); -+ if (btop >= 0) -+ AuDebugOn(bbot < 0 && btop > bbot); -+ else { -+ err = -EIO; -+ AuDebugOn(bbot >= 0); -+ } -+ -+ return err; -+} -+ -+int au_digen_test(struct dentry *dentry, unsigned int sigen) -+{ -+ int err; -+ -+ err = 0; -+ if (unlikely(au_digen(dentry) != sigen -+ || au_iigen_test(d_inode(dentry), sigen))) -+ err = -EIO; -+ -+ return err; -+} -+ -+void au_update_digen(struct dentry *dentry) -+{ -+ atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb)); -+ /* smp_mb(); */ /* atomic_set */ -+} -+ -+void au_update_dbrange(struct dentry *dentry, int do_put_zero) -+{ -+ struct au_dinfo *dinfo; -+ struct dentry *h_d; -+ struct au_hdentry *hdp; -+ aufs_bindex_t bindex, bbot; -+ -+ DiMustWriteLock(dentry); -+ -+ dinfo = au_di(dentry); -+ if (!dinfo || dinfo->di_btop < 0) -+ return; -+ -+ if (do_put_zero) { -+ bbot = dinfo->di_bbot; -+ bindex = dinfo->di_btop; -+ hdp = au_hdentry(dinfo, bindex); -+ for (; bindex <= bbot; bindex++, hdp++) { -+ h_d = hdp->hd_dentry; -+ if (h_d && d_is_negative(h_d)) -+ au_set_h_dptr(dentry, bindex, NULL); -+ } -+ } -+ -+ dinfo->di_btop = 0; -+ hdp = au_hdentry(dinfo, dinfo->di_btop); -+ for (; dinfo->di_btop <= dinfo->di_bbot; dinfo->di_btop++, hdp++) -+ if (hdp->hd_dentry) -+ break; -+ if (dinfo->di_btop > dinfo->di_bbot) { -+ dinfo->di_btop = -1; -+ dinfo->di_bbot = -1; -+ return; -+ } -+ -+ hdp = au_hdentry(dinfo, dinfo->di_bbot); -+ for (; dinfo->di_bbot >= 0; dinfo->di_bbot--, hdp--) -+ if (hdp->hd_dentry) -+ break; -+ AuDebugOn(dinfo->di_btop > dinfo->di_bbot || dinfo->di_bbot < 0); -+} -+ -+void au_update_dbtop(struct dentry *dentry) -+{ -+ aufs_bindex_t bindex, bbot; -+ struct dentry *h_dentry; -+ -+ bbot = au_dbbot(dentry); -+ for (bindex = au_dbtop(dentry); bindex <= bbot; bindex++) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (!h_dentry) -+ continue; -+ if (d_is_positive(h_dentry)) { -+ au_set_dbtop(dentry, bindex); -+ return; -+ } -+ au_set_h_dptr(dentry, bindex, NULL); -+ } -+} -+ -+void au_update_dbbot(struct dentry *dentry) -+{ -+ aufs_bindex_t bindex, btop; -+ struct dentry *h_dentry; -+ -+ btop = au_dbtop(dentry); -+ for (bindex = au_dbbot(dentry); bindex >= btop; bindex--) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (!h_dentry) -+ continue; -+ if (d_is_positive(h_dentry)) { -+ au_set_dbbot(dentry, bindex); -+ return; -+ } -+ au_set_h_dptr(dentry, bindex, NULL); -+ } -+} -+ -+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry) -+{ -+ aufs_bindex_t bindex, bbot; -+ -+ bbot = au_dbbot(dentry); -+ for (bindex = au_dbtop(dentry); bindex <= bbot; bindex++) -+ if (au_h_dptr(dentry, bindex) == h_dentry) -+ return bindex; -+ return -1; -+} -diff -Naur null/fs/aufs/dir.c linux-6.6.63/fs/aufs/dir.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/dir.c 2024-12-18 15:12:59.294519601 +0300 -@@ -0,0 +1,765 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * directory operations -+ */ -+ -+#include -+#include -+#include "aufs.h" -+ -+void au_add_nlink(struct inode *dir, struct inode *h_dir) -+{ -+ unsigned int nlink, h_nlink; -+ -+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode)); -+ -+ nlink = vfsub_inode_nlink(dir, AU_I_AUFS); -+ h_nlink = vfsub_inode_nlink(h_dir, AU_I_BRANCH); -+ nlink += h_nlink - 2; -+ if (h_nlink < 2) -+ nlink += 2; -+ /* 0 can happen in revaliding */ -+ vfsub_set_nlink(dir, nlink); -+} -+ -+void au_sub_nlink(struct inode *dir, struct inode *h_dir) -+{ -+ unsigned int nlink, h_nlink; -+ -+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode)); -+ -+ nlink = vfsub_inode_nlink(dir, AU_I_AUFS); -+ h_nlink = vfsub_inode_nlink(h_dir, AU_I_BRANCH); -+ nlink -= h_nlink - 2; -+ if (h_nlink < 2) -+ nlink -= 2; -+ /* nlink == 0 means the branch-fs is broken */ -+ vfsub_set_nlink(dir, nlink); -+} -+ -+loff_t au_dir_size(struct file *file, struct dentry *dentry) -+{ -+ loff_t sz; -+ aufs_bindex_t bindex, bbot; -+ struct file *h_file; -+ struct dentry *h_dentry; -+ -+ sz = 0; -+ if (file) { -+ AuDebugOn(!d_is_dir(file->f_path.dentry)); -+ -+ bbot = au_fbbot_dir(file); -+ for (bindex = au_fbtop(file); -+ bindex <= bbot && sz < KMALLOC_MAX_SIZE; -+ bindex++) { -+ h_file = au_hf_dir(file, bindex); -+ if (h_file && file_inode(h_file)) -+ sz += vfsub_f_size_read(h_file); -+ } -+ } else { -+ AuDebugOn(!dentry); -+ AuDebugOn(!d_is_dir(dentry)); -+ -+ bbot = au_dbtaildir(dentry); -+ for (bindex = au_dbtop(dentry); -+ bindex <= bbot && sz < KMALLOC_MAX_SIZE; -+ bindex++) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (h_dentry && d_is_positive(h_dentry)) -+ sz += i_size_read(d_inode(h_dentry)); -+ } -+ } -+ if (sz < KMALLOC_MAX_SIZE) -+ sz = roundup_pow_of_two(sz); -+ if (sz > KMALLOC_MAX_SIZE) -+ sz = KMALLOC_MAX_SIZE; -+ else if (sz < NAME_MAX) { -+ BUILD_BUG_ON(AUFS_RDBLK_DEF < NAME_MAX); -+ sz = AUFS_RDBLK_DEF; -+ } -+ return sz; -+} -+ -+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 btop, bindex; -+ -+ sb = a->dentry->d_sb; -+ if (d_really_is_negative(a->dentry)) -+ goto out; -+ /* no dir->i_mutex lock */ -+ aufs_read_lock(a->dentry, AuLock_DW); /* noflush */ -+ -+ dir = d_inode(a->dentry); -+ btop = au_ibtop(dir); -+ bindex = au_br_index(sb, a->brid); -+ if (bindex < btop) -+ 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, btop); -+ if (!au_br_writable(br->br_perm)) -+ goto out_unlock; -+ h_path.dentry = au_h_dptr(a->dentry, btop); -+ h_path.mnt = au_br_mnt(br); -+ err = vfsub_mnt_want_write(h_path.mnt); -+ if (err) -+ goto out_unlock; -+ hdir = au_hi(dir, btop); -+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT); -+ h_dir = au_h_iptr(dir, btop); -+ if (vfsub_inode_nlink(h_dir, AU_I_BRANCH) -+ && timespec64_compare(&h_dir->i_mtime, &dt.dt_mtime) < 0) { -+ dt.dt_h_path = h_path; -+ au_dtime_revert(&dt); -+ } -+ au_hn_inode_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); -+ au_kfree_try_rcu(arg); -+} -+ -+void au_dir_ts(struct inode *dir, aufs_bindex_t bindex) -+{ -+ int perm, wkq_err; -+ aufs_bindex_t btop; -+ 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; -+ btop = au_ibtop(dir); -+ if (btop == bindex) { -+ au_cpup_attr_timesizes(dir); -+ goto out; -+ } -+ -+ perm = au_sbr_perm(sb, btop); -+ 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); -+ au_kfree_try_rcu(arg); -+ } -+ -+out: -+ dput(dentry); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int reopen_dir(struct file *file) -+{ -+ int err; -+ unsigned int flags; -+ aufs_bindex_t bindex, btail, btop; -+ struct dentry *dentry, *h_dentry; -+ struct file *h_file; -+ -+ /* open all lower dirs */ -+ dentry = file->f_path.dentry; -+ btop = au_dbtop(dentry); -+ for (bindex = au_fbtop(file); bindex < btop; bindex++) -+ au_set_h_fptr(file, bindex, NULL); -+ au_set_fbtop(file, btop); -+ -+ btail = au_dbtaildir(dentry); -+ for (bindex = au_fbbot_dir(file); btail < bindex; bindex--) -+ au_set_h_fptr(file, bindex, NULL); -+ au_set_fbbot_dir(file, btail); -+ -+ flags = vfsub_file_flags(file); -+ for (bindex = btop; bindex <= btail; bindex++) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (!h_dentry) -+ continue; -+ h_file = au_hf_dir(file, bindex); -+ if (h_file) -+ continue; -+ -+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; /* close all? */ -+ au_set_h_fptr(file, bindex, h_file); -+ } -+ au_update_figen(file); -+ /* todo: necessary? */ -+ /* file->f_ra = h_file->f_ra; */ -+ err = 0; -+ -+out: -+ return err; -+} -+ -+static int do_open_dir(struct file *file, int flags, struct file *h_file) -+{ -+ int err; -+ aufs_bindex_t bindex, btail; -+ struct dentry *dentry, *h_dentry; -+ struct vfsmount *mnt; -+ -+ FiMustWriteLock(file); -+ AuDebugOn(h_file); -+ -+ err = 0; -+ mnt = file->f_path.mnt; -+ dentry = file->f_path.dentry; -+ file->f_version = inode_query_iversion(d_inode(dentry)); -+ bindex = au_dbtop(dentry); -+ au_set_fbtop(file, bindex); -+ btail = au_dbtaildir(dentry); -+ au_set_fbbot_dir(file, btail); -+ for (; !err && bindex <= btail; bindex++) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (!h_dentry) -+ continue; -+ -+ err = vfsub_test_mntns(mnt, h_dentry->d_sb); -+ if (unlikely(err)) -+ break; -+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0); -+ if (IS_ERR(h_file)) { -+ err = PTR_ERR(h_file); -+ break; -+ } -+ au_set_h_fptr(file, bindex, h_file); -+ } -+ au_update_figen(file); -+ /* todo: necessary? */ -+ /* file->f_ra = h_file->f_ra; */ -+ if (!err) -+ return 0; /* success */ -+ -+ /* close all */ -+ for (bindex = au_fbtop(file); bindex <= btail; bindex++) -+ au_set_h_fptr(file, bindex, NULL); -+ au_set_fbtop(file, -1); -+ au_set_fbbot_dir(file, -1); -+ -+ return err; -+} -+ -+static int aufs_open_dir(struct inode *inode __maybe_unused, -+ struct file *file) -+{ -+ int err; -+ struct super_block *sb; -+ struct au_fidir *fidir; -+ -+ err = -ENOMEM; -+ sb = file->f_path.dentry->d_sb; -+ si_read_lock(sb, AuLock_FLUSH); -+ fidir = au_fidir_alloc(sb); -+ if (fidir) { -+ struct au_do_open_args args = { -+ .open = do_open_dir, -+ .fidir = fidir -+ }; -+ err = au_do_open(file, &args); -+ if (unlikely(err)) -+ au_kfree_rcu(fidir); -+ } -+ si_read_unlock(sb); -+ return err; -+} -+ -+static int aufs_release_dir(struct inode *inode __maybe_unused, -+ struct file *file) -+{ -+ struct au_vdir *vdir_cache; -+ struct au_finfo *finfo; -+ struct au_fidir *fidir; -+ struct au_hfile *hf; -+ aufs_bindex_t bindex, bbot; -+ -+ finfo = au_fi(file); -+ fidir = finfo->fi_hdir; -+ if (fidir) { -+ au_hbl_del(&finfo->fi_hlist, -+ &au_sbi(file->f_path.dentry->d_sb)->si_files); -+ vdir_cache = fidir->fd_vdir_cache; /* lock-free */ -+ if (vdir_cache) -+ au_vdir_free(vdir_cache); -+ -+ bindex = finfo->fi_btop; -+ if (bindex >= 0) { -+ hf = fidir->fd_hfile + bindex; -+ /* -+ * calls fput() instead of filp_close(), -+ * since no dnotify or lock for the lower file. -+ */ -+ bbot = fidir->fd_bbot; -+ for (; bindex <= bbot; bindex++, hf++) -+ if (hf->hf_file) -+ au_hfput(hf, /*execed*/0); -+ } -+ au_kfree_rcu(fidir); -+ finfo->fi_hdir = NULL; -+ } -+ au_finfo_fin(file); -+ return 0; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_do_flush_dir(struct file *file, fl_owner_t id) -+{ -+ int err; -+ aufs_bindex_t bindex, bbot; -+ struct file *h_file; -+ -+ err = 0; -+ bbot = au_fbbot_dir(file); -+ for (bindex = au_fbtop(file); !err && bindex <= bbot; bindex++) { -+ h_file = au_hf_dir(file, bindex); -+ if (h_file) -+ err = vfsub_flush(h_file, id); -+ } -+ return err; -+} -+ -+static int aufs_flush_dir(struct file *file, fl_owner_t id) -+{ -+ return au_do_flush(file, id, au_do_flush_dir); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_do_fsync_dir_no_file(struct dentry *dentry, int datasync) -+{ -+ int err; -+ aufs_bindex_t bbot, bindex; -+ struct inode *inode; -+ struct super_block *sb; -+ -+ err = 0; -+ sb = dentry->d_sb; -+ inode = d_inode(dentry); -+ IMustLock(inode); -+ bbot = au_dbbot(dentry); -+ for (bindex = au_dbtop(dentry); !err && bindex <= bbot; bindex++) { -+ struct path h_path; -+ -+ if (au_test_ro(sb, bindex, inode)) -+ continue; -+ h_path.dentry = au_h_dptr(dentry, bindex); -+ if (!h_path.dentry) -+ continue; -+ -+ h_path.mnt = au_sbr_mnt(sb, bindex); -+ err = vfsub_fsync(NULL, &h_path, datasync); -+ } -+ -+ return err; -+} -+ -+static int au_do_fsync_dir(struct file *file, int datasync) -+{ -+ int err; -+ aufs_bindex_t bbot, bindex; -+ struct file *h_file; -+ struct super_block *sb; -+ struct inode *inode; -+ -+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1, /*fi_lsc*/0); -+ if (unlikely(err)) -+ goto out; -+ -+ inode = file_inode(file); -+ sb = inode->i_sb; -+ bbot = au_fbbot_dir(file); -+ for (bindex = au_fbtop(file); !err && bindex <= bbot; bindex++) { -+ h_file = au_hf_dir(file, bindex); -+ if (!h_file || au_test_ro(sb, bindex, inode)) -+ continue; -+ -+ err = vfsub_fsync(h_file, &h_file->f_path, datasync); -+ } -+ -+out: -+ return err; -+} -+ -+/* -+ * @file may be NULL -+ */ -+static int aufs_fsync_dir(struct file *file, loff_t start, loff_t end, -+ int datasync) -+{ -+ int err; -+ struct dentry *dentry; -+ struct inode *inode; -+ struct super_block *sb; -+ -+ err = 0; -+ dentry = file->f_path.dentry; -+ inode = d_inode(dentry); -+ inode_lock(inode); -+ sb = dentry->d_sb; -+ si_noflush_read_lock(sb); -+ if (file) -+ err = au_do_fsync_dir(file, datasync); -+ else { -+ di_write_lock_child(dentry); -+ err = au_do_fsync_dir_no_file(dentry, datasync); -+ } -+ au_cpup_attr_timesizes(inode); -+ di_write_unlock(dentry); -+ if (file) -+ fi_write_unlock(file); -+ -+ si_read_unlock(sb); -+ inode_unlock(inode); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int aufs_iterate_shared(struct file *file, struct dir_context *ctx) -+{ -+ int err; -+ struct dentry *dentry; -+ struct inode *inode, *h_inode; -+ struct super_block *sb; -+ -+ AuDbg("%pD, ctx{%ps, %llu}\n", file, ctx->actor, ctx->pos); -+ -+ dentry = file->f_path.dentry; -+ inode = d_inode(dentry); -+ IMustLock(inode); -+ -+ sb = dentry->d_sb; -+ si_read_lock(sb, AuLock_FLUSH); -+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1, /*fi_lsc*/0); -+ if (unlikely(err)) -+ goto out; -+ err = au_alive_dir(dentry); -+ if (!err) -+ err = au_vdir_init(file); -+ di_downgrade_lock(dentry, AuLock_IR); -+ if (unlikely(err)) -+ goto out_unlock; -+ -+ h_inode = au_h_iptr(inode, au_ibtop(inode)); -+ if (!au_test_nfsd()) { -+ err = au_vdir_fill_de(file, ctx); -+ fsstack_copy_attr_atime(inode, h_inode); -+ } else { -+ /* -+ * nfsd filldir may call lookup_one_len(), vfs_getattr(), -+ * encode_fh() and others. -+ */ -+ atomic_inc(&h_inode->i_count); -+ di_read_unlock(dentry, AuLock_IR); -+ si_read_unlock(sb); -+ err = au_vdir_fill_de(file, ctx); -+ fsstack_copy_attr_atime(inode, h_inode); -+ fi_write_unlock(file); -+ iput(h_inode); -+ -+ AuTraceErr(err); -+ return err; -+ } -+ -+out_unlock: -+ di_read_unlock(dentry, AuLock_IR); -+ fi_write_unlock(file); -+out: -+ si_read_unlock(sb); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+#define AuTestEmpty_WHONLY 1 -+#define AuTestEmpty_CALLED (1 << 1) -+#define AuTestEmpty_SHWH (1 << 2) -+#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name) -+#define au_fset_testempty(flags, name) \ -+ do { (flags) |= AuTestEmpty_##name; } while (0) -+#define au_fclr_testempty(flags, name) \ -+ do { (flags) &= ~AuTestEmpty_##name; } while (0) -+ -+#ifndef CONFIG_AUFS_SHWH -+#undef AuTestEmpty_SHWH -+#define AuTestEmpty_SHWH 0 -+#endif -+ -+struct test_empty_arg { -+ struct dir_context ctx; -+ struct au_nhash *whlist; -+ unsigned int flags; -+ int err; -+ aufs_bindex_t bindex; -+}; -+ -+static bool test_empty_cb(struct dir_context *ctx, const char *__name, -+ int namelen, loff_t offset __maybe_unused, u64 ino, -+ unsigned int d_type) -+{ -+ struct test_empty_arg *arg = container_of(ctx, struct test_empty_arg, -+ ctx); -+ char *name = (void *)__name; -+ -+ arg->err = 0; -+ au_fset_testempty(arg->flags, CALLED); -+ /* smp_mb(); */ -+ if (name[0] == '.' -+ && (namelen == 1 || (name[1] == '.' && namelen == 2))) -+ goto out; /* success */ -+ -+ if (namelen <= AUFS_WH_PFX_LEN -+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) { -+ if (au_ftest_testempty(arg->flags, WHONLY) -+ && !au_nhash_test_known_wh(arg->whlist, name, namelen)) -+ arg->err = -ENOTEMPTY; -+ goto out; -+ } -+ -+ name += AUFS_WH_PFX_LEN; -+ namelen -= AUFS_WH_PFX_LEN; -+ if (!au_nhash_test_known_wh(arg->whlist, name, namelen)) -+ arg->err = au_nhash_append_wh -+ (arg->whlist, name, namelen, ino, d_type, arg->bindex, -+ au_ftest_testempty(arg->flags, SHWH)); -+ -+out: -+ /* smp_mb(); */ -+ AuTraceErr(arg->err); -+ return !arg->err; -+} -+ -+static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg) -+{ -+ int err; -+ struct file *h_file; -+ struct au_branch *br; -+ -+ h_file = au_h_open(dentry, arg->bindex, -+ O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE, -+ /*file*/NULL, /*force_wr*/0); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ err = 0; -+ if (!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE) -+ && !vfsub_inode_nlink(file_inode(h_file), AU_I_BRANCH)) -+ goto out_put; -+ -+ do { -+ arg->err = 0; -+ au_fclr_testempty(arg->flags, CALLED); -+ /* smp_mb(); */ -+ err = vfsub_iterate_dir(h_file, &arg->ctx); -+ if (err >= 0) -+ err = arg->err; -+ } while (!err && au_ftest_testempty(arg->flags, CALLED)); -+ -+out_put: -+ fput(h_file); -+ br = au_sbr(dentry->d_sb, arg->bindex); -+ au_lcnt_dec(&br->br_nfiles); -+out: -+ return err; -+} -+ -+struct do_test_empty_args { -+ int *errp; -+ struct dentry *dentry; -+ struct test_empty_arg *arg; -+}; -+ -+static void call_do_test_empty(void *args) -+{ -+ struct do_test_empty_args *a = args; -+ *a->errp = do_test_empty(a->dentry, a->arg); -+} -+ -+static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg) -+{ -+ int err, wkq_err; -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ struct mnt_idmap *h_idmap; -+ -+ h_idmap = au_sbr_idmap(dentry->d_sb, arg->bindex); -+ h_dentry = au_h_dptr(dentry, arg->bindex); -+ h_inode = d_inode(h_dentry); -+ /* todo: i_mode changes anytime? */ -+ inode_lock_shared_nested(h_inode, AuLsc_I_CHILD); -+ err = au_test_h_perm_sio(h_idmap, h_inode, MAY_EXEC | MAY_READ); -+ inode_unlock_shared(h_inode); -+ if (!err) -+ err = do_test_empty(dentry, arg); -+ else { -+ struct do_test_empty_args args = { -+ .errp = &err, -+ .dentry = dentry, -+ .arg = arg -+ }; -+ unsigned int flags = arg->flags; -+ -+ wkq_err = au_wkq_wait(call_do_test_empty, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ arg->flags = flags; -+ } -+ -+ return err; -+} -+ -+int au_test_empty_lower(struct dentry *dentry) -+{ -+ int err; -+ unsigned int rdhash; -+ aufs_bindex_t bindex, btop, btail; -+ struct au_nhash whlist; -+ struct test_empty_arg arg = { -+ .ctx = { -+ .actor = test_empty_cb -+ } -+ }; -+ int (*test_empty)(struct dentry *dentry, struct test_empty_arg *arg); -+ -+ SiMustAnyLock(dentry->d_sb); -+ -+ rdhash = au_sbi(dentry->d_sb)->si_rdhash; -+ if (!rdhash) -+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, dentry)); -+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS); -+ if (unlikely(err)) -+ goto out; -+ -+ arg.flags = 0; -+ arg.whlist = &whlist; -+ btop = au_dbtop(dentry); -+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)) -+ au_fset_testempty(arg.flags, SHWH); -+ test_empty = do_test_empty; -+ if (au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1)) -+ test_empty = sio_test_empty; -+ arg.bindex = btop; -+ err = test_empty(dentry, &arg); -+ if (unlikely(err)) -+ goto out_whlist; -+ -+ au_fset_testempty(arg.flags, WHONLY); -+ btail = au_dbtaildir(dentry); -+ for (bindex = btop + 1; !err && bindex <= btail; bindex++) { -+ struct dentry *h_dentry; -+ -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (h_dentry && d_is_positive(h_dentry)) { -+ arg.bindex = bindex; -+ err = test_empty(dentry, &arg); -+ } -+ } -+ -+out_whlist: -+ au_nhash_wh_free(&whlist); -+out: -+ return err; -+} -+ -+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist) -+{ -+ int err; -+ struct test_empty_arg arg = { -+ .ctx = { -+ .actor = test_empty_cb -+ } -+ }; -+ aufs_bindex_t bindex, btail; -+ -+ err = 0; -+ arg.whlist = whlist; -+ arg.flags = AuTestEmpty_WHONLY; -+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)) -+ au_fset_testempty(arg.flags, SHWH); -+ btail = au_dbtaildir(dentry); -+ for (bindex = au_dbtop(dentry); !err && bindex <= btail; bindex++) { -+ struct dentry *h_dentry; -+ -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (h_dentry && d_is_positive(h_dentry)) { -+ arg.bindex = bindex; -+ err = sio_test_empty(dentry, &arg); -+ } -+ } -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+const struct file_operations aufs_dir_fop = { -+ .owner = THIS_MODULE, -+ .llseek = default_llseek, -+ .read = generic_read_dir, -+ .iterate_shared = aufs_iterate_shared, -+ .unlocked_ioctl = aufs_ioctl_dir, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = aufs_compat_ioctl_dir, -+#endif -+ .open = aufs_open_dir, -+ .release = aufs_release_dir, -+ .flush = aufs_flush_dir, -+ .fsync = aufs_fsync_dir -+}; -diff -Naur null/fs/aufs/dir.h linux-6.6.63/fs/aufs/dir.h ---- /dev/null -+++ linux-6.6.63/fs/aufs/dir.h 2024-12-18 15:12:59.295519588 +0300 -@@ -0,0 +1,134 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * directory operations -+ */ -+ -+#ifndef __AUFS_DIR_H__ -+#define __AUFS_DIR_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* need to be faster and smaller */ -+ -+struct au_nhash { -+ unsigned int nh_num; -+ struct hlist_head *nh_head; -+}; -+ -+struct au_vdir_destr { -+ unsigned char len; -+ unsigned char name[]; -+} __packed; -+ -+struct au_vdir_dehstr { -+ struct hlist_node hash; -+ struct au_vdir_destr *str; -+ struct rcu_head rcu; -+} ____cacheline_aligned_in_smp; -+ -+struct au_vdir_de { -+ ino_t de_ino; -+ unsigned char de_type; -+ /* caution: packed */ -+ struct au_vdir_destr de_str; -+} __packed; -+ -+struct au_vdir_wh { -+ struct hlist_node wh_hash; -+#ifdef CONFIG_AUFS_SHWH -+ ino_t wh_ino; -+ aufs_bindex_t wh_bindex; -+ unsigned char wh_type; -+#else -+ aufs_bindex_t wh_bindex; -+#endif -+ /* caution: packed */ -+ struct au_vdir_destr wh_str; -+} __packed; -+ -+union au_vdir_deblk_p { -+ unsigned char *deblk; -+ struct au_vdir_de *de; -+}; -+ -+struct au_vdir { -+ unsigned char **vd_deblk; -+ unsigned long vd_nblk; -+ struct { -+ unsigned long ul; -+ union au_vdir_deblk_p p; -+ } vd_last; -+ -+ u64 vd_version; -+ unsigned int vd_deblk_sz; -+ unsigned long vd_jiffy; -+ struct rcu_head rcu; -+} ____cacheline_aligned_in_smp; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* dir.c */ -+extern const struct file_operations aufs_dir_fop; -+void au_add_nlink(struct inode *dir, struct inode *h_dir); -+void au_sub_nlink(struct inode *dir, struct inode *h_dir); -+loff_t au_dir_size(struct file *file, struct dentry *dentry); -+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); -+ -+/* vdir.c */ -+unsigned int au_rdhash_est(loff_t sz); -+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp); -+void au_nhash_wh_free(struct au_nhash *whlist); -+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt, -+ int limit); -+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen); -+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino, -+ unsigned int d_type, aufs_bindex_t bindex, -+ unsigned char shwh); -+void au_vdir_free(struct au_vdir *vdir); -+int au_vdir_init(struct file *file); -+int au_vdir_fill_de(struct file *file, struct dir_context *ctx); -+ -+/* ioctl.c */ -+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg); -+ -+#ifdef CONFIG_AUFS_RDU -+/* rdu.c */ -+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg); -+#ifdef CONFIG_COMPAT -+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd, -+ unsigned long arg); -+#endif -+#else -+AuStub(long, au_rdu_ioctl, return -EINVAL, struct file *file, -+ unsigned int cmd, unsigned long arg) -+#ifdef CONFIG_COMPAT -+AuStub(long, au_rdu_compat_ioctl, return -EINVAL, struct file *file, -+ unsigned int cmd, unsigned long arg) -+#endif -+#endif -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_DIR_H__ */ -diff -Naur null/fs/aufs/dirren.c linux-6.6.63/fs/aufs/dirren.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/dirren.c 2024-12-18 15:12:59.295519588 +0300 -@@ -0,0 +1,1315 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2017-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * special handling in renaming a directory -+ * in order to support looking-up the before-renamed name on the lower readonly -+ * branches -+ */ -+ -+#include -+#include "aufs.h" -+ -+static void au_dr_hino_del(struct au_dr_br *dr, struct au_dr_hino *ent) -+{ -+ int idx; -+ -+ idx = au_dr_ihash(ent->dr_h_ino); -+ au_hbl_del(&ent->dr_hnode, dr->dr_h_ino + idx); -+} -+ -+static int au_dr_hino_test_empty(struct au_dr_br *dr) -+{ -+ int ret, i; -+ struct hlist_bl_head *hbl; -+ -+ ret = 1; -+ for (i = 0; ret && i < AuDirren_NHASH; i++) { -+ hbl = dr->dr_h_ino + i; -+ hlist_bl_lock(hbl); -+ ret &= hlist_bl_empty(hbl); -+ hlist_bl_unlock(hbl); -+ } -+ -+ return ret; -+} -+ -+static struct au_dr_hino *au_dr_hino_find(struct au_dr_br *dr, ino_t ino) -+{ -+ struct au_dr_hino *found, *ent; -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *pos; -+ int idx; -+ -+ found = NULL; -+ idx = au_dr_ihash(ino); -+ hbl = dr->dr_h_ino + idx; -+ hlist_bl_lock(hbl); -+ hlist_bl_for_each_entry(ent, pos, hbl, dr_hnode) -+ if (ent->dr_h_ino == ino) { -+ found = ent; -+ break; -+ } -+ hlist_bl_unlock(hbl); -+ -+ return found; -+} -+ -+int au_dr_hino_test_add(struct au_dr_br *dr, ino_t ino, -+ struct au_dr_hino *add_ent) -+{ -+ int found, idx; -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *pos; -+ struct au_dr_hino *ent; -+ -+ found = 0; -+ idx = au_dr_ihash(ino); -+ hbl = dr->dr_h_ino + idx; -+#if 0 /* debug print */ -+ { -+ struct hlist_bl_node *tmp; -+ -+ hlist_bl_for_each_entry_safe(ent, pos, tmp, hbl, dr_hnode) -+ AuDbg("hi%llu\n", (unsigned long long)ent->dr_h_ino); -+ } -+#endif -+ hlist_bl_lock(hbl); -+ hlist_bl_for_each_entry(ent, pos, hbl, dr_hnode) -+ if (ent->dr_h_ino == ino) { -+ found = 1; -+ break; -+ } -+ if (!found && add_ent) -+ hlist_bl_add_head(&add_ent->dr_hnode, hbl); -+ hlist_bl_unlock(hbl); -+ -+ if (!found && add_ent) -+ AuDbg("i%llu added\n", (unsigned long long)add_ent->dr_h_ino); -+ -+ return found; -+} -+ -+void au_dr_hino_free(struct au_dr_br *dr) -+{ -+ int i; -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *pos, *tmp; -+ struct au_dr_hino *ent; -+ -+ /* SiMustWriteLock(sb); */ -+ -+ for (i = 0; i < AuDirren_NHASH; i++) { -+ hbl = dr->dr_h_ino + i; -+ /* no spinlock since sbinfo must be write-locked */ -+ hlist_bl_for_each_entry_safe(ent, pos, tmp, hbl, dr_hnode) -+ au_kfree_rcu(ent); -+ INIT_HLIST_BL_HEAD(hbl); -+ } -+} -+ -+/* returns the number of inodes or an error */ -+static int au_dr_hino_store(struct super_block *sb, struct au_branch *br, -+ struct file *hinofile) -+{ -+ int err, i; -+ ssize_t ssz; -+ loff_t pos, oldsize; -+ __be64 u64; -+ struct inode *hinoinode; -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *n1, *n2; -+ struct au_dr_hino *ent; -+ -+ SiMustWriteLock(sb); -+ AuDebugOn(!au_br_writable(br->br_perm)); -+ -+ hinoinode = file_inode(hinofile); -+ oldsize = i_size_read(hinoinode); -+ -+ err = 0; -+ pos = 0; -+ hbl = br->br_dirren.dr_h_ino; -+ for (i = 0; !err && i < AuDirren_NHASH; i++, hbl++) { -+ /* no bit-lock since sbinfo must be write-locked */ -+ hlist_bl_for_each_entry_safe(ent, n1, n2, hbl, dr_hnode) { -+ AuDbg("hi%llu, %pD2\n", -+ (unsigned long long)ent->dr_h_ino, hinofile); -+ u64 = cpu_to_be64(ent->dr_h_ino); -+ ssz = vfsub_write_k(hinofile, &u64, sizeof(u64), &pos); -+ if (ssz == sizeof(u64)) -+ continue; -+ -+ /* write error */ -+ pr_err("ssz %zd, %pD2\n", ssz, hinofile); -+ err = -ENOSPC; -+ if (ssz < 0) -+ err = ssz; -+ break; -+ } -+ } -+ /* regardless the error */ -+ if (pos < oldsize) { -+ err = vfsub_trunc(&hinofile->f_path, pos, /*attr*/0, hinofile); -+ AuTraceErr(err); -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_dr_hino_load(struct au_dr_br *dr, struct file *hinofile) -+{ -+ int err, hidx; -+ ssize_t ssz; -+ size_t sz, n; -+ loff_t pos; -+ uint64_t u64; -+ struct au_dr_hino *ent; -+ struct inode *hinoinode; -+ struct hlist_bl_head *hbl; -+ -+ err = 0; -+ pos = 0; -+ hbl = dr->dr_h_ino; -+ hinoinode = file_inode(hinofile); -+ sz = i_size_read(hinoinode); -+ AuDebugOn(sz % sizeof(u64)); -+ n = sz / sizeof(u64); -+ while (n--) { -+ ssz = vfsub_read_k(hinofile, &u64, sizeof(u64), &pos); -+ if (unlikely(ssz != sizeof(u64))) { -+ pr_err("ssz %zd, %pD2\n", ssz, hinofile); -+ err = -EINVAL; -+ if (ssz < 0) -+ err = ssz; -+ goto out_free; -+ } -+ -+ ent = kmalloc(sizeof(*ent), GFP_NOFS); -+ if (!ent) { -+ err = -ENOMEM; -+ AuTraceErr(err); -+ goto out_free; -+ } -+ ent->dr_h_ino = be64_to_cpu((__force __be64)u64); -+ AuDbg("hi%llu, %pD2\n", -+ (unsigned long long)ent->dr_h_ino, hinofile); -+ hidx = au_dr_ihash(ent->dr_h_ino); -+ au_hbl_add(&ent->dr_hnode, hbl + hidx); -+ } -+ goto out; /* success */ -+ -+out_free: -+ au_dr_hino_free(dr); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* -+ * @bindex/@br is a switch to distinguish whether suspending hnotify or not. -+ * @path is a switch to distinguish load and store. -+ */ -+static int au_dr_hino(struct super_block *sb, aufs_bindex_t bindex, -+ struct au_branch *br, const struct path *path) -+{ -+ int err, flags; -+ unsigned char load, suspend; -+ struct file *hinofile; -+ struct au_hinode *hdir; -+ struct inode *dir, *delegated; -+ struct path hinopath; -+ struct qstr hinoname = QSTR_INIT(AUFS_WH_DR_BRHINO, -+ sizeof(AUFS_WH_DR_BRHINO) - 1); -+ -+ AuDebugOn(bindex < 0 && !br); -+ AuDebugOn(bindex >= 0 && br); -+ -+ err = -EINVAL; -+ suspend = !br; -+ if (suspend) -+ br = au_sbr(sb, bindex); -+ load = !!path; -+ if (!load) { -+ path = &br->br_path; -+ AuDebugOn(!au_br_writable(br->br_perm)); -+ if (unlikely(!au_br_writable(br->br_perm))) -+ goto out; -+ } -+ -+ hdir = NULL; -+ if (suspend) { -+ dir = d_inode(sb->s_root); -+ hdir = au_hinode(au_ii(dir), bindex); -+ dir = hdir->hi_inode; -+ au_hn_inode_lock_nested(hdir, AuLsc_I_CHILD); -+ } else { -+ dir = d_inode(path->dentry); -+ inode_lock_nested(dir, AuLsc_I_CHILD); -+ } -+ hinopath.mnt = path->mnt; -+ hinopath.dentry = vfsub_lkup_one(&hinoname, (struct path *)path); -+ err = PTR_ERR(hinopath.dentry); -+ if (IS_ERR(hinopath.dentry)) -+ goto out_unlock; -+ -+ err = 0; -+ flags = O_RDONLY; -+ if (load) { -+ if (d_is_negative(hinopath.dentry)) -+ goto out_dput; /* success */ -+ } else { -+ if (au_dr_hino_test_empty(&br->br_dirren)) { -+ if (d_is_positive(hinopath.dentry)) { -+ delegated = NULL; -+ err = vfsub_unlink(dir, &hinopath, &delegated, -+ /*force*/0); -+ AuTraceErr(err); -+ if (unlikely(err)) -+ pr_err("ignored err %d, %pd2\n", -+ err, hinopath.dentry); -+ if (unlikely(err == -EWOULDBLOCK)) -+ iput(delegated); -+ err = 0; -+ } -+ goto out_dput; -+ } else if (!d_is_positive(hinopath.dentry)) { -+ err = vfsub_create(dir, &hinopath, 0600, -+ /*want_excl*/false); -+ AuTraceErr(err); -+ if (unlikely(err)) -+ goto out_dput; -+ } -+ flags = O_WRONLY; -+ } -+ hinofile = vfsub_dentry_open(&hinopath, flags); -+ if (suspend) -+ au_hn_inode_unlock(hdir); -+ else -+ inode_unlock(dir); -+ dput(hinopath.dentry); -+ AuTraceErrPtr(hinofile); -+ if (IS_ERR(hinofile)) { -+ err = PTR_ERR(hinofile); -+ goto out; -+ } -+ -+ if (load) -+ err = au_dr_hino_load(&br->br_dirren, hinofile); -+ else -+ err = au_dr_hino_store(sb, br, hinofile); -+ fput(hinofile); -+ goto out; -+ -+out_dput: -+ dput(hinopath.dentry); -+out_unlock: -+ if (suspend) -+ au_hn_inode_unlock(hdir); -+ else -+ inode_unlock(dir); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_dr_brid_init(struct au_dr_brid *brid, const struct path *path) -+{ -+ int err; -+ struct kstatfs kstfs; -+ dev_t dev; -+ struct dentry *dentry; -+ struct super_block *sb; -+ -+ err = vfs_statfs((void *)path, &kstfs); -+ AuTraceErr(err); -+ if (unlikely(err)) -+ goto out; -+ -+ /* todo: support for UUID */ -+ -+ if (kstfs.f_fsid.val[0] || kstfs.f_fsid.val[1]) { -+ brid->type = AuBrid_FSID; -+ brid->fsid = kstfs.f_fsid; -+ } else { -+ dentry = path->dentry; -+ sb = dentry->d_sb; -+ dev = sb->s_dev; -+ if (dev) { -+ brid->type = AuBrid_DEV; -+ brid->dev = dev; -+ } -+ } -+ -+out: -+ return err; -+} -+ -+int au_dr_br_init(struct super_block *sb, struct au_branch *br, -+ const struct path *path) -+{ -+ int err, i; -+ struct au_dr_br *dr; -+ struct hlist_bl_head *hbl; -+ -+ dr = &br->br_dirren; -+ hbl = dr->dr_h_ino; -+ for (i = 0; i < AuDirren_NHASH; i++, hbl++) -+ INIT_HLIST_BL_HEAD(hbl); -+ -+ err = au_dr_brid_init(&dr->dr_brid, path); -+ if (unlikely(err)) -+ goto out; -+ -+ if (au_opt_test(au_mntflags(sb), DIRREN)) -+ err = au_dr_hino(sb, /*bindex*/-1, br, path); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_dr_br_fin(struct super_block *sb, struct au_branch *br) -+{ -+ int err; -+ -+ err = 0; -+ if (au_br_writable(br->br_perm)) -+ err = au_dr_hino(sb, /*bindex*/-1, br, /*path*/NULL); -+ if (!err) -+ au_dr_hino_free(&br->br_dirren); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_brid_str(struct au_dr_brid *brid, struct inode *h_inode, -+ char *buf, size_t sz) -+{ -+ int err; -+ unsigned int major, minor; -+ char *p; -+ -+ p = buf; -+ err = snprintf(p, sz, "%d_", brid->type); -+ AuDebugOn(err > sz); -+ p += err; -+ sz -= err; -+ switch (brid->type) { -+ case AuBrid_Unset: -+ return -EINVAL; -+ case AuBrid_UUID: -+ err = snprintf(p, sz, "%pU", brid->uuid.b); -+ break; -+ case AuBrid_FSID: -+ err = snprintf(p, sz, "%08x-%08x", -+ brid->fsid.val[0], brid->fsid.val[1]); -+ break; -+ case AuBrid_DEV: -+ major = MAJOR(brid->dev); -+ minor = MINOR(brid->dev); -+ if (major <= 0xff && minor <= 0xff) -+ err = snprintf(p, sz, "%02x%02x", major, minor); -+ else -+ err = snprintf(p, sz, "%03x:%05x", major, minor); -+ break; -+ } -+ AuDebugOn(err > sz); -+ p += err; -+ sz -= err; -+ err = snprintf(p, sz, "_%llu", (unsigned long long)h_inode->i_ino); -+ AuDebugOn(err > sz); -+ p += err; -+ sz -= err; -+ -+ return p - buf; -+} -+ -+static int au_drinfo_name(struct au_branch *br, char *name, int len) -+{ -+ int rlen; -+ struct dentry *br_dentry; -+ struct inode *br_inode; -+ -+ br_dentry = au_br_dentry(br); -+ br_inode = d_inode(br_dentry); -+ rlen = au_brid_str(&br->br_dirren.dr_brid, br_inode, name, len); -+ AuDebugOn(rlen >= AUFS_DIRREN_ENV_VAL_SZ); -+ AuDebugOn(rlen > len); -+ -+ return rlen; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * from the given @h_dentry, construct drinfo at @*fdata. -+ * when the size of @*fdata is not enough, reallocate and return new @fdata and -+ * @allocated. -+ */ -+static int au_drinfo_construct(struct au_drinfo_fdata **fdata, -+ struct dentry *h_dentry, -+ unsigned char *allocated) -+{ -+ int err, v; -+ struct au_drinfo_fdata *f, *p; -+ struct au_drinfo *drinfo; -+ struct inode *h_inode; -+ struct qstr *qname; -+ -+ err = 0; -+ f = *fdata; -+ h_inode = d_inode(h_dentry); -+ qname = &h_dentry->d_name; -+ drinfo = &f->drinfo; -+ drinfo->ino = (__force uint64_t)cpu_to_be64(h_inode->i_ino); -+ drinfo->oldnamelen = qname->len; -+ if (*allocated < sizeof(*f) + qname->len) { -+ v = roundup_pow_of_two(*allocated + qname->len); -+ p = au_krealloc(f, v, GFP_NOFS, /*may_shrink*/0); -+ if (unlikely(!p)) { -+ err = -ENOMEM; -+ AuTraceErr(err); -+ goto out; -+ } -+ f = p; -+ *fdata = f; -+ *allocated = v; -+ drinfo = &f->drinfo; -+ } -+ memcpy(drinfo->oldname, qname->name, qname->len); -+ AuDbg("i%llu, %.*s\n", -+ be64_to_cpu((__force __be64)drinfo->ino), drinfo->oldnamelen, -+ drinfo->oldname); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* callers have to free the return value */ -+static struct au_drinfo *au_drinfo_read_k(struct file *file, ino_t h_ino) -+{ -+ struct au_drinfo *ret, *drinfo; -+ struct au_drinfo_fdata fdata; -+ int len; -+ loff_t pos; -+ ssize_t ssz; -+ -+ ret = ERR_PTR(-EIO); -+ pos = 0; -+ ssz = vfsub_read_k(file, &fdata, sizeof(fdata), &pos); -+ if (unlikely(ssz != sizeof(fdata))) { -+ AuIOErr("ssz %zd, %u, %pD2\n", -+ ssz, (unsigned int)sizeof(fdata), file); -+ goto out; -+ } -+ -+ fdata.magic = ntohl((__force __be32)fdata.magic); -+ switch (fdata.magic) { -+ case AUFS_DRINFO_MAGIC_V1: -+ break; -+ default: -+ AuIOErr("magic-num 0x%x, 0x%x, %pD2\n", -+ fdata.magic, AUFS_DRINFO_MAGIC_V1, file); -+ goto out; -+ } -+ -+ drinfo = &fdata.drinfo; -+ len = drinfo->oldnamelen; -+ if (!len) { -+ AuIOErr("broken drinfo %pD2\n", file); -+ goto out; -+ } -+ -+ ret = NULL; -+ drinfo->ino = be64_to_cpu((__force __be64)drinfo->ino); -+ if (unlikely(h_ino && drinfo->ino != h_ino)) { -+ AuDbg("ignored i%llu, i%llu, %pD2\n", -+ (unsigned long long)drinfo->ino, -+ (unsigned long long)h_ino, file); -+ goto out; /* success */ -+ } -+ -+ ret = kmalloc(sizeof(*ret) + len, GFP_NOFS); -+ if (unlikely(!ret)) { -+ ret = ERR_PTR(-ENOMEM); -+ AuTraceErrPtr(ret); -+ goto out; -+ } -+ -+ *ret = *drinfo; -+ ssz = vfsub_read_k(file, (void *)ret->oldname, len, &pos); -+ if (unlikely(ssz != len)) { -+ au_kfree_rcu(ret); -+ ret = ERR_PTR(-EIO); -+ AuIOErr("ssz %zd, %u, %pD2\n", ssz, len, file); -+ goto out; -+ } -+ -+ AuDbg("oldname %.*s\n", ret->oldnamelen, ret->oldname); -+ -+out: -+ return ret; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* in order to be revertible */ -+struct au_drinfo_rev_elm { -+ int created; -+ struct dentry *info_dentry; -+ struct au_drinfo *info_last; -+}; -+ -+struct au_drinfo_rev { -+ unsigned char already; -+ aufs_bindex_t nelm; -+ struct au_drinfo_rev_elm elm[]; -+}; -+ -+/* todo: isn't it too large? */ -+struct au_drinfo_store { -+ struct path h_ppath; -+ struct dentry *h_dentry; -+ struct au_drinfo_fdata *fdata; -+ char *infoname; /* inside of whname, just after PFX */ -+ char whname[sizeof(AUFS_WH_DR_INFO_PFX) + AUFS_DIRREN_ENV_VAL_SZ]; -+ aufs_bindex_t btgt, btail; -+ unsigned char no_sio, -+ allocated, /* current size of *fdata */ -+ infonamelen, /* room size for p */ -+ whnamelen, /* length of the generated name */ -+ renameback; /* renamed back */ -+}; -+ -+/* on rename(2) error, the caller should revert it using @elm */ -+static int au_drinfo_do_store(struct au_drinfo_store *w, -+ struct au_drinfo_rev_elm *elm) -+{ -+ int err, len; -+ ssize_t ssz; -+ loff_t pos; -+ struct path infopath = { -+ .mnt = w->h_ppath.mnt -+ }; -+ struct inode *h_dir, *h_inode, *delegated; -+ struct file *infofile; -+ struct qstr *qname; -+ -+ AuDebugOn(elm -+ && memcmp(elm, page_address(ZERO_PAGE(0)), sizeof(*elm))); -+ -+ infopath.dentry = vfsub_lookup_one_len(w->whname, &w->h_ppath, -+ w->whnamelen); -+ AuTraceErrPtr(infopath.dentry); -+ if (IS_ERR(infopath.dentry)) { -+ err = PTR_ERR(infopath.dentry); -+ goto out; -+ } -+ -+ err = 0; -+ h_dir = d_inode(w->h_ppath.dentry); -+ if (elm && d_is_negative(infopath.dentry)) { -+ err = vfsub_create(h_dir, &infopath, 0600, /*want_excl*/true); -+ AuTraceErr(err); -+ if (unlikely(err)) -+ goto out_dput; -+ elm->created = 1; -+ elm->info_dentry = dget(infopath.dentry); -+ } -+ -+ infofile = vfsub_dentry_open(&infopath, O_RDWR); -+ AuTraceErrPtr(infofile); -+ if (IS_ERR(infofile)) { -+ err = PTR_ERR(infofile); -+ goto out_dput; -+ } -+ -+ h_inode = d_inode(infopath.dentry); -+ if (elm && i_size_read(h_inode)) { -+ h_inode = d_inode(w->h_dentry); -+ elm->info_last = au_drinfo_read_k(infofile, h_inode->i_ino); -+ AuTraceErrPtr(elm->info_last); -+ if (IS_ERR(elm->info_last)) { -+ err = PTR_ERR(elm->info_last); -+ elm->info_last = NULL; -+ AuDebugOn(elm->info_dentry); -+ goto out_fput; -+ } -+ } -+ -+ if (elm && w->renameback) { -+ delegated = NULL; -+ err = vfsub_unlink(h_dir, &infopath, &delegated, /*force*/0); -+ AuTraceErr(err); -+ if (unlikely(err == -EWOULDBLOCK)) -+ iput(delegated); -+ goto out_fput; -+ } -+ -+ pos = 0; -+ qname = &w->h_dentry->d_name; -+ len = sizeof(*w->fdata) + qname->len; -+ if (!elm) -+ len = sizeof(*w->fdata) + w->fdata->drinfo.oldnamelen; -+ ssz = vfsub_write_k(infofile, w->fdata, len, &pos); -+ if (ssz == len) { -+ AuDbg("hi%llu, %.*s\n", w->fdata->drinfo.ino, -+ w->fdata->drinfo.oldnamelen, w->fdata->drinfo.oldname); -+ goto out_fput; /* success */ -+ } else { -+ err = -EIO; -+ if (ssz < 0) -+ err = ssz; -+ /* the caller should revert it using @elm */ -+ } -+ -+out_fput: -+ fput(infofile); -+out_dput: -+ dput(infopath.dentry); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+struct au_call_drinfo_do_store_args { -+ int *errp; -+ struct au_drinfo_store *w; -+ struct au_drinfo_rev_elm *elm; -+}; -+ -+static void au_call_drinfo_do_store(void *args) -+{ -+ struct au_call_drinfo_do_store_args *a = args; -+ -+ *a->errp = au_drinfo_do_store(a->w, a->elm); -+} -+ -+static int au_drinfo_store_sio(struct au_drinfo_store *w, -+ struct au_drinfo_rev_elm *elm) -+{ -+ int err, wkq_err; -+ -+ if (w->no_sio) -+ err = au_drinfo_do_store(w, elm); -+ else { -+ struct au_call_drinfo_do_store_args a = { -+ .errp = &err, -+ .w = w, -+ .elm = elm -+ }; -+ wkq_err = au_wkq_wait(au_call_drinfo_do_store, &a); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } -+ AuTraceErr(err); -+ -+ return err; -+} -+ -+static int au_drinfo_store_work_init(struct au_drinfo_store *w, -+ aufs_bindex_t btgt) -+{ -+ int err; -+ -+ memset(w, 0, sizeof(*w)); -+ w->allocated = roundup_pow_of_two(sizeof(*w->fdata) + 40); -+ strscpy(w->whname, AUFS_WH_DR_INFO_PFX, sizeof(AUFS_WH_DR_INFO_PFX)); -+ w->infoname = w->whname + sizeof(AUFS_WH_DR_INFO_PFX) - 1; -+ w->infonamelen = sizeof(w->whname) - sizeof(AUFS_WH_DR_INFO_PFX); -+ w->btgt = btgt; -+ w->no_sio = !!uid_eq(current_fsuid(), GLOBAL_ROOT_UID); -+ -+ err = -ENOMEM; -+ w->fdata = kcalloc(1, w->allocated, GFP_NOFS); -+ if (unlikely(!w->fdata)) { -+ AuTraceErr(err); -+ goto out; -+ } -+ w->fdata->magic = (__force uint32_t)htonl(AUFS_DRINFO_MAGIC_V1); -+ err = 0; -+ -+out: -+ return err; -+} -+ -+static void au_drinfo_store_work_fin(struct au_drinfo_store *w) -+{ -+ au_kfree_rcu(w->fdata); -+} -+ -+static void au_drinfo_store_rev(struct au_drinfo_rev *rev, -+ struct au_drinfo_store *w) -+{ -+ struct au_drinfo_rev_elm *elm; -+ struct inode *h_dir, *delegated; -+ int err, nelm; -+ struct path infopath = { -+ .mnt = w->h_ppath.mnt -+ }; -+ -+ h_dir = d_inode(w->h_ppath.dentry); -+ IMustLock(h_dir); -+ -+ err = 0; -+ elm = rev->elm; -+ for (nelm = rev->nelm; nelm > 0; nelm--, elm++) { -+ AuDebugOn(elm->created && elm->info_last); -+ if (elm->created) { -+ AuDbg("here\n"); -+ delegated = NULL; -+ infopath.dentry = elm->info_dentry; -+ err = vfsub_unlink(h_dir, &infopath, &delegated, -+ !w->no_sio); -+ AuTraceErr(err); -+ if (unlikely(err == -EWOULDBLOCK)) -+ iput(delegated); -+ dput(elm->info_dentry); -+ } else if (elm->info_last) { -+ AuDbg("here\n"); -+ w->fdata->drinfo = *elm->info_last; -+ memcpy(w->fdata->drinfo.oldname, -+ elm->info_last->oldname, -+ elm->info_last->oldnamelen); -+ err = au_drinfo_store_sio(w, /*elm*/NULL); -+ au_kfree_rcu(elm->info_last); -+ } -+ if (unlikely(err)) -+ AuIOErr("%d, %s\n", err, w->whname); -+ /* go on even if err */ -+ } -+} -+ -+/* caller has to call au_dr_rename_fin() later */ -+static int au_drinfo_store(struct dentry *dentry, aufs_bindex_t btgt, -+ struct qstr *dst_name, void *_rev) -+{ -+ int err, sz, nelm; -+ aufs_bindex_t bindex, btail; -+ struct au_drinfo_store work; -+ struct au_drinfo_rev *rev, **p; -+ struct au_drinfo_rev_elm *elm; -+ struct super_block *sb; -+ struct au_branch *br; -+ struct au_hinode *hdir; -+ -+ err = au_drinfo_store_work_init(&work, btgt); -+ AuTraceErr(err); -+ if (unlikely(err)) -+ goto out; -+ -+ err = -ENOMEM; -+ btail = au_dbtaildir(dentry); -+ nelm = btail - btgt; -+ sz = sizeof(*rev) + sizeof(*elm) * nelm; -+ rev = kcalloc(1, sz, GFP_NOFS); -+ if (unlikely(!rev)) { -+ AuTraceErr(err); -+ goto out_args; -+ } -+ rev->nelm = nelm; -+ elm = rev->elm; -+ p = _rev; -+ *p = rev; -+ -+ err = 0; -+ sb = dentry->d_sb; -+ work.h_ppath.dentry = au_h_dptr(dentry, btgt); -+ work.h_ppath.mnt = au_sbr_mnt(sb, btgt); -+ hdir = au_hi(d_inode(dentry), btgt); -+ au_hn_inode_lock_nested(hdir, AuLsc_I_CHILD); -+ for (bindex = btgt + 1; bindex <= btail; bindex++, elm++) { -+ work.h_dentry = au_h_dptr(dentry, bindex); -+ if (!work.h_dentry) -+ continue; -+ -+ err = au_drinfo_construct(&work.fdata, work.h_dentry, -+ &work.allocated); -+ AuTraceErr(err); -+ if (unlikely(err)) -+ break; -+ -+ work.renameback = au_qstreq(&work.h_dentry->d_name, dst_name); -+ br = au_sbr(sb, bindex); -+ work.whnamelen = sizeof(AUFS_WH_DR_INFO_PFX) - 1; -+ work.whnamelen += au_drinfo_name(br, work.infoname, -+ work.infonamelen); -+ AuDbg("whname %.*s, i%llu, %.*s\n", -+ work.whnamelen, work.whname, -+ be64_to_cpu((__force __be64)work.fdata->drinfo.ino), -+ work.fdata->drinfo.oldnamelen, -+ work.fdata->drinfo.oldname); -+ -+ err = au_drinfo_store_sio(&work, elm); -+ AuTraceErr(err); -+ if (unlikely(err)) -+ break; -+ } -+ if (unlikely(err)) { -+ /* revert all drinfo */ -+ au_drinfo_store_rev(rev, &work); -+ au_kfree_try_rcu(rev); -+ *p = NULL; -+ } -+ au_hn_inode_unlock(hdir); -+ -+out_args: -+ au_drinfo_store_work_fin(&work); -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_dr_rename(struct dentry *src, aufs_bindex_t bindex, -+ struct qstr *dst_name, void *_rev) -+{ -+ int err, already; -+ ino_t ino; -+ struct super_block *sb; -+ struct au_branch *br; -+ struct au_dr_br *dr; -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ struct au_dr_hino *ent; -+ struct au_drinfo_rev *rev, **p; -+ -+ AuDbg("bindex %d\n", bindex); -+ -+ err = -ENOMEM; -+ ent = kmalloc(sizeof(*ent), GFP_NOFS); -+ if (unlikely(!ent)) -+ goto out; -+ -+ sb = src->d_sb; -+ br = au_sbr(sb, bindex); -+ dr = &br->br_dirren; -+ h_dentry = au_h_dptr(src, bindex); -+ h_inode = d_inode(h_dentry); -+ ino = h_inode->i_ino; -+ ent->dr_h_ino = ino; -+ already = au_dr_hino_test_add(dr, ino, ent); -+ AuDbg("b%d, hi%llu, already %d\n", -+ bindex, (unsigned long long)ino, already); -+ -+ err = au_drinfo_store(src, bindex, dst_name, _rev); -+ AuTraceErr(err); -+ if (!err) { -+ p = _rev; -+ rev = *p; -+ rev->already = already; -+ goto out; /* success */ -+ } -+ -+ /* revert */ -+ if (!already) -+ au_dr_hino_del(dr, ent); -+ au_kfree_rcu(ent); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+void au_dr_rename_fin(struct dentry *src, aufs_bindex_t btgt, void *_rev) -+{ -+ struct au_drinfo_rev *rev; -+ struct au_drinfo_rev_elm *elm; -+ int nelm; -+ -+ rev = _rev; -+ elm = rev->elm; -+ for (nelm = rev->nelm; nelm > 0; nelm--, elm++) { -+ dput(elm->info_dentry); -+ au_kfree_rcu(elm->info_last); -+ } -+ au_kfree_try_rcu(rev); -+} -+ -+void au_dr_rename_rev(struct dentry *src, aufs_bindex_t btgt, void *_rev) -+{ -+ int err; -+ struct au_drinfo_store work; -+ struct au_drinfo_rev *rev = _rev; -+ struct super_block *sb; -+ struct au_branch *br; -+ struct inode *h_inode; -+ struct au_dr_br *dr; -+ struct au_dr_hino *ent; -+ -+ err = au_drinfo_store_work_init(&work, btgt); -+ if (unlikely(err)) -+ goto out; -+ -+ sb = src->d_sb; -+ br = au_sbr(sb, btgt); -+ work.h_ppath.dentry = au_h_dptr(src, btgt); -+ work.h_ppath.mnt = au_br_mnt(br); -+ au_drinfo_store_rev(rev, &work); -+ au_drinfo_store_work_fin(&work); -+ if (rev->already) -+ goto out; -+ -+ dr = &br->br_dirren; -+ h_inode = d_inode(work.h_ppath.dentry); -+ ent = au_dr_hino_find(dr, h_inode->i_ino); -+ BUG_ON(!ent); -+ au_dr_hino_del(dr, ent); -+ au_kfree_rcu(ent); -+ -+out: -+ au_kfree_try_rcu(rev); -+ if (unlikely(err)) -+ pr_err("failed to remove dirren info\n"); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static struct au_drinfo *au_drinfo_do_load(struct path *h_ppath, -+ char *whname, int whnamelen, -+ struct dentry **info_dentry) -+{ -+ struct au_drinfo *drinfo; -+ struct file *f; -+ struct inode *h_dir; -+ struct path infopath; -+ int unlocked; -+ -+ AuDbg("%pd/%.*s\n", h_ppath->dentry, whnamelen, whname); -+ -+ *info_dentry = NULL; -+ drinfo = NULL; -+ unlocked = 0; -+ h_dir = d_inode(h_ppath->dentry); -+ inode_lock_shared_nested(h_dir, AuLsc_I_PARENT); -+ infopath.dentry = vfsub_lookup_one_len(whname, h_ppath, whnamelen); -+ if (IS_ERR(infopath.dentry)) { -+ drinfo = (void *)infopath.dentry; -+ goto out; -+ } -+ -+ if (d_is_negative(infopath.dentry)) -+ goto out_dput; /* success */ -+ -+ infopath.mnt = h_ppath->mnt; -+ f = vfsub_dentry_open(&infopath, O_RDONLY); -+ inode_unlock_shared(h_dir); -+ unlocked = 1; -+ if (IS_ERR(f)) { -+ drinfo = (void *)f; -+ goto out_dput; -+ } -+ -+ drinfo = au_drinfo_read_k(f, /*h_ino*/0); -+ if (IS_ERR_OR_NULL(drinfo)) -+ goto out_fput; -+ -+ AuDbg("oldname %.*s\n", drinfo->oldnamelen, drinfo->oldname); -+ *info_dentry = dget(infopath.dentry); /* keep it alive */ -+ -+out_fput: -+ fput(f); -+out_dput: -+ dput(infopath.dentry); -+out: -+ if (!unlocked) -+ inode_unlock_shared(h_dir); -+ AuTraceErrPtr(drinfo); -+ return drinfo; -+} -+ -+struct au_drinfo_do_load_args { -+ struct au_drinfo **drinfop; -+ struct path *h_ppath; -+ char *whname; -+ int whnamelen; -+ struct dentry **info_dentry; -+}; -+ -+static void au_call_drinfo_do_load(void *args) -+{ -+ struct au_drinfo_do_load_args *a = args; -+ -+ *a->drinfop = au_drinfo_do_load(a->h_ppath, a->whname, a->whnamelen, -+ a->info_dentry); -+} -+ -+struct au_drinfo_load { -+ struct path h_ppath; -+ struct qstr *qname; -+ unsigned char no_sio; -+ -+ aufs_bindex_t ninfo; -+ struct au_drinfo **drinfo; -+}; -+ -+static int au_drinfo_load(struct au_drinfo_load *w, aufs_bindex_t bindex, -+ struct au_branch *br) -+{ -+ int err, wkq_err, whnamelen, e; -+ char whname[sizeof(AUFS_WH_DR_INFO_PFX) + AUFS_DIRREN_ENV_VAL_SZ] -+ = AUFS_WH_DR_INFO_PFX; -+ struct au_drinfo *drinfo; -+ struct qstr oldname; -+ struct inode *h_dir, *delegated; -+ struct dentry *info_dentry; -+ struct path infopath; -+ -+ whnamelen = sizeof(AUFS_WH_DR_INFO_PFX) - 1; -+ whnamelen += au_drinfo_name(br, whname + whnamelen, -+ sizeof(whname) - whnamelen); -+ if (w->no_sio) -+ drinfo = au_drinfo_do_load(&w->h_ppath, whname, whnamelen, -+ &info_dentry); -+ else { -+ struct au_drinfo_do_load_args args = { -+ .drinfop = &drinfo, -+ .h_ppath = &w->h_ppath, -+ .whname = whname, -+ .whnamelen = whnamelen, -+ .info_dentry = &info_dentry -+ }; -+ wkq_err = au_wkq_wait(au_call_drinfo_do_load, &args); -+ if (unlikely(wkq_err)) -+ drinfo = ERR_PTR(wkq_err); -+ } -+ err = PTR_ERR(drinfo); -+ if (IS_ERR_OR_NULL(drinfo)) -+ goto out; -+ -+ err = 0; -+ oldname.len = drinfo->oldnamelen; -+ oldname.name = drinfo->oldname; -+ if (au_qstreq(w->qname, &oldname)) { -+ /* the name is renamed back */ -+ au_kfree_rcu(drinfo); -+ drinfo = NULL; -+ -+ infopath.dentry = info_dentry; -+ infopath.mnt = w->h_ppath.mnt; -+ h_dir = d_inode(w->h_ppath.dentry); -+ delegated = NULL; -+ inode_lock_nested(h_dir, AuLsc_I_PARENT); -+ e = vfsub_unlink(h_dir, &infopath, &delegated, !w->no_sio); -+ inode_unlock(h_dir); -+ if (unlikely(e)) -+ AuIOErr("ignored %d, %pd2\n", e, &infopath.dentry); -+ if (unlikely(e == -EWOULDBLOCK)) -+ iput(delegated); -+ } -+ au_kfree_rcu(w->drinfo[bindex]); -+ w->drinfo[bindex] = drinfo; -+ dput(info_dentry); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void au_dr_lkup_free(struct au_drinfo **drinfo, int n) -+{ -+ struct au_drinfo **p = drinfo; -+ -+ while (n-- > 0) -+ au_kfree_rcu(*drinfo++); -+ au_kfree_try_rcu(p); -+} -+ -+int au_dr_lkup(struct au_do_lookup_args *lkup, struct dentry *dentry, -+ aufs_bindex_t btgt) -+{ -+ int err, ninfo; -+ struct au_drinfo_load w; -+ aufs_bindex_t bindex, bbot; -+ struct au_branch *br; -+ struct inode *h_dir; -+ struct au_dr_hino *ent; -+ struct super_block *sb; -+ -+ AuDbg("%.*s, name %.*s, whname %.*s, b%d\n", -+ AuLNPair(&dentry->d_name), AuLNPair(&lkup->dirren.dr_name), -+ AuLNPair(&lkup->whname), btgt); -+ -+ sb = dentry->d_sb; -+ bbot = au_sbbot(sb); -+ w.ninfo = bbot + 1; -+ if (!lkup->dirren.drinfo) { -+ lkup->dirren.drinfo = kcalloc(w.ninfo, -+ sizeof(*lkup->dirren.drinfo), -+ GFP_NOFS); -+ if (unlikely(!lkup->dirren.drinfo)) { -+ err = -ENOMEM; -+ goto out; -+ } -+ lkup->dirren.ninfo = w.ninfo; -+ } -+ w.drinfo = lkup->dirren.drinfo; -+ w.no_sio = !!uid_eq(current_fsuid(), GLOBAL_ROOT_UID); -+ w.h_ppath.dentry = au_h_dptr(dentry, btgt); -+ AuDebugOn(!w.h_ppath.dentry); -+ w.h_ppath.mnt = au_sbr_mnt(sb, btgt); -+ w.qname = &dentry->d_name; -+ -+ ninfo = 0; -+ for (bindex = btgt + 1; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ err = au_drinfo_load(&w, bindex, br); -+ if (unlikely(err)) -+ goto out_free; -+ if (w.drinfo[bindex]) -+ ninfo++; -+ } -+ if (!ninfo) { -+ br = au_sbr(sb, btgt); -+ h_dir = d_inode(w.h_ppath.dentry); -+ ent = au_dr_hino_find(&br->br_dirren, h_dir->i_ino); -+ AuDebugOn(!ent); -+ au_dr_hino_del(&br->br_dirren, ent); -+ au_kfree_rcu(ent); -+ } -+ goto out; /* success */ -+ -+out_free: -+ au_dr_lkup_free(lkup->dirren.drinfo, lkup->dirren.ninfo); -+ lkup->dirren.ninfo = 0; -+ lkup->dirren.drinfo = NULL; -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+void au_dr_lkup_fin(struct au_do_lookup_args *lkup) -+{ -+ au_dr_lkup_free(lkup->dirren.drinfo, lkup->dirren.ninfo); -+} -+ -+int au_dr_lkup_name(struct au_do_lookup_args *lkup, aufs_bindex_t btgt) -+{ -+ int err; -+ struct au_drinfo *drinfo; -+ -+ err = 0; -+ if (!lkup->dirren.drinfo) -+ goto out; -+ AuDebugOn(lkup->dirren.ninfo <= btgt); -+ drinfo = lkup->dirren.drinfo[btgt]; -+ if (!drinfo) -+ goto out; -+ -+ au_kfree_try_rcu(lkup->whname.name); -+ lkup->whname.name = NULL; -+ lkup->dirren.dr_name.len = drinfo->oldnamelen; -+ lkup->dirren.dr_name.name = drinfo->oldname; -+ lkup->name = &lkup->dirren.dr_name; -+ err = au_wh_name_alloc(&lkup->whname, lkup->name); -+ if (!err) -+ AuDbg("name %.*s, whname %.*s, b%d\n", -+ AuLNPair(lkup->name), AuLNPair(&lkup->whname), -+ btgt); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_dr_lkup_h_ino(struct au_do_lookup_args *lkup, aufs_bindex_t bindex, -+ ino_t h_ino) -+{ -+ int match; -+ struct au_drinfo *drinfo; -+ -+ match = 1; -+ if (!lkup->dirren.drinfo) -+ goto out; -+ AuDebugOn(lkup->dirren.ninfo <= bindex); -+ drinfo = lkup->dirren.drinfo[bindex]; -+ if (!drinfo) -+ goto out; -+ -+ match = (drinfo->ino == h_ino); -+ AuDbg("match %d\n", match); -+ -+out: -+ return match; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_dr_opt_set(struct super_block *sb) -+{ -+ int err; -+ aufs_bindex_t bindex, bbot; -+ struct au_branch *br; -+ -+ err = 0; -+ bbot = au_sbbot(sb); -+ for (bindex = 0; !err && bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ err = au_dr_hino(sb, bindex, /*br*/NULL, &br->br_path); -+ } -+ -+ return err; -+} -+ -+int au_dr_opt_flush(struct super_block *sb) -+{ -+ int err; -+ aufs_bindex_t bindex, bbot; -+ struct au_branch *br; -+ -+ err = 0; -+ bbot = au_sbbot(sb); -+ for (bindex = 0; !err && bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (au_br_writable(br->br_perm)) -+ err = au_dr_hino(sb, bindex, /*br*/NULL, /*path*/NULL); -+ } -+ -+ return err; -+} -+ -+int au_dr_opt_clr(struct super_block *sb, int no_flush) -+{ -+ int err; -+ aufs_bindex_t bindex, bbot; -+ struct au_branch *br; -+ -+ err = 0; -+ if (!no_flush) { -+ err = au_dr_opt_flush(sb); -+ if (unlikely(err)) -+ goto out; -+ } -+ -+ bbot = au_sbbot(sb); -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ au_dr_hino_free(&br->br_dirren); -+ } -+ -+out: -+ return err; -+} -diff -Naur null/fs/aufs/dirren.h linux-6.6.63/fs/aufs/dirren.h ---- /dev/null -+++ linux-6.6.63/fs/aufs/dirren.h 2024-12-18 15:12:59.295519588 +0300 -@@ -0,0 +1,140 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2017-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * renamed dir info -+ */ -+ -+#ifndef __AUFS_DIRREN_H__ -+#define __AUFS_DIRREN_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+#include -+#include "hbl.h" -+ -+#define AuDirren_NHASH 100 -+ -+#ifdef CONFIG_AUFS_DIRREN -+enum au_brid_type { -+ AuBrid_Unset, -+ AuBrid_UUID, -+ AuBrid_FSID, -+ AuBrid_DEV -+}; -+ -+struct au_dr_brid { -+ enum au_brid_type type; -+ union { -+ uuid_t uuid; /* unimplemented yet */ -+ fsid_t fsid; -+ dev_t dev; -+ }; -+}; -+ -+/* 20 is the max digits length of ulong 64 */ -+/* brid-type "_" uuid "_" inum */ -+#define AUFS_DIRREN_FNAME_SZ (1 + 1 + UUID_STRING_LEN + 20) -+#define AUFS_DIRREN_ENV_VAL_SZ (AUFS_DIRREN_FNAME_SZ + 1 + 20) -+ -+struct au_dr_hino { -+ struct hlist_bl_node dr_hnode; -+ ino_t dr_h_ino; -+}; -+ -+struct au_dr_br { -+ struct hlist_bl_head dr_h_ino[AuDirren_NHASH]; -+ struct au_dr_brid dr_brid; -+}; -+ -+struct au_dr_lookup { -+ /* dr_name is pointed by struct au_do_lookup_args.name */ -+ struct qstr dr_name; /* subset of dr_info */ -+ aufs_bindex_t ninfo; -+ struct au_drinfo **drinfo; -+}; -+#else -+struct au_dr_hino; -+/* empty */ -+struct au_dr_br { }; -+struct au_dr_lookup { }; -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_branch; -+struct au_do_lookup_args; -+struct au_hinode; -+#ifdef CONFIG_AUFS_DIRREN -+int au_dr_hino_test_add(struct au_dr_br *dr, ino_t h_ino, -+ struct au_dr_hino *add_ent); -+void au_dr_hino_free(struct au_dr_br *dr); -+int au_dr_br_init(struct super_block *sb, struct au_branch *br, -+ const struct path *path); -+int au_dr_br_fin(struct super_block *sb, struct au_branch *br); -+int au_dr_rename(struct dentry *src, aufs_bindex_t bindex, -+ struct qstr *dst_name, void *_rev); -+void au_dr_rename_fin(struct dentry *src, aufs_bindex_t btgt, void *rev); -+void au_dr_rename_rev(struct dentry *src, aufs_bindex_t bindex, void *rev); -+int au_dr_lkup(struct au_do_lookup_args *lkup, struct dentry *dentry, -+ aufs_bindex_t bindex); -+int au_dr_lkup_name(struct au_do_lookup_args *lkup, aufs_bindex_t btgt); -+int au_dr_lkup_h_ino(struct au_do_lookup_args *lkup, aufs_bindex_t bindex, -+ ino_t h_ino); -+void au_dr_lkup_fin(struct au_do_lookup_args *lkup); -+int au_dr_opt_set(struct super_block *sb); -+int au_dr_opt_flush(struct super_block *sb); -+int au_dr_opt_clr(struct super_block *sb, int no_flush); -+#else -+AuStubInt0(au_dr_hino_test_add, struct au_dr_br *dr, ino_t h_ino, -+ struct au_dr_hino *add_ent); -+AuStubVoid(au_dr_hino_free, struct au_dr_br *dr); -+AuStubInt0(au_dr_br_init, struct super_block *sb, struct au_branch *br, -+ const struct path *path); -+AuStubInt0(au_dr_br_fin, struct super_block *sb, struct au_branch *br); -+AuStubInt0(au_dr_rename, struct dentry *src, aufs_bindex_t bindex, -+ struct qstr *dst_name, void *_rev); -+AuStubVoid(au_dr_rename_fin, struct dentry *src, aufs_bindex_t btgt, void *rev); -+AuStubVoid(au_dr_rename_rev, struct dentry *src, aufs_bindex_t bindex, -+ void *rev); -+AuStubInt0(au_dr_lkup, struct au_do_lookup_args *lkup, struct dentry *dentry, -+ aufs_bindex_t bindex); -+AuStubInt0(au_dr_lkup_name, struct au_do_lookup_args *lkup, aufs_bindex_t btgt); -+AuStubInt0(au_dr_lkup_h_ino, struct au_do_lookup_args *lkup, -+ aufs_bindex_t bindex, ino_t h_ino); -+AuStubVoid(au_dr_lkup_fin, struct au_do_lookup_args *lkup); -+AuStubInt0(au_dr_opt_set, struct super_block *sb); -+AuStubInt0(au_dr_opt_flush, struct super_block *sb); -+AuStubInt0(au_dr_opt_clr, struct super_block *sb, int no_flush); -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+#ifdef CONFIG_AUFS_DIRREN -+static inline int au_dr_ihash(ino_t h_ino) -+{ -+ return h_ino % AuDirren_NHASH; -+} -+#else -+AuStubInt0(au_dr_ihash, ino_t h_ino); -+#endif -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_DIRREN_H__ */ -diff -Naur null/fs/aufs/dynop.c linux-6.6.63/fs/aufs/dynop.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/dynop.c 2024-12-18 15:12:59.295519588 +0300 -@@ -0,0 +1,365 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2010-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * dynamically customizable operations for regular files -+ */ -+ -+#include "aufs.h" -+ -+#define DyPrSym(key) AuDbgSym((void*)(key->dk_op.dy_hop)) -+ -+/* -+ * How large will these lists be? -+ * Usually just a few elements, 20-30 at most for each, I guess. -+ */ -+static struct hlist_bl_head dynop[AuDyLast]; -+ -+static struct au_dykey *dy_gfind_get(struct hlist_bl_head *hbl, -+ const void *h_op) -+{ -+ struct au_dykey *key, *tmp; -+ struct hlist_bl_node *pos; -+ -+ key = NULL; -+ hlist_bl_lock(hbl); -+ hlist_bl_for_each_entry(tmp, pos, hbl, dk_hnode) -+ if (tmp->dk_op.dy_hop == h_op) { -+ if (kref_get_unless_zero(&tmp->dk_kref)) -+ key = tmp; -+ break; -+ } -+ hlist_bl_unlock(hbl); -+ -+ return key; -+} -+ -+static struct au_dykey *dy_bradd(struct au_branch *br, struct au_dykey *key) -+{ -+ struct au_dykey **k, *found; -+ const void *h_op = key->dk_op.dy_hop; -+ int i; -+ -+ found = NULL; -+ k = br->br_dykey; -+ for (i = 0; i < AuBrDynOp; i++) -+ if (k[i]) { -+ if (k[i]->dk_op.dy_hop == h_op) { -+ found = k[i]; -+ break; -+ } -+ } else -+ break; -+ if (!found) { -+ spin_lock(&br->br_dykey_lock); -+ for (; i < AuBrDynOp; i++) -+ if (k[i]) { -+ if (k[i]->dk_op.dy_hop == h_op) { -+ found = k[i]; -+ break; -+ } -+ } else { -+ k[i] = key; -+ break; -+ } -+ spin_unlock(&br->br_dykey_lock); -+ BUG_ON(i == AuBrDynOp); /* expand the array */ -+ } -+ -+ return found; -+} -+ -+/* kref_get() if @key is already added */ -+static struct au_dykey *dy_gadd(struct hlist_bl_head *hbl, struct au_dykey *key) -+{ -+ struct au_dykey *tmp, *found; -+ struct hlist_bl_node *pos; -+ const void *h_op = key->dk_op.dy_hop; -+ -+ found = NULL; -+ hlist_bl_lock(hbl); -+ hlist_bl_for_each_entry(tmp, pos, hbl, dk_hnode) -+ if (tmp->dk_op.dy_hop == h_op) { -+ if (kref_get_unless_zero(&tmp->dk_kref)) -+ found = tmp; -+ break; -+ } -+ if (!found) -+ hlist_bl_add_head(&key->dk_hnode, hbl); -+ hlist_bl_unlock(hbl); -+ -+ if (!found) -+ DyPrSym(key); -+ return found; -+} -+ -+static void dy_free_rcu(struct rcu_head *rcu) -+{ -+ struct au_dykey *key; -+ -+ key = container_of(rcu, struct au_dykey, dk_rcu); -+ DyPrSym(key); -+ kfree(key); -+} -+ -+static void dy_free(struct kref *kref) -+{ -+ struct au_dykey *key; -+ struct hlist_bl_head *hbl; -+ -+ key = container_of(kref, struct au_dykey, dk_kref); -+ hbl = dynop + key->dk_op.dy_type; -+ au_hbl_del(&key->dk_hnode, hbl); -+ call_rcu(&key->dk_rcu, dy_free_rcu); -+} -+ -+void au_dy_put(struct au_dykey *key) -+{ -+ kref_put(&key->dk_kref, dy_free); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+#define DyDbgSize(cnt, op) AuDebugOn(cnt != sizeof(op)/sizeof(void *)) -+ -+#define DyDbgDeclare(cnt) unsigned int cnt __maybe_unused = 0 -+#ifdef CONFIG_AUFS_DEBUG -+#define DyDbgInc(cnt) do { cnt++; } while (0) -+#else -+AuStubVoid(DyDbgInc, unsigned int cnt __maybe_unused); -+#endif -+ -+#define DySet(func, dst, src, h_op, h_sb) do { \ -+ DyDbgInc(cnt); \ -+ if (h_op->func) { \ -+ if (src.func) \ -+ dst.func = src.func; \ -+ else \ -+ AuDbg("%s %s\n", au_sbtype(h_sb), #func); \ -+ } \ -+} while (0) -+ -+#define DySetForce(func, dst, src) do { \ -+ AuDebugOn(!src.func); \ -+ DyDbgInc(cnt); \ -+ dst.func = src.func; \ -+} while (0) -+ -+#define DySetAop(func) \ -+ DySet(func, dyaop->da_op, aufs_aop, h_aop, h_sb) -+#define DySetAopForce(func) \ -+ DySetForce(func, dyaop->da_op, aufs_aop) -+ -+static void dy_aop(struct au_dykey *key, const void *h_op, -+ struct super_block *h_sb __maybe_unused) -+{ -+ struct au_dyaop *dyaop = (void *)key; -+ const struct address_space_operations *h_aop = h_op; -+ DyDbgDeclare(cnt); -+ -+ AuDbg("%s\n", au_sbtype(h_sb)); -+ -+ DySetAop(writepage); -+ DySetAopForce(read_folio); /* force */ -+ DySetAop(writepages); -+ DySetAop(dirty_folio); -+ DySetAop(invalidate_folio); -+ DySetAop(readahead); -+ DySetAop(write_begin); -+ DySetAop(write_end); -+ DySetAop(bmap); -+ DySetAop(release_folio); -+ DySetAop(free_folio); -+ /* this one will be changed according to an aufs mount option */ -+ DySetAop(direct_IO); -+ DySetAop(migrate_folio); -+ DySetAop(launder_folio); -+ DySetAop(is_partially_uptodate); -+ DySetAop(is_dirty_writeback); -+ DySetAop(error_remove_page); -+ DySetAop(swap_activate); -+ DySetAop(swap_deactivate); -+ DySetAop(swap_rw); -+ -+ DyDbgSize(cnt, *h_aop); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void dy_bug(struct kref *kref) -+{ -+ BUG(); -+} -+ -+static struct au_dykey *dy_get(struct au_dynop *op, struct au_branch *br) -+{ -+ struct au_dykey *key, *old; -+ struct hlist_bl_head *hbl; -+ struct op { -+ unsigned int sz; -+ void (*set)(struct au_dykey *key, const void *h_op, -+ struct super_block *h_sb __maybe_unused); -+ }; -+ static const struct op a[] = { -+ [AuDy_AOP] = { -+ .sz = sizeof(struct au_dyaop), -+ .set = dy_aop -+ } -+ }; -+ const struct op *p; -+ -+ hbl = dynop + op->dy_type; -+ key = dy_gfind_get(hbl, op->dy_hop); -+ if (key) -+ goto out_add; /* success */ -+ -+ p = a + op->dy_type; -+ key = kzalloc(p->sz, GFP_NOFS); -+ if (unlikely(!key)) { -+ key = ERR_PTR(-ENOMEM); -+ goto out; -+ } -+ -+ key->dk_op.dy_hop = op->dy_hop; -+ kref_init(&key->dk_kref); -+ p->set(key, op->dy_hop, au_br_sb(br)); -+ old = dy_gadd(hbl, key); -+ if (old) { -+ au_kfree_rcu(key); -+ key = old; -+ } -+ -+out_add: -+ old = dy_bradd(br, key); -+ if (old) -+ /* its ref-count should never be zero here */ -+ kref_put(&key->dk_kref, dy_bug); -+out: -+ return key; -+} -+ -+/* ---------------------------------------------------------------------- */ -+/* -+ * Aufs prohibits O_DIRECT by default even if the branch supports it. -+ * This behaviour is necessary to return an error from open(O_DIRECT) instead -+ * of the succeeding I/O. The dio mount option enables O_DIRECT and makes -+ * open(O_DIRECT) always succeed, but the succeeding I/O may return an error. -+ * See the aufs manual in detail. -+ */ -+static void dy_adx(struct au_dyaop *dyaop, int do_dx) -+{ -+ if (!do_dx) -+ dyaop->da_op.direct_IO = NULL; -+ else -+ dyaop->da_op.direct_IO = aufs_aop.direct_IO; -+} -+ -+static struct au_dyaop *dy_aget(struct au_branch *br, -+ const struct address_space_operations *h_aop, -+ int do_dx) -+{ -+ struct au_dyaop *dyaop; -+ struct au_dynop op; -+ -+ op.dy_type = AuDy_AOP; -+ op.dy_haop = h_aop; -+ dyaop = (void *)dy_get(&op, br); -+ if (IS_ERR(dyaop)) -+ goto out; -+ dy_adx(dyaop, do_dx); -+ -+out: -+ return dyaop; -+} -+ -+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex, -+ struct inode *h_inode) -+{ -+ int err, do_dx; -+ struct super_block *sb; -+ struct au_branch *br; -+ struct au_dyaop *dyaop; -+ -+ AuDebugOn(!S_ISREG(h_inode->i_mode)); -+ IiMustWriteLock(inode); -+ -+ sb = inode->i_sb; -+ br = au_sbr(sb, bindex); -+ do_dx = !!au_opt_test(au_mntflags(sb), DIO); -+ dyaop = dy_aget(br, h_inode->i_mapping->a_ops, do_dx); -+ err = PTR_ERR(dyaop); -+ if (IS_ERR(dyaop)) -+ /* unnecessary to call dy_fput() */ -+ goto out; -+ -+ err = 0; -+ inode->i_mapping->a_ops = &dyaop->da_op; -+ -+out: -+ return err; -+} -+ -+/* -+ * Is it safe to replace a_ops during the inode/file is in operation? -+ * Yes, I hope so. -+ */ -+int au_dy_irefresh(struct inode *inode) -+{ -+ int err; -+ aufs_bindex_t btop; -+ struct inode *h_inode; -+ -+ err = 0; -+ if (S_ISREG(inode->i_mode)) { -+ btop = au_ibtop(inode); -+ h_inode = au_h_iptr(inode, btop); -+ err = au_dy_iaop(inode, btop, h_inode); -+ } -+ return err; -+} -+ -+void au_dy_arefresh(int do_dx) -+{ -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *pos; -+ struct au_dykey *key; -+ -+ hbl = dynop + AuDy_AOP; -+ hlist_bl_lock(hbl); -+ hlist_bl_for_each_entry(key, pos, hbl, dk_hnode) -+ dy_adx((void *)key, do_dx); -+ hlist_bl_unlock(hbl); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void __init au_dy_init(void) -+{ -+ int i; -+ -+ for (i = 0; i < AuDyLast; i++) -+ INIT_HLIST_BL_HEAD(dynop + i); -+} -+ -+void au_dy_fin(void) -+{ -+ int i; -+ -+ for (i = 0; i < AuDyLast; i++) -+ WARN_ON(!hlist_bl_empty(dynop + i)); -+} -diff -Naur null/fs/aufs/dynop.h linux-6.6.63/fs/aufs/dynop.h ---- /dev/null -+++ linux-6.6.63/fs/aufs/dynop.h 2024-12-18 15:12:59.295519588 +0300 -@@ -0,0 +1,77 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2010-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * dynamically customizable operations (for regular files only) -+ */ -+ -+#ifndef __AUFS_DYNOP_H__ -+#define __AUFS_DYNOP_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+ -+enum {AuDy_AOP, AuDyLast}; -+ -+struct au_dynop { -+ int dy_type; -+ union { -+ const void *dy_hop; -+ const struct address_space_operations *dy_haop; -+ }; -+}; -+ -+struct au_dykey { -+ union { -+ struct hlist_bl_node dk_hnode; -+ struct rcu_head dk_rcu; -+ }; -+ struct au_dynop dk_op; -+ -+ /* -+ * during I am in the branch local array, kref is gotten. when the -+ * branch is removed, kref is put. -+ */ -+ struct kref dk_kref; -+}; -+ -+/* stop unioning since their sizes are very different from each other */ -+struct au_dyaop { -+ struct au_dykey da_key; -+ struct address_space_operations da_op; /* not const */ -+}; -+/* make sure that 'struct au_dykey *' can be any type */ -+static_assert(!offsetof(struct au_dyaop, da_key)); -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* dynop.c */ -+struct au_branch; -+void au_dy_put(struct au_dykey *key); -+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex, -+ struct inode *h_inode); -+int au_dy_irefresh(struct inode *inode); -+void au_dy_arefresh(int do_dio); -+ -+void __init au_dy_init(void); -+void au_dy_fin(void); -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_DYNOP_H__ */ -diff -Naur null/fs/aufs/export.c linux-6.6.63/fs/aufs/export.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/export.c 2024-12-18 15:12:59.295519588 +0300 -@@ -0,0 +1,830 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * export via nfs -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include "aufs.h" -+ -+union conv { -+#ifdef CONFIG_AUFS_INO_T_64 -+ __u32 a[2]; -+#else -+ __u32 a[1]; -+#endif -+ ino_t ino; -+}; -+ -+static ino_t decode_ino(__u32 *a) -+{ -+ union conv u; -+ -+ BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a)); -+ u.a[0] = a[0]; -+#ifdef CONFIG_AUFS_INO_T_64 -+ u.a[1] = a[1]; -+#endif -+ return u.ino; -+} -+ -+static void encode_ino(__u32 *a, ino_t ino) -+{ -+ union conv u; -+ -+ u.ino = ino; -+ a[0] = u.a[0]; -+#ifdef CONFIG_AUFS_INO_T_64 -+ a[1] = u.a[1]; -+#endif -+} -+ -+/* NFS file handle */ -+enum { -+ Fh_br_id, -+ Fh_sigen, -+#ifdef CONFIG_AUFS_INO_T_64 -+ /* support 64bit inode number */ -+ Fh_ino1, -+ Fh_ino2, -+ Fh_dir_ino1, -+ Fh_dir_ino2, -+#else -+ Fh_ino1, -+ Fh_dir_ino1, -+#endif -+ Fh_igen, -+ Fh_h_type, -+ Fh_tail, -+ -+ Fh_ino = Fh_ino1, -+ Fh_dir_ino = Fh_dir_ino1 -+}; -+ -+static int au_test_anon(struct dentry *dentry) -+{ -+ /* note: read d_flags without d_lock */ -+ return !!(dentry->d_flags & DCACHE_DISCONNECTED); -+} -+ -+int au_test_nfsd(void) -+{ -+ int ret; -+ struct task_struct *tsk = current; -+ char comm[sizeof(tsk->comm)]; -+ -+ ret = 0; -+ if (tsk->flags & PF_KTHREAD) { -+ get_task_comm(comm, tsk); -+ ret = !strcmp(comm, "nfsd"); -+ } -+ -+ return ret; -+} -+ -+/* ---------------------------------------------------------------------- */ -+/* inode generation external table */ -+ -+void au_xigen_inc(struct inode *inode) -+{ -+ loff_t pos; -+ ssize_t sz; -+ __u32 igen; -+ struct super_block *sb; -+ struct au_sbinfo *sbinfo; -+ -+ sb = inode->i_sb; -+ AuDebugOn(!au_opt_test(au_mntflags(sb), XINO)); -+ -+ sbinfo = au_sbi(sb); -+ pos = inode->i_ino; -+ pos *= sizeof(igen); -+ igen = inode->i_generation + 1; -+ sz = xino_fwrite(sbinfo->si_xigen, &igen, sizeof(igen), &pos); -+ if (sz == sizeof(igen)) -+ return; /* success */ -+ -+ if (unlikely(sz >= 0)) -+ AuIOErr("xigen error (%zd)\n", sz); -+} -+ -+int au_xigen_new(struct inode *inode) -+{ -+ int err; -+ loff_t pos; -+ ssize_t sz; -+ struct super_block *sb; -+ struct au_sbinfo *sbinfo; -+ struct file *file; -+ -+ err = 0; -+ /* todo: dirty, at mount time */ -+ if (inode->i_ino == AUFS_ROOT_INO) -+ goto out; -+ sb = inode->i_sb; -+ SiMustAnyLock(sb); -+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO))) -+ goto out; -+ -+ err = -EFBIG; -+ pos = inode->i_ino; -+ if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) { -+ AuIOErr1("too large i%lld\n", pos); -+ goto out; -+ } -+ pos *= sizeof(inode->i_generation); -+ -+ err = 0; -+ sbinfo = au_sbi(sb); -+ file = sbinfo->si_xigen; -+ BUG_ON(!file); -+ -+ if (vfsub_f_size_read(file) -+ < pos + sizeof(inode->i_generation)) { -+ inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next); -+ sz = xino_fwrite(file, &inode->i_generation, -+ sizeof(inode->i_generation), &pos); -+ } else -+ sz = xino_fread(file, &inode->i_generation, -+ sizeof(inode->i_generation), &pos); -+ if (sz == sizeof(inode->i_generation)) -+ goto out; /* success */ -+ -+ err = sz; -+ if (unlikely(sz >= 0)) { -+ err = -EIO; -+ AuIOErr("xigen error (%zd)\n", sz); -+ } -+ -+out: -+ return err; -+} -+ -+int au_xigen_set(struct super_block *sb, struct path *path) -+{ -+ int err; -+ struct au_sbinfo *sbinfo; -+ struct file *file; -+ -+ SiMustWriteLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ file = au_xino_create2(sb, path, sbinfo->si_xigen); -+ err = PTR_ERR(file); -+ if (IS_ERR(file)) -+ goto out; -+ err = 0; -+ if (sbinfo->si_xigen) -+ fput(sbinfo->si_xigen); -+ sbinfo->si_xigen = file; -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+void au_xigen_clr(struct super_block *sb) -+{ -+ struct au_sbinfo *sbinfo; -+ -+ SiMustWriteLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ if (sbinfo->si_xigen) { -+ fput(sbinfo->si_xigen); -+ sbinfo->si_xigen = NULL; -+ } -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino, -+ ino_t dir_ino) -+{ -+ struct dentry *dentry, *d; -+ struct inode *inode; -+ unsigned int sigen; -+ -+ dentry = NULL; -+ inode = ilookup(sb, ino); -+ if (!inode) -+ goto out; -+ -+ dentry = ERR_PTR(-ESTALE); -+ sigen = au_sigen(sb); -+ if (unlikely(au_is_bad_inode(inode) -+ || IS_DEADDIR(inode) -+ || sigen != au_iigen(inode, NULL))) -+ goto out_iput; -+ -+ dentry = NULL; -+ if (!dir_ino || S_ISDIR(inode->i_mode)) -+ dentry = d_find_alias(inode); -+ else { -+ spin_lock(&inode->i_lock); -+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) { -+ spin_lock(&d->d_lock); -+ if (!au_test_anon(d) -+ && d_inode(d->d_parent)->i_ino == dir_ino) { -+ dentry = dget_dlock(d); -+ spin_unlock(&d->d_lock); -+ break; -+ } -+ spin_unlock(&d->d_lock); -+ } -+ spin_unlock(&inode->i_lock); -+ } -+ if (unlikely(dentry && au_digen_test(dentry, sigen))) { -+ /* need to refresh */ -+ dput(dentry); -+ dentry = NULL; -+ } -+ -+out_iput: -+ iput(inode); -+out: -+ AuTraceErrPtr(dentry); -+ return dentry; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* todo: dirty? */ -+/* if exportfs_decode_fh() passed vfsmount*, we could be happy */ -+ -+struct au_compare_mnt_args { -+ /* input */ -+ struct super_block *sb; -+ -+ /* output */ -+ struct vfsmount *mnt; -+}; -+ -+static int au_compare_mnt(struct vfsmount *mnt, void *arg) -+{ -+ struct au_compare_mnt_args *a = arg; -+ -+ if (mnt->mnt_sb != a->sb) -+ return 0; -+ a->mnt = mntget(mnt); -+ return 1; -+} -+ -+static struct vfsmount *au_mnt_get(struct super_block *sb) -+{ -+ int err; -+ struct path root; -+ struct au_compare_mnt_args args = { -+ .sb = sb -+ }; -+ -+ get_fs_root(current->fs, &root); -+ rcu_read_lock(); -+ err = iterate_mounts(au_compare_mnt, &args, root.mnt); -+ rcu_read_unlock(); -+ path_put(&root); -+ AuDebugOn(!err); -+ AuDebugOn(!args.mnt); -+ return args.mnt; -+} -+ -+struct au_nfsd_si_lock { -+ unsigned int sigen; -+ aufs_bindex_t bindex, br_id; -+ unsigned char force_lock; -+}; -+ -+static int si_nfsd_read_lock(struct super_block *sb, -+ struct au_nfsd_si_lock *nsi_lock) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ -+ si_read_lock(sb, AuLock_FLUSH); -+ -+ /* branch id may be wrapped around */ -+ err = 0; -+ bindex = au_br_index(sb, nsi_lock->br_id); -+ if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb)) -+ goto out; /* success */ -+ -+ err = -ESTALE; -+ bindex = -1; -+ if (!nsi_lock->force_lock) -+ si_read_unlock(sb); -+ -+out: -+ nsi_lock->bindex = bindex; -+ return err; -+} -+ -+struct find_name_by_ino { -+ struct dir_context ctx; -+ int called, found; -+ ino_t ino; -+ char *name; -+ int namelen; -+}; -+ -+static bool -+find_name_by_ino(struct dir_context *ctx, const char *name, int namelen, -+ loff_t offset, u64 ino, unsigned int d_type) -+{ -+ struct find_name_by_ino *a = container_of(ctx, struct find_name_by_ino, -+ ctx); -+ -+ a->called++; -+ if (a->ino != ino) -+ return true; -+ -+ memcpy(a->name, name, namelen); -+ a->namelen = namelen; -+ a->found = 1; -+ return false; -+} -+ -+static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino, -+ struct au_nfsd_si_lock *nsi_lock) -+{ -+ struct dentry *dentry, *parent; -+ struct file *file; -+ struct inode *dir; -+ struct find_name_by_ino arg = { -+ .ctx = { -+ .actor = find_name_by_ino -+ } -+ }; -+ int err; -+ -+ parent = path->dentry; -+ if (nsi_lock) -+ si_read_unlock(parent->d_sb); -+ file = vfsub_dentry_open(path, au_dir_roflags); -+ dentry = (void *)file; -+ if (IS_ERR(file)) -+ goto out; -+ -+ dentry = ERR_PTR(-ENOMEM); -+ arg.name = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!arg.name)) -+ goto out_file; -+ arg.ino = ino; -+ arg.found = 0; -+ do { -+ arg.called = 0; -+ /* smp_mb(); */ -+ err = vfsub_iterate_dir(file, &arg.ctx); -+ } while (!err && !arg.found && arg.called); -+ dentry = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out_name; -+ /* instead of ENOENT */ -+ dentry = ERR_PTR(-ESTALE); -+ if (!arg.found) -+ goto out_name; -+ -+ /* do not call vfsub_lkup_one() */ -+ dir = d_inode(parent); -+ dentry = vfsub_lookup_one_len_unlocked(arg.name, path, arg.namelen); -+ AuTraceErrPtr(dentry); -+ if (IS_ERR(dentry)) -+ goto out_name; -+ AuDebugOn(au_test_anon(dentry)); -+ if (unlikely(d_really_is_negative(dentry))) { -+ dput(dentry); -+ dentry = ERR_PTR(-ENOENT); -+ } -+ -+out_name: -+ free_page((unsigned long)arg.name); -+out_file: -+ fput(file); -+out: -+ if (unlikely(nsi_lock -+ && si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0)) -+ if (!IS_ERR(dentry)) { -+ dput(dentry); -+ dentry = ERR_PTR(-ESTALE); -+ } -+ AuTraceErrPtr(dentry); -+ return dentry; -+} -+ -+static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino, -+ ino_t dir_ino, -+ struct au_nfsd_si_lock *nsi_lock) -+{ -+ struct dentry *dentry; -+ struct path path; -+ -+ if (dir_ino != AUFS_ROOT_INO) { -+ path.dentry = decode_by_ino(sb, dir_ino, 0); -+ dentry = path.dentry; -+ if (!path.dentry || IS_ERR(path.dentry)) -+ goto out; -+ AuDebugOn(au_test_anon(path.dentry)); -+ } else -+ path.dentry = dget(sb->s_root); -+ -+ path.mnt = au_mnt_get(sb); -+ dentry = au_lkup_by_ino(&path, ino, nsi_lock); -+ path_put(&path); -+ -+out: -+ AuTraceErrPtr(dentry); -+ return dentry; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int h_acceptable(void *expv, struct dentry *dentry) -+{ -+ return 1; -+} -+ -+static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath, -+ char *buf, int len, struct super_block *sb) -+{ -+ char *p; -+ int n; -+ struct path path; -+ -+ p = d_path(h_rootpath, buf, len); -+ if (IS_ERR(p)) -+ goto out; -+ n = strlen(p); -+ -+ path.mnt = h_rootpath->mnt; -+ path.dentry = h_parent; -+ p = d_path(&path, buf, len); -+ if (IS_ERR(p)) -+ goto out; -+ if (n != 1) -+ p += n; -+ -+ path.mnt = au_mnt_get(sb); -+ path.dentry = sb->s_root; -+ p = d_path(&path, buf, len - strlen(p)); -+ mntput(path.mnt); -+ if (IS_ERR(p)) -+ goto out; -+ if (n != 1) -+ p[strlen(p)] = '/'; -+ -+out: -+ AuTraceErrPtr(p); -+ return p; -+} -+ -+static -+struct dentry *decode_by_path(struct super_block *sb, ino_t ino, __u32 *fh, -+ int fh_len, struct au_nfsd_si_lock *nsi_lock) -+{ -+ struct dentry *dentry, *h_parent, *root; -+ struct super_block *h_sb; -+ char *pathname, *p; -+ struct vfsmount *h_mnt; -+ struct au_branch *br; -+ int err; -+ struct path path; -+ -+ br = au_sbr(sb, nsi_lock->bindex); -+ h_mnt = au_br_mnt(br); -+ h_sb = h_mnt->mnt_sb; -+ /* todo: call lower fh_to_dentry()? fh_to_parent()? */ -+ lockdep_off(); -+ h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail), -+ fh_len - Fh_tail, fh[Fh_h_type], -+ h_acceptable, /*context*/NULL); -+ lockdep_on(); -+ dentry = h_parent; -+ if (unlikely(!h_parent || IS_ERR(h_parent))) { -+ AuWarn1("%s decode_fh failed, %ld\n", -+ au_sbtype(h_sb), PTR_ERR(h_parent)); -+ goto out; -+ } -+ dentry = NULL; -+ if (unlikely(au_test_anon(h_parent))) { -+ AuWarn1("%s decode_fh returned a disconnected dentry\n", -+ au_sbtype(h_sb)); -+ goto out_h_parent; -+ } -+ -+ dentry = ERR_PTR(-ENOMEM); -+ pathname = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!pathname)) -+ goto out_h_parent; -+ -+ root = sb->s_root; -+ path.mnt = h_mnt; -+ di_read_lock_parent(root, !AuLock_IR); -+ path.dentry = au_h_dptr(root, nsi_lock->bindex); -+ di_read_unlock(root, !AuLock_IR); -+ p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb); -+ dentry = (void *)p; -+ if (IS_ERR(p)) -+ goto out_pathname; -+ -+ si_read_unlock(sb); -+ err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path); -+ dentry = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out_relock; -+ -+ dentry = ERR_PTR(-ENOENT); -+ AuDebugOn(au_test_anon(path.dentry)); -+ if (unlikely(d_really_is_negative(path.dentry))) -+ goto out_path; -+ -+ if (ino != d_inode(path.dentry)->i_ino) -+ dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL); -+ else -+ dentry = dget(path.dentry); -+ -+out_path: -+ path_put(&path); -+out_relock: -+ if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0)) -+ if (!IS_ERR(dentry)) { -+ dput(dentry); -+ dentry = ERR_PTR(-ESTALE); -+ } -+out_pathname: -+ free_page((unsigned long)pathname); -+out_h_parent: -+ dput(h_parent); -+out: -+ AuTraceErrPtr(dentry); -+ return dentry; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static struct dentry * -+aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len, -+ int fh_type) -+{ -+ struct dentry *dentry; -+ __u32 *fh = fid->raw; -+ struct au_branch *br; -+ ino_t ino, dir_ino; -+ struct au_nfsd_si_lock nsi_lock = { -+ .force_lock = 0 -+ }; -+ -+ dentry = ERR_PTR(-ESTALE); -+ /* it should never happen, but the file handle is unreliable */ -+ if (unlikely(fh_len < Fh_tail)) -+ goto out; -+ nsi_lock.sigen = fh[Fh_sigen]; -+ nsi_lock.br_id = fh[Fh_br_id]; -+ -+ /* branch id may be wrapped around */ -+ br = NULL; -+ if (unlikely(si_nfsd_read_lock(sb, &nsi_lock))) -+ goto out; -+ nsi_lock.force_lock = 1; -+ -+ /* is this inode still cached? */ -+ ino = decode_ino(fh + Fh_ino); -+ /* it should never happen */ -+ if (unlikely(ino == AUFS_ROOT_INO)) -+ goto out_unlock; -+ -+ dir_ino = decode_ino(fh + Fh_dir_ino); -+ dentry = decode_by_ino(sb, ino, dir_ino); -+ if (IS_ERR(dentry)) -+ goto out_unlock; -+ if (dentry) -+ goto accept; -+ -+ /* is the parent dir cached? */ -+ br = au_sbr(sb, nsi_lock.bindex); -+ au_lcnt_inc(&br->br_nfiles); -+ dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock); -+ if (IS_ERR(dentry)) -+ goto out_unlock; -+ if (dentry) -+ goto accept; -+ -+ /* lookup path */ -+ dentry = decode_by_path(sb, ino, fh, fh_len, &nsi_lock); -+ if (IS_ERR(dentry)) -+ goto out_unlock; -+ if (unlikely(!dentry)) -+ /* todo?: make it ESTALE */ -+ goto out_unlock; -+ -+accept: -+ if (!au_digen_test(dentry, au_sigen(sb)) -+ && d_inode(dentry)->i_generation == fh[Fh_igen]) -+ goto out_unlock; /* success */ -+ -+ dput(dentry); -+ dentry = ERR_PTR(-ESTALE); -+out_unlock: -+ if (br) -+ au_lcnt_dec(&br->br_nfiles); -+ si_read_unlock(sb); -+out: -+ AuTraceErrPtr(dentry); -+ return dentry; -+} -+ -+#if 0 /* reserved for future use */ -+/* support subtreecheck option */ -+static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid, -+ int fh_len, int fh_type) -+{ -+ struct dentry *parent; -+ __u32 *fh = fid->raw; -+ ino_t dir_ino; -+ -+ dir_ino = decode_ino(fh + Fh_dir_ino); -+ parent = decode_by_ino(sb, dir_ino, 0); -+ if (IS_ERR(parent)) -+ goto out; -+ if (!parent) -+ parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]), -+ dir_ino, fh, fh_len); -+ -+out: -+ AuTraceErrPtr(parent); -+ return parent; -+} -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int aufs_encode_fh(struct inode *inode, __u32 *fh, int *max_len, -+ struct inode *dir) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ struct super_block *sb, *h_sb; -+ struct dentry *dentry, *parent, *h_parent; -+ struct inode *h_dir; -+ struct au_branch *br; -+ -+ err = -ENOSPC; -+ if (unlikely(*max_len <= Fh_tail)) { -+ AuWarn1("NFSv2 client (max_len %d)?\n", *max_len); -+ goto out; -+ } -+ -+ err = FILEID_ROOT; -+ if (inode->i_ino == AUFS_ROOT_INO) { -+ AuDebugOn(inode->i_ino != AUFS_ROOT_INO); -+ goto out; -+ } -+ -+ h_parent = NULL; -+ sb = inode->i_sb; -+ err = si_read_lock(sb, AuLock_FLUSH); -+ if (unlikely(err)) -+ goto out; -+ -+#ifdef CONFIG_AUFS_DEBUG -+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO))) -+ AuWarn1("NFS-exporting requires xino\n"); -+#endif -+ err = -EIO; -+ parent = NULL; -+ ii_read_lock_child(inode); -+ bindex = au_ibtop(inode); -+ if (!dir) { -+ dentry = d_find_any_alias(inode); -+ if (unlikely(!dentry)) -+ goto out_unlock; -+ AuDebugOn(au_test_anon(dentry)); -+ parent = dget_parent(dentry); -+ dput(dentry); -+ if (unlikely(!parent)) -+ goto out_unlock; -+ if (d_really_is_positive(parent)) -+ dir = d_inode(parent); -+ } -+ -+ ii_read_lock_parent(dir); -+ h_dir = au_h_iptr(dir, bindex); -+ ii_read_unlock(dir); -+ if (unlikely(!h_dir)) -+ goto out_parent; -+ h_parent = d_find_any_alias(h_dir); -+ if (unlikely(!h_parent)) -+ goto out_hparent; -+ -+ err = -EPERM; -+ br = au_sbr(sb, bindex); -+ h_sb = au_br_sb(br); -+ if (unlikely(!h_sb->s_export_op)) { -+ AuErr1("%s branch is not exportable\n", au_sbtype(h_sb)); -+ goto out_hparent; -+ } -+ -+ fh[Fh_br_id] = br->br_id; -+ fh[Fh_sigen] = au_sigen(sb); -+ encode_ino(fh + Fh_ino, inode->i_ino); -+ encode_ino(fh + Fh_dir_ino, dir->i_ino); -+ fh[Fh_igen] = inode->i_generation; -+ -+ *max_len -= Fh_tail; -+ fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail), -+ max_len, -+ /*connectable or subtreecheck*/0); -+ err = fh[Fh_h_type]; -+ *max_len += Fh_tail; -+ /* todo: macros? */ -+ if (err != FILEID_INVALID) -+ err = 99; -+ else -+ AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb)); -+ -+out_hparent: -+ dput(h_parent); -+out_parent: -+ dput(parent); -+out_unlock: -+ ii_read_unlock(inode); -+ si_read_unlock(sb); -+out: -+ if (unlikely(err < 0)) -+ err = FILEID_INVALID; -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int aufs_commit_metadata(struct inode *inode) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ struct super_block *sb; -+ struct inode *h_inode; -+ int (*f)(struct inode *inode); -+ -+ sb = inode->i_sb; -+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); -+ ii_write_lock_child(inode); -+ bindex = au_ibtop(inode); -+ AuDebugOn(bindex < 0); -+ h_inode = au_h_iptr(inode, bindex); -+ -+ f = h_inode->i_sb->s_export_op->commit_metadata; -+ if (f) -+ err = f(h_inode); -+ else -+ err = sync_inode_metadata(h_inode, /*wait*/1); -+ -+ au_cpup_attr_timesizes(inode); -+ ii_write_unlock(inode); -+ si_read_unlock(sb); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static struct export_operations aufs_export_op = { -+ .fh_to_dentry = aufs_fh_to_dentry, -+ /* .fh_to_parent = aufs_fh_to_parent, */ -+ .encode_fh = aufs_encode_fh, -+ .commit_metadata = aufs_commit_metadata -+}; -+ -+void au_export_init(struct super_block *sb) -+{ -+ struct au_sbinfo *sbinfo; -+ __u32 u; -+ -+ BUILD_BUG_ON_MSG(IS_BUILTIN(CONFIG_AUFS_FS) -+ && IS_MODULE(CONFIG_EXPORTFS), -+ AUFS_NAME ": unsupported configuration " -+ "CONFIG_EXPORTFS=m and CONFIG_AUFS_FS=y"); -+ -+ sb->s_export_op = &aufs_export_op; -+ sbinfo = au_sbi(sb); -+ sbinfo->si_xigen = NULL; -+ get_random_bytes(&u, sizeof(u)); -+ BUILD_BUG_ON(sizeof(u) != sizeof(int)); -+ atomic_set(&sbinfo->si_xigen_next, u); -+} -diff -Naur null/fs/aufs/fhsm.c linux-6.6.63/fs/aufs/fhsm.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/fhsm.c 2024-12-18 15:12:59.295519588 +0300 -@@ -0,0 +1,426 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2011-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * File-based Hierarchy Storage Management -+ */ -+ -+#include -+#include -+#include -+#include -+#include "aufs.h" -+ -+static aufs_bindex_t au_fhsm_bottom(struct super_block *sb) -+{ -+ struct au_sbinfo *sbinfo; -+ struct au_fhsm *fhsm; -+ -+ SiMustAnyLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ fhsm = &sbinfo->si_fhsm; -+ AuDebugOn(!fhsm); -+ return fhsm->fhsm_bottom; -+} -+ -+void au_fhsm_set_bottom(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ struct au_sbinfo *sbinfo; -+ struct au_fhsm *fhsm; -+ -+ SiMustWriteLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ fhsm = &sbinfo->si_fhsm; -+ AuDebugOn(!fhsm); -+ fhsm->fhsm_bottom = bindex; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_fhsm_test_jiffy(struct au_sbinfo *sbinfo, struct au_branch *br) -+{ -+ struct au_br_fhsm *bf; -+ -+ bf = br->br_fhsm; -+ MtxMustLock(&bf->bf_lock); -+ -+ return !bf->bf_readable -+ || time_after(jiffies, -+ bf->bf_jiffy + sbinfo->si_fhsm.fhsm_expire); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void au_fhsm_notify(struct super_block *sb, int val) -+{ -+ struct au_sbinfo *sbinfo; -+ struct au_fhsm *fhsm; -+ -+ SiMustAnyLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ fhsm = &sbinfo->si_fhsm; -+ if (au_fhsm_pid(fhsm) -+ && atomic_read(&fhsm->fhsm_readable) != -1) { -+ atomic_set(&fhsm->fhsm_readable, val); -+ if (val) -+ wake_up(&fhsm->fhsm_wqh); -+ } -+} -+ -+static int au_fhsm_stfs(struct super_block *sb, aufs_bindex_t bindex, -+ struct aufs_stfs *rstfs, int do_lock, int do_notify) -+{ -+ int err; -+ struct au_branch *br; -+ struct au_br_fhsm *bf; -+ -+ br = au_sbr(sb, bindex); -+ AuDebugOn(au_br_rdonly(br)); -+ bf = br->br_fhsm; -+ AuDebugOn(!bf); -+ -+ if (do_lock) -+ mutex_lock(&bf->bf_lock); -+ else -+ MtxMustLock(&bf->bf_lock); -+ -+ /* sb->s_root for NFS is unreliable */ -+ err = au_br_stfs(br, &bf->bf_stfs); -+ if (unlikely(err)) { -+ AuErr1("FHSM failed (%d), b%d, ignored.\n", bindex, err); -+ goto out; -+ } -+ -+ bf->bf_jiffy = jiffies; -+ bf->bf_readable = 1; -+ if (do_notify) -+ au_fhsm_notify(sb, /*val*/1); -+ if (rstfs) -+ *rstfs = bf->bf_stfs; -+ -+out: -+ if (do_lock) -+ mutex_unlock(&bf->bf_lock); -+ au_fhsm_notify(sb, /*val*/1); -+ -+ return err; -+} -+ -+void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force) -+{ -+ int err; -+ struct au_sbinfo *sbinfo; -+ struct au_fhsm *fhsm; -+ struct au_branch *br; -+ struct au_br_fhsm *bf; -+ -+ AuDbg("b%d, force %d\n", bindex, force); -+ SiMustAnyLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ fhsm = &sbinfo->si_fhsm; -+ if (!au_ftest_si(sbinfo, FHSM) -+ || fhsm->fhsm_bottom == bindex) -+ return; -+ -+ br = au_sbr(sb, bindex); -+ bf = br->br_fhsm; -+ AuDebugOn(!bf); -+ mutex_lock(&bf->bf_lock); -+ if (force -+ || au_fhsm_pid(fhsm) -+ || au_fhsm_test_jiffy(sbinfo, br)) -+ err = au_fhsm_stfs(sb, bindex, /*rstfs*/NULL, /*do_lock*/0, -+ /*do_notify*/1); -+ mutex_unlock(&bf->bf_lock); -+} -+ -+void au_fhsm_wrote_all(struct super_block *sb, int force) -+{ -+ aufs_bindex_t bindex, bbot; -+ struct au_branch *br; -+ -+ /* exclude the bottom */ -+ bbot = au_fhsm_bottom(sb); -+ for (bindex = 0; bindex < bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (au_br_fhsm(br->br_perm)) -+ au_fhsm_wrote(sb, bindex, force); -+ } -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static __poll_t au_fhsm_poll(struct file *file, struct poll_table_struct *wait) -+{ -+ __poll_t mask; -+ struct au_sbinfo *sbinfo; -+ struct au_fhsm *fhsm; -+ -+ mask = 0; -+ sbinfo = file->private_data; -+ fhsm = &sbinfo->si_fhsm; -+ poll_wait(file, &fhsm->fhsm_wqh, wait); -+ if (atomic_read(&fhsm->fhsm_readable)) -+ mask = EPOLLIN /* | EPOLLRDNORM */; -+ -+ if (!mask) -+ AuDbg("mask 0x%x\n", mask); -+ return mask; -+} -+ -+static int au_fhsm_do_read_one(struct aufs_stbr __user *stbr, -+ struct aufs_stfs *stfs, __s16 brid) -+{ -+ int err; -+ -+ err = copy_to_user(&stbr->stfs, stfs, sizeof(*stfs)); -+ if (!err) -+ err = __put_user(brid, &stbr->brid); -+ if (unlikely(err)) -+ err = -EFAULT; -+ -+ return err; -+} -+ -+static ssize_t au_fhsm_do_read(struct super_block *sb, -+ struct aufs_stbr __user *stbr, size_t count) -+{ -+ ssize_t err; -+ int nstbr; -+ aufs_bindex_t bindex, bbot; -+ struct au_branch *br; -+ struct au_br_fhsm *bf; -+ -+ /* except the bottom branch */ -+ err = 0; -+ nstbr = 0; -+ bbot = au_fhsm_bottom(sb); -+ for (bindex = 0; !err && bindex < bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (!au_br_fhsm(br->br_perm)) -+ continue; -+ -+ bf = br->br_fhsm; -+ mutex_lock(&bf->bf_lock); -+ if (bf->bf_readable) { -+ err = -EFAULT; -+ if (count >= sizeof(*stbr)) -+ err = au_fhsm_do_read_one(stbr++, &bf->bf_stfs, -+ br->br_id); -+ if (!err) { -+ bf->bf_readable = 0; -+ count -= sizeof(*stbr); -+ nstbr++; -+ } -+ } -+ mutex_unlock(&bf->bf_lock); -+ } -+ if (!err) -+ err = sizeof(*stbr) * nstbr; -+ -+ return err; -+} -+ -+static ssize_t au_fhsm_read(struct file *file, char __user *buf, size_t count, -+ loff_t *pos) -+{ -+ ssize_t err; -+ int readable; -+ aufs_bindex_t nfhsm, bindex, bbot; -+ struct au_sbinfo *sbinfo; -+ struct au_fhsm *fhsm; -+ struct au_branch *br; -+ struct super_block *sb; -+ -+ err = 0; -+ sbinfo = file->private_data; -+ fhsm = &sbinfo->si_fhsm; -+need_data: -+ spin_lock_irq(&fhsm->fhsm_wqh.lock); -+ if (!atomic_read(&fhsm->fhsm_readable)) { -+ if (vfsub_file_flags(file) & O_NONBLOCK) -+ err = -EAGAIN; -+ else -+ err = wait_event_interruptible_locked_irq -+ (fhsm->fhsm_wqh, -+ atomic_read(&fhsm->fhsm_readable)); -+ } -+ spin_unlock_irq(&fhsm->fhsm_wqh.lock); -+ if (unlikely(err)) -+ goto out; -+ -+ /* sb may already be dead */ -+ au_rw_read_lock(&sbinfo->si_rwsem); -+ readable = atomic_read(&fhsm->fhsm_readable); -+ if (readable > 0) { -+ sb = sbinfo->si_sb; -+ AuDebugOn(!sb); -+ /* exclude the bottom branch */ -+ nfhsm = 0; -+ bbot = au_fhsm_bottom(sb); -+ for (bindex = 0; bindex < bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (au_br_fhsm(br->br_perm)) -+ nfhsm++; -+ } -+ err = -EMSGSIZE; -+ if (nfhsm * sizeof(struct aufs_stbr) <= count) { -+ atomic_set(&fhsm->fhsm_readable, 0); -+ err = au_fhsm_do_read(sbinfo->si_sb, (void __user *)buf, -+ count); -+ } -+ } -+ au_rw_read_unlock(&sbinfo->si_rwsem); -+ if (!readable) -+ goto need_data; -+ -+out: -+ return err; -+} -+ -+static int au_fhsm_release(struct inode *inode, struct file *file) -+{ -+ struct au_sbinfo *sbinfo; -+ struct au_fhsm *fhsm; -+ -+ /* sb may already be dead */ -+ sbinfo = file->private_data; -+ fhsm = &sbinfo->si_fhsm; -+ spin_lock(&fhsm->fhsm_spin); -+ fhsm->fhsm_pid = 0; -+ spin_unlock(&fhsm->fhsm_spin); -+ kobject_put(&sbinfo->si_kobj); -+ -+ return 0; -+} -+ -+static const struct file_operations au_fhsm_fops = { -+ .owner = THIS_MODULE, -+ .llseek = noop_llseek, -+ .read = au_fhsm_read, -+ .poll = au_fhsm_poll, -+ .release = au_fhsm_release -+}; -+ -+int au_fhsm_fd(struct super_block *sb, int oflags) -+{ -+ int err, fd; -+ struct au_sbinfo *sbinfo; -+ struct au_fhsm *fhsm; -+ -+ err = -EPERM; -+ if (unlikely(!capable(CAP_SYS_ADMIN))) -+ goto out; -+ -+ err = -EINVAL; -+ if (unlikely(oflags & ~(O_CLOEXEC | O_NONBLOCK))) -+ goto out; -+ -+ err = 0; -+ sbinfo = au_sbi(sb); -+ fhsm = &sbinfo->si_fhsm; -+ spin_lock(&fhsm->fhsm_spin); -+ if (!fhsm->fhsm_pid) -+ fhsm->fhsm_pid = current->pid; -+ else -+ err = -EBUSY; -+ spin_unlock(&fhsm->fhsm_spin); -+ if (unlikely(err)) -+ goto out; -+ -+ oflags |= O_RDONLY; -+ /* oflags |= FMODE_NONOTIFY; */ -+ fd = anon_inode_getfd("[aufs_fhsm]", &au_fhsm_fops, sbinfo, oflags); -+ err = fd; -+ if (unlikely(fd < 0)) -+ goto out_pid; -+ -+ /* succeed regardless 'fhsm' status */ -+ kobject_get(&sbinfo->si_kobj); -+ si_noflush_read_lock(sb); -+ if (au_ftest_si(sbinfo, FHSM)) -+ au_fhsm_wrote_all(sb, /*force*/0); -+ si_read_unlock(sb); -+ goto out; /* success */ -+ -+out_pid: -+ spin_lock(&fhsm->fhsm_spin); -+ fhsm->fhsm_pid = 0; -+ spin_unlock(&fhsm->fhsm_spin); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_fhsm_br_alloc(struct au_branch *br) -+{ -+ int err; -+ -+ err = 0; -+ br->br_fhsm = kmalloc(sizeof(*br->br_fhsm), GFP_NOFS); -+ if (br->br_fhsm) -+ au_br_fhsm_init(br->br_fhsm); -+ else -+ err = -ENOMEM; -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void au_fhsm_fin(struct super_block *sb) -+{ -+ au_fhsm_notify(sb, /*val*/-1); -+} -+ -+void au_fhsm_init(struct au_sbinfo *sbinfo) -+{ -+ struct au_fhsm *fhsm; -+ -+ fhsm = &sbinfo->si_fhsm; -+ spin_lock_init(&fhsm->fhsm_spin); -+ init_waitqueue_head(&fhsm->fhsm_wqh); -+ atomic_set(&fhsm->fhsm_readable, 0); -+ fhsm->fhsm_expire -+ = msecs_to_jiffies(AUFS_FHSM_CACHE_DEF_SEC * MSEC_PER_SEC); -+ fhsm->fhsm_bottom = -1; -+} -+ -+void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec) -+{ -+ sbinfo->si_fhsm.fhsm_expire -+ = msecs_to_jiffies(sec * MSEC_PER_SEC); -+} -+ -+void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo) -+{ -+ unsigned int u; -+ -+ if (!au_ftest_si(sbinfo, FHSM)) -+ return; -+ -+ u = jiffies_to_msecs(sbinfo->si_fhsm.fhsm_expire) / MSEC_PER_SEC; -+ if (u != AUFS_FHSM_CACHE_DEF_SEC) -+ seq_printf(seq, ",fhsm_sec=%u", u); -+} -diff -Naur null/fs/aufs/file.c linux-6.6.63/fs/aufs/file.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/file.c 2024-12-18 15:12:59.296519576 +0300 -@@ -0,0 +1,866 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * handling file/dir, and address_space operation -+ */ -+ -+#ifdef CONFIG_AUFS_DEBUG -+#include -+#endif -+#include -+#include "aufs.h" -+ -+/* drop flags for writing */ -+unsigned int au_file_roflags(unsigned int flags) -+{ -+ flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC); -+ flags |= O_RDONLY | O_NOATIME; -+ return flags; -+} -+ -+/* common functions to regular file and dir */ -+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags, -+ struct file *file, int force_wr) -+{ -+ struct file *h_file; -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ struct super_block *sb; -+ struct au_branch *br; -+ struct path h_path; -+ int err; -+ -+ /* 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 || 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)) -+ /* || !d_inode(dentry)->i_nlink */ -+ ; -+ spin_unlock(&h_dentry->d_lock); -+ if (unlikely(err)) -+ goto out; -+ -+ sb = dentry->d_sb; -+ br = au_sbr(sb, bindex); -+ 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, d_inode(dentry))) { -+ if (force_wr && !(flags & O_WRONLY)) -+ force_wr = 0; -+ flags = au_file_roflags(flags); -+ if (force_wr) { -+ h_file = ERR_PTR(-EROFS); -+ flags = au_file_roflags(flags); -+ if (unlikely(vfsub_native_ro(h_inode) -+ || IS_APPEND(h_inode))) -+ goto out; -+ flags &= ~O_ACCMODE; -+ flags |= O_WRONLY; -+ } -+ } -+ flags &= ~O_CREAT; -+ au_lcnt_inc(&br->br_nfiles); -+ h_path.dentry = h_dentry; -+ h_path.mnt = au_br_mnt(br); -+ /* -+ * vfs::backing_file_open() looks promising since it can get rid of -+ * mm::vm_prfile approach from my mind. -+ * but I keep current approach for a while. -+ */ -+ h_file = vfsub_dentry_open(&h_path, flags); -+ if (IS_ERR(h_file)) -+ goto out_br; -+ -+ if (flags & __FMODE_EXEC) { -+ err = deny_write_access(h_file); -+ if (unlikely(err)) { -+ fput(h_file); -+ h_file = ERR_PTR(err); -+ goto out_br; -+ } -+ } -+ fsnotify_open(h_file); -+ goto out; /* success */ -+ -+out_br: -+ au_lcnt_dec(&br->br_nfiles); -+out: -+ return h_file; -+} -+ -+static int au_cmoo(struct dentry *dentry) -+{ -+ int err, cmoo, matched; -+ unsigned int udba; -+ struct path h_path; -+ struct au_pin pin; -+ struct au_cp_generic cpg = { -+ .dentry = dentry, -+ .bdst = -1, -+ .bsrc = -1, -+ .len = -1, -+ .pin = &pin, -+ .flags = AuCpup_DTIME | AuCpup_HOPEN -+ }; -+ struct inode *delegated; -+ struct super_block *sb; -+ struct au_sbinfo *sbinfo; -+ struct au_fhsm *fhsm; -+ pid_t pid; -+ struct au_branch *br; -+ struct dentry *parent; -+ struct au_hinode *hdir; -+ -+ DiMustWriteLock(dentry); -+ IiMustWriteLock(d_inode(dentry)); -+ -+ err = 0; -+ if (IS_ROOT(dentry)) -+ goto out; -+ cpg.bsrc = au_dbtop(dentry); -+ if (!cpg.bsrc) -+ goto out; -+ -+ sb = dentry->d_sb; -+ sbinfo = au_sbi(sb); -+ fhsm = &sbinfo->si_fhsm; -+ pid = au_fhsm_pid(fhsm); -+ rcu_read_lock(); -+ matched = (pid -+ && (current->pid == pid -+ || rcu_dereference(current->real_parent)->pid == pid)); -+ rcu_read_unlock(); -+ if (matched) -+ goto out; -+ -+ br = au_sbr(sb, cpg.bsrc); -+ cmoo = au_br_cmoo(br->br_perm); -+ if (!cmoo) -+ goto out; -+ if (!d_is_reg(dentry)) -+ cmoo &= AuBrAttr_COO_ALL; -+ if (!cmoo) -+ goto out; -+ -+ parent = dget_parent(dentry); -+ di_write_lock_parent(parent); -+ err = au_wbr_do_copyup_bu(dentry, cpg.bsrc - 1); -+ cpg.bdst = err; -+ if (unlikely(err < 0)) { -+ err = 0; /* there is no upper writable branch */ -+ goto out_dgrade; -+ } -+ AuDbg("bsrc %d, bdst %d\n", cpg.bsrc, cpg.bdst); -+ -+ /* do not respect the coo attrib for the target branch */ -+ err = au_cpup_dirs(dentry, cpg.bdst); -+ if (unlikely(err)) -+ goto out_dgrade; -+ -+ di_downgrade_lock(parent, AuLock_IR); -+ udba = au_opt_udba(sb); -+ err = au_pin(&pin, dentry, cpg.bdst, udba, -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ if (unlikely(err)) -+ goto out_parent; -+ -+ err = au_sio_cpup_simple(&cpg); -+ au_unpin(&pin); -+ if (unlikely(err)) -+ goto out_parent; -+ if (!(cmoo & AuBrWAttr_MOO)) -+ goto out_parent; /* success */ -+ -+ err = au_pin(&pin, dentry, cpg.bsrc, udba, -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ if (unlikely(err)) -+ goto out_parent; -+ -+ h_path.mnt = au_br_mnt(br); -+ h_path.dentry = au_h_dptr(dentry, 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); -+ /* todo: keep h_dentry or not? */ -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal unlink\n"); -+ iput(delegated); -+ } -+ if (unlikely(err)) { -+ pr_err("unlink %pd after coo failed (%d), ignored\n", -+ dentry, err); -+ err = 0; -+ } -+ goto out_parent; /* success */ -+ -+out_dgrade: -+ di_downgrade_lock(parent, AuLock_IR); -+out_parent: -+ di_read_unlock(parent, AuLock_IR); -+ dput(parent); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_do_open(struct file *file, struct au_do_open_args *args) -+{ -+ int err, aopen = args->aopen; -+ struct dentry *dentry; -+ struct au_finfo *finfo; -+ -+ if (!aopen) -+ 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; -+ AuDebugOn(IS_ERR_OR_NULL(dentry)); -+ di_write_lock_child(dentry); -+ err = au_cmoo(dentry); -+ if (!err) { -+ if (!aopen) { -+ err = args->open(file, vfsub_file_flags(file), -+ au_di(dentry)->di_htmpfile); -+ di_write_unlock(dentry); -+ } else { -+ di_downgrade_lock(dentry, AuLock_IR); -+ lockdep_off(); -+ err = args->open(file, vfsub_file_flags(file), -+ args->h_file); -+ lockdep_on(); -+ di_read_unlock(dentry, AuLock_IR); -+ } -+ } -+ -+ finfo = au_fi(file); -+ if (!err) { -+ finfo->fi_file = file; -+ au_hbl_add(&finfo->fi_hlist, -+ &au_sbi(file->f_path.dentry->d_sb)->si_files); -+ } -+ if (!aopen) -+ fi_write_unlock(file); -+ else { -+ lockdep_off(); -+ fi_write_unlock(file); -+ lockdep_on(); -+ } -+ if (unlikely(err)) { -+ finfo->fi_hdir = NULL; -+ au_finfo_fin(file); -+ } -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_reopen_nondir(struct file *file) -+{ -+ int err; -+ aufs_bindex_t btop; -+ struct dentry *dentry; -+ struct au_branch *br; -+ struct file *h_file, *h_file_tmp; -+ -+ dentry = file->f_path.dentry; -+ btop = au_dbtop(dentry); -+ br = au_sbr(dentry->d_sb, btop); -+ h_file_tmp = NULL; -+ if (au_fbtop(file) == btop) { -+ h_file = au_hf_top(file); -+ if (file->f_mode == h_file->f_mode) -+ return 0; /* success */ -+ h_file_tmp = h_file; -+ get_file(h_file_tmp); -+ au_lcnt_inc(&br->br_nfiles); -+ au_set_h_fptr(file, btop, NULL); -+ } -+ AuDebugOn(au_fi(file)->fi_hdir); -+ /* -+ * it can happen -+ * file exists on both of rw and ro -+ * open --> dbtop and fbtop are both 0 -+ * prepend a branch as rw, "rw" become ro -+ * remove rw/file -+ * delete the top branch, "rw" becomes rw again -+ * --> dbtop is 1, fbtop is still 0 -+ * write --> fbtop is 0 but dbtop is 1 -+ */ -+ /* AuDebugOn(au_fbtop(file) < btop); */ -+ -+ h_file = au_h_open(dentry, btop, vfsub_file_flags(file) & ~O_TRUNC, -+ file, /*force_wr*/0); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) { -+ if (h_file_tmp) { -+ /* revert */ -+ au_set_h_fptr(file, btop, h_file_tmp); -+ h_file_tmp = NULL; -+ } -+ goto out; /* todo: close all? */ -+ } -+ -+ err = 0; -+ au_set_fbtop(file, btop); -+ au_set_h_fptr(file, btop, h_file); -+ au_update_figen(file); -+ file->f_mode |= h_file->f_mode & FMODE_CAN_ODIRECT; -+ /* todo: necessary? */ -+ /* file->f_ra = h_file->f_ra; */ -+ -+out: -+ if (h_file_tmp) { -+ fput(h_file_tmp); -+ au_lcnt_dec(&br->br_nfiles); -+ } -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_reopen_wh(struct file *file, aufs_bindex_t btgt, -+ struct dentry *hi_wh) -+{ -+ int err; -+ aufs_bindex_t btop; -+ struct au_dinfo *dinfo; -+ struct dentry *h_dentry; -+ struct au_hdentry *hdp; -+ -+ dinfo = au_di(file->f_path.dentry); -+ AuRwMustWriteLock(&dinfo->di_rwsem); -+ -+ btop = dinfo->di_btop; -+ dinfo->di_btop = btgt; -+ hdp = au_hdentry(dinfo, btgt); -+ h_dentry = hdp->hd_dentry; -+ hdp->hd_dentry = hi_wh; -+ err = au_reopen_nondir(file); -+ hdp->hd_dentry = h_dentry; -+ dinfo->di_btop = btop; -+ -+ return err; -+} -+ -+static int au_ready_to_write_wh(struct file *file, loff_t len, -+ aufs_bindex_t bcpup, struct au_pin *pin) -+{ -+ int err; -+ struct inode *inode, *h_inode; -+ struct dentry *h_dentry, *hi_wh; -+ struct au_cp_generic cpg = { -+ .dentry = file->f_path.dentry, -+ .bdst = bcpup, -+ .bsrc = -1, -+ .len = len, -+ .pin = pin -+ }; -+ -+ au_update_dbtop(cpg.dentry); -+ inode = d_inode(cpg.dentry); -+ h_inode = NULL; -+ if (au_dbtop(cpg.dentry) <= bcpup -+ && au_dbbot(cpg.dentry) >= bcpup) { -+ h_dentry = au_h_dptr(cpg.dentry, bcpup); -+ 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) -+ err = au_sio_cpup_wh(&cpg, file); -+ else -+ /* already copied-up after unlink */ -+ err = au_reopen_wh(file, bcpup, hi_wh); -+ -+ if (!err -+ && (vfsub_inode_nlink(inode, AU_I_AUFS) > 1 -+ || (inode->i_state & I_LINKABLE)) -+ && au_opt_test(au_mntflags(cpg.dentry->d_sb), PLINK)) -+ au_plink_append(inode, bcpup, au_h_dptr(cpg.dentry, bcpup)); -+ -+ return err; -+} -+ -+/* -+ * prepare the @file for writing. -+ */ -+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin) -+{ -+ int err; -+ aufs_bindex_t dbtop; -+ struct dentry *parent; -+ struct inode *inode; -+ struct super_block *sb; -+ struct file *h_file; -+ struct au_cp_generic cpg = { -+ .dentry = file->f_path.dentry, -+ .bdst = -1, -+ .bsrc = -1, -+ .len = len, -+ .pin = pin, -+ .flags = AuCpup_DTIME -+ }; -+ -+ sb = cpg.dentry->d_sb; -+ inode = d_inode(cpg.dentry); -+ cpg.bsrc = au_fbtop(file); -+ err = au_test_ro(sb, cpg.bsrc, inode); -+ if (!err && (au_hf_top(file)->f_mode & FMODE_WRITE)) { -+ err = au_pin(pin, cpg.dentry, cpg.bsrc, AuOpt_UDBA_NONE, -+ /*flags*/0); -+ goto out; -+ } -+ -+ /* need to cpup or reopen */ -+ parent = dget_parent(cpg.dentry); -+ di_write_lock_parent(parent); -+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry); -+ cpg.bdst = err; -+ if (unlikely(err < 0)) -+ goto out_dgrade; -+ err = 0; -+ -+ if (!d_unhashed(cpg.dentry) && !au_h_dptr(parent, cpg.bdst)) { -+ err = au_cpup_dirs(cpg.dentry, cpg.bdst); -+ if (unlikely(err)) -+ goto out_dgrade; -+ } -+ -+ err = au_pin(pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE, -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ if (unlikely(err)) -+ goto out_dgrade; -+ -+ dbtop = au_dbtop(cpg.dentry); -+ if (dbtop <= cpg.bdst) -+ cpg.bsrc = cpg.bdst; -+ -+ if (dbtop <= cpg.bdst /* just reopen */ -+ || !d_unhashed(cpg.dentry) /* copyup and reopen */ -+ ) { -+ h_file = au_h_open_pre(cpg.dentry, cpg.bsrc, /*force_wr*/0); -+ if (IS_ERR(h_file)) -+ err = PTR_ERR(h_file); -+ else { -+ di_downgrade_lock(parent, AuLock_IR); -+ if (dbtop > cpg.bdst) -+ err = au_sio_cpup_simple(&cpg); -+ if (!err) -+ err = au_reopen_nondir(file); -+ au_h_open_post(cpg.dentry, cpg.bsrc, h_file); -+ } -+ } else { /* copyup as wh and reopen */ -+ /* -+ * since writable hfsplus branch is not supported, -+ * h_open_pre/post() are unnecessary. -+ */ -+ err = au_ready_to_write_wh(file, len, cpg.bdst, pin); -+ di_downgrade_lock(parent, AuLock_IR); -+ } -+ -+ if (!err) { -+ au_pin_set_parent_lflag(pin, /*lflag*/0); -+ goto out_dput; /* success */ -+ } -+ au_unpin(pin); -+ goto out_unlock; -+ -+out_dgrade: -+ di_downgrade_lock(parent, AuLock_IR); -+out_unlock: -+ di_read_unlock(parent, AuLock_IR); -+out_dput: -+ dput(parent); -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_do_flush(struct file *file, fl_owner_t id, -+ int (*flush)(struct file *file, fl_owner_t id)) -+{ -+ int err; -+ struct super_block *sb; -+ struct inode *inode; -+ -+ inode = file_inode(file); -+ sb = inode->i_sb; -+ si_noflush_read_lock(sb); -+ fi_read_lock(file); -+ ii_read_lock_child(inode); -+ -+ err = flush(file, id); -+ au_cpup_attr_timesizes(inode); -+ -+ ii_read_unlock(inode); -+ fi_read_unlock(file); -+ si_read_unlock(sb); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_file_refresh_by_inode(struct file *file, int *need_reopen) -+{ -+ int err; -+ struct au_pin pin; -+ struct au_finfo *finfo; -+ struct dentry *parent, *hi_wh; -+ struct inode *inode; -+ struct super_block *sb; -+ struct au_cp_generic cpg = { -+ .dentry = file->f_path.dentry, -+ .bdst = -1, -+ .bsrc = -1, -+ .len = -1, -+ .pin = &pin, -+ .flags = AuCpup_DTIME -+ }; -+ -+ FiMustWriteLock(file); -+ -+ err = 0; -+ finfo = au_fi(file); -+ sb = cpg.dentry->d_sb; -+ inode = d_inode(cpg.dentry); -+ cpg.bdst = au_ibtop(inode); -+ if (cpg.bdst == finfo->fi_btop || IS_ROOT(cpg.dentry)) -+ goto out; -+ -+ parent = dget_parent(cpg.dentry); -+ if (au_test_ro(sb, cpg.bdst, inode)) { -+ di_read_lock_parent(parent, !AuLock_IR); -+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry); -+ cpg.bdst = err; -+ di_read_unlock(parent, !AuLock_IR); -+ if (unlikely(err < 0)) -+ goto out_parent; -+ err = 0; -+ } -+ -+ di_read_lock_parent(parent, AuLock_IR); -+ hi_wh = au_hi_wh(inode, cpg.bdst); -+ if (!S_ISDIR(inode->i_mode) -+ && au_opt_test(au_mntflags(sb), PLINK) -+ && au_plink_test(inode) -+ && !d_unhashed(cpg.dentry) -+ && cpg.bdst < au_dbtop(cpg.dentry)) { -+ err = au_test_and_cpup_dirs(cpg.dentry, cpg.bdst); -+ if (unlikely(err)) -+ goto out_unlock; -+ -+ /* always superio. */ -+ err = au_pin(&pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE, -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ if (!err) { -+ err = au_sio_cpup_simple(&cpg); -+ au_unpin(&pin); -+ } -+ } else if (hi_wh) { -+ /* already copied-up after unlink */ -+ err = au_reopen_wh(file, cpg.bdst, hi_wh); -+ *need_reopen = 0; -+ } -+ -+out_unlock: -+ di_read_unlock(parent, AuLock_IR); -+out_parent: -+ dput(parent); -+out: -+ return err; -+} -+ -+static void au_do_refresh_dir(struct file *file) -+{ -+ aufs_bindex_t bindex, bbot, new_bindex, brid; -+ struct au_hfile *p, tmp, *q; -+ struct au_finfo *finfo; -+ struct super_block *sb; -+ struct au_fidir *fidir; -+ -+ FiMustWriteLock(file); -+ -+ sb = file->f_path.dentry->d_sb; -+ finfo = au_fi(file); -+ fidir = finfo->fi_hdir; -+ AuDebugOn(!fidir); -+ p = fidir->fd_hfile + finfo->fi_btop; -+ brid = p->hf_br->br_id; -+ bbot = fidir->fd_bbot; -+ for (bindex = finfo->fi_btop; bindex <= bbot; bindex++, p++) { -+ if (!p->hf_file) -+ continue; -+ -+ new_bindex = au_br_index(sb, p->hf_br->br_id); -+ if (new_bindex == bindex) -+ continue; -+ if (new_bindex < 0) { -+ au_set_h_fptr(file, bindex, NULL); -+ continue; -+ } -+ -+ /* swap two lower inode, and loop again */ -+ q = fidir->fd_hfile + new_bindex; -+ tmp = *q; -+ *q = *p; -+ *p = tmp; -+ if (tmp.hf_file) { -+ bindex--; -+ p--; -+ } -+ } -+ -+ p = fidir->fd_hfile; -+ if (!au_test_mmapped(file) && !d_unlinked(file->f_path.dentry)) { -+ bbot = au_sbbot(sb); -+ for (finfo->fi_btop = 0; finfo->fi_btop <= bbot; -+ finfo->fi_btop++, p++) -+ if (p->hf_file) { -+ if (file_inode(p->hf_file)) -+ break; -+ au_hfput(p, /*execed*/0); -+ } -+ } else { -+ bbot = au_br_index(sb, brid); -+ for (finfo->fi_btop = 0; finfo->fi_btop < bbot; -+ finfo->fi_btop++, p++) -+ if (p->hf_file) -+ au_hfput(p, /*execed*/0); -+ bbot = au_sbbot(sb); -+ } -+ -+ p = fidir->fd_hfile + bbot; -+ for (fidir->fd_bbot = bbot; fidir->fd_bbot >= finfo->fi_btop; -+ fidir->fd_bbot--, p--) -+ if (p->hf_file) { -+ if (file_inode(p->hf_file)) -+ break; -+ au_hfput(p, /*execed*/0); -+ } -+ AuDebugOn(fidir->fd_bbot < finfo->fi_btop); -+} -+ -+/* -+ * after branch manipulating, refresh the file. -+ */ -+static int refresh_file(struct file *file, int (*reopen)(struct file *file)) -+{ -+ int err, need_reopen, nbr; -+ aufs_bindex_t bbot, bindex; -+ struct dentry *dentry; -+ struct super_block *sb; -+ struct au_finfo *finfo; -+ struct au_hfile *hfile; -+ -+ dentry = file->f_path.dentry; -+ sb = dentry->d_sb; -+ nbr = au_sbbot(sb) + 1; -+ finfo = au_fi(file); -+ if (!finfo->fi_hdir) { -+ hfile = &finfo->fi_htop; -+ AuDebugOn(!hfile->hf_file); -+ bindex = au_br_index(sb, hfile->hf_br->br_id); -+ AuDebugOn(bindex < 0); -+ if (bindex != finfo->fi_btop) -+ au_set_fbtop(file, bindex); -+ } else { -+ err = au_fidir_realloc(finfo, nbr, /*may_shrink*/0); -+ if (unlikely(err)) -+ goto out; -+ au_do_refresh_dir(file); -+ } -+ -+ err = 0; -+ need_reopen = 1; -+ if (!au_test_mmapped(file)) -+ err = au_file_refresh_by_inode(file, &need_reopen); -+ if (finfo->fi_hdir) -+ /* harmless if err */ -+ au_fidir_realloc(finfo, nbr, /*may_shrink*/1); -+ if (!err && need_reopen && !d_unlinked(dentry)) -+ err = reopen(file); -+ if (!err) { -+ au_update_figen(file); -+ goto out; /* success */ -+ } -+ -+ /* error, close all lower files */ -+ if (finfo->fi_hdir) { -+ bbot = au_fbbot_dir(file); -+ for (bindex = au_fbtop(file); bindex <= bbot; bindex++) -+ au_set_h_fptr(file, bindex, NULL); -+ } -+ -+out: -+ return err; -+} -+ -+/* common function to regular file and dir */ -+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file), -+ int wlock, unsigned int fi_lsc) -+{ -+ int err; -+ unsigned int sigen, figen; -+ aufs_bindex_t btop; -+ unsigned char pseudo_link; -+ struct dentry *dentry; -+ struct inode *inode; -+ -+ err = 0; -+ dentry = file->f_path.dentry; -+ inode = d_inode(dentry); -+ sigen = au_sigen(dentry->d_sb); -+ fi_write_lock_nested(file, fi_lsc); -+ figen = au_figen(file); -+ if (!fi_lsc) -+ di_write_lock_child(dentry); -+ else -+ di_write_lock_child2(dentry); -+ btop = au_dbtop(dentry); -+ pseudo_link = (btop != au_ibtop(inode)); -+ if (sigen == figen && !pseudo_link && au_fbtop(file) == btop) { -+ if (!wlock) { -+ di_downgrade_lock(dentry, AuLock_IR); -+ fi_downgrade_lock(file); -+ } -+ goto out; /* success */ -+ } -+ -+ AuDbg("sigen %d, figen %d\n", sigen, figen); -+ if (au_digen_test(dentry, sigen)) { -+ err = au_reval_dpath(dentry, sigen); -+ AuDebugOn(!err && au_digen_test(dentry, sigen)); -+ } -+ -+ if (!err) -+ err = refresh_file(file, reopen); -+ if (!err) { -+ if (!wlock) { -+ di_downgrade_lock(dentry, AuLock_IR); -+ fi_downgrade_lock(file); -+ } -+ } else { -+ di_write_unlock(dentry); -+ fi_write_unlock(file); -+ } -+ -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* cf. aufs_nopage() */ -+/* for madvise(2) */ -+static int aufs_read_folio(struct file *file __maybe_unused, struct folio *folio) -+{ -+ folio_unlock(folio); -+ return 0; -+} -+ -+/* it will never be called, but necessary to support O_DIRECT */ -+static ssize_t aufs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) -+{ BUG(); return 0; } -+ -+/* they will never be called. */ -+#ifdef CONFIG_AUFS_DEBUG -+static int aufs_write_begin(struct file *file, struct address_space *mapping, -+ loff_t pos, unsigned len, -+ struct page **pagep, void **fsdata) -+{ AuUnsupport(); return 0; } -+static int aufs_write_end(struct file *file, struct address_space *mapping, -+ loff_t pos, unsigned len, unsigned copied, -+ struct page *page, void *fsdata) -+{ AuUnsupport(); return 0; } -+static int aufs_writepage(struct page *page, struct writeback_control *wbc) -+{ AuUnsupport(); return 0; } -+ -+static bool aufs_dirty_folio(struct address_space *mapping, struct folio *folio) -+{ AuUnsupport(); return true; } -+static void aufs_invalidate_folio(struct folio *folio, size_t offset, size_t len) -+{ AuUnsupport(); } -+static bool aufs_release_folio(struct folio *folio, gfp_t gfp) -+{ AuUnsupport(); return true; } -+#if 0 /* called by memory compaction regardless file */ -+static int aufs_migrate_folio(struct address_space *mapping, struct folio *dst, -+ struct folio *src, enum migrate_mode mode) -+{ AuUnsupport(); return 0; } -+#endif -+static int aufs_launder_folio(struct folio *folio) -+{ AuUnsupport(); return 0; } -+static bool aufs_is_partially_uptodate(struct folio *folio, size_t from, -+ size_t count) -+{ AuUnsupport(); return true; } -+static void aufs_is_dirty_writeback(struct folio *folio, bool *dirty, -+ bool *writeback) -+{ AuUnsupport(); } -+static int aufs_error_remove_page(struct address_space *mapping, -+ struct page *page) -+{ AuUnsupport(); return 0; } -+static int aufs_swap_activate(struct swap_info_struct *sis, struct file *file, -+ sector_t *span) -+{ AuUnsupport(); return 0; } -+static void aufs_swap_deactivate(struct file *file) -+{ AuUnsupport(); } -+static int aufs_swap_rw(struct kiocb *iocb, struct iov_iter *iter) -+{ AuUnsupport(); return 0; } -+#endif /* CONFIG_AUFS_DEBUG */ -+ -+const struct address_space_operations aufs_aop = { -+ .read_folio = aufs_read_folio, -+ .direct_IO = aufs_direct_IO, -+#ifdef CONFIG_AUFS_DEBUG -+ .writepage = aufs_writepage, -+ /* no writepages, because of writepage */ -+ .dirty_folio = aufs_dirty_folio, -+ /* no readpages, because of readpage */ -+ .write_begin = aufs_write_begin, -+ .write_end = aufs_write_end, -+ /* no bmap, no block device */ -+ .invalidate_folio = aufs_invalidate_folio, -+ .release_folio = aufs_release_folio, -+ /* is fallback_migrate_page ok? */ -+ /* .migrate_folio = aufs_migrate_folio, */ -+ .launder_folio = aufs_launder_folio, -+ .is_partially_uptodate = aufs_is_partially_uptodate, -+ .is_dirty_writeback = aufs_is_dirty_writeback, -+ .error_remove_page = aufs_error_remove_page, -+ .swap_activate = aufs_swap_activate, -+ .swap_deactivate = aufs_swap_deactivate, -+ .swap_rw = aufs_swap_rw -+#endif /* CONFIG_AUFS_DEBUG */ -+}; -diff -Naur null/fs/aufs/file.h linux-6.6.63/fs/aufs/file.h ---- /dev/null -+++ linux-6.6.63/fs/aufs/file.h 2024-12-18 15:12:59.296519576 +0300 -@@ -0,0 +1,342 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * file operations -+ */ -+ -+#ifndef __AUFS_FILE_H__ -+#define __AUFS_FILE_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+#include -+#include -+#include "rwsem.h" -+ -+struct au_branch; -+struct au_hfile { -+ struct file *hf_file; -+ struct au_branch *hf_br; -+}; -+ -+struct au_vdir; -+struct au_fidir { -+ aufs_bindex_t fd_bbot; -+ aufs_bindex_t fd_nent; -+ struct au_vdir *fd_vdir_cache; -+ struct au_hfile fd_hfile[]; -+}; -+ -+static inline int au_fidir_sz(int nent) -+{ -+ AuDebugOn(nent < 0); -+ return sizeof(struct au_fidir) + sizeof(struct au_hfile) * nent; -+} -+ -+struct au_finfo { -+ atomic_t fi_generation; -+ -+ struct au_rwsem fi_rwsem; -+ aufs_bindex_t fi_btop; -+ -+ /* do not union them */ -+ struct { /* for non-dir */ -+ struct au_hfile fi_htop; -+ atomic_t fi_mmapped; -+ }; -+ struct au_fidir *fi_hdir; /* for dir only */ -+ -+ struct hlist_bl_node fi_hlist; -+ struct file *fi_file; /* very ugly */ -+ struct rcu_head rcu; -+} ____cacheline_aligned_in_smp; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* file.c */ -+extern const struct address_space_operations aufs_aop; -+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); -+struct au_do_open_args { -+ int aopen; -+ 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); -+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file), -+ int wlock, unsigned int fi_lsc); -+int au_do_flush(struct file *file, fl_owner_t id, -+ int (*flush)(struct file *file, fl_owner_t id)); -+ -+/* poll.c */ -+#ifdef CONFIG_AUFS_POLL -+__poll_t aufs_poll(struct file *file, struct poll_table_struct *pt); -+#endif -+ -+#ifdef CONFIG_AUFS_BR_HFSPLUS -+/* hfsplus.c */ -+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex, -+ int force_wr); -+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex, -+ struct file *h_file); -+#else -+AuStub(struct file *, au_h_open_pre, return NULL, struct dentry *dentry, -+ aufs_bindex_t bindex, int force_wr) -+AuStubVoid(au_h_open_post, struct dentry *dentry, aufs_bindex_t bindex, -+ struct file *h_file); -+#endif -+ -+/* f_op.c */ -+extern const struct file_operations aufs_file_fop; -+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, unsigned int lsc); -+ -+/* finfo.c */ -+void au_hfput(struct au_hfile *hf, int execed); -+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, -+ struct file *h_file); -+ -+void au_update_figen(struct file *file); -+struct au_fidir *au_fidir_alloc(struct super_block *sb); -+int au_fidir_realloc(struct au_finfo *finfo, int nbr, int may_shrink); -+ -+void au_fi_init_once(void *_fi); -+void au_finfo_fin(struct file *file); -+int au_finfo_init(struct file *file, struct au_fidir *fidir); -+ -+/* ioctl.c */ -+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg); -+#ifdef CONFIG_COMPAT -+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd, -+ unsigned long arg); -+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd, -+ unsigned long arg); -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline struct au_finfo *au_fi(struct file *file) -+{ -+ return file->private_data; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+#define fi_read_lock(f) au_rw_read_lock(&au_fi(f)->fi_rwsem) -+#define fi_write_lock(f) au_rw_write_lock(&au_fi(f)->fi_rwsem) -+#define fi_read_trylock(f) au_rw_read_trylock(&au_fi(f)->fi_rwsem) -+#define fi_write_trylock(f) au_rw_write_trylock(&au_fi(f)->fi_rwsem) -+/* -+#define fi_read_trylock_nested(f) \ -+ au_rw_read_trylock_nested(&au_fi(f)->fi_rwsem) -+#define fi_write_trylock_nested(f) \ -+ au_rw_write_trylock_nested(&au_fi(f)->fi_rwsem) -+*/ -+ -+#define fi_read_unlock(f) au_rw_read_unlock(&au_fi(f)->fi_rwsem) -+#define fi_write_unlock(f) au_rw_write_unlock(&au_fi(f)->fi_rwsem) -+#define fi_downgrade_lock(f) au_rw_dgrade_lock(&au_fi(f)->fi_rwsem) -+ -+/* lock subclass for finfo */ -+enum { -+ AuLsc_FI_1, -+ AuLsc_FI_2 -+}; -+ -+static inline void fi_read_lock_nested(struct file *f, unsigned int lsc) -+{ -+ au_rw_read_lock_nested(&au_fi(f)->fi_rwsem, lsc); -+} -+ -+static inline void fi_write_lock_nested(struct file *f, unsigned int lsc) -+{ -+ au_rw_write_lock_nested(&au_fi(f)->fi_rwsem, lsc); -+} -+ -+/* -+ * fi_read_lock_1, fi_write_lock_1, -+ * fi_read_lock_2, fi_write_lock_2 -+ */ -+#define AuReadLockFunc(name) \ -+static inline void fi_read_lock_##name(struct file *f) \ -+{ fi_read_lock_nested(f, AuLsc_FI_##name); } -+ -+#define AuWriteLockFunc(name) \ -+static inline void fi_write_lock_##name(struct file *f) \ -+{ fi_write_lock_nested(f, AuLsc_FI_##name); } -+ -+#define AuRWLockFuncs(name) \ -+ AuReadLockFunc(name) \ -+ AuWriteLockFunc(name) -+ -+AuRWLockFuncs(1); -+AuRWLockFuncs(2); -+ -+#undef AuReadLockFunc -+#undef AuWriteLockFunc -+#undef AuRWLockFuncs -+ -+#define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem) -+#define FiMustAnyLock(f) AuRwMustAnyLock(&au_fi(f)->fi_rwsem) -+#define FiMustWriteLock(f) AuRwMustWriteLock(&au_fi(f)->fi_rwsem) -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* todo: hard/soft set? */ -+static inline aufs_bindex_t au_fbtop(struct file *file) -+{ -+ FiMustAnyLock(file); -+ return au_fi(file)->fi_btop; -+} -+ -+static inline aufs_bindex_t au_fbbot_dir(struct file *file) -+{ -+ FiMustAnyLock(file); -+ AuDebugOn(!au_fi(file)->fi_hdir); -+ return au_fi(file)->fi_hdir->fd_bbot; -+} -+ -+static inline struct au_vdir *au_fvdir_cache(struct file *file) -+{ -+ FiMustAnyLock(file); -+ AuDebugOn(!au_fi(file)->fi_hdir); -+ return au_fi(file)->fi_hdir->fd_vdir_cache; -+} -+ -+static inline void au_set_fbtop(struct file *file, aufs_bindex_t bindex) -+{ -+ FiMustWriteLock(file); -+ au_fi(file)->fi_btop = bindex; -+} -+ -+static inline void au_set_fbbot_dir(struct file *file, aufs_bindex_t bindex) -+{ -+ FiMustWriteLock(file); -+ AuDebugOn(!au_fi(file)->fi_hdir); -+ au_fi(file)->fi_hdir->fd_bbot = bindex; -+} -+ -+static inline void au_set_fvdir_cache(struct file *file, -+ struct au_vdir *vdir_cache) -+{ -+ FiMustWriteLock(file); -+ AuDebugOn(!au_fi(file)->fi_hdir); -+ au_fi(file)->fi_hdir->fd_vdir_cache = vdir_cache; -+} -+ -+static inline struct file *au_hf_top(struct file *file) -+{ -+ FiMustAnyLock(file); -+ AuDebugOn(au_fi(file)->fi_hdir); -+ return au_fi(file)->fi_htop.hf_file; -+} -+ -+static inline struct file *au_hf_dir(struct file *file, aufs_bindex_t bindex) -+{ -+ FiMustAnyLock(file); -+ AuDebugOn(!au_fi(file)->fi_hdir); -+ return au_fi(file)->fi_hdir->fd_hfile[0 + bindex].hf_file; -+} -+ -+/* todo: memory barrier? */ -+static inline unsigned int au_figen(struct file *f) -+{ -+ return atomic_read(&au_fi(f)->fi_generation); -+} -+ -+static inline void au_set_mmapped(struct file *f) -+{ -+ if (atomic_inc_return(&au_fi(f)->fi_mmapped)) -+ return; -+ pr_warn("fi_mmapped wrapped around\n"); -+ while (!atomic_inc_return(&au_fi(f)->fi_mmapped)) -+ ; -+} -+ -+static inline void au_unset_mmapped(struct file *f) -+{ -+ atomic_dec(&au_fi(f)->fi_mmapped); -+} -+ -+static inline int au_test_mmapped(struct file *f) -+{ -+ return atomic_read(&au_fi(f)->fi_mmapped); -+} -+ -+/* customize vma->vm_file */ -+ -+static inline void au_do_vm_file_reset(struct vm_area_struct *vma, -+ struct file *file) -+{ -+ struct file *f; -+ -+ f = vma->vm_file; -+ get_file(file); -+ vma->vm_file = file; -+ fput(f); -+} -+ -+#ifdef CONFIG_MMU -+AuStubVoid(AuDbgVmRegion, struct file *file, struct vm_area_struct *vma) -+ -+static inline void au_vm_file_reset(struct vm_area_struct *vma, -+ struct file *file) -+{ -+ au_do_vm_file_reset(vma, file); -+} -+#else -+#define AuDbgVmRegion(file, vma) \ -+ AuDebugOn((vma)->vm_region && (vma)->vm_region->vm_file != (file)) -+ -+static inline void au_vm_file_reset(struct vm_area_struct *vma, -+ struct file *file) -+{ -+ struct file *f; -+ -+ au_do_vm_file_reset(vma, file); -+ f = vma->vm_region->vm_file; -+ get_file(file); -+ vma->vm_region->vm_file = file; -+ fput(f); -+} -+#endif /* CONFIG_MMU */ -+ -+/* handle vma->vm_prfile */ -+static inline void au_vm_prfile_set(struct vm_area_struct *vma, -+ struct file *file) -+{ -+ get_file(file); -+ vma->vm_prfile = file; -+#ifndef CONFIG_MMU -+ get_file(file); -+ vma->vm_region->vm_prfile = file; -+#endif -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_FILE_H__ */ -diff -Naur null/fs/aufs/finfo.c linux-6.6.63/fs/aufs/finfo.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/finfo.c 2024-12-18 15:12:59.296519576 +0300 -@@ -0,0 +1,149 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * file private data -+ */ -+ -+#include "aufs.h" -+ -+void au_hfput(struct au_hfile *hf, int execed) -+{ -+ if (execed) -+ allow_write_access(hf->hf_file); -+ fput(hf->hf_file); -+ hf->hf_file = NULL; -+ au_lcnt_dec(&hf->hf_br->br_nfiles); -+ hf->hf_br = NULL; -+} -+ -+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val) -+{ -+ struct au_finfo *finfo = au_fi(file); -+ struct au_hfile *hf; -+ struct au_fidir *fidir; -+ -+ fidir = finfo->fi_hdir; -+ if (!fidir) { -+ AuDebugOn(finfo->fi_btop != bindex); -+ hf = &finfo->fi_htop; -+ } else -+ hf = fidir->fd_hfile + bindex; -+ -+ if (hf && hf->hf_file) -+ au_hfput(hf, vfsub_file_execed(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); -+ } -+} -+ -+void au_update_figen(struct file *file) -+{ -+ atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_path.dentry)); -+ /* smp_mb(); */ /* atomic_set */ -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_fidir *au_fidir_alloc(struct super_block *sb) -+{ -+ struct au_fidir *fidir; -+ int nbr; -+ -+ nbr = au_sbbot(sb) + 1; -+ if (nbr < 2) -+ nbr = 2; /* initial allocate for 2 branches */ -+ fidir = kzalloc(au_fidir_sz(nbr), GFP_NOFS); -+ if (fidir) { -+ fidir->fd_bbot = -1; -+ fidir->fd_nent = nbr; -+ } -+ -+ return fidir; -+} -+ -+int au_fidir_realloc(struct au_finfo *finfo, int nbr, int may_shrink) -+{ -+ int err; -+ struct au_fidir *fidir, *p; -+ -+ AuRwMustWriteLock(&finfo->fi_rwsem); -+ fidir = finfo->fi_hdir; -+ AuDebugOn(!fidir); -+ -+ err = -ENOMEM; -+ p = au_kzrealloc(fidir, au_fidir_sz(fidir->fd_nent), au_fidir_sz(nbr), -+ GFP_NOFS, may_shrink); -+ if (p) { -+ p->fd_nent = nbr; -+ finfo->fi_hdir = p; -+ err = 0; -+ } -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void au_finfo_fin(struct file *file) -+{ -+ struct au_finfo *finfo; -+ -+ au_lcnt_dec(&au_sbi(file->f_path.dentry->d_sb)->si_nfiles); -+ -+ finfo = au_fi(file); -+ AuDebugOn(finfo->fi_hdir); -+ AuRwDestroy(&finfo->fi_rwsem); -+ au_cache_free_finfo(finfo); -+} -+ -+void au_fi_init_once(void *_finfo) -+{ -+ struct au_finfo *finfo = _finfo; -+ -+ au_rw_init(&finfo->fi_rwsem); -+} -+ -+int au_finfo_init(struct file *file, struct au_fidir *fidir) -+{ -+ int err; -+ struct au_finfo *finfo; -+ struct dentry *dentry; -+ -+ err = -ENOMEM; -+ dentry = file->f_path.dentry; -+ finfo = au_cache_alloc_finfo(); -+ if (unlikely(!finfo)) -+ goto out; -+ -+ err = 0; -+ au_lcnt_inc(&au_sbi(dentry->d_sb)->si_nfiles); -+ au_rw_write_lock(&finfo->fi_rwsem); -+ finfo->fi_btop = -1; -+ finfo->fi_hdir = fidir; -+ atomic_set(&finfo->fi_generation, au_digen(dentry)); -+ /* smp_mb(); */ /* atomic_set */ -+ -+ file->private_data = finfo; -+ -+out: -+ return err; -+} -diff -Naur null/fs/aufs/f_op.c linux-6.6.63/fs/aufs/f_op.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/f_op.c 2024-12-18 15:12:59.295519588 +0300 -@@ -0,0 +1,782 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * file and vm operations -+ */ -+ -+#include -+#include -+#include -+#include -+#include "aufs.h" -+ -+int au_do_open_nondir(struct file *file, int flags, struct file *h_file) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ struct dentry *dentry, *h_dentry; -+ struct au_finfo *finfo; -+ struct inode *h_inode; -+ -+ FiMustWriteLock(file); -+ -+ 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_dbtop(dentry); -+ if (!h_file) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ err = vfsub_test_mntns(file->f_path.mnt, h_dentry->d_sb); -+ if (unlikely(err)) -+ goto out; -+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0); -+ if (IS_ERR(h_file)) { -+ err = PTR_ERR(h_file); -+ goto out; -+ } -+ } else { -+ h_dentry = h_file->f_path.dentry; -+ err = vfsub_test_mntns(file->f_path.mnt, h_dentry->d_sb); -+ if (unlikely(err)) -+ goto out; -+ /* br ref is already inc-ed */ -+ } -+ -+ if (flags & __O_TMPFILE) { -+ AuDebugOn(!h_file); -+ AuDebugOn(h_file != au_di(dentry)->di_htmpfile); -+ au_di(dentry)->di_htmpfile = NULL; -+ -+ if (!(flags & O_EXCL)) { -+ h_inode = file_inode(h_file); -+ spin_lock(&h_inode->i_lock); -+ h_inode->i_state |= I_LINKABLE; -+ spin_unlock(&h_inode->i_lock); -+ } -+ } -+ au_set_fbtop(file, bindex); -+ au_set_h_fptr(file, bindex, h_file); -+ au_update_figen(file); -+ file->f_mode |= h_file->f_mode & FMODE_CAN_ODIRECT; -+ /* todo: necessary? */ -+ /* file->f_ra = h_file->f_ra; */ -+ -+out: -+ return err; -+} -+ -+static int aufs_open_nondir(struct inode *inode __maybe_unused, -+ struct file *file) -+{ -+ int err; -+ struct super_block *sb; -+ 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, &args); -+ si_read_unlock(sb); -+ return err; -+} -+ -+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file) -+{ -+ struct au_finfo *finfo; -+ aufs_bindex_t bindex; -+ -+ finfo = au_fi(file); -+ au_hbl_del(&finfo->fi_hlist, -+ &au_sbi(file->f_path.dentry->d_sb)->si_files); -+ bindex = finfo->fi_btop; -+ if (bindex >= 0) -+ au_set_h_fptr(file, bindex, NULL); -+ -+ au_finfo_fin(file); -+ return 0; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_do_flush_nondir(struct file *file, fl_owner_t id) -+{ -+ int err; -+ struct file *h_file; -+ -+ err = 0; -+ h_file = au_hf_top(file); -+ if (h_file) -+ err = vfsub_flush(h_file, id); -+ return err; -+} -+ -+static int aufs_flush_nondir(struct file *file, fl_owner_t id) -+{ -+ return au_do_flush(file, id, au_do_flush_nondir); -+} -+ -+/* ---------------------------------------------------------------------- */ -+/* -+ * read and write functions acquire [fdi]_rwsem once, but release before -+ * mmap_sem. This is because to stop a race condition between mmap(2). -+ * Releasing these aufs-rwsem should be safe, no branch-management (by keeping -+ * si_rwsem), no harmful copy-up should happen. Actually copy-up may happen in -+ * read functions after [fdi]_rwsem are released, but it should be harmless. -+ */ -+ -+/* Callers should call au_read_post() or fput() in the end */ -+struct file *au_read_pre(struct file *file, int keep_fi, unsigned int lsc) -+{ -+ struct file *h_file; -+ int err; -+ -+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0, lsc); -+ 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 { -+ /* input */ -+ unsigned int lsc; -+ -+ /* output */ -+ blkcnt_t blks; -+ aufs_bindex_t btop; -+}; -+ -+/* -+ * 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; -+ unsigned int lsc; -+ struct au_pin pin; -+ -+ lsc = 0; -+ if (wpre) -+ lsc = wpre->lsc; -+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1, lsc); -+ 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->btop = au_fbtop(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); -+ vfsub_file_start_write(h_file); -+ -+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; -+ -+ vfsub_file_end_write(h_file); -+ au_cpup_attr_timesizes(inode); -+ AuDebugOn(au_ibtop(inode) != wpre->btop); -+ h_inode = file_inode(h_file); -+ inode->i_mode = h_inode->i_mode; -+ ii_write_unlock(inode); -+ /* AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks); */ -+ if (written > 0) -+ au_fhsm_wrote(inode->i_sb, wpre->btop, -+ /*force*/h_inode->i_blocks > wpre->blks); -+ fput(h_file); -+} -+ -+/* -+ * todo: very ugly -+ * it locks both of i_mutex and si_rwsem for read in safe. -+ * if the plink maintenance mode continues forever (that is the problem), -+ * may loop forever. -+ */ -+static void au_mtx_and_read_lock(struct inode *inode) -+{ -+ int err; -+ struct super_block *sb = inode->i_sb; -+ -+ while (1) { -+ inode_lock(inode); -+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (!err) -+ break; -+ inode_unlock(inode); -+ si_read_lock(sb, AuLock_NOPLMW); -+ si_read_unlock(sb); -+ } -+} -+ -+static ssize_t au_do_iter(struct file *h_file, int rw, struct kiocb *kio, -+ struct iov_iter *iov_iter) -+{ -+ ssize_t err; -+ struct file *file; -+ ssize_t (*iter)(struct kiocb *, struct iov_iter *); -+ -+ err = security_file_permission(h_file, rw); -+ if (unlikely(err)) -+ goto out; -+ -+ err = -ENOSYS; /* the branch doesn't have its ->(read|write)_iter() */ -+ iter = NULL; -+ if (rw == MAY_READ) -+ iter = h_file->f_op->read_iter; -+ else if (rw == MAY_WRITE) -+ iter = h_file->f_op->write_iter; -+ -+ file = kio->ki_filp; -+ kio->ki_filp = h_file; -+ if (iter) { -+ lockdep_off(); -+ err = iter(kio, iov_iter); -+ lockdep_on(); -+ } else -+ /* currently there is no such fs */ -+ WARN_ON_ONCE(1); -+ if (!is_sync_kiocb(kio)) { -+ /* do not restore ki_filp */ -+ fput(file); -+ get_file(h_file); -+ } else -+ kio->ki_filp = file; -+ -+out: -+ return err; -+} -+ -+static ssize_t aufs_read_iter(struct kiocb *kio, struct iov_iter *iov_iter) -+{ -+ ssize_t err; -+ struct file *file, *h_file; -+ struct inode *inode; -+ struct super_block *sb; -+ -+ file = kio->ki_filp; -+ inode = file_inode(file); -+ sb = inode->i_sb; -+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); -+ -+ h_file = au_read_pre(file, /*keep_fi*/1, /*lsc*/0); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ if (au_test_loopback_kthread()) { -+ au_warn_loopback(h_file->f_path.dentry->d_sb); -+ if (file->f_mapping != h_file->f_mapping) { -+ file->f_mapping = h_file->f_mapping; -+ smp_mb(); /* unnecessary? */ -+ } -+ } -+ fi_read_unlock(file); -+ -+ err = au_do_iter(h_file, MAY_READ, kio, iov_iter); -+ /* todo: necessary? */ -+ /* file->f_ra = h_file->f_ra; */ -+ au_read_post(inode, h_file); -+ -+out: -+ si_read_unlock(sb); -+ return err; -+} -+ -+static ssize_t aufs_write_iter(struct kiocb *kio, struct iov_iter *iov_iter) -+{ -+ ssize_t err; -+ struct au_write_pre wpre; -+ struct inode *inode; -+ struct file *file, *h_file; -+ -+ file = kio->ki_filp; -+ inode = file_inode(file); -+ au_mtx_and_read_lock(inode); -+ -+ wpre.lsc = 0; -+ h_file = au_write_pre(file, /*do_ready*/1, &wpre); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ if (!is_sync_kiocb(kio)) { -+ /* .vs. sb_start_write() in aio_write() */ -+ if (S_ISREG(inode->i_mode)) -+ __sb_writers_acquired(inode->i_sb, SB_FREEZE_WRITE); -+ file_end_write(file); -+ } -+ err = au_do_iter(h_file, MAY_WRITE, kio, iov_iter); -+ au_write_post(inode, h_file, &wpre, err); -+ -+out: -+ si_read_unlock(inode->i_sb); -+ inode_unlock(inode); -+ return err; -+} -+ -+/* -+ * We may be able to remove aufs_splice_{read,write}() since almost all FSes -+ * don't have their own .splice_{read,write} implimentations, and they use -+ * generic_file_splice_read() and iter_file_splice_write() who can act like the -+ * simple converters to f_op->iter_read() and ->iter_write(). -+ * But we keep our own implementations because some non-mainlined FSes may have -+ * their own .splice_{read,write} implimentations and aufs doesn't want to take -+ * away an opportunity to co-work with aufs from them. -+ */ -+static ssize_t aufs_splice_read(struct file *file, loff_t *ppos, -+ struct pipe_inode_info *pipe, size_t len, -+ unsigned int flags) -+{ -+ ssize_t err; -+ struct file *h_file; -+ struct inode *inode; -+ struct super_block *sb; -+ -+ inode = file_inode(file); -+ sb = inode->i_sb; -+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); -+ -+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ err = vfsub_splice_read(h_file, ppos, pipe, len, flags); -+ /* todo: necessary? */ -+ /* file->f_ra = h_file->f_ra; */ -+ au_read_post(inode, h_file); -+ -+out: -+ si_read_unlock(sb); -+ return err; -+} -+ -+static ssize_t -+aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos, -+ size_t len, unsigned int flags) -+{ -+ ssize_t err; -+ struct au_write_pre wpre; -+ struct inode *inode; -+ struct file *h_file; -+ -+ inode = file_inode(file); -+ au_mtx_and_read_lock(inode); -+ -+ wpre.lsc = 0; -+ h_file = au_write_pre(file, /*do_ready*/1, &wpre); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ err = vfsub_splice_from(pipe, h_file, ppos, len, flags); -+ au_write_post(inode, h_file, &wpre, err); -+ -+out: -+ si_read_unlock(inode->i_sb); -+ inode_unlock(inode); -+ return err; -+} -+ -+static long aufs_fallocate(struct file *file, int mode, loff_t offset, -+ loff_t len) -+{ -+ long err; -+ struct au_write_pre wpre; -+ struct inode *inode; -+ struct file *h_file; -+ -+ inode = file_inode(file); -+ au_mtx_and_read_lock(inode); -+ -+ wpre.lsc = 0; -+ h_file = au_write_pre(file, /*do_ready*/1, &wpre); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ lockdep_off(); -+ err = vfs_fallocate(h_file, mode, offset, len); -+ lockdep_on(); -+ /* -+ * we don't need to call file_modifed() here since au_write_post() -+ * is equivalent and copies-up all timestamps and permission bits. -+ */ -+ au_write_post(inode, h_file, &wpre, /*written*/1); -+ -+out: -+ si_read_unlock(inode->i_sb); -+ inode_unlock(inode); -+ return err; -+} -+ -+static ssize_t aufs_copy_file_range(struct file *src, loff_t src_pos, -+ struct file *dst, loff_t dst_pos, -+ size_t len, unsigned int flags) -+{ -+ ssize_t err; -+ struct au_write_pre wpre; -+ enum { SRC, DST }; -+ struct { -+ struct inode *inode; -+ struct file *h_file; -+ struct super_block *h_sb; -+ } a[2]; -+#define a_src a[SRC] -+#define a_dst a[DST] -+ -+ err = -EINVAL; -+ a_src.inode = file_inode(src); -+ if (unlikely(!S_ISREG(a_src.inode->i_mode))) -+ goto out; -+ a_dst.inode = file_inode(dst); -+ if (unlikely(!S_ISREG(a_dst.inode->i_mode))) -+ goto out; -+ -+ au_mtx_and_read_lock(a_dst.inode); -+ /* -+ * in order to match the order in di_write_lock2_{child,parent}(), -+ * use f_path.dentry for this comparison. -+ */ -+ if (src->f_path.dentry < dst->f_path.dentry) { -+ a_src.h_file = au_read_pre(src, /*keep_fi*/1, AuLsc_FI_1); -+ err = PTR_ERR(a_src.h_file); -+ if (IS_ERR(a_src.h_file)) -+ goto out_si; -+ -+ wpre.lsc = AuLsc_FI_2; -+ a_dst.h_file = au_write_pre(dst, /*do_ready*/1, &wpre); -+ err = PTR_ERR(a_dst.h_file); -+ if (IS_ERR(a_dst.h_file)) { -+ au_read_post(a_src.inode, a_src.h_file); -+ goto out_si; -+ } -+ } else { -+ wpre.lsc = AuLsc_FI_1; -+ a_dst.h_file = au_write_pre(dst, /*do_ready*/1, &wpre); -+ err = PTR_ERR(a_dst.h_file); -+ if (IS_ERR(a_dst.h_file)) -+ goto out_si; -+ -+ a_src.h_file = au_read_pre(src, /*keep_fi*/1, AuLsc_FI_2); -+ err = PTR_ERR(a_src.h_file); -+ if (IS_ERR(a_src.h_file)) { -+ au_write_post(a_dst.inode, a_dst.h_file, &wpre, -+ /*written*/0); -+ goto out_si; -+ } -+ } -+ -+ err = -EXDEV; -+ a_src.h_sb = file_inode(a_src.h_file)->i_sb; -+ a_dst.h_sb = file_inode(a_dst.h_file)->i_sb; -+ if (unlikely(a_src.h_sb != a_dst.h_sb)) { -+ AuDbgFile(src); -+ AuDbgFile(dst); -+ goto out_file; -+ } -+ -+ err = vfsub_copy_file_range(a_src.h_file, src_pos, a_dst.h_file, -+ dst_pos, len, flags); -+ -+out_file: -+ au_write_post(a_dst.inode, a_dst.h_file, &wpre, err); -+ fi_read_unlock(src); -+ au_read_post(a_src.inode, a_src.h_file); -+out_si: -+ si_read_unlock(a_dst.inode->i_sb); -+ inode_unlock(a_dst.inode); -+out: -+ return err; -+#undef a_src -+#undef a_dst -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * The locking order around current->mmap_sem. -+ * - in most and regular cases -+ * file I/O syscall -- aufs_read() or something -+ * -- si_rwsem for read -- mmap_sem -+ * (Note that [fdi]i_rwsem are released before mmap_sem). -+ * - in mmap case -+ * mmap(2) -- mmap_sem -- aufs_mmap() -- si_rwsem for read -- [fdi]i_rwsem -+ * This AB-BA order is definitely bad, but is not a problem since "si_rwsem for -+ * read" allows multiple processes to acquire it and [fdi]i_rwsem are not held -+ * in file I/O. Aufs needs to stop lockdep in aufs_mmap() though. -+ * It means that when aufs acquires si_rwsem for write, the process should never -+ * acquire mmap_sem. -+ * -+ * Actually aufs_iterate() holds [fdi]i_rwsem before mmap_sem, but this is not a -+ * problem either since any directory is not able to be mmap-ed. -+ * The similar scenario is applied to aufs_readlink() too. -+ */ -+ -+#if 0 /* stop calling security_file_mmap() */ -+/* cf. linux/include/linux/mman.h: calc_vm_prot_bits() */ -+#define AuConv_VM_PROT(f, b) _calc_vm_trans(f, VM_##b, PROT_##b) -+ -+static unsigned long au_arch_prot_conv(unsigned long flags) -+{ -+ /* currently ppc64 only */ -+#ifdef CONFIG_PPC64 -+ /* cf. linux/arch/powerpc/include/asm/mman.h */ -+ AuDebugOn(arch_calc_vm_prot_bits(-1) != VM_SAO); -+ return AuConv_VM_PROT(flags, SAO); -+#else -+ AuDebugOn(arch_calc_vm_prot_bits(-1)); -+ return 0; -+#endif -+} -+ -+static unsigned long au_prot_conv(unsigned long flags) -+{ -+ return AuConv_VM_PROT(flags, READ) -+ | AuConv_VM_PROT(flags, WRITE) -+ | AuConv_VM_PROT(flags, EXEC) -+ | au_arch_prot_conv(flags); -+} -+ -+/* cf. linux/include/linux/mman.h: calc_vm_flag_bits() */ -+#define AuConv_VM_MAP(f, b) _calc_vm_trans(f, VM_##b, MAP_##b) -+ -+static unsigned long au_flag_conv(unsigned long flags) -+{ -+ return AuConv_VM_MAP(flags, GROWSDOWN) -+ | AuConv_VM_MAP(flags, DENYWRITE) -+ | AuConv_VM_MAP(flags, LOCKED); -+} -+#endif -+ -+static int aufs_mmap(struct file *file, struct vm_area_struct *vma) -+{ -+ int err; -+ const unsigned char wlock -+ = (file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED); -+ struct super_block *sb; -+ struct file *h_file; -+ struct inode *inode; -+ -+ AuDbgVmRegion(file, vma); -+ -+ inode = file_inode(file); -+ sb = inode->i_sb; -+ lockdep_off(); -+ si_read_lock(sb, AuLock_NOPLMW); -+ -+ h_file = au_write_pre(file, wlock, /*wpre*/NULL); -+ lockdep_on(); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ err = 0; -+ au_set_mmapped(file); -+ au_vm_file_reset(vma, h_file); -+ /* -+ * we cannot call security_mmap_file() here since it may acquire -+ * mmap_sem or i_mutex. -+ * -+ * err = security_mmap_file(h_file, au_prot_conv(vma->vm_flags), -+ * au_flag_conv(vma->vm_flags)); -+ */ -+ if (!err) -+ err = call_mmap(h_file, vma); -+ 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: -+ lockdep_off(); -+ ii_write_unlock(inode); -+ lockdep_on(); -+ fput(h_file); -+out: -+ lockdep_off(); -+ si_read_unlock(sb); -+ lockdep_on(); -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int aufs_fsync_nondir(struct file *file, loff_t start, loff_t end, -+ int datasync) -+{ -+ int err; -+ struct au_write_pre wpre; -+ struct inode *inode; -+ struct file *h_file; -+ -+ err = 0; /* -EBADF; */ /* posix? */ -+ if (unlikely(!(file->f_mode & FMODE_WRITE))) -+ goto out; -+ -+ inode = file_inode(file); -+ au_mtx_and_read_lock(inode); -+ -+ wpre.lsc = 0; -+ h_file = au_write_pre(file, /*do_ready*/1, &wpre); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out_unlock; -+ -+ err = vfsub_fsync(h_file, &h_file->f_path, datasync); -+ au_write_post(inode, h_file, &wpre, /*written*/0); -+ -+out_unlock: -+ si_read_unlock(inode->i_sb); -+ inode_unlock(inode); -+out: -+ return err; -+} -+ -+static int aufs_fasync(int fd, struct file *file, int flag) -+{ -+ int err; -+ struct file *h_file; -+ struct super_block *sb; -+ -+ sb = file->f_path.dentry->d_sb; -+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); -+ -+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ if (h_file->f_op->fasync) -+ err = h_file->f_op->fasync(fd, h_file, flag); -+ fput(h_file); /* instead of au_read_post() */ -+ -+out: -+ si_read_unlock(sb); -+ return err; -+} -+ -+static int aufs_setfl(struct file *file, unsigned long arg) -+{ -+ int err; -+ struct file *h_file; -+ struct super_block *sb; -+ -+ sb = file->f_path.dentry->d_sb; -+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); -+ -+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ /* stop calling h_file->fasync */ -+ arg |= vfsub_file_flags(file) & FASYNC; -+ err = setfl(/*unused fd*/-1, h_file, arg); -+ fput(h_file); /* instead of au_read_post() */ -+ -+out: -+ si_read_unlock(sb); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+const struct file_operations aufs_file_fop = { -+ .owner = THIS_MODULE, -+ -+ .llseek = default_llseek, -+ -+ .read_iter = aufs_read_iter, -+ .write_iter = aufs_write_iter, -+ -+#ifdef CONFIG_AUFS_POLL -+ .poll = aufs_poll, -+#endif -+ .unlocked_ioctl = aufs_ioctl_nondir, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = aufs_compat_ioctl_nondir, -+#endif -+ .mmap = aufs_mmap, -+ .open = aufs_open_nondir, -+ .flush = aufs_flush_nondir, -+ .release = aufs_release_nondir, -+ .fsync = aufs_fsync_nondir, -+ .fasync = aufs_fasync, -+ .setfl = aufs_setfl, -+ .splice_write = aufs_splice_write, -+ .splice_read = aufs_splice_read, -+#if 0 /* reserved for future use */ -+ .aio_splice_write = aufs_aio_splice_write, -+ .aio_splice_read = aufs_aio_splice_read, -+#endif -+ .fallocate = aufs_fallocate, -+ .copy_file_range = aufs_copy_file_range -+}; -diff -Naur null/fs/aufs/fsctx.c linux-6.6.63/fs/aufs/fsctx.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/fsctx.c 2024-12-18 15:12:59.296519576 +0300 -@@ -0,0 +1,1244 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * fs context, aka new mount api -+ */ -+ -+#include -+#include "aufs.h" -+ -+struct au_fsctx_opts { -+ aufs_bindex_t bindex; -+ unsigned char skipped; -+ struct au_opt *opt, *opt_tail; -+ struct super_block *sb; -+ struct au_sbinfo *sbinfo; -+ struct au_opts opts; -+}; -+ -+/* stop extra interpretation of errno in mount(8), and strange error messages */ -+static int cvt_err(int err) -+{ -+ AuTraceErr(err); -+ -+ switch (err) { -+ case -ENOENT: -+ case -ENOTDIR: -+ case -EEXIST: -+ case -EIO: -+ err = -EINVAL; -+ } -+ return err; -+} -+ -+static int au_fsctx_reconfigure(struct fs_context *fc) -+{ -+ int err, do_dx; -+ unsigned int mntflags; -+ struct dentry *root; -+ struct super_block *sb; -+ struct inode *inode; -+ struct au_fsctx_opts *a = fc->fs_private; -+ -+ AuDbg("fc %p\n", fc); -+ -+ root = fc->root; -+ sb = root->d_sb; -+ root = sb->s_root; /* "bind"-mount may give us non-root */ -+ AuDebugOn(!IS_ROOT(root)); -+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (!err) { -+ di_write_lock_child(root); -+ err = au_opts_verify(sb, fc->sb_flags, /*pending*/0); -+ aufs_write_unlock(root); -+ } -+ -+ inode = d_inode(root); -+ inode_lock(inode); -+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (unlikely(err)) -+ goto out; -+ di_write_lock_child(root); -+ -+ /* au_opts_remount() may return an error */ -+ err = au_opts_remount(sb, &a->opts); -+ -+ if (au_ftest_opts(a->opts.flags, REFRESH)) -+ au_remount_refresh(sb, au_ftest_opts(a->opts.flags, -+ REFRESH_IDOP)); -+ -+ if (au_ftest_opts(a->opts.flags, REFRESH_DYAOP)) { -+ mntflags = au_mntflags(sb); -+ do_dx = !!au_opt_test(mntflags, DIO); -+ au_dy_arefresh(do_dx); -+ } -+ -+ au_fhsm_wrote_all(sb, /*force*/1); /* ?? */ -+ aufs_write_unlock(root); -+ -+out: -+ inode_unlock(inode); -+ err = cvt_err(err); -+ AuTraceErr(err); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_fsctx_fill_super(struct super_block *sb, struct fs_context *fc) -+{ -+ int err; -+ struct au_fsctx_opts *a = fc->fs_private; -+ struct au_sbinfo *sbinfo = a->sbinfo; -+ struct dentry *root; -+ struct inode *inode; -+ -+ sbinfo->si_sb = sb; -+ sb->s_fs_info = sbinfo; -+ kobject_get(&sbinfo->si_kobj); -+ -+ __si_write_lock(sb); -+ si_pid_set(sb); -+ au_sbilist_add(sb); -+ -+ /* all timestamps always follow the ones on the branch */ -+ sb->s_flags |= SB_NOATIME | SB_NODIRATIME; -+ sb->s_flags |= SB_I_VERSION; /* do we really need this? */ -+ sb->s_op = &aufs_sop; -+ sb->s_d_op = &aufs_dop; -+ sb->s_magic = AUFS_SUPER_MAGIC; -+ sb->s_maxbytes = 0; -+ sb->s_stack_depth = 1; -+ au_export_init(sb); -+ au_xattr_init(sb); -+ -+ err = au_alloc_root(sb); -+ if (unlikely(err)) { -+ si_write_unlock(sb); -+ goto out; -+ } -+ root = sb->s_root; -+ inode = d_inode(root); -+ ii_write_lock_parent(inode); -+ aufs_write_unlock(root); -+ -+ /* lock vfs_inode first, then aufs. */ -+ inode_lock(inode); -+ aufs_write_lock(root); -+ err = au_opts_mount(sb, &a->opts); -+ AuTraceErr(err); -+ if (!err && au_ftest_si(sbinfo, NO_DREVAL)) { -+ sb->s_d_op = &aufs_dop_noreval; -+ /* infofc(fc, "%ps", sb->s_d_op); */ -+ pr_info("%ps\n", sb->s_d_op); -+ au_refresh_dop(root, /*force_reval*/0); -+ sbinfo->si_iop_array = aufs_iop_nogetattr; -+ au_refresh_iop(inode, /*force_getattr*/0); -+ } -+ aufs_write_unlock(root); -+ inode_unlock(inode); -+ if (!err) -+ goto out; /* success */ -+ -+ dput(root); -+ sb->s_root = NULL; -+ -+out: -+ if (unlikely(err)) -+ kobject_put(&sbinfo->si_kobj); -+ AuTraceErr(err); -+ err = cvt_err(err); -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_fsctx_get_tree(struct fs_context *fc) -+{ -+ int err; -+ -+ AuDbg("fc %p\n", fc); -+ err = get_tree_nodev(fc, au_fsctx_fill_super); -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void au_fsctx_dump(struct au_opts *opts) -+{ -+#ifdef CONFIG_AUFS_DEBUG -+ /* reduce stack space */ -+ union { -+ struct au_opt_add *add; -+ struct au_opt_del *del; -+ struct au_opt_mod *mod; -+ struct au_opt_xino *xino; -+ struct au_opt_xino_itrunc *xino_itrunc; -+ struct au_opt_wbr_create *create; -+ } u; -+ struct au_opt *opt; -+ -+ opt = opts->opt; -+ while (opt->type != Opt_tail) { -+ switch (opt->type) { -+ case Opt_add: -+ u.add = &opt->add; -+ AuDbg("add {b%d, %s, 0x%x, %p}\n", -+ u.add->bindex, u.add->pathname, u.add->perm, -+ u.add->path.dentry); -+ break; -+ case Opt_del: -+ fallthrough; -+ case Opt_idel: -+ u.del = &opt->del; -+ AuDbg("del {%s, %p}\n", -+ u.del->pathname, u.del->h_path.dentry); -+ break; -+ case Opt_mod: -+ fallthrough; -+ case Opt_imod: -+ u.mod = &opt->mod; -+ AuDbg("mod {%s, 0x%x, %p}\n", -+ u.mod->path, u.mod->perm, u.mod->h_root); -+ break; -+ case Opt_append: -+ u.add = &opt->add; -+ AuDbg("append {b%d, %s, 0x%x, %p}\n", -+ u.add->bindex, u.add->pathname, u.add->perm, -+ u.add->path.dentry); -+ break; -+ case Opt_prepend: -+ u.add = &opt->add; -+ AuDbg("prepend {b%d, %s, 0x%x, %p}\n", -+ u.add->bindex, u.add->pathname, u.add->perm, -+ u.add->path.dentry); -+ break; -+ -+ case Opt_dirwh: -+ AuDbg("dirwh %d\n", opt->dirwh); -+ break; -+ case Opt_rdcache: -+ AuDbg("rdcache %d\n", opt->rdcache); -+ break; -+ case Opt_rdblk: -+ AuDbg("rdblk %d\n", opt->rdblk); -+ break; -+ case Opt_rdhash: -+ AuDbg("rdhash %u\n", opt->rdhash); -+ break; -+ -+ case Opt_xino: -+ u.xino = &opt->xino; -+ AuDbg("xino {%s %pD}\n", u.xino->path, u.xino->file); -+ break; -+ -+#define au_fsctx_TF(name) \ -+ case Opt_##name: \ -+ if (opt->tf) \ -+ AuLabel(name); \ -+ else \ -+ AuLabel(no##name); \ -+ break; -+ -+ /* simple true/false flag */ -+ au_fsctx_TF(trunc_xino); -+ au_fsctx_TF(trunc_xib); -+ au_fsctx_TF(dirperm1); -+ au_fsctx_TF(plink); -+ au_fsctx_TF(shwh); -+ au_fsctx_TF(dio); -+ au_fsctx_TF(warn_perm); -+ au_fsctx_TF(verbose); -+ au_fsctx_TF(sum); -+ au_fsctx_TF(dirren); -+ au_fsctx_TF(acl); -+#undef au_fsctx_TF -+ -+ case Opt_trunc_xino_path: -+ fallthrough; -+ case Opt_itrunc_xino: -+ u.xino_itrunc = &opt->xino_itrunc; -+ AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex); -+ break; -+ case Opt_noxino: -+ AuLabel(noxino); -+ break; -+ -+ case Opt_list_plink: -+ AuLabel(list_plink); -+ break; -+ case Opt_udba: -+ AuDbg("udba %d, %s\n", -+ opt->udba, au_optstr_udba(opt->udba)); -+ break; -+ case Opt_diropq_a: -+ AuLabel(diropq_a); -+ break; -+ case Opt_diropq_w: -+ AuLabel(diropq_w); -+ break; -+ case Opt_wsum: -+ AuLabel(wsum); -+ break; -+ case Opt_wbr_create: -+ u.create = &opt->wbr_create; -+ AuDbg("create %d, %s\n", u.create->wbr_create, -+ au_optstr_wbr_create(u.create->wbr_create)); -+ switch (u.create->wbr_create) { -+ case AuWbrCreate_MFSV: -+ fallthrough; -+ case AuWbrCreate_PMFSV: -+ AuDbg("%d sec\n", u.create->mfs_second); -+ break; -+ case AuWbrCreate_MFSRR: -+ fallthrough; -+ case AuWbrCreate_TDMFS: -+ AuDbg("%llu watermark\n", -+ u.create->mfsrr_watermark); -+ break; -+ case AuWbrCreate_MFSRRV: -+ fallthrough; -+ case AuWbrCreate_TDMFSV: -+ fallthrough; -+ case AuWbrCreate_PMFSRRV: -+ AuDbg("%llu watermark, %d sec\n", -+ u.create->mfsrr_watermark, -+ u.create->mfs_second); -+ break; -+ } -+ break; -+ case Opt_wbr_copyup: -+ AuDbg("copyup %d, %s\n", opt->wbr_copyup, -+ au_optstr_wbr_copyup(opt->wbr_copyup)); -+ break; -+ case Opt_fhsm_sec: -+ AuDbg("fhsm_sec %u\n", opt->fhsm_second); -+ break; -+ -+ default: -+ AuDbg("type %d\n", opt->type); -+ BUG(); -+ } -+ opt++; -+ } -+#endif -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * For conditionally compiled mount options. -+ * Instead of fsparam_flag_no(), use this macro to distinguish ignore_silent. -+ */ -+#define au_ignore_flag(name, action) \ -+ fsparam_flag(name, action), \ -+ fsparam_flag("no" name, Opt_ignore_silent) -+ -+const struct fs_parameter_spec aufs_fsctx_paramspec[] = { -+ fsparam_string("br", Opt_br), -+ -+ /* "add=%d:%s" or "ins=%d:%s" */ -+ fsparam_string("add", Opt_add), -+ fsparam_string("ins", Opt_add), -+ fsparam_path("append", Opt_append), -+ fsparam_path("prepend", Opt_prepend), -+ -+ fsparam_path("del", Opt_del), -+ /* fsparam_s32("idel", Opt_idel), */ -+ fsparam_path("mod", Opt_mod), -+ /* fsparam_string("imod", Opt_imod), */ -+ -+ fsparam_s32("dirwh", Opt_dirwh), -+ -+ fsparam_path("xino", Opt_xino), -+ fsparam_flag("noxino", Opt_noxino), -+ fsparam_flag_no("trunc_xino", Opt_trunc_xino), -+ /* "trunc_xino_v=%d:%d" */ -+ /* fsparam_string("trunc_xino_v", Opt_trunc_xino_v), */ -+ fsparam_path("trunc_xino", Opt_trunc_xino_path), -+ fsparam_s32("itrunc_xino", Opt_itrunc_xino), -+ /* fsparam_path("zxino", Opt_zxino), */ -+ fsparam_flag_no("trunc_xib", Opt_trunc_xib), -+ -+#ifdef CONFIG_PROC_FS -+ fsparam_flag_no("plink", Opt_plink), -+#else -+ au_ignore_flag("plink", Opt_ignore), -+#endif -+ -+#ifdef CONFIG_AUFS_DEBUG -+ fsparam_flag("list_plink", Opt_list_plink), -+#endif -+ -+ fsparam_string("udba", Opt_udba), -+ -+ fsparam_flag_no("dio", Opt_dio), -+ -+#ifdef CONFIG_AUFS_DIRREN -+ fsparam_flag_no("dirren", Opt_dirren), -+#else -+ au_ignore_flag("dirren", Opt_ignore), -+#endif -+ -+#ifdef CONFIG_AUFS_FHSM -+ fsparam_s32("fhsm_sec", Opt_fhsm_sec), -+#else -+ fsparam_s32("fhsm_sec", Opt_ignore), -+#endif -+ -+ /* always | a | whiteouted | w */ -+ fsparam_string("diropq", Opt_diropq), -+ -+ fsparam_flag_no("warn_perm", Opt_warn_perm), -+ -+#ifdef CONFIG_AUFS_SHWH -+ fsparam_flag_no("shwh", Opt_shwh), -+#else -+ au_ignore_flag("shwh", Opt_err), -+#endif -+ -+ fsparam_flag_no("dirperm1", Opt_dirperm1), -+ -+ fsparam_flag_no("verbose", Opt_verbose), -+ fsparam_flag("v", Opt_verbose), -+ fsparam_flag("quiet", Opt_noverbose), -+ fsparam_flag("q", Opt_noverbose), -+ /* user-space may handle this */ -+ fsparam_flag("silent", Opt_noverbose), -+ -+ fsparam_flag_no("sum", Opt_sum), -+ fsparam_flag("wsum", Opt_wsum), -+ -+ fsparam_s32("rdcache", Opt_rdcache), -+ /* "def" or s32 */ -+ fsparam_string("rdblk", Opt_rdblk), -+ /* "def" or s32 */ -+ fsparam_string("rdhash", Opt_rdhash), -+ -+ fsparam_string("create", Opt_wbr_create), -+ fsparam_string("create_policy", Opt_wbr_create), -+ fsparam_string("cpup", Opt_wbr_copyup), -+ fsparam_string("copyup", Opt_wbr_copyup), -+ fsparam_string("copyup_policy", Opt_wbr_copyup), -+ -+ /* generic VFS flag */ -+#ifdef CONFIG_FS_POSIX_ACL -+ fsparam_flag_no("acl", Opt_acl), -+#else -+ au_ignore_flag("acl", Opt_ignore), -+#endif -+ -+ /* internal use for the scripts */ -+ fsparam_string("si", Opt_ignore_silent), -+ -+ /* obsoleted, keep them temporary */ -+ fsparam_flag("nodlgt", Opt_ignore_silent), -+ fsparam_flag("clean_plink", Opt_ignore), -+ fsparam_string("dirs", Opt_br), -+ fsparam_u32("debug", Opt_ignore), -+ /* "whiteout" or "all" */ -+ fsparam_string("delete", Opt_ignore), -+ fsparam_string("imap", Opt_ignore), -+ -+ /* temporary workaround, due to old mount(8)? */ -+ fsparam_flag("relatime", Opt_ignore_silent), -+ -+ {} -+}; -+ -+static int au_fsctx_parse_do_add(struct fs_context *fc, struct au_opt *opt, -+ char *brspec, size_t speclen, -+ aufs_bindex_t bindex) -+{ -+ int err; -+ char *p; -+ -+ AuDbg("brspec %s\n", brspec); -+ -+ err = -ENOMEM; -+ if (!speclen) -+ speclen = strlen(brspec); -+ /* will be freed by au_fsctx_free() */ -+ p = kmemdup_nul(brspec, speclen, GFP_NOFS); -+ if (unlikely(!p)) { -+ errorfc(fc, "failed in %s", brspec); -+ goto out; -+ } -+ err = au_opt_add(opt, p, fc->sb_flags, bindex); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_fsctx_parse_br(struct fs_context *fc, char *brspec) -+{ -+ int err; -+ char *p; -+ struct au_fsctx_opts *a = fc->fs_private; -+ struct au_opt *opt = a->opt; -+ aufs_bindex_t bindex = a->bindex; -+ -+ AuDbg("brspec %s\n", brspec); -+ -+ err = -EINVAL; -+ while ((p = strsep(&brspec, ":")) && *p) { -+ err = au_fsctx_parse_do_add(fc, opt, p, /*len*/0, bindex); -+ AuTraceErr(err); -+ if (unlikely(err)) -+ break; -+ bindex++; -+ opt++; -+ if (unlikely(opt > a->opt_tail)) { -+ err = -E2BIG; -+ bindex--; -+ opt--; -+ break; -+ } -+ opt->type = Opt_tail; -+ a->skipped = 1; -+ } -+ a->bindex = bindex; -+ a->opt = opt; -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_fsctx_parse_add(struct fs_context *fc, char *addspec) -+{ -+ int err, n; -+ char *p; -+ struct au_fsctx_opts *a = fc->fs_private; -+ struct au_opt *opt = a->opt; -+ -+ err = -EINVAL; -+ p = strchr(addspec, ':'); -+ if (unlikely(!p)) { -+ errorfc(fc, "bad arg in %s", addspec); -+ goto out; -+ } -+ *p++ = '\0'; -+ err = kstrtoint(addspec, 0, &n); -+ if (unlikely(err)) { -+ errorfc(fc, "bad integer in %s", addspec); -+ goto out; -+ } -+ AuDbg("n %d\n", n); -+ err = au_fsctx_parse_do_add(fc, opt, p, /*len*/0, n); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_fsctx_parse_del(struct fs_context *fc, struct au_opt_del *del, -+ struct fs_parameter *param) -+{ -+ int err; -+ -+ err = -ENOMEM; -+ /* will be freed by au_fsctx_free() */ -+ del->pathname = kmemdup_nul(param->string, param->size, GFP_NOFS); -+ if (unlikely(!del->pathname)) -+ goto out; -+ AuDbg("del %s\n", del->pathname); -+ err = vfsub_kern_path(del->pathname, AuOpt_LkupDirFlags, &del->h_path); -+ if (unlikely(err)) -+ errorfc(fc, "lookup failed %s (%d)", del->pathname, err); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+#if 0 /* reserved for future use */ -+static int au_fsctx_parse_idel(struct fs_context *fc, struct au_opt_del *del, -+ aufs_bindex_t bindex) -+{ -+ int err; -+ struct super_block *sb; -+ struct dentry *root; -+ struct au_fsctx_opts *a = fc->fs_private; -+ -+ sb = a->sb; -+ AuDebugOn(!sb); -+ -+ err = -EINVAL; -+ root = sb->s_root; -+ aufs_read_lock(root, AuLock_FLUSH); -+ if (bindex < 0 || au_sbbot(sb) < bindex) { -+ errorfc(fc, "out of bounds, %d", bindex); -+ goto out; -+ } -+ -+ err = 0; -+ del->h_path.dentry = dget(au_h_dptr(root, bindex)); -+ del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex)); -+ -+out: -+ aufs_read_unlock(root, !AuLock_IR); -+ AuTraceErr(err); -+ return err; -+} -+#endif -+ -+static int au_fsctx_parse_mod(struct fs_context *fc, struct au_opt_mod *mod, -+ struct fs_parameter *param) -+{ -+ int err; -+ struct path path; -+ char *p; -+ -+ err = -ENOMEM; -+ /* will be freed by au_fsctx_free() */ -+ mod->path = kmemdup_nul(param->string, param->size, GFP_NOFS); -+ if (unlikely(!mod->path)) -+ goto out; -+ -+ err = -EINVAL; -+ p = strchr(mod->path, '='); -+ if (unlikely(!p)) { -+ errorfc(fc, "no permission %s", mod->path); -+ goto out; -+ } -+ -+ *p++ = 0; -+ err = vfsub_kern_path(mod->path, AuOpt_LkupDirFlags, &path); -+ if (unlikely(err)) { -+ errorfc(fc, "lookup failed %s (%d)", mod->path, err); -+ goto out; -+ } -+ -+ mod->perm = au_br_perm_val(p); -+ AuDbg("mod path %s, perm 0x%x, %s", mod->path, mod->perm, p); -+ mod->h_root = dget(path.dentry); -+ path_put(&path); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+#if 0 /* reserved for future use */ -+static int au_fsctx_parse_imod(struct fs_context *fc, struct au_opt_mod *mod, -+ char *ibrspec) -+{ -+ int err, n; -+ char *p; -+ struct super_block *sb; -+ struct dentry *root; -+ struct au_fsctx_opts *a = fc->fs_private; -+ -+ sb = a->sb; -+ AuDebugOn(!sb); -+ -+ err = -EINVAL; -+ p = strchr(ibrspec, ':'); -+ if (unlikely(!p)) { -+ errorfc(fc, "no index, %s", ibrspec); -+ goto out; -+ } -+ *p++ = '\0'; -+ err = kstrtoint(ibrspec, 0, &n); -+ if (unlikely(err)) { -+ errorfc(fc, "bad integer in %s", ibrspec); -+ goto out; -+ } -+ AuDbg("n %d\n", n); -+ -+ root = sb->s_root; -+ aufs_read_lock(root, AuLock_FLUSH); -+ if (n < 0 || au_sbbot(sb) < n) { -+ errorfc(fc, "out of bounds, %d", bindex); -+ goto out_root; -+ } -+ -+ err = 0; -+ mod->perm = au_br_perm_val(p); -+ AuDbg("mod path %s, perm 0x%x, %s\n", -+ mod->path, mod->perm, p); -+ mod->h_root = dget(au_h_dptr(root, bindex)); -+ -+out_root: -+ aufs_read_unlock(root, !AuLock_IR); -+out: -+ AuTraceErr(err); -+ return err; -+} -+#endif -+ -+static int au_fsctx_parse_xino(struct fs_context *fc, -+ struct au_opt_xino *xino, -+ struct fs_parameter *param) -+{ -+ int err; -+ struct au_fsctx_opts *a = fc->fs_private; -+ -+ err = -ENOMEM; -+ /* will be freed by au_opts_free() */ -+ xino->path = kmemdup_nul(param->string, param->size, GFP_NOFS); -+ if (unlikely(!xino->path)) -+ goto out; -+ AuDbg("path %s\n", xino->path); -+ -+ xino->file = au_xino_create(a->sb, xino->path, /*silent*/0, -+ /*wbrtop*/0); -+ err = PTR_ERR(xino->file); -+ if (IS_ERR(xino->file)) { -+ xino->file = NULL; -+ goto out; -+ } -+ -+ err = 0; -+ if (unlikely(a->sb && xino->file->f_path.dentry->d_sb == a->sb)) { -+ err = -EINVAL; -+ errorfc(fc, "%s must be outside", xino->path); -+ } -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static -+int au_fsctx_parse_xino_itrunc_path(struct fs_context *fc, -+ struct au_opt_xino_itrunc *xino_itrunc, -+ char *pathname) -+{ -+ int err; -+ aufs_bindex_t bbot, bindex; -+ struct path path; -+ struct dentry *root; -+ struct au_fsctx_opts *a = fc->fs_private; -+ -+ AuDebugOn(!a->sb); -+ -+ err = vfsub_kern_path(pathname, AuOpt_LkupDirFlags, &path); -+ if (unlikely(err)) { -+ errorfc(fc, "lookup failed %s (%d)", pathname, err); -+ goto out; -+ } -+ -+ xino_itrunc->bindex = -1; -+ root = a->sb->s_root; -+ aufs_read_lock(root, AuLock_FLUSH); -+ bbot = au_sbbot(a->sb); -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ if (au_h_dptr(root, bindex) == path.dentry) { -+ xino_itrunc->bindex = bindex; -+ break; -+ } -+ } -+ aufs_read_unlock(root, !AuLock_IR); -+ path_put(&path); -+ -+ if (unlikely(xino_itrunc->bindex < 0)) { -+ err = -EINVAL; -+ errorfc(fc, "no such branch %s", pathname); -+ } -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_fsctx_parse_xino_itrunc(struct fs_context *fc, -+ struct au_opt_xino_itrunc *xino_itrunc, -+ unsigned int bindex) -+{ -+ int err; -+ aufs_bindex_t bbot; -+ struct super_block *sb; -+ struct au_fsctx_opts *a = fc->fs_private; -+ -+ sb = a->sb; -+ AuDebugOn(!sb); -+ -+ err = 0; -+ si_noflush_read_lock(sb); -+ bbot = au_sbbot(sb); -+ si_read_unlock(sb); -+ if (bindex <= bbot) -+ xino_itrunc->bindex = bindex; -+ else { -+ err = -EINVAL; -+ errorfc(fc, "out of bounds, %u", bindex); -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_fsctx_parse_param(struct fs_context *fc, struct fs_parameter *param) -+{ -+ int err, token; -+ struct fs_parse_result result; -+ struct au_fsctx_opts *a = fc->fs_private; -+ struct au_opt *opt = a->opt; -+ -+ AuDbg("fc %p, param {key %s, string %s}\n", -+ fc, param->key, param->string); -+ err = fs_parse(fc, aufs_fsctx_paramspec, param, &result); -+ if (unlikely(err < 0)) -+ goto out; -+ token = err; -+ AuDbg("token %d, res{negated %d, uint64 %llu}\n", -+ token, result.negated, result.uint_64); -+ -+ err = -EINVAL; -+ a->skipped = 0; -+ switch (token) { -+ case Opt_br: -+ err = au_fsctx_parse_br(fc, param->string); -+ break; -+ case Opt_add: -+ err = au_fsctx_parse_add(fc, param->string); -+ break; -+ case Opt_append: -+ err = au_fsctx_parse_do_add(fc, opt, param->string, param->size, -+ /*dummy bindex*/1); -+ break; -+ case Opt_prepend: -+ err = au_fsctx_parse_do_add(fc, opt, param->string, param->size, -+ /*bindex*/0); -+ break; -+ -+ case Opt_del: -+ err = au_fsctx_parse_del(fc, &opt->del, param); -+ break; -+#if 0 /* reserved for future use */ -+ case Opt_idel: -+ if (!a->sb) { -+ err = 0; -+ a->skipped = 1; -+ break; -+ } -+ del->pathname = "(indexed)"; -+ err = au_opts_parse_idel(fc, &opt->del, result.uint_32); -+ break; -+#endif -+ -+ case Opt_mod: -+ err = au_fsctx_parse_mod(fc, &opt->mod, param); -+ break; -+#ifdef IMOD /* reserved for future use */ -+ case Opt_imod: -+ if (!a->sb) { -+ err = 0; -+ a->skipped = 1; -+ break; -+ } -+ u.mod->path = "(indexed)"; -+ err = au_opts_parse_imod(fc, &opt->mod, param->string); -+ break; -+#endif -+ -+ case Opt_xino: -+ err = au_fsctx_parse_xino(fc, &opt->xino, param); -+ break; -+ case Opt_trunc_xino_path: -+ if (!a->sb) { -+ errorfc(fc, "no such branch %s", param->string); -+ break; -+ } -+ err = au_fsctx_parse_xino_itrunc_path(fc, &opt->xino_itrunc, -+ param->string); -+ break; -+#if 0 -+ case Opt_trunc_xino_v: -+ if (!a->sb) { -+ err = 0; -+ a->skipped = 1; -+ break; -+ } -+ err = au_fsctx_parse_xino_itrunc_path(fc, &opt->xino_itrunc, -+ param->string); -+ break; -+#endif -+ case Opt_itrunc_xino: -+ if (!a->sb) { -+ errorfc(fc, "out of bounds %s", param->string); -+ break; -+ } -+ err = au_fsctx_parse_xino_itrunc(fc, &opt->xino_itrunc, -+ result.int_32); -+ break; -+ -+ case Opt_dirwh: -+ err = 0; -+ opt->dirwh = result.int_32; -+ break; -+ -+ case Opt_rdcache: -+ if (unlikely(result.int_32 > AUFS_RDCACHE_MAX)) { -+ errorfc(fc, "rdcache must be smaller than %d", -+ AUFS_RDCACHE_MAX); -+ break; -+ } -+ err = 0; -+ opt->rdcache = result.int_32; -+ break; -+ -+ case Opt_rdblk: -+ err = 0; -+ opt->rdblk = AUFS_RDBLK_DEF; -+ if (!strcmp(param->string, "def")) -+ break; -+ -+ err = kstrtoint(param->string, 0, &result.int_32); -+ if (unlikely(err)) { -+ errorfc(fc, "bad value in %s", param->key); -+ break; -+ } -+ err = -EINVAL; -+ if (unlikely(result.int_32 < 0 -+ || result.int_32 > KMALLOC_MAX_SIZE)) { -+ errorfc(fc, "bad value in %s", param->key); -+ break; -+ } -+ if (unlikely(result.int_32 && result.int_32 < NAME_MAX)) { -+ errorfc(fc, "rdblk must be larger than %d", NAME_MAX); -+ break; -+ } -+ err = 0; -+ opt->rdblk = result.int_32; -+ break; -+ -+ case Opt_rdhash: -+ err = 0; -+ opt->rdhash = AUFS_RDHASH_DEF; -+ if (!strcmp(param->string, "def")) -+ break; -+ -+ err = kstrtoint(param->string, 0, &result.int_32); -+ if (unlikely(err)) { -+ errorfc(fc, "bad value in %s", param->key); -+ break; -+ } -+ /* how about zero? */ -+ if (result.int_32 < 0 -+ || result.int_32 * sizeof(struct hlist_head) -+ > KMALLOC_MAX_SIZE) { -+ err = -EINVAL; -+ errorfc(fc, "bad integer in %s", param->key); -+ break; -+ } -+ opt->rdhash = result.int_32; -+ break; -+ -+ case Opt_diropq: -+ /* -+ * As other options, fs/aufs/opts.c can handle these strings by -+ * match_token(). But "diropq=" is deprecated now and will -+ * never have other value. So simple strcmp() is enough here. -+ */ -+ if (!strcmp(param->string, "a") || -+ !strcmp(param->string, "always")) { -+ err = 0; -+ opt->type = Opt_diropq_a; -+ } else if (!strcmp(param->string, "w") || -+ !strcmp(param->string, "whiteouted")) { -+ err = 0; -+ opt->type = Opt_diropq_w; -+ } else -+ errorfc(fc, "unknown value %s", param->string); -+ break; -+ -+ case Opt_udba: -+ opt->udba = au_udba_val(param->string); -+ if (opt->udba >= 0) -+ err = 0; -+ else -+ errorf(fc, "wrong value, %s", param->string); -+ break; -+ -+ case Opt_wbr_create: -+ opt->wbr_create.wbr_create -+ = au_wbr_create_val(param->string, &opt->wbr_create); -+ if (opt->wbr_create.wbr_create >= 0) -+ err = 0; -+ else -+ errorf(fc, "wrong value, %s", param->key); -+ break; -+ -+ case Opt_wbr_copyup: -+ opt->wbr_copyup = au_wbr_copyup_val(param->string); -+ if (opt->wbr_copyup >= 0) -+ err = 0; -+ else -+ errorfc(fc, "wrong value, %s", param->key); -+ break; -+ -+ case Opt_fhsm_sec: -+ if (unlikely(result.int_32 < 0)) { -+ errorfc(fc, "bad integer in %s\n", param->key); -+ break; -+ } -+ err = 0; -+ if (sysaufs_brs) -+ opt->fhsm_second = result.int_32; -+ else -+ warnfc(fc, "ignored %s %s", param->key, param->string); -+ break; -+ -+ /* simple true/false flag */ -+#define au_fsctx_TF(name) \ -+ case Opt_##name: \ -+ err = 0; \ -+ opt->tf = !result.negated; \ -+ break -+ au_fsctx_TF(trunc_xino); -+ au_fsctx_TF(trunc_xib); -+ au_fsctx_TF(dirperm1); -+ au_fsctx_TF(plink); -+ au_fsctx_TF(shwh); -+ au_fsctx_TF(dio); -+ au_fsctx_TF(warn_perm); -+ au_fsctx_TF(verbose); -+ au_fsctx_TF(sum); -+ au_fsctx_TF(dirren); -+ au_fsctx_TF(acl); -+#undef au_fsctx_TF -+ -+ case Opt_noverbose: -+ err = 0; -+ opt->type = Opt_verbose; -+ opt->tf = false; -+ break; -+ -+ case Opt_noxino: -+ fallthrough; -+ case Opt_list_plink: -+ fallthrough; -+ case Opt_wsum: -+ err = 0; -+ break; -+ -+ case Opt_ignore: -+ warnfc(fc, "ignored %s", param->key); -+ fallthrough; -+ case Opt_ignore_silent: -+ a->skipped = 1; -+ err = 0; -+ break; -+ default: -+ a->skipped = 1; -+ err = -ENOPARAM; -+ break; -+ } -+ if (unlikely(err)) -+ goto out; -+ if (a->skipped) -+ goto out; -+ -+ switch (token) { -+ case Opt_br: -+ fallthrough; -+ case Opt_noverbose: -+ fallthrough; -+ case Opt_diropq: -+ break; -+ default: -+ opt->type = token; -+ break; -+ } -+ opt++; -+ if (unlikely(opt > a->opt_tail)) { -+ err = -E2BIG; -+ opt--; -+ } -+ opt->type = Opt_tail; -+ a->opt = opt; -+ -+out: -+ return err; -+} -+ -+/* -+ * these options accept both 'name=val' and 'name:val' form. -+ * some accept optional '=' in its value. -+ * eg. br:/br1=rw:/br2=ro and br=/br1=rw:/br2=ro -+ */ -+static inline unsigned int is_colonopt(char *str) -+{ -+#define do_test(name) \ -+ if (!strncmp(str, name ":", sizeof(name))) \ -+ return sizeof(name) - 1 -+ do_test("br"); -+ do_test("add"); -+ do_test("ins"); -+ do_test("append"); -+ do_test("prepend"); -+ do_test("del"); -+ /* do_test("idel"); */ -+ do_test("mod"); -+ /* do_test("imod"); */ -+#undef do_test -+ -+ return 0; -+} -+ -+static int au_fsctx_parse_monolithic(struct fs_context *fc, void *data) -+{ -+ int err; -+ unsigned int u; -+ char *str; -+ struct au_fsctx_opts *a = fc->fs_private; -+ -+ str = data; -+ AuDbg("str %s\n", str); -+ while (str) { -+ u = is_colonopt(str); -+ if (u) -+ str[u] = '='; -+ str = strchr(str, ','); -+ if (!str) -+ break; -+ str++; -+ } -+ str = data; -+ AuDbg("str %s\n", str); -+ -+ err = generic_parse_monolithic(fc, str); -+ AuTraceErr(err); -+ au_fsctx_dump(&a->opts); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void au_fsctx_opts_free(struct au_opts *opts) -+{ -+ struct au_opt *opt; -+ -+ opt = opts->opt; -+ while (opt->type != Opt_tail) { -+ switch (opt->type) { -+ case Opt_add: -+ fallthrough; -+ case Opt_append: -+ fallthrough; -+ case Opt_prepend: -+ kfree(opt->add.pathname); -+ path_put(&opt->add.path); -+ break; -+ case Opt_del: -+ kfree(opt->del.pathname); -+ fallthrough; -+ case Opt_idel: -+ path_put(&opt->del.h_path); -+ break; -+ case Opt_mod: -+ kfree(opt->mod.path); -+ fallthrough; -+ case Opt_imod: -+ dput(opt->mod.h_root); -+ break; -+ case Opt_xino: -+ kfree(opt->xino.path); -+ fput(opt->xino.file); -+ break; -+ } -+ opt++; -+ } -+} -+ -+static void au_fsctx_free(struct fs_context *fc) -+{ -+ struct au_fsctx_opts *a = fc->fs_private; -+ -+ /* fs_type=%p, root=%pD */ -+ AuDbg("fc %p{sb_flags 0x%x, sb_flags_mask 0x%x, purpose %u\n", -+ fc, fc->sb_flags, fc->sb_flags_mask, fc->purpose); -+ -+ kobject_put(&a->sbinfo->si_kobj); -+ au_fsctx_opts_free(&a->opts); -+ free_page((unsigned long)a->opts.opt); -+ au_kfree_rcu(a); -+} -+ -+static const struct fs_context_operations au_fsctx_ops = { -+ .free = au_fsctx_free, -+ .parse_param = au_fsctx_parse_param, -+ .parse_monolithic = au_fsctx_parse_monolithic, -+ .get_tree = au_fsctx_get_tree, -+ .reconfigure = au_fsctx_reconfigure -+ /* -+ * nfs4 requires ->dup()? No. -+ * I don't know what is this ->dup() for. -+ */ -+}; -+ -+int aufs_fsctx_init(struct fs_context *fc) -+{ -+ int err; -+ struct au_fsctx_opts *a; -+ -+ /* fs_type=%p, root=%pD */ -+ AuDbg("fc %p{sb_flags 0x%x, sb_flags_mask 0x%x, purpose %u\n", -+ fc, fc->sb_flags, fc->sb_flags_mask, fc->purpose); -+ -+ /* they will be freed by au_fsctx_free() */ -+ err = -ENOMEM; -+ a = kzalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ a->bindex = 0; -+ a->opts.opt = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!a->opts.opt)) -+ goto out_a; -+ a->opt = a->opts.opt; -+ a->opt->type = Opt_tail; -+ a->opts.max_opt = PAGE_SIZE / sizeof(*a->opts.opt); -+ a->opt_tail = a->opt + a->opts.max_opt - 1; -+ a->opts.sb_flags = fc->sb_flags; -+ -+ a->sb = NULL; -+ if (fc->root) { -+ AuDebugOn(fc->purpose != FS_CONTEXT_FOR_RECONFIGURE); -+ a->opts.flags = AuOpts_REMOUNT; -+ a->sb = fc->root->d_sb; -+ a->sbinfo = au_sbi(a->sb); -+ kobject_get(&a->sbinfo->si_kobj); -+ } else { -+ a->sbinfo = au_si_alloc(a->sb); -+ AuDebugOn(!a->sbinfo); -+ err = PTR_ERR(a->sbinfo); -+ if (IS_ERR(a->sbinfo)) -+ goto out_opt; -+ au_rw_write_unlock(&a->sbinfo->si_rwsem); -+ } -+ -+ err = 0; -+ fc->fs_private = a; -+ fc->ops = &au_fsctx_ops; -+ goto out; /* success */ -+ -+out_opt: -+ free_page((unsigned long)a->opts.opt); -+out_a: -+ au_kfree_rcu(a); -+out: -+ AuTraceErr(err); -+ return err; -+} -diff -Naur null/fs/aufs/fstype.h linux-6.6.63/fs/aufs/fstype.h ---- /dev/null -+++ linux-6.6.63/fs/aufs/fstype.h 2024-12-18 15:12:59.296519576 +0300 -@@ -0,0 +1,419 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * judging filesystem type -+ */ -+ -+#ifndef __AUFS_FSTYPE_H__ -+#define __AUFS_FSTYPE_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+#include -+#include -+ -+static inline int au_test_aufs(struct super_block *sb) -+{ -+ return sb->s_magic == AUFS_SUPER_MAGIC; -+} -+ -+static inline const char *au_sbtype(struct super_block *sb) -+{ -+ return sb->s_type->name; -+} -+ -+static inline int au_test_iso9660(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_ISO9660_FS) -+ return sb->s_magic == ISOFS_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_romfs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_ROMFS_FS) -+ return sb->s_magic == ROMFS_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_cramfs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_CRAMFS) -+ return sb->s_magic == CRAMFS_MAGIC; -+#endif -+ return 0; -+} -+ -+static inline int au_test_nfs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_NFS_FS) -+ return sb->s_magic == NFS_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_fuse(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_FUSE_FS) -+ return sb->s_magic == FUSE_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_xfs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_XFS_FS) -+ return sb->s_magic == XFS_SB_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_tmpfs(struct super_block *sb __maybe_unused) -+{ -+#ifdef CONFIG_TMPFS -+ return sb->s_magic == TMPFS_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_ECRYPT_FS) -+ return !strcmp(au_sbtype(sb), "ecryptfs"); -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_ramfs(struct super_block *sb) -+{ -+ return sb->s_magic == RAMFS_MAGIC; -+} -+ -+static inline int au_test_ubifs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_UBIFS_FS) -+ return sb->s_magic == UBIFS_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_procfs(struct super_block *sb __maybe_unused) -+{ -+#ifdef CONFIG_PROC_FS -+ return sb->s_magic == PROC_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_sysfs(struct super_block *sb __maybe_unused) -+{ -+#ifdef CONFIG_SYSFS -+ return sb->s_magic == SYSFS_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_configfs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_CONFIGFS_FS) -+ return sb->s_magic == CONFIGFS_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_minix(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_MINIX_FS) -+ return sb->s_magic == MINIX3_SUPER_MAGIC -+ || sb->s_magic == MINIX2_SUPER_MAGIC -+ || sb->s_magic == MINIX2_SUPER_MAGIC2 -+ || sb->s_magic == MINIX_SUPER_MAGIC -+ || sb->s_magic == MINIX_SUPER_MAGIC2; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_fat(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_FAT_FS) -+ return sb->s_magic == MSDOS_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_msdos(struct super_block *sb) -+{ -+ return au_test_fat(sb); -+} -+ -+static inline int au_test_vfat(struct super_block *sb) -+{ -+ return au_test_fat(sb); -+} -+ -+static inline int au_test_securityfs(struct super_block *sb __maybe_unused) -+{ -+#ifdef CONFIG_SECURITYFS -+ return sb->s_magic == SECURITYFS_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_squashfs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_SQUASHFS) -+ return sb->s_magic == SQUASHFS_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_btrfs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_BTRFS_FS) -+ return sb->s_magic == BTRFS_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_xenfs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_XENFS) -+ return sb->s_magic == XENFS_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_debugfs(struct super_block *sb __maybe_unused) -+{ -+#ifdef CONFIG_DEBUG_FS -+ return sb->s_magic == DEBUGFS_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_nilfs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_NILFS) -+ return sb->s_magic == NILFS_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_hfsplus(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_HFSPLUS_FS) -+ return sb->s_magic == HFSPLUS_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_f2fs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_F2FS_FS) -+ return sb->s_magic == F2FS_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+/* ---------------------------------------------------------------------- */ -+/* -+ * they can't be an aufs branch. -+ */ -+static inline int au_test_fs_unsuppoted(struct super_block *sb) -+{ -+ return -+#ifndef CONFIG_AUFS_BR_RAMFS -+ au_test_ramfs(sb) || -+#endif -+ au_test_procfs(sb) -+ || au_test_sysfs(sb) -+ || au_test_configfs(sb) -+ || au_test_debugfs(sb) -+ || au_test_securityfs(sb) -+ || au_test_xenfs(sb) -+ || au_test_ecryptfs(sb) -+ /* || !strcmp(au_sbtype(sb), "unionfs") */ -+ || au_test_aufs(sb); /* will be supported in next version */ -+} -+ -+static inline int au_test_fs_remote(struct super_block *sb) -+{ -+ return !au_test_tmpfs(sb) -+#ifdef CONFIG_AUFS_BR_RAMFS -+ && !au_test_ramfs(sb) -+#endif -+ && !(sb->s_type->fs_flags & FS_REQUIRES_DEV); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * Note: these functions (below) are created after reading ->getattr() in all -+ * filesystems under linux/fs. it means we have to do so in every update... -+ */ -+ -+/* -+ * some filesystems require getattr to refresh the inode attributes before -+ * referencing. -+ * in most cases, we can rely on the inode attribute in NFS (or every remote fs) -+ * and leave the work for d_revalidate() -+ */ -+static inline int au_test_fs_refresh_iattr(struct super_block *sb) -+{ -+ return au_test_nfs(sb) -+ || au_test_fuse(sb) -+ /* || au_test_btrfs(sb) */ /* untested */ -+ ; -+} -+ -+/* -+ * filesystems which don't maintain i_size or i_blocks. -+ */ -+static inline int au_test_fs_bad_iattr_size(struct super_block *sb) -+{ -+ return au_test_xfs(sb) -+ || au_test_btrfs(sb) -+ || au_test_ubifs(sb) -+ || au_test_hfsplus(sb) /* maintained, but incorrect */ -+ /* || au_test_minix(sb) */ /* untested */ -+ ; -+} -+ -+/* -+ * filesystems which don't store the correct value in some of their inode -+ * attributes. -+ */ -+static inline int au_test_fs_bad_iattr(struct super_block *sb) -+{ -+ return au_test_fs_bad_iattr_size(sb) -+ || au_test_fat(sb) -+ || au_test_msdos(sb) -+ || au_test_vfat(sb); -+} -+ -+/* they don't check i_nlink in link(2) */ -+static inline int au_test_fs_no_limit_nlink(struct super_block *sb) -+{ -+ return au_test_tmpfs(sb) -+#ifdef CONFIG_AUFS_BR_RAMFS -+ || au_test_ramfs(sb) -+#endif -+ || au_test_ubifs(sb) -+ || au_test_hfsplus(sb); -+} -+ -+/* -+ * filesystems which sets S_NOATIME and S_NOCMTIME. -+ */ -+static inline int au_test_fs_notime(struct super_block *sb) -+{ -+ return au_test_nfs(sb) -+ || 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) -+{ -+ if (au_test_cramfs(inode->i_sb)) -+ return inode->i_ino != 1; -+ return 1; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * the filesystem where the xino files placed must support i/o after unlink and -+ * maintain i_size and i_blocks. -+ */ -+static inline int au_test_fs_bad_xino(struct super_block *sb) -+{ -+ return au_test_fs_remote(sb) -+ || au_test_fs_bad_iattr_size(sb) -+ /* don't want unnecessary work for xino */ -+ || au_test_aufs(sb) -+ || au_test_ecryptfs(sb) -+ || au_test_nilfs(sb); -+} -+ -+static inline int au_test_fs_trunc_xino(struct super_block *sb) -+{ -+ return au_test_tmpfs(sb) -+ || au_test_ramfs(sb); -+} -+ -+/* -+ * test if the @sb is real-readonly. -+ */ -+static inline int au_test_fs_rr(struct super_block *sb) -+{ -+ return au_test_squashfs(sb) -+ || au_test_iso9660(sb) -+ || au_test_cramfs(sb) -+ || au_test_romfs(sb); -+} -+ -+/* -+ * test if the @inode is nfs with 'noacl' option -+ * NFS always sets SB_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); -+} -+ -+/* -+ * filesystems which requires inode-lock in open. -+ */ -+static inline int au_test_fs_unlock_for_open(struct super_block *sb) -+{ -+ return au_test_nfs(sb) -+ || au_test_f2fs(sb); -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_FSTYPE_H__ */ -diff -Naur null/fs/aufs/hbl.h linux-6.6.63/fs/aufs/hbl.h ---- /dev/null -+++ linux-6.6.63/fs/aufs/hbl.h 2024-12-18 15:12:59.296519576 +0300 -@@ -0,0 +1,65 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2017-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * helpers for hlist_bl.h -+ */ -+ -+#ifndef __AUFS_HBL_H__ -+#define __AUFS_HBL_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+ -+static inline void au_hbl_add(struct hlist_bl_node *node, -+ struct hlist_bl_head *hbl) -+{ -+ hlist_bl_lock(hbl); -+ hlist_bl_add_head(node, hbl); -+ hlist_bl_unlock(hbl); -+} -+ -+static inline void au_hbl_del(struct hlist_bl_node *node, -+ struct hlist_bl_head *hbl) -+{ -+ hlist_bl_lock(hbl); -+ hlist_bl_del(node); -+ hlist_bl_unlock(hbl); -+} -+ -+#define au_hbl_for_each(pos, head) \ -+ for (pos = hlist_bl_first(head); \ -+ pos; \ -+ pos = pos->next) -+ -+static inline unsigned long au_hbl_count(struct hlist_bl_head *hbl) -+{ -+ unsigned long cnt; -+ struct hlist_bl_node *pos; -+ -+ cnt = 0; -+ hlist_bl_lock(hbl); -+ au_hbl_for_each(pos, hbl) -+ cnt++; -+ hlist_bl_unlock(hbl); -+ return cnt; -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_HBL_H__ */ -diff -Naur null/fs/aufs/hfsnotify.c linux-6.6.63/fs/aufs/hfsnotify.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/hfsnotify.c 2024-12-18 15:12:59.296519576 +0300 -@@ -0,0 +1,290 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * fsnotify for the lower directories -+ */ -+ -+#include "aufs.h" -+ -+/* FS_IN_IGNORED is unnecessary */ -+static const __u32 AuHfsnMask = (FS_MOVED_TO | FS_MOVED_FROM | FS_DELETE -+ | FS_CREATE | FS_EVENT_ON_CHILD); -+static DECLARE_WAIT_QUEUE_HEAD(au_hfsn_wq); -+static __cacheline_aligned_in_smp atomic64_t au_hfsn_ifree = ATOMIC64_INIT(0); -+ -+static void au_hfsn_free_mark(struct fsnotify_mark *mark) -+{ -+ struct au_hnotify *hn = container_of(mark, struct au_hnotify, -+ hn_mark); -+ /* AuDbg("here\n"); */ -+ au_cache_free_hnotify(hn); -+ smp_mb__before_atomic(); /* for atomic64_dec */ -+ if (atomic64_dec_and_test(&au_hfsn_ifree)) -+ wake_up(&au_hfsn_wq); -+} -+ -+static int au_hfsn_alloc(struct au_hinode *hinode) -+{ -+ int err; -+ struct au_hnotify *hn; -+ struct super_block *sb; -+ struct au_branch *br; -+ struct fsnotify_mark *mark; -+ aufs_bindex_t bindex; -+ -+ hn = hinode->hi_notify; -+ sb = hn->hn_aufs_inode->i_sb; -+ bindex = au_br_index(sb, hinode->hi_id); -+ br = au_sbr(sb, bindex); -+ AuDebugOn(!br->br_hfsn); -+ -+ mark = &hn->hn_mark; -+ fsnotify_init_mark(mark, br->br_hfsn->hfsn_group); -+ mark->mask = AuHfsnMask; -+ /* -+ * by udba rename or rmdir, aufs assign a new inode to the known -+ * h_inode, so specify 1 to allow dups. -+ */ -+ lockdep_off(); -+ err = fsnotify_add_inode_mark(mark, hinode->hi_inode, /*allow_dups*/1); -+ lockdep_on(); -+ -+ return err; -+} -+ -+static int au_hfsn_free(struct au_hinode *hinode, struct au_hnotify *hn) -+{ -+ struct fsnotify_mark *mark; -+ unsigned long long ull; -+ struct fsnotify_group *group; -+ -+ ull = atomic64_inc_return(&au_hfsn_ifree); -+ BUG_ON(!ull); -+ -+ mark = &hn->hn_mark; -+ spin_lock(&mark->lock); -+ group = mark->group; -+ fsnotify_get_group(group); -+ spin_unlock(&mark->lock); -+ lockdep_off(); -+ fsnotify_destroy_mark(mark, group); -+ fsnotify_put_mark(mark); -+ fsnotify_put_group(group); -+ lockdep_on(); -+ -+ /* free hn by myself */ -+ return 0; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void au_hfsn_ctl(struct au_hinode *hinode, int do_set) -+{ -+ struct fsnotify_mark *mark; -+ -+ mark = &hinode->hi_notify->hn_mark; -+ spin_lock(&mark->lock); -+ if (do_set) { -+ AuDebugOn(mark->mask & AuHfsnMask); -+ mark->mask |= AuHfsnMask; -+ } else { -+ AuDebugOn(!(mark->mask & AuHfsnMask)); -+ mark->mask &= ~AuHfsnMask; -+ } -+ spin_unlock(&mark->lock); -+ /* fsnotify_recalc_inode_mask(hinode->hi_inode); */ -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* #define AuDbgHnotify */ -+#ifdef AuDbgHnotify -+static char *au_hfsn_name(u32 mask) -+{ -+#ifdef CONFIG_AUFS_DEBUG -+#define test_ret(flag) \ -+ do { \ -+ if (mask & flag) \ -+ return #flag; \ -+ } while (0) -+ test_ret(FS_ACCESS); -+ test_ret(FS_MODIFY); -+ test_ret(FS_ATTRIB); -+ test_ret(FS_CLOSE_WRITE); -+ test_ret(FS_CLOSE_NOWRITE); -+ test_ret(FS_OPEN); -+ test_ret(FS_MOVED_FROM); -+ test_ret(FS_MOVED_TO); -+ test_ret(FS_CREATE); -+ test_ret(FS_DELETE); -+ test_ret(FS_DELETE_SELF); -+ test_ret(FS_MOVE_SELF); -+ test_ret(FS_UNMOUNT); -+ test_ret(FS_Q_OVERFLOW); -+ test_ret(FS_IN_IGNORED); -+ test_ret(FS_ISDIR); -+ test_ret(FS_IN_ONESHOT); -+ test_ret(FS_EVENT_ON_CHILD); -+ return ""; -+#undef test_ret -+#else -+ return "??"; -+#endif -+} -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void au_hfsn_free_group(struct fsnotify_group *group) -+{ -+ struct au_br_hfsnotify *hfsn = group->private; -+ -+ /* AuDbg("here\n"); */ -+ au_kfree_try_rcu(hfsn); -+} -+ -+static int au_hfsn_handle_event(struct fsnotify_group *group, -+ u32 mask, const void *data, int data_type, -+ struct inode *dir, -+ const struct qstr *file_name, u32 cookie, -+ struct fsnotify_iter_info *iter_info) -+{ -+ int err; -+ struct au_hnotify *hnotify; -+ struct inode *h_dir, *h_inode; -+ struct fsnotify_mark *inode_mark; -+ -+ AuDebugOn(!(data_type == FSNOTIFY_EVENT_INODE -+ || data_type == FSNOTIFY_EVENT_DENTRY)); -+ -+ err = 0; -+ /* if FS_UNMOUNT happens, there must be another bug */ -+ AuDebugOn(mask & FS_UNMOUNT); -+ if (mask & (FS_IN_IGNORED | FS_UNMOUNT)) -+ goto out; -+ -+ h_dir = dir; -+ h_inode = NULL; -+#ifdef AuDbgHnotify -+ au_debug_on(); -+ if (1 || file_name.len != sizeof(AUFS_XINO_FNAME) - 1 -+ || strncmp(file_name.name, AUFS_XINO_FNAME, file_name.len)) { -+ AuDbg("i%lu, mask 0x%x %s, hcname %.*s, hi%lu\n", -+ h_dir->i_ino, mask, au_hfsn_name(mask), -+ AuLNPair(file_name), h_inode ? h_inode->i_ino : 0); -+ /* WARN_ON(1); */ -+ } -+ au_debug_off(); -+#endif -+ -+ inode_mark = fsnotify_iter_inode_mark(iter_info); -+ AuDebugOn(!inode_mark); -+ hnotify = container_of(inode_mark, struct au_hnotify, hn_mark); -+ err = au_hnotify(h_dir, hnotify, mask, file_name, h_inode); -+ -+out: -+ return err; -+} -+ -+static struct fsnotify_ops au_hfsn_ops = { -+ .handle_event = au_hfsn_handle_event, -+ .free_group_priv = au_hfsn_free_group, -+ .free_mark = au_hfsn_free_mark -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void au_hfsn_fin_br(struct au_branch *br) -+{ -+ struct au_br_hfsnotify *hfsn; -+ -+ hfsn = br->br_hfsn; -+ if (hfsn) { -+ lockdep_off(); -+ fsnotify_put_group(hfsn->hfsn_group); -+ lockdep_on(); -+ } -+} -+ -+static int au_hfsn_init_br(struct au_branch *br, int perm) -+{ -+ int err; -+ struct fsnotify_group *group; -+ struct au_br_hfsnotify *hfsn; -+ -+ err = 0; -+ br->br_hfsn = NULL; -+ if (!au_br_hnotifyable(perm)) -+ goto out; -+ -+ err = -ENOMEM; -+ hfsn = kmalloc(sizeof(*hfsn), GFP_NOFS); -+ if (unlikely(!hfsn)) -+ goto out; -+ -+ err = 0; -+ group = fsnotify_alloc_group(&au_hfsn_ops, -+ /*flags - not for userspace*/0); -+ if (IS_ERR(group)) { -+ err = PTR_ERR(group); -+ pr_err("fsnotify_alloc_group() failed, %d\n", err); -+ goto out_hfsn; -+ } -+ -+ group->private = hfsn; -+ hfsn->hfsn_group = group; -+ br->br_hfsn = hfsn; -+ goto out; /* success */ -+ -+out_hfsn: -+ au_kfree_try_rcu(hfsn); -+out: -+ return err; -+} -+ -+static int au_hfsn_reset_br(unsigned int udba, struct au_branch *br, int perm) -+{ -+ int err; -+ -+ err = 0; -+ if (!br->br_hfsn) -+ err = au_hfsn_init_br(br, perm); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void au_hfsn_fin(void) -+{ -+ AuDbg("au_hfsn_ifree %lld\n", (long long)atomic64_read(&au_hfsn_ifree)); -+ wait_event(au_hfsn_wq, !atomic64_read(&au_hfsn_ifree)); -+} -+ -+const struct au_hnotify_op au_hnotify_op = { -+ .ctl = au_hfsn_ctl, -+ .alloc = au_hfsn_alloc, -+ .free = au_hfsn_free, -+ -+ .fin = au_hfsn_fin, -+ -+ .reset_br = au_hfsn_reset_br, -+ .fin_br = au_hfsn_fin_br, -+ .init_br = au_hfsn_init_br -+}; -diff -Naur null/fs/aufs/hfsplus.c linux-6.6.63/fs/aufs/hfsplus.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/hfsplus.c 2024-12-18 15:12:59.296519576 +0300 -@@ -0,0 +1,60 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2010-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * special support for filesystems which acquires an inode mutex -+ * at final closing a file, eg, hfsplus. -+ * -+ * This trick is very simple and stupid, just to open the file before really -+ * necessary open to tell hfsplus that this is not the final closing. -+ * The caller should call au_h_open_pre() after acquiring the inode mutex, -+ * and au_h_open_post() after releasing it. -+ */ -+ -+#include "aufs.h" -+ -+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex, -+ int force_wr) -+{ -+ struct file *h_file; -+ struct dentry *h_dentry; -+ -+ h_dentry = au_h_dptr(dentry, bindex); -+ AuDebugOn(!h_dentry); -+ AuDebugOn(d_is_negative(h_dentry)); -+ -+ h_file = NULL; -+ if (au_test_hfsplus(h_dentry->d_sb) -+ && d_is_reg(h_dentry)) -+ h_file = au_h_open(dentry, bindex, -+ O_RDONLY | O_NOATIME | O_LARGEFILE, -+ /*file*/NULL, force_wr); -+ return h_file; -+} -+ -+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex, -+ struct file *h_file) -+{ -+ struct au_branch *br; -+ -+ if (h_file) { -+ fput(h_file); -+ br = au_sbr(dentry->d_sb, bindex); -+ au_lcnt_dec(&br->br_nfiles); -+ } -+} -diff -Naur null/fs/aufs/hnotify.c linux-6.6.63/fs/aufs/hnotify.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/hnotify.c 2024-12-18 15:12:59.296519576 +0300 -@@ -0,0 +1,715 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * abstraction to notify the direct changes on lower directories -+ */ -+ -+/* #include */ -+#include "aufs.h" -+ -+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode) -+{ -+ int err; -+ struct au_hnotify *hn; -+ -+ err = -ENOMEM; -+ hn = au_cache_alloc_hnotify(); -+ if (hn) { -+ hn->hn_aufs_inode = inode; -+ hinode->hi_notify = hn; -+ err = au_hnotify_op.alloc(hinode); -+ AuTraceErr(err); -+ if (unlikely(err)) { -+ hinode->hi_notify = NULL; -+ au_cache_free_hnotify(hn); -+ /* -+ * The upper dir was removed by udba, but the same named -+ * dir left. In this case, aufs assigns a new inode -+ * number and set the monitor again. -+ * For the lower dir, the old monitor is still left. -+ */ -+ if (err == -EEXIST) -+ err = 0; -+ } -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+void au_hn_free(struct au_hinode *hinode) -+{ -+ struct au_hnotify *hn; -+ -+ hn = hinode->hi_notify; -+ if (hn) { -+ hinode->hi_notify = NULL; -+ if (au_hnotify_op.free(hinode, hn)) -+ au_cache_free_hnotify(hn); -+ } -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void au_hn_ctl(struct au_hinode *hinode, int do_set) -+{ -+ if (hinode->hi_notify) -+ au_hnotify_op.ctl(hinode, do_set); -+} -+ -+void au_hn_reset(struct inode *inode, unsigned int flags) -+{ -+ aufs_bindex_t bindex, bbot; -+ struct inode *hi; -+ struct dentry *iwhdentry; -+ -+ bbot = au_ibbot(inode); -+ for (bindex = au_ibtop(inode); bindex <= bbot; bindex++) { -+ hi = au_h_iptr(inode, bindex); -+ if (!hi) -+ continue; -+ -+ /* inode_lock_nested(hi, AuLsc_I_CHILD); */ -+ iwhdentry = au_hi_wh(inode, bindex); -+ if (iwhdentry) -+ dget(iwhdentry); -+ au_igrab(hi); -+ au_set_h_iptr(inode, bindex, NULL, 0); -+ au_set_h_iptr(inode, bindex, au_igrab(hi), -+ flags & ~AuHi_XINO); -+ iput(hi); -+ dput(iwhdentry); -+ /* inode_unlock(hi); */ -+ } -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int hn_xino(struct inode *inode, struct inode *h_inode) -+{ -+ int err; -+ aufs_bindex_t bindex, bbot, bfound, btop; -+ struct inode *h_i; -+ -+ err = 0; -+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) { -+ pr_warn("branch root dir was changed\n"); -+ goto out; -+ } -+ -+ bfound = -1; -+ bbot = au_ibbot(inode); -+ btop = au_ibtop(inode); -+#if 0 /* reserved for future use */ -+ if (bindex == bbot) { -+ /* keep this ino in rename case */ -+ goto out; -+ } -+#endif -+ for (bindex = btop; bindex <= bbot; bindex++) -+ if (au_h_iptr(inode, bindex) == h_inode) { -+ bfound = bindex; -+ break; -+ } -+ if (bfound < 0) -+ goto out; -+ -+ for (bindex = btop; bindex <= bbot; bindex++) { -+ h_i = au_h_iptr(inode, bindex); -+ if (!h_i) -+ continue; -+ -+ err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0); -+ /* ignore this error */ -+ /* bad action? */ -+ } -+ -+ /* children inode number will be broken */ -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static int hn_gen_tree(struct dentry *dentry) -+{ -+ int err, i, j, ndentry; -+ struct au_dcsub_pages dpages; -+ struct au_dpage *dpage; -+ struct dentry **dentries; -+ -+ err = au_dpages_init(&dpages, GFP_NOFS); -+ if (unlikely(err)) -+ goto out; -+ err = au_dcsub_pages(&dpages, dentry, NULL, NULL); -+ if (unlikely(err)) -+ goto out_dpages; -+ -+ for (i = 0; i < dpages.ndpage; i++) { -+ dpage = dpages.dpages + i; -+ dentries = dpage->dentries; -+ ndentry = dpage->ndentry; -+ for (j = 0; j < ndentry; j++) { -+ struct dentry *d; -+ -+ d = dentries[j]; -+ if (IS_ROOT(d)) -+ continue; -+ -+ au_digen_dec(d); -+ if (d_really_is_positive(d)) -+ /* todo: reset children xino? -+ cached children only? */ -+ au_iigen_dec(d_inode(d)); -+ } -+ } -+ -+out_dpages: -+ au_dpages_free(&dpages); -+out: -+ return err; -+} -+ -+/* -+ * return 0 if processed. -+ */ -+static int hn_gen_by_inode(char *name, unsigned int nlen, struct inode *inode, -+ const unsigned int isdir) -+{ -+ int err; -+ struct dentry *d; -+ struct qstr *dname; -+ -+ err = 1; -+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) { -+ pr_warn("branch root dir was changed\n"); -+ err = 0; -+ goto out; -+ } -+ -+ if (!isdir) { -+ AuDebugOn(!name); -+ au_iigen_dec(inode); -+ spin_lock(&inode->i_lock); -+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) { -+ spin_lock(&d->d_lock); -+ dname = &d->d_name; -+ if (dname->len != nlen -+ && memcmp(dname->name, name, nlen)) { -+ spin_unlock(&d->d_lock); -+ continue; -+ } -+ err = 0; -+ au_digen_dec(d); -+ spin_unlock(&d->d_lock); -+ break; -+ } -+ spin_unlock(&inode->i_lock); -+ } else { -+ au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIR); -+ d = d_find_any_alias(inode); -+ if (!d) { -+ au_iigen_dec(inode); -+ goto out; -+ } -+ -+ spin_lock(&d->d_lock); -+ dname = &d->d_name; -+ if (dname->len == nlen && !memcmp(dname->name, name, nlen)) { -+ spin_unlock(&d->d_lock); -+ err = hn_gen_tree(d); -+ spin_lock(&d->d_lock); -+ } -+ spin_unlock(&d->d_lock); -+ dput(d); -+ } -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static int hn_gen_by_name(struct dentry *dentry, const unsigned int isdir) -+{ -+ int err; -+ -+ if (IS_ROOT(dentry)) { -+ pr_warn("branch root dir was changed\n"); -+ return 0; -+ } -+ -+ err = 0; -+ if (!isdir) { -+ au_digen_dec(dentry); -+ 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 (d_really_is_positive(dentry)) -+ err = hn_gen_tree(dentry); -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* hnotify job flags */ -+#define AuHnJob_XINO0 1 -+#define AuHnJob_GEN (1 << 1) -+#define AuHnJob_DIRENT (1 << 2) -+#define AuHnJob_ISDIR (1 << 3) -+#define AuHnJob_TRYXINO0 (1 << 4) -+#define AuHnJob_MNTPNT (1 << 5) -+#define au_ftest_hnjob(flags, name) ((flags) & AuHnJob_##name) -+#define au_fset_hnjob(flags, name) \ -+ do { (flags) |= AuHnJob_##name; } while (0) -+#define au_fclr_hnjob(flags, name) \ -+ do { (flags) &= ~AuHnJob_##name; } while (0) -+ -+enum { -+ AuHn_CHILD, -+ AuHn_PARENT, -+ AuHnLast -+}; -+ -+struct au_hnotify_args { -+ struct inode *h_dir, *dir, *h_child_inode; -+ u32 mask; -+ unsigned int flags[AuHnLast]; -+ unsigned int h_child_nlen; -+ char h_child_name[]; -+}; -+ -+struct hn_job_args { -+ unsigned int flags; -+ struct inode *inode, *h_inode, *dir, *h_dir; -+ struct dentry *dentry; -+ char *h_name; -+ int h_nlen; -+}; -+ -+static int hn_job(struct hn_job_args *a) -+{ -+ const unsigned int isdir = au_ftest_hnjob(a->flags, ISDIR); -+ int e; -+ -+ /* reset xino */ -+ if (au_ftest_hnjob(a->flags, XINO0) && a->inode) -+ hn_xino(a->inode, a->h_inode); /* ignore this error */ -+ -+ if (au_ftest_hnjob(a->flags, TRYXINO0) -+ && a->inode -+ && a->h_inode) { -+ inode_lock_shared_nested(a->h_inode, AuLsc_I_CHILD); -+ if (!vfsub_inode_nlink(a->h_inode, AU_I_BRANCH) -+ && !(a->h_inode->i_state & I_LINKABLE)) -+ hn_xino(a->inode, a->h_inode); /* ignore this error */ -+ inode_unlock_shared(a->h_inode); -+ } -+ -+ /* make the generation obsolete */ -+ if (au_ftest_hnjob(a->flags, GEN)) { -+ e = -1; -+ if (a->inode) -+ e = hn_gen_by_inode(a->h_name, a->h_nlen, a->inode, -+ isdir); -+ if (e && a->dentry) -+ hn_gen_by_name(a->dentry, isdir); -+ /* ignore this error */ -+ } -+ -+ /* make dir entries obsolete */ -+ if (au_ftest_hnjob(a->flags, DIRENT) && a->inode) { -+ struct au_vdir *vdir; -+ -+ vdir = au_ivdir(a->inode); -+ if (vdir) -+ vdir->vd_jiffy = 0; -+ /* IMustLock(a->inode); */ -+ /* inode_inc_iversion(a->inode); */ -+ } -+ -+ /* can do nothing but warn */ -+ if (au_ftest_hnjob(a->flags, MNTPNT) -+ && a->dentry -+ && d_mountpoint(a->dentry)) -+ pr_warn("mount-point %pd is removed or renamed\n", a->dentry); -+ -+ return 0; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen, -+ struct inode *dir) -+{ -+ struct dentry *dentry, *d, *parent; -+ struct qstr *dname; -+ -+ parent = d_find_any_alias(dir); -+ if (!parent) -+ return NULL; -+ -+ dentry = NULL; -+ spin_lock(&parent->d_lock); -+ list_for_each_entry(d, &parent->d_subdirs, d_child) { -+ /* AuDbg("%pd\n", d); */ -+ spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED); -+ dname = &d->d_name; -+ if (dname->len != nlen || memcmp(dname->name, name, nlen)) -+ goto cont_unlock; -+ if (au_di(d)) -+ au_digen_dec(d); -+ else -+ goto cont_unlock; -+ if (au_dcount(d) > 0) { -+ dentry = dget_dlock(d); -+ spin_unlock(&d->d_lock); -+ break; -+ } -+ -+cont_unlock: -+ spin_unlock(&d->d_lock); -+ } -+ spin_unlock(&parent->d_lock); -+ dput(parent); -+ -+ if (dentry) -+ di_write_lock_child(dentry); -+ -+ return dentry; -+} -+ -+static struct inode *lookup_wlock_by_ino(struct super_block *sb, -+ aufs_bindex_t bindex, ino_t h_ino) -+{ -+ struct inode *inode; -+ ino_t ino; -+ int err; -+ -+ inode = NULL; -+ err = au_xino_read(sb, bindex, h_ino, &ino); -+ if (!err && ino) -+ inode = ilookup(sb, ino); -+ if (!inode) -+ goto out; -+ -+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) { -+ pr_warn("wrong root branch\n"); -+ iput(inode); -+ inode = NULL; -+ goto out; -+ } -+ -+ ii_write_lock_child(inode); -+ -+out: -+ return inode; -+} -+ -+static void au_hn_bh(void *_args) -+{ -+ struct au_hnotify_args *a = _args; -+ struct super_block *sb; -+ aufs_bindex_t bindex, bbot, bfound; -+ unsigned char xino, try_iput; -+ int err; -+ struct inode *inode; -+ ino_t h_ino; -+ struct hn_job_args args; -+ struct dentry *dentry; -+ struct au_sbinfo *sbinfo; -+ -+ AuDebugOn(!_args); -+ AuDebugOn(!a->h_dir); -+ AuDebugOn(!a->dir); -+ AuDebugOn(!a->mask); -+ AuDbg("mask 0x%x, i%lu, hi%lu, hci%lu\n", -+ a->mask, a->dir->i_ino, a->h_dir->i_ino, -+ a->h_child_inode ? a->h_child_inode->i_ino : 0); -+ -+ inode = NULL; -+ dentry = NULL; -+ /* -+ * do not lock a->dir->i_mutex here -+ * because of d_revalidate() may cause a deadlock. -+ */ -+ sb = a->dir->i_sb; -+ AuDebugOn(!sb); -+ sbinfo = au_sbi(sb); -+ AuDebugOn(!sbinfo); -+ si_write_lock(sb, AuLock_NOPLMW); -+ -+ if (au_opt_test(sbinfo->si_mntflags, DIRREN)) -+ switch (a->mask & FS_EVENTS_POSS_ON_CHILD) { -+ case FS_MOVED_FROM: -+ case FS_MOVED_TO: -+ AuWarn1("DIRREN with UDBA may not work correctly " -+ "for the direct rename(2)\n"); -+ } -+ -+ ii_read_lock_parent(a->dir); -+ bfound = -1; -+ bbot = au_ibbot(a->dir); -+ for (bindex = au_ibtop(a->dir); bindex <= bbot; bindex++) -+ if (au_h_iptr(a->dir, bindex) == a->h_dir) { -+ bfound = bindex; -+ break; -+ } -+ ii_read_unlock(a->dir); -+ if (unlikely(bfound < 0)) -+ goto out; -+ -+ xino = !!au_opt_test(au_mntflags(sb), XINO); -+ h_ino = 0; -+ if (a->h_child_inode) -+ h_ino = a->h_child_inode->i_ino; -+ -+ if (a->h_child_nlen -+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], GEN) -+ || au_ftest_hnjob(a->flags[AuHn_CHILD], MNTPNT))) -+ dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen, -+ a->dir); -+ try_iput = 0; -+ 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) -+ || au_ftest_hnjob(a->flags[AuHn_CHILD], GEN))) { -+ inode = lookup_wlock_by_ino(sb, bfound, h_ino); -+ try_iput = 1; -+ } -+ -+ args.flags = a->flags[AuHn_CHILD]; -+ args.dentry = dentry; -+ args.inode = inode; -+ args.h_inode = a->h_child_inode; -+ args.dir = a->dir; -+ args.h_dir = a->h_dir; -+ args.h_name = a->h_child_name; -+ args.h_nlen = a->h_child_nlen; -+ err = hn_job(&args); -+ if (dentry) { -+ if (au_di(dentry)) -+ di_write_unlock(dentry); -+ dput(dentry); -+ } -+ if (inode && try_iput) { -+ ii_write_unlock(inode); -+ iput(inode); -+ } -+ -+ ii_write_lock_parent(a->dir); -+ args.flags = a->flags[AuHn_PARENT]; -+ args.dentry = NULL; -+ args.inode = a->dir; -+ args.h_inode = a->h_dir; -+ args.dir = NULL; -+ args.h_dir = NULL; -+ args.h_name = NULL; -+ args.h_nlen = 0; -+ err = hn_job(&args); -+ ii_write_unlock(a->dir); -+ -+out: -+ iput(a->h_child_inode); -+ iput(a->h_dir); -+ iput(a->dir); -+ si_write_unlock(sb); -+ au_nwt_done(&sbinfo->si_nowait); -+ au_kfree_rcu(a); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask, -+ const struct qstr *h_child_qstr, struct inode *h_child_inode) -+{ -+ int err, len; -+ unsigned int flags[AuHnLast], f; -+ unsigned char isdir, isroot, wh; -+ struct inode *dir; -+ struct au_hnotify_args *args; -+ char *p, *h_child_name; -+ -+ err = 0; -+ AuDebugOn(!hnotify || !hnotify->hn_aufs_inode); -+ dir = igrab(hnotify->hn_aufs_inode); -+ if (!dir) -+ goto out; -+ -+ isroot = (dir->i_ino == AUFS_ROOT_INO); -+ wh = 0; -+ h_child_name = (void *)h_child_qstr->name; -+ len = h_child_qstr->len; -+ if (h_child_name) { -+ if (len > AUFS_WH_PFX_LEN -+ && !memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) { -+ h_child_name += AUFS_WH_PFX_LEN; -+ len -= AUFS_WH_PFX_LEN; -+ wh = 1; -+ } -+ } -+ -+ isdir = 0; -+ if (h_child_inode) -+ isdir = !!S_ISDIR(h_child_inode->i_mode); -+ flags[AuHn_PARENT] = AuHnJob_ISDIR; -+ flags[AuHn_CHILD] = 0; -+ if (isdir) -+ flags[AuHn_CHILD] = AuHnJob_ISDIR; -+ au_fset_hnjob(flags[AuHn_PARENT], DIRENT); -+ au_fset_hnjob(flags[AuHn_CHILD], GEN); -+ switch (mask & ALL_FSNOTIFY_DIRENT_EVENTS) { -+ case FS_MOVED_FROM: -+ case FS_MOVED_TO: -+ au_fset_hnjob(flags[AuHn_CHILD], XINO0); -+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT); -+ fallthrough; -+ case FS_CREATE: -+ AuDebugOn(!h_child_name); -+ break; -+ -+ case FS_DELETE: -+ /* -+ * aufs never be able to get this child inode. -+ * revalidation should be in d_revalidate() -+ * by checking i_nlink, i_generation or d_unhashed(). -+ */ -+ AuDebugOn(!h_child_name); -+ au_fset_hnjob(flags[AuHn_CHILD], TRYXINO0); -+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT); -+ break; -+ -+ default: -+ AuDebugOn(1); -+ } -+ -+ if (wh) -+ h_child_inode = NULL; -+ -+ err = -ENOMEM; -+ /* iput() and kfree() will be called in au_hnotify() */ -+ args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS); -+ if (unlikely(!args)) { -+ AuErr1("no memory\n"); -+ iput(dir); -+ goto out; -+ } -+ args->flags[AuHn_PARENT] = flags[AuHn_PARENT]; -+ args->flags[AuHn_CHILD] = flags[AuHn_CHILD]; -+ args->mask = mask; -+ args->dir = dir; -+ args->h_dir = igrab(h_dir); -+ if (h_child_inode) -+ h_child_inode = igrab(h_child_inode); /* can be NULL */ -+ args->h_child_inode = h_child_inode; -+ args->h_child_nlen = len; -+ if (len) { -+ p = (void *)args; -+ p += sizeof(*args); -+ memcpy(p, h_child_name, len); -+ p[len] = 0; -+ } -+ -+ /* NFS fires the event for silly-renamed one from kworker */ -+ f = 0; -+ if (!vfsub_inode_nlink(dir, AU_I_AUFS) -+ || (au_test_nfs(h_dir->i_sb) && (mask & FS_DELETE))) -+ f = AuWkq_NEST; -+ err = au_wkq_nowait(au_hn_bh, args, dir->i_sb, f); -+ if (unlikely(err)) { -+ pr_err("wkq %d\n", err); -+ iput(args->h_child_inode); -+ iput(args->h_dir); -+ iput(args->dir); -+ au_kfree_rcu(args); -+ } -+ -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm) -+{ -+ int err; -+ -+ AuDebugOn(!(udba & AuOptMask_UDBA)); -+ -+ err = 0; -+ if (au_hnotify_op.reset_br) -+ err = au_hnotify_op.reset_br(udba, br, perm); -+ -+ return err; -+} -+ -+int au_hnotify_init_br(struct au_branch *br, int perm) -+{ -+ int err; -+ -+ err = 0; -+ if (au_hnotify_op.init_br) -+ err = au_hnotify_op.init_br(br, perm); -+ -+ return err; -+} -+ -+void au_hnotify_fin_br(struct au_branch *br) -+{ -+ if (au_hnotify_op.fin_br) -+ au_hnotify_op.fin_br(br); -+} -+ -+static void au_hn_destroy_cache(void) -+{ -+ kmem_cache_destroy(au_cache[AuCache_HNOTIFY]); -+ au_cache[AuCache_HNOTIFY] = NULL; -+} -+ -+int __init au_hnotify_init(void) -+{ -+ int err; -+ -+ err = -ENOMEM; -+ au_cache[AuCache_HNOTIFY] = AuCache(au_hnotify); -+ if (au_cache[AuCache_HNOTIFY]) { -+ err = 0; -+ if (au_hnotify_op.init) -+ err = au_hnotify_op.init(); -+ if (unlikely(err)) -+ au_hn_destroy_cache(); -+ } -+ AuTraceErr(err); -+ return err; -+} -+ -+void au_hnotify_fin(void) -+{ -+ if (au_hnotify_op.fin) -+ au_hnotify_op.fin(); -+ -+ /* cf. au_cache_fin() */ -+ if (au_cache[AuCache_HNOTIFY]) -+ au_hn_destroy_cache(); -+} -diff -Naur null/fs/aufs/iinfo.c linux-6.6.63/fs/aufs/iinfo.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/iinfo.c 2024-12-18 15:12:59.297519563 +0300 -@@ -0,0 +1,287 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * inode private data -+ */ -+ -+#include "aufs.h" -+ -+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex) -+{ -+ struct inode *h_inode; -+ struct au_hinode *hinode; -+ -+ IiMustAnyLock(inode); -+ -+ hinode = au_hinode(au_ii(inode), bindex); -+ h_inode = hinode->hi_inode; -+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0); -+ return h_inode; -+} -+ -+/* todo: hard/soft set? */ -+void au_hiput(struct au_hinode *hinode) -+{ -+ au_hn_free(hinode); -+ dput(hinode->hi_whdentry); -+ iput(hinode->hi_inode); -+} -+ -+unsigned int au_hi_flags(struct inode *inode, int isdir) -+{ -+ unsigned int flags; -+ const unsigned int mnt_flags = au_mntflags(inode->i_sb); -+ -+ flags = 0; -+ if (au_opt_test(mnt_flags, XINO)) -+ au_fset_hi(flags, XINO); -+ if (isdir && au_opt_test(mnt_flags, UDBA_HNOTIFY)) -+ au_fset_hi(flags, HNOTIFY); -+ return flags; -+} -+ -+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex, -+ struct inode *h_inode, unsigned int flags) -+{ -+ struct au_hinode *hinode; -+ struct inode *hi; -+ struct au_iinfo *iinfo = au_ii(inode); -+ -+ IiMustWriteLock(inode); -+ -+ hinode = au_hinode(iinfo, bindex); -+ hi = hinode->hi_inode; -+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0); -+ -+ if (hi) -+ au_hiput(hinode); -+ hinode->hi_inode = h_inode; -+ if (h_inode) { -+ int err; -+ struct super_block *sb = inode->i_sb; -+ struct au_branch *br; -+ -+ AuDebugOn(inode->i_mode -+ && (h_inode->i_mode & S_IFMT) -+ != (inode->i_mode & S_IFMT)); -+ if (bindex == iinfo->ii_btop) -+ au_cpup_igen(inode, h_inode); -+ br = au_sbr(sb, bindex); -+ hinode->hi_id = br->br_id; -+ if (au_ftest_hi(flags, XINO)) { -+ err = au_xino_write(sb, bindex, h_inode->i_ino, -+ inode->i_ino); -+ if (unlikely(err)) -+ AuIOErr1("failed au_xino_write() %d\n", err); -+ } -+ -+ if (au_ftest_hi(flags, HNOTIFY) -+ && au_br_hnotifyable(br->br_perm)) { -+ err = au_hn_alloc(hinode, inode); -+ if (unlikely(err)) -+ AuIOErr1("au_hn_alloc() %d\n", err); -+ } -+ } -+} -+ -+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex, -+ struct dentry *h_wh) -+{ -+ struct au_hinode *hinode; -+ -+ IiMustWriteLock(inode); -+ -+ hinode = au_hinode(au_ii(inode), bindex); -+ AuDebugOn(hinode->hi_whdentry); -+ hinode->hi_whdentry = h_wh; -+} -+ -+void au_update_iigen(struct inode *inode, int half) -+{ -+ struct au_iinfo *iinfo; -+ struct au_iigen *iigen; -+ unsigned int sigen; -+ -+ sigen = au_sigen(inode->i_sb); -+ iinfo = au_ii(inode); -+ iigen = &iinfo->ii_generation; -+ spin_lock(&iigen->ig_spin); -+ iigen->ig_generation = sigen; -+ if (half) -+ au_ig_fset(iigen->ig_flags, HALF_REFRESHED); -+ else -+ au_ig_fclr(iigen->ig_flags, HALF_REFRESHED); -+ spin_unlock(&iigen->ig_spin); -+} -+ -+/* it may be called at remount time, too */ -+void au_update_ibrange(struct inode *inode, int do_put_zero) -+{ -+ struct au_iinfo *iinfo; -+ aufs_bindex_t bindex, bbot; -+ -+ AuDebugOn(au_is_bad_inode(inode)); -+ IiMustWriteLock(inode); -+ -+ iinfo = au_ii(inode); -+ if (do_put_zero && iinfo->ii_btop >= 0) { -+ for (bindex = iinfo->ii_btop; bindex <= iinfo->ii_bbot; -+ bindex++) { -+ struct inode *h_i; -+ -+ h_i = au_hinode(iinfo, bindex)->hi_inode; -+ if (h_i -+ && !vfsub_inode_nlink(h_i, AU_I_BRANCH) -+ && !(h_i->i_state & I_LINKABLE)) -+ au_set_h_iptr(inode, bindex, NULL, 0); -+ } -+ } -+ -+ iinfo->ii_btop = -1; -+ iinfo->ii_bbot = -1; -+ bbot = au_sbbot(inode->i_sb); -+ for (bindex = 0; bindex <= bbot; bindex++) -+ if (au_hinode(iinfo, bindex)->hi_inode) { -+ iinfo->ii_btop = bindex; -+ break; -+ } -+ if (iinfo->ii_btop >= 0) -+ for (bindex = bbot; bindex >= iinfo->ii_btop; bindex--) -+ if (au_hinode(iinfo, bindex)->hi_inode) { -+ iinfo->ii_bbot = bindex; -+ break; -+ } -+ AuDebugOn(iinfo->ii_btop > iinfo->ii_bbot); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void au_icntnr_init_once(void *_c) -+{ -+ struct au_icntnr *c = _c; -+ struct au_iinfo *iinfo = &c->iinfo; -+ -+ spin_lock_init(&iinfo->ii_generation.ig_spin); -+ au_rw_init(&iinfo->ii_rwsem); -+ inode_init_once(&c->vfs_inode); -+ spin_lock_init(&c->nlink_spin); -+} -+ -+void au_hinode_init(struct au_hinode *hinode) -+{ -+ hinode->hi_inode = NULL; -+ hinode->hi_id = -1; -+ au_hn_init(hinode); -+ hinode->hi_whdentry = NULL; -+} -+ -+int au_iinfo_init(struct inode *inode) -+{ -+ struct au_iinfo *iinfo; -+ struct super_block *sb; -+ struct au_hinode *hi; -+ int nbr, i; -+ -+ sb = inode->i_sb; -+ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo); -+ nbr = au_sbbot(sb) + 1; -+ if (unlikely(nbr <= 0)) -+ nbr = 1; -+ hi = kmalloc_array(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS); -+ if (hi) { -+ au_lcnt_inc(&au_sbi(sb)->si_ninodes); -+ -+ iinfo->ii_hinode = hi; -+ for (i = 0; i < nbr; i++, hi++) -+ au_hinode_init(hi); -+ -+ iinfo->ii_generation.ig_generation = au_sigen(sb); -+ iinfo->ii_btop = -1; -+ iinfo->ii_bbot = -1; -+ iinfo->ii_vdir = NULL; -+ return 0; -+ } -+ return -ENOMEM; -+} -+ -+int au_hinode_realloc(struct au_iinfo *iinfo, int nbr, int may_shrink) -+{ -+ int err, i; -+ struct au_hinode *hip; -+ -+ AuRwMustWriteLock(&iinfo->ii_rwsem); -+ -+ err = -ENOMEM; -+ hip = au_krealloc(iinfo->ii_hinode, sizeof(*hip) * nbr, GFP_NOFS, -+ may_shrink); -+ if (hip) { -+ iinfo->ii_hinode = hip; -+ i = iinfo->ii_bbot + 1; -+ hip += i; -+ for (; i < nbr; i++, hip++) -+ au_hinode_init(hip); -+ err = 0; -+ } -+ -+ return err; -+} -+ -+void au_iinfo_fin(struct inode *inode) -+{ -+ struct au_iinfo *iinfo; -+ struct au_hinode *hi; -+ struct super_block *sb; -+ aufs_bindex_t bindex, bbot; -+ const unsigned char unlinked = !vfsub_inode_nlink(inode, AU_I_AUFS); -+ -+ AuDebugOn(au_is_bad_inode(inode)); -+ -+ sb = inode->i_sb; -+ au_lcnt_dec(&au_sbi(sb)->si_ninodes); -+ if (si_pid_test(sb)) -+ au_xino_delete_inode(inode, unlinked); -+ else { -+ /* -+ * it is safe to hide the dependency between sbinfo and -+ * sb->s_umount. -+ */ -+ lockdep_off(); -+ si_noflush_read_lock(sb); -+ au_xino_delete_inode(inode, unlinked); -+ si_read_unlock(sb); -+ lockdep_on(); -+ } -+ -+ iinfo = au_ii(inode); -+ if (iinfo->ii_vdir) -+ au_vdir_free(iinfo->ii_vdir); -+ -+ bindex = iinfo->ii_btop; -+ if (bindex >= 0) { -+ hi = au_hinode(iinfo, bindex); -+ bbot = iinfo->ii_bbot; -+ while (bindex++ <= bbot) { -+ if (hi->hi_inode) -+ au_hiput(hi); -+ hi++; -+ } -+ } -+ au_kfree_rcu(iinfo->ii_hinode); -+ AuRwDestroy(&iinfo->ii_rwsem); -+} -diff -Naur null/fs/aufs/inode.c linux-6.6.63/fs/aufs/inode.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/inode.c 2024-12-18 15:12:59.297519563 +0300 -@@ -0,0 +1,532 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * inode functions -+ */ -+ -+#include -+#include "aufs.h" -+ -+struct inode *au_igrab(struct inode *inode) -+{ -+ if (inode) { -+ AuDebugOn(!atomic_read(&inode->i_count)); -+ ihold(inode); -+ } -+ return inode; -+} -+ -+static void au_refresh_hinode_attr(struct inode *inode, int do_version) -+{ -+ au_cpup_attr_all(inode, /*force*/0); -+ au_update_iigen(inode, /*half*/1); -+ if (do_version) -+ inode_inc_iversion(inode); -+} -+ -+static int au_ii_refresh(struct inode *inode, int *update) -+{ -+ int err, e, nbr; -+ umode_t type; -+ aufs_bindex_t bindex, new_bindex; -+ struct super_block *sb; -+ struct au_iinfo *iinfo; -+ struct au_hinode *p, *q, tmp; -+ -+ AuDebugOn(au_is_bad_inode(inode)); -+ IiMustWriteLock(inode); -+ -+ *update = 0; -+ sb = inode->i_sb; -+ nbr = au_sbbot(sb) + 1; -+ type = inode->i_mode & S_IFMT; -+ iinfo = au_ii(inode); -+ err = au_hinode_realloc(iinfo, nbr, /*may_shrink*/0); -+ if (unlikely(err)) -+ goto out; -+ -+ AuDebugOn(iinfo->ii_btop < 0); -+ p = au_hinode(iinfo, iinfo->ii_btop); -+ for (bindex = iinfo->ii_btop; bindex <= iinfo->ii_bbot; -+ bindex++, p++) { -+ if (!p->hi_inode) -+ continue; -+ -+ AuDebugOn(type != (p->hi_inode->i_mode & S_IFMT)); -+ new_bindex = au_br_index(sb, p->hi_id); -+ if (new_bindex == bindex) -+ continue; -+ -+ if (new_bindex < 0) { -+ *update = 1; -+ au_hiput(p); -+ p->hi_inode = NULL; -+ continue; -+ } -+ -+ if (new_bindex < iinfo->ii_btop) -+ iinfo->ii_btop = new_bindex; -+ if (iinfo->ii_bbot < new_bindex) -+ iinfo->ii_bbot = new_bindex; -+ /* swap two lower inode, and loop again */ -+ q = au_hinode(iinfo, new_bindex); -+ tmp = *q; -+ *q = *p; -+ *p = tmp; -+ if (tmp.hi_inode) { -+ bindex--; -+ p--; -+ } -+ } -+ au_update_ibrange(inode, /*do_put_zero*/0); -+ au_hinode_realloc(iinfo, nbr, /*may_shrink*/1); /* harmless if err */ -+ e = au_dy_irefresh(inode); -+ if (unlikely(e && !err)) -+ err = e; -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+void au_refresh_iop(struct inode *inode, int force_getattr) -+{ -+ int type; -+ struct au_sbinfo *sbi = au_sbi(inode->i_sb); -+ const struct inode_operations *iop -+ = force_getattr ? aufs_iop : sbi->si_iop_array; -+ -+ if (inode->i_op == iop) -+ return; -+ -+ switch (inode->i_mode & S_IFMT) { -+ case S_IFDIR: -+ type = AuIop_DIR; -+ break; -+ case S_IFLNK: -+ type = AuIop_SYMLINK; -+ break; -+ default: -+ type = AuIop_OTHER; -+ break; -+ } -+ -+ inode->i_op = iop + type; -+ /* unnecessary smp_wmb() */ -+} -+ -+int au_refresh_hinode_self(struct inode *inode) -+{ -+ int err, update; -+ -+ err = au_ii_refresh(inode, &update); -+ if (!err) -+ au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode)); -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_refresh_hinode(struct inode *inode, struct dentry *dentry) -+{ -+ int err, e, update; -+ unsigned int flags; -+ umode_t mode; -+ aufs_bindex_t bindex, bbot; -+ unsigned char isdir; -+ struct au_hinode *p; -+ struct au_iinfo *iinfo; -+ -+ err = au_ii_refresh(inode, &update); -+ if (unlikely(err)) -+ goto out; -+ -+ update = 0; -+ iinfo = au_ii(inode); -+ p = au_hinode(iinfo, iinfo->ii_btop); -+ mode = (inode->i_mode & S_IFMT); -+ isdir = S_ISDIR(mode); -+ flags = au_hi_flags(inode, isdir); -+ bbot = au_dbbot(dentry); -+ for (bindex = au_dbtop(dentry); bindex <= bbot; bindex++) { -+ struct inode *h_i, *h_inode; -+ struct dentry *h_d; -+ -+ h_d = au_h_dptr(dentry, bindex); -+ if (!h_d || d_is_negative(h_d)) -+ continue; -+ -+ h_inode = d_inode(h_d); -+ AuDebugOn(mode != (h_inode->i_mode & S_IFMT)); -+ if (iinfo->ii_btop <= bindex && bindex <= iinfo->ii_bbot) { -+ h_i = au_h_iptr(inode, bindex); -+ if (h_i) { -+ if (h_i == h_inode) -+ continue; -+ err = -EIO; -+ break; -+ } -+ } -+ if (bindex < iinfo->ii_btop) -+ iinfo->ii_btop = bindex; -+ if (iinfo->ii_bbot < bindex) -+ iinfo->ii_bbot = bindex; -+ au_set_h_iptr(inode, bindex, au_igrab(h_inode), flags); -+ update = 1; -+ } -+ au_update_ibrange(inode, /*do_put_zero*/0); -+ e = au_dy_irefresh(inode); -+ if (unlikely(e && !err)) -+ err = e; -+ if (!err) -+ au_refresh_hinode_attr(inode, update && isdir); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static int set_inode(struct inode *inode, struct dentry *dentry) -+{ -+ int err; -+ unsigned int flags; -+ umode_t mode; -+ aufs_bindex_t bindex, btop, btail; -+ unsigned char isdir; -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ struct au_iinfo *iinfo; -+ const struct inode_operations *iop; -+ -+ IiMustWriteLock(inode); -+ -+ err = 0; -+ isdir = 0; -+ iop = au_sbi(inode->i_sb)->si_iop_array; -+ btop = au_dbtop(dentry); -+ h_dentry = au_h_dptr(dentry, btop); -+ h_inode = d_inode(h_dentry); -+ mode = h_inode->i_mode; -+ switch (mode & S_IFMT) { -+ case S_IFREG: -+ btail = au_dbtail(dentry); -+ inode->i_op = iop + AuIop_OTHER; -+ inode->i_fop = &aufs_file_fop; -+ err = au_dy_iaop(inode, btop, h_inode); -+ if (unlikely(err)) -+ goto out; -+ break; -+ case S_IFDIR: -+ isdir = 1; -+ btail = au_dbtaildir(dentry); -+ inode->i_op = iop + AuIop_DIR; -+ inode->i_fop = &aufs_dir_fop; -+ break; -+ case S_IFLNK: -+ btail = au_dbtail(dentry); -+ inode->i_op = iop + AuIop_SYMLINK; -+ break; -+ case S_IFBLK: -+ case S_IFCHR: -+ case S_IFIFO: -+ case S_IFSOCK: -+ btail = au_dbtail(dentry); -+ inode->i_op = iop + AuIop_OTHER; -+ init_special_inode(inode, mode, h_inode->i_rdev); -+ break; -+ default: -+ AuIOErr("Unknown file type 0%o\n", mode); -+ err = -EIO; -+ goto out; -+ } -+ -+ /* do not set hnotify for whiteouted dirs (SHWH mode) */ -+ flags = au_hi_flags(inode, isdir); -+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH) -+ && au_ftest_hi(flags, HNOTIFY) -+ && dentry->d_name.len > AUFS_WH_PFX_LEN -+ && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) -+ au_fclr_hi(flags, HNOTIFY); -+ iinfo = au_ii(inode); -+ iinfo->ii_btop = btop; -+ iinfo->ii_bbot = btail; -+ for (bindex = btop; bindex <= btail; bindex++) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (h_dentry) -+ au_set_h_iptr(inode, bindex, -+ au_igrab(d_inode(h_dentry)), flags); -+ } -+ au_cpup_attr_all(inode, /*force*/1); -+ /* -+ * to force calling aufs_get_inode_acl() every time, -+ * do not call cache_no_acl() for aufs inode. -+ */ -+ -+out: -+ return err; -+} -+ -+/* -+ * successful returns with iinfo write_locked -+ * minus: errno -+ * zero: success, matched -+ * plus: no error, but unmatched -+ */ -+static int reval_inode(struct inode *inode, struct dentry *dentry) -+{ -+ int err; -+ unsigned int gen, igflags; -+ aufs_bindex_t bindex, bbot; -+ struct inode *h_inode, *h_dinode; -+ struct dentry *h_dentry; -+ -+ /* -+ * before this function, if aufs got any iinfo lock, it must be only -+ * one, the parent dir. -+ * it can happen by UDBA and the obsoleted inode number. -+ */ -+ err = -EIO; -+ if (unlikely(inode->i_ino == parent_ino(dentry))) -+ goto out; -+ -+ err = 1; -+ ii_write_lock_new_child(inode); -+ h_dentry = au_h_dptr(dentry, au_dbtop(dentry)); -+ h_dinode = d_inode(h_dentry); -+ bbot = au_ibbot(inode); -+ for (bindex = au_ibtop(inode); bindex <= bbot; bindex++) { -+ h_inode = au_h_iptr(inode, bindex); -+ if (!h_inode || h_inode != h_dinode) -+ continue; -+ -+ err = 0; -+ gen = au_iigen(inode, &igflags); -+ if (gen == au_digen(dentry) -+ && !au_ig_ftest(igflags, HALF_REFRESHED)) -+ break; -+ -+ /* fully refresh inode using dentry */ -+ err = au_refresh_hinode(inode, dentry); -+ if (!err) -+ au_update_iigen(inode, /*half*/0); -+ break; -+ } -+ -+ if (unlikely(err)) -+ ii_write_unlock(inode); -+out: -+ return err; -+} -+ -+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, -+ unsigned int d_type, ino_t *ino) -+{ -+ int err, idx; -+ const int isnondir = d_type != DT_DIR; -+ -+ /* prevent hardlinked inode number from race condition */ -+ if (isnondir) { -+ err = au_xinondir_enter(sb, bindex, h_ino, &idx); -+ if (unlikely(err)) -+ goto out; -+ } -+ -+ err = au_xino_read(sb, bindex, h_ino, ino); -+ if (unlikely(err)) -+ goto out_xinondir; -+ -+ if (!*ino) { -+ err = -EIO; -+ *ino = au_xino_new_ino(sb); -+ if (unlikely(!*ino)) -+ goto out_xinondir; -+ err = au_xino_write(sb, bindex, h_ino, *ino); -+ if (unlikely(err)) -+ goto out_xinondir; -+ } -+ -+out_xinondir: -+ if (isnondir && idx >= 0) -+ au_xinondir_leave(sb, bindex, h_ino, idx); -+out: -+ return err; -+} -+ -+/* successful returns with iinfo write_locked */ -+/* todo: return with unlocked? */ -+struct inode *au_new_inode(struct dentry *dentry, int must_new) -+{ -+ struct inode *inode, *h_inode; -+ struct dentry *h_dentry; -+ struct super_block *sb; -+ ino_t h_ino, ino; -+ int err, idx, hlinked; -+ aufs_bindex_t btop; -+ -+ sb = dentry->d_sb; -+ btop = au_dbtop(dentry); -+ h_dentry = au_h_dptr(dentry, btop); -+ h_inode = d_inode(h_dentry); -+ h_ino = h_inode->i_ino; -+ hlinked = !d_is_dir(h_dentry) && vfsub_inode_nlink(h_inode, AU_I_BRANCH) > 1; -+ -+new_ino: -+ /* -+ * stop 'race'-ing between hardlinks under different -+ * parents. -+ */ -+ if (hlinked) { -+ err = au_xinondir_enter(sb, btop, h_ino, &idx); -+ inode = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out; -+ } -+ -+ err = au_xino_read(sb, btop, h_ino, &ino); -+ inode = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out_xinondir; -+ -+ if (!ino) { -+ ino = au_xino_new_ino(sb); -+ if (unlikely(!ino)) { -+ inode = ERR_PTR(-EIO); -+ goto out_xinondir; -+ } -+ } -+ -+ AuDbg("i%lu\n", (unsigned long)ino); -+ inode = au_iget_locked(sb, ino); -+ err = PTR_ERR(inode); -+ if (IS_ERR(inode)) -+ goto out_xinondir; -+ -+ AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW)); -+ if (inode->i_state & I_NEW) { -+ ii_write_lock_new_child(inode); -+ err = set_inode(inode, dentry); -+ if (!err) { -+ unlock_new_inode(inode); -+ goto out_xinondir; /* success */ -+ } -+ -+ /* -+ * iget_failed() calls iput(), but we need to call -+ * ii_write_unlock() after iget_failed(). so dirty hack for -+ * i_count. -+ */ -+ atomic_inc(&inode->i_count); -+ iget_failed(inode); -+ ii_write_unlock(inode); -+ au_xino_write(sb, btop, h_ino, /*ino*/0); -+ /* ignore this error */ -+ goto out_iput; -+ } else if (!must_new && !IS_DEADDIR(inode) -+ && vfsub_inode_nlink(inode, AU_I_AUFS)) { -+ /* -+ * horrible race condition between lookup, readdir and copyup -+ * (or something). -+ */ -+ if (hlinked && idx >= 0) -+ au_xinondir_leave(sb, btop, h_ino, idx); -+ err = reval_inode(inode, dentry); -+ if (unlikely(err < 0)) { -+ hlinked = 0; -+ goto out_iput; -+ } -+ if (!err) -+ goto out; /* success */ -+ else if (hlinked && idx >= 0) { -+ err = au_xinondir_enter(sb, btop, h_ino, &idx); -+ if (unlikely(err)) { -+ iput(inode); -+ inode = ERR_PTR(err); -+ goto out; -+ } -+ } -+ } -+ -+ 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", -+ btop, au_sbtype(h_dentry->d_sb), dentry, -+ (unsigned long)h_ino, (unsigned long)ino); -+ ino = 0; -+ err = au_xino_write(sb, btop, h_ino, /*ino*/0); -+ if (!err) { -+ iput(inode); -+ if (hlinked && idx >= 0) -+ au_xinondir_leave(sb, btop, h_ino, idx); -+ goto new_ino; -+ } -+ -+out_iput: -+ iput(inode); -+ inode = ERR_PTR(err); -+out_xinondir: -+ if (hlinked && idx >= 0) -+ au_xinondir_leave(sb, btop, h_ino, idx); -+out: -+ return inode; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex, -+ struct inode *inode) -+{ -+ int err; -+ struct inode *hi; -+ -+ err = au_br_rdonly(au_sbr(sb, bindex)); -+ -+ /* pseudo-link after flushed may happen out of bounds */ -+ if (!err -+ && inode -+ && au_ibtop(inode) <= bindex -+ && bindex <= au_ibbot(inode)) { -+ /* -+ * permission check is unnecessary since vfsub routine -+ * will be called later -+ */ -+ hi = au_h_iptr(inode, bindex); -+ if (hi) -+ err = IS_IMMUTABLE(hi) ? -EROFS : 0; -+ } -+ -+ return err; -+} -+ -+int au_test_h_perm(struct mnt_idmap *h_idmap, struct inode *h_inode, -+ int mask) -+{ -+ if (uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) -+ return 0; -+ return inode_permission(h_idmap, h_inode, mask); -+} -+ -+int au_test_h_perm_sio(struct mnt_idmap *h_idmap, struct inode *h_inode, -+ int mask) -+{ -+ if (au_test_nfs(h_inode->i_sb) -+ && (mask & MAY_WRITE) -+ && S_ISDIR(h_inode->i_mode)) -+ mask |= MAY_READ; /* force permission check */ -+ return au_test_h_perm(h_idmap, h_inode, mask); -+} -diff -Naur null/fs/aufs/inode.h linux-6.6.63/fs/aufs/inode.h ---- /dev/null -+++ linux-6.6.63/fs/aufs/inode.h 2024-12-18 15:12:59.298519551 +0300 -@@ -0,0 +1,727 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * inode operations -+ */ -+ -+#ifndef __AUFS_INODE_H__ -+#define __AUFS_INODE_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include "fstype.h" -+#include "rwsem.h" -+ -+struct vfsmount; -+ -+struct au_hnotify { -+#ifdef CONFIG_AUFS_HNOTIFY -+#ifdef CONFIG_AUFS_HFSNOTIFY -+ /* never use fsnotify_add_vfsmount_mark() */ -+ struct fsnotify_mark hn_mark; -+#endif -+ struct inode *hn_aufs_inode; /* no get/put */ -+ struct rcu_head rcu; -+#endif -+} ____cacheline_aligned_in_smp; -+ -+struct au_hinode { -+ struct inode *hi_inode; -+ aufs_bindex_t hi_id; -+#ifdef CONFIG_AUFS_HNOTIFY -+ struct au_hnotify *hi_notify; -+#endif -+ -+ /* reference to the copied-up whiteout with get/put */ -+ struct dentry *hi_whdentry; -+}; -+ -+/* ig_flags */ -+#define AuIG_HALF_REFRESHED 1 -+#define au_ig_ftest(flags, name) ((flags) & AuIG_##name) -+#define au_ig_fset(flags, name) \ -+ do { (flags) |= AuIG_##name; } while (0) -+#define au_ig_fclr(flags, name) \ -+ do { (flags) &= ~AuIG_##name; } while (0) -+ -+struct au_iigen { -+ spinlock_t ig_spin; -+ __u32 ig_generation, ig_flags; -+}; -+ -+struct au_vdir; -+struct au_iinfo { -+ struct au_iigen ii_generation; -+ struct super_block *ii_hsb1; /* no get/put */ -+ -+ struct au_rwsem ii_rwsem; -+ aufs_bindex_t ii_btop, ii_bbot; -+ __u32 ii_higen; -+ struct au_hinode *ii_hinode; -+ struct au_vdir *ii_vdir; -+}; -+ -+struct au_icntnr { -+ struct au_iinfo iinfo; -+ struct inode vfs_inode; -+ spinlock_t nlink_spin; /* protects vfs_inode.i_nlink */ -+ struct hlist_bl_node plink; -+ struct rcu_head rcu; -+} ____cacheline_aligned_in_smp; -+ -+/* au_pin flags */ -+#define AuPin_DI_LOCKED 1 -+#define AuPin_MNT_WRITE (1 << 1) -+#define au_ftest_pin(flags, name) ((flags) & AuPin_##name) -+#define au_fset_pin(flags, name) \ -+ do { (flags) |= AuPin_##name; } while (0) -+#define au_fclr_pin(flags, name) \ -+ do { (flags) &= ~AuPin_##name; } while (0) -+ -+struct au_pin { -+ /* input */ -+ struct dentry *dentry; -+ unsigned int udba; -+ unsigned char lsc_di, lsc_hi, flags; -+ aufs_bindex_t bindex; -+ -+ /* output */ -+ struct dentry *parent; -+ struct au_hinode *hdir; -+ struct vfsmount *h_mnt; -+ -+ /* temporary unlock/relock for copyup */ -+ struct dentry *h_dentry, *h_parent; -+ struct au_branch *br; -+ struct task_struct *task; -+}; -+ -+void au_pin_hdir_unlock(struct au_pin *p); -+int au_pin_hdir_lock(struct au_pin *p); -+int au_pin_hdir_relock(struct au_pin *p); -+void au_pin_hdir_acquire_nest(struct au_pin *p); -+void au_pin_hdir_release(struct au_pin *p); -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline struct au_iinfo *au_ii(struct inode *inode) -+{ -+ BUG_ON(is_bad_inode(inode)); -+ return &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo); -+} -+ -+static inline void au_nlink_lock(struct inode *inode) -+{ -+ spinlock_t *spin; -+ -+ AuDebugOn(!au_test_aufs(inode->i_sb)); -+ AuDebugOn(is_bad_inode(inode)); -+ spin = &(container_of(inode, struct au_icntnr, vfs_inode)->nlink_spin); -+ spin_lock(spin); -+} -+ -+static inline void au_nlink_unlock(struct inode *inode) -+{ -+ spinlock_t *spin; -+ -+ spin = &(container_of(inode, struct au_icntnr, vfs_inode)->nlink_spin); -+ spin_unlock(spin); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* inode.c */ -+struct inode *au_igrab(struct inode *inode); -+void au_refresh_iop(struct inode *inode, int force_getattr); -+int au_refresh_hinode_self(struct inode *inode); -+int au_refresh_hinode(struct inode *inode, struct dentry *dentry); -+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, -+ unsigned int d_type, ino_t *ino); -+struct inode *au_new_inode(struct dentry *dentry, int must_new); -+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex, -+ struct inode *inode); -+int au_test_h_perm(struct mnt_idmap *h_idmap, struct inode *h_inode, -+ int mask); -+int au_test_h_perm_sio(struct mnt_idmap *h_idmap, struct inode *h_inode, -+ int mask); -+ -+static inline int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex, -+ ino_t h_ino, unsigned int d_type, ino_t *ino) -+{ -+#ifdef CONFIG_AUFS_SHWH -+ return au_ino(sb, bindex, h_ino, d_type, ino); -+#else -+ return 0; -+#endif -+} -+ -+/* i_op.c */ -+enum { -+ AuIop_SYMLINK, -+ AuIop_DIR, -+ AuIop_OTHER, -+ AuIop_Last -+}; -+extern struct inode_operations aufs_iop[AuIop_Last], /* not const */ -+ aufs_iop_nogetattr[AuIop_Last]; -+ -+/* au_wr_dir flags */ -+#define AuWrDir_ADD_ENTRY 1 -+#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) -+#define au_fclr_wrdir(flags, name) \ -+ do { (flags) &= ~AuWrDir_##name; } while (0) -+ -+struct au_wr_dir_args { -+ aufs_bindex_t force_btgt; -+ unsigned char flags; -+}; -+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry, -+ struct au_wr_dir_args *args); -+ -+struct dentry *au_pinned_h_parent(struct au_pin *pin); -+void au_pin_init(struct au_pin *pin, struct dentry *dentry, -+ aufs_bindex_t bindex, int lsc_di, int lsc_hi, -+ unsigned int udba, unsigned char flags); -+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex, -+ unsigned int udba, unsigned char flags) __must_check; -+int au_do_pin(struct au_pin *pin) __must_check; -+void au_unpin(struct au_pin *pin); -+int au_reval_for_attr(struct dentry *dentry, unsigned int sigen); -+ -+#define AuIcpup_DID_CPUP 1 -+#define au_ftest_icpup(flags, name) ((flags) & AuIcpup_##name) -+#define au_fset_icpup(flags, name) \ -+ do { (flags) |= AuIcpup_##name; } while (0) -+#define au_fclr_icpup(flags, name) \ -+ do { (flags) &= ~AuIcpup_##name; } while (0) -+ -+struct au_icpup_args { -+ unsigned char flags; -+ unsigned char pin_flags; -+ aufs_bindex_t btgt; -+ unsigned int udba; -+ struct au_pin pin; -+ struct path h_path; -+ struct inode *h_inode; -+}; -+ -+int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia, -+ struct au_icpup_args *a); -+ -+int au_h_path_getattr(struct dentry *dentry, struct inode *inode, int force, -+ struct path *h_path, int locked); -+ -+/* i_op_add.c */ -+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex, -+ struct dentry *h_parent, int isdir); -+int aufs_mknod(struct mnt_idmap *idmap, struct inode *dir, -+ struct dentry *dentry, umode_t mode, dev_t dev); -+int aufs_symlink(struct mnt_idmap *idmap, struct inode *dir, -+ struct dentry *dentry, const char *symname); -+int aufs_create(struct mnt_idmap *idmap, 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 mnt_idmap *idmap, struct inode *dir, -+ struct file *file, umode_t mode); -+int aufs_link(struct dentry *src_dentry, struct inode *dir, -+ struct dentry *dentry); -+int aufs_mkdir(struct mnt_idmap *idmap, struct inode *dir, -+ struct dentry *dentry, umode_t mode); -+ -+/* i_op_del.c */ -+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup); -+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex, -+ struct dentry *h_parent, int isdir); -+int aufs_unlink(struct inode *dir, struct dentry *dentry); -+int aufs_rmdir(struct inode *dir, struct dentry *dentry); -+ -+/* i_op_ren.c */ -+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt); -+int aufs_rename(struct mnt_idmap *idmap, -+ struct inode *_src_dir, struct dentry *_src_dentry, -+ struct inode *_dst_dir, struct dentry *_dst_dentry, -+ unsigned int _flags); -+ -+/* iinfo.c */ -+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex); -+void au_hiput(struct au_hinode *hinode); -+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex, -+ struct dentry *h_wh); -+unsigned int au_hi_flags(struct inode *inode, int isdir); -+ -+/* hinode flags */ -+#define AuHi_XINO 1 -+#define AuHi_HNOTIFY (1 << 1) -+#define au_ftest_hi(flags, name) ((flags) & AuHi_##name) -+#define au_fset_hi(flags, name) \ -+ do { (flags) |= AuHi_##name; } while (0) -+#define au_fclr_hi(flags, name) \ -+ do { (flags) &= ~AuHi_##name; } while (0) -+ -+#ifndef CONFIG_AUFS_HNOTIFY -+#undef AuHi_HNOTIFY -+#define AuHi_HNOTIFY 0 -+#endif -+ -+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex, -+ struct inode *h_inode, unsigned int flags); -+ -+void au_update_iigen(struct inode *inode, int half); -+void au_update_ibrange(struct inode *inode, int do_put_zero); -+ -+void au_icntnr_init_once(void *_c); -+void au_hinode_init(struct au_hinode *hinode); -+int au_iinfo_init(struct inode *inode); -+void au_iinfo_fin(struct inode *inode); -+int au_hinode_realloc(struct au_iinfo *iinfo, int nbr, int may_shrink); -+ -+#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 -+void au_plink_list(struct super_block *sb); -+#else -+AuStubVoid(au_plink_list, struct super_block *sb) -+#endif -+int au_plink_test(struct inode *inode); -+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex); -+void au_plink_append(struct inode *inode, aufs_bindex_t bindex, -+ struct dentry *h_dentry); -+void au_plink_put(struct super_block *sb, int verbose); -+void au_plink_clean(struct super_block *sb, int verbose); -+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id); -+#else -+AuStubInt0(au_plink_maint, struct super_block *sb, int flags); -+AuStubVoid(au_plink_maint_leave, struct au_sbinfo *sbinfo); -+AuStubInt0(au_plink_maint_enter, struct super_block *sb); -+AuStubVoid(au_plink_list, struct super_block *sb); -+AuStubInt0(au_plink_test, struct inode *inode); -+AuStub(struct dentry *, au_plink_lkup, return NULL, -+ struct inode *inode, aufs_bindex_t bindex); -+AuStubVoid(au_plink_append, struct inode *inode, aufs_bindex_t bindex, -+ struct dentry *h_dentry); -+AuStubVoid(au_plink_put, struct super_block *sb, int verbose); -+AuStubVoid(au_plink_clean, struct super_block *sb, int verbose); -+AuStubVoid(au_plink_half_refresh, struct super_block *sb, aufs_bindex_t br_id); -+#endif /* CONFIG_PROC_FS */ -+ -+#ifdef CONFIG_AUFS_XATTR -+/* xattr.c */ -+int au_cpup_xattr(struct path *h_dst, struct path *h_src, int ignore_flags, -+ unsigned int verbose); -+ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size); -+void au_xattr_init(struct super_block *sb); -+#else -+AuStubInt0(au_cpup_xattr, struct path *h_dst, struct path *h_src, -+ int ignore_flags, unsigned int verbose); -+AuStubVoid(au_xattr_init, struct super_block *sb); -+#endif -+ -+#ifdef CONFIG_FS_POSIX_ACL -+struct posix_acl *aufs_get_inode_acl(struct inode *inode, int type, bool rcu); -+struct posix_acl *aufs_get_acl(struct mnt_idmap *idmap, -+ struct dentry *dentry, int type); -+int aufs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry, -+ struct posix_acl *acl, int type); -+#endif -+ -+#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL) -+enum { -+ AU_XATTR_SET, -+ AU_ACL_SET -+}; -+ -+struct au_sxattr { -+ int type; -+ union { -+ struct { -+ const char *name; -+ const void *value; -+ size_t size; -+ int flags; -+ } set; -+ struct { -+ struct posix_acl *acl; -+ int type; -+ } acl_set; -+ } u; -+}; -+ssize_t au_sxattr(struct dentry *dentry, struct inode *inode, -+ struct au_sxattr *arg); -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* lock subclass for iinfo */ -+enum { -+ AuLsc_II_CHILD, /* child first */ -+ AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hnotify */ -+ AuLsc_II_CHILD3, /* copyup dirs */ -+ AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */ -+ AuLsc_II_PARENT2, -+ AuLsc_II_PARENT3, /* copyup dirs */ -+ AuLsc_II_NEW_CHILD -+}; -+ -+/* -+ * ii_read_lock_child, ii_write_lock_child, -+ * ii_read_lock_child2, ii_write_lock_child2, -+ * ii_read_lock_child3, ii_write_lock_child3, -+ * ii_read_lock_parent, ii_write_lock_parent, -+ * ii_read_lock_parent2, ii_write_lock_parent2, -+ * ii_read_lock_parent3, ii_write_lock_parent3, -+ * ii_read_lock_new_child, ii_write_lock_new_child, -+ */ -+#define AuReadLockFunc(name, lsc) \ -+static inline void ii_read_lock_##name(struct inode *i) \ -+{ \ -+ au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \ -+} -+ -+#define AuWriteLockFunc(name, lsc) \ -+static inline void ii_write_lock_##name(struct inode *i) \ -+{ \ -+ au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \ -+} -+ -+#define AuRWLockFuncs(name, lsc) \ -+ AuReadLockFunc(name, lsc) \ -+ AuWriteLockFunc(name, lsc) -+ -+AuRWLockFuncs(child, CHILD); -+AuRWLockFuncs(child2, CHILD2); -+AuRWLockFuncs(child3, CHILD3); -+AuRWLockFuncs(parent, PARENT); -+AuRWLockFuncs(parent2, PARENT2); -+AuRWLockFuncs(parent3, PARENT3); -+AuRWLockFuncs(new_child, NEW_CHILD); -+ -+#undef AuReadLockFunc -+#undef AuWriteLockFunc -+#undef AuRWLockFuncs -+ -+#define ii_read_unlock(i) au_rw_read_unlock(&au_ii(i)->ii_rwsem) -+#define ii_write_unlock(i) au_rw_write_unlock(&au_ii(i)->ii_rwsem) -+#define ii_downgrade_lock(i) au_rw_dgrade_lock(&au_ii(i)->ii_rwsem) -+ -+#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem) -+#define IiMustAnyLock(i) AuRwMustAnyLock(&au_ii(i)->ii_rwsem) -+#define IiMustWriteLock(i) AuRwMustWriteLock(&au_ii(i)->ii_rwsem) -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline void au_icntnr_init(struct au_icntnr *c) -+{ -+#ifdef CONFIG_AUFS_DEBUG -+ c->vfs_inode.i_mode = 0; -+#endif -+} -+ -+static inline unsigned int au_iigen(struct inode *inode, unsigned int *igflags) -+{ -+ unsigned int gen; -+ struct au_iinfo *iinfo; -+ struct au_iigen *iigen; -+ -+ iinfo = au_ii(inode); -+ iigen = &iinfo->ii_generation; -+ spin_lock(&iigen->ig_spin); -+ if (igflags) -+ *igflags = iigen->ig_flags; -+ gen = iigen->ig_generation; -+ spin_unlock(&iigen->ig_spin); -+ -+ return gen; -+} -+ -+/* tiny test for inode number */ -+/* tmpfs generation is too rough */ -+static inline int au_test_higen(struct inode *inode, struct inode *h_inode) -+{ -+ struct au_iinfo *iinfo; -+ -+ iinfo = au_ii(inode); -+ AuRwMustAnyLock(&iinfo->ii_rwsem); -+ return !(iinfo->ii_hsb1 == h_inode->i_sb -+ && iinfo->ii_higen == h_inode->i_generation); -+} -+ -+static inline void au_iigen_dec(struct inode *inode) -+{ -+ struct au_iinfo *iinfo; -+ struct au_iigen *iigen; -+ -+ iinfo = au_ii(inode); -+ iigen = &iinfo->ii_generation; -+ spin_lock(&iigen->ig_spin); -+ iigen->ig_generation--; -+ spin_unlock(&iigen->ig_spin); -+} -+ -+static inline int au_iigen_test(struct inode *inode, unsigned int sigen) -+{ -+ int err; -+ -+ err = 0; -+ if (unlikely(inode && au_iigen(inode, NULL) != sigen)) -+ err = -EIO; -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline struct au_hinode *au_hinode(struct au_iinfo *iinfo, -+ aufs_bindex_t bindex) -+{ -+ return iinfo->ii_hinode + bindex; -+} -+ -+static inline int au_is_bad_inode(struct inode *inode) -+{ -+ return !!(is_bad_inode(inode) || !au_hinode(au_ii(inode), 0)); -+} -+ -+static inline aufs_bindex_t au_ii_br_id(struct inode *inode, -+ aufs_bindex_t bindex) -+{ -+ IiMustAnyLock(inode); -+ return au_hinode(au_ii(inode), bindex)->hi_id; -+} -+ -+static inline aufs_bindex_t au_ibtop(struct inode *inode) -+{ -+ IiMustAnyLock(inode); -+ return au_ii(inode)->ii_btop; -+} -+ -+static inline aufs_bindex_t au_ibbot(struct inode *inode) -+{ -+ IiMustAnyLock(inode); -+ return au_ii(inode)->ii_bbot; -+} -+ -+static inline struct au_vdir *au_ivdir(struct inode *inode) -+{ -+ IiMustAnyLock(inode); -+ return au_ii(inode)->ii_vdir; -+} -+ -+static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex) -+{ -+ IiMustAnyLock(inode); -+ return au_hinode(au_ii(inode), bindex)->hi_whdentry; -+} -+ -+static inline void au_set_ibtop(struct inode *inode, aufs_bindex_t bindex) -+{ -+ IiMustWriteLock(inode); -+ au_ii(inode)->ii_btop = bindex; -+} -+ -+static inline void au_set_ibbot(struct inode *inode, aufs_bindex_t bindex) -+{ -+ IiMustWriteLock(inode); -+ au_ii(inode)->ii_bbot = bindex; -+} -+ -+static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir) -+{ -+ IiMustWriteLock(inode); -+ au_ii(inode)->ii_vdir = vdir; -+} -+ -+static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex) -+{ -+ IiMustAnyLock(inode); -+ return au_hinode(au_ii(inode), bindex); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline struct dentry *au_pinned_parent(struct au_pin *pin) -+{ -+ if (pin) -+ return pin->parent; -+ return NULL; -+} -+ -+static inline struct inode *au_pinned_h_dir(struct au_pin *pin) -+{ -+ if (pin && pin->hdir) -+ return pin->hdir->hi_inode; -+ return NULL; -+} -+ -+static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin) -+{ -+ if (pin) -+ return pin->hdir; -+ return NULL; -+} -+ -+static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry) -+{ -+ if (pin) -+ pin->dentry = dentry; -+} -+ -+static inline void au_pin_set_parent_lflag(struct au_pin *pin, -+ unsigned char lflag) -+{ -+ if (pin) { -+ if (lflag) -+ au_fset_pin(pin->flags, DI_LOCKED); -+ else -+ au_fclr_pin(pin->flags, DI_LOCKED); -+ } -+} -+ -+#if 0 /* reserved */ -+static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent) -+{ -+ if (pin) { -+ dput(pin->parent); -+ pin->parent = dget(parent); -+ } -+} -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_branch; -+#ifdef CONFIG_AUFS_HNOTIFY -+struct au_hnotify_op { -+ void (*ctl)(struct au_hinode *hinode, int do_set); -+ int (*alloc)(struct au_hinode *hinode); -+ -+ /* -+ * if it returns true, the caller should free hinode->hi_notify, -+ * otherwise ->free() frees it. -+ */ -+ int (*free)(struct au_hinode *hinode, -+ struct au_hnotify *hn) __must_check; -+ -+ void (*fin)(void); -+ int (*init)(void); -+ -+ int (*reset_br)(unsigned int udba, struct au_branch *br, int perm); -+ void (*fin_br)(struct au_branch *br); -+ int (*init_br)(struct au_branch *br, int perm); -+}; -+ -+/* hnotify.c */ -+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode); -+void au_hn_free(struct au_hinode *hinode); -+void au_hn_ctl(struct au_hinode *hinode, int do_set); -+void au_hn_reset(struct inode *inode, unsigned int flags); -+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask, -+ const struct qstr *h_child_qstr, struct inode *h_child_inode); -+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm); -+int au_hnotify_init_br(struct au_branch *br, int perm); -+void au_hnotify_fin_br(struct au_branch *br); -+int __init au_hnotify_init(void); -+void au_hnotify_fin(void); -+ -+/* hfsnotify.c */ -+extern const struct au_hnotify_op au_hnotify_op; -+ -+static inline -+void au_hn_init(struct au_hinode *hinode) -+{ -+ hinode->hi_notify = NULL; -+} -+ -+static inline struct au_hnotify *au_hn(struct au_hinode *hinode) -+{ -+ return hinode->hi_notify; -+} -+ -+#else -+AuStub(int, au_hn_alloc, return -EOPNOTSUPP, -+ struct au_hinode *hinode __maybe_unused, -+ struct inode *inode __maybe_unused) -+AuStub(struct au_hnotify *, au_hn, return NULL, struct au_hinode *hinode) -+AuStubVoid(au_hn_free, struct au_hinode *hinode __maybe_unused) -+AuStubVoid(au_hn_ctl, struct au_hinode *hinode __maybe_unused, -+ int do_set __maybe_unused) -+AuStubVoid(au_hn_reset, struct inode *inode __maybe_unused, -+ unsigned int flags __maybe_unused) -+AuStubInt0(au_hnotify_reset_br, unsigned int udba __maybe_unused, -+ struct au_branch *br __maybe_unused, -+ int perm __maybe_unused) -+AuStubInt0(au_hnotify_init_br, struct au_branch *br __maybe_unused, -+ int perm __maybe_unused) -+AuStubVoid(au_hnotify_fin_br, struct au_branch *br __maybe_unused) -+AuStubInt0(__init au_hnotify_init, void) -+AuStubVoid(au_hnotify_fin, void) -+AuStubVoid(au_hn_init, struct au_hinode *hinode __maybe_unused) -+#endif /* CONFIG_AUFS_HNOTIFY */ -+ -+static inline void au_hn_suspend(struct au_hinode *hdir) -+{ -+ au_hn_ctl(hdir, /*do_set*/0); -+} -+ -+static inline void au_hn_resume(struct au_hinode *hdir) -+{ -+ au_hn_ctl(hdir, /*do_set*/1); -+} -+ -+static inline void au_hn_inode_lock(struct au_hinode *hdir) -+{ -+ inode_lock(hdir->hi_inode); -+ au_hn_suspend(hdir); -+} -+ -+static inline void au_hn_inode_lock_nested(struct au_hinode *hdir, -+ unsigned int sc __maybe_unused) -+{ -+ inode_lock_nested(hdir->hi_inode, sc); -+ au_hn_suspend(hdir); -+} -+ -+#if 0 /* unused */ -+#include "vfsub.h" -+static inline void au_hn_inode_lock_shared_nested(struct au_hinode *hdir, -+ unsigned int sc) -+{ -+ inode_lock_shared_nested(hdir->hi_inode, sc); -+ au_hn_suspend(hdir); -+} -+#endif -+ -+static inline void au_hn_inode_unlock(struct au_hinode *hdir) -+{ -+ au_hn_resume(hdir); -+ inode_unlock(hdir->hi_inode); -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_INODE_H__ */ -diff -Naur null/fs/aufs/ioctl.c linux-6.6.63/fs/aufs/ioctl.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/ioctl.c 2024-12-18 15:12:59.298519551 +0300 -@@ -0,0 +1,220 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * ioctl -+ * plink-management and readdir in userspace. -+ * assist the pathconf(3) wrapper library. -+ * move-down -+ * File-based Hierarchical Storage Management. -+ */ -+ -+#include -+#include -+#include "aufs.h" -+ -+static int au_wbr_fd(struct path *path, struct aufs_wbr_fd __user *arg) -+{ -+ int err, fd; -+ aufs_bindex_t wbi, bindex, bbot; -+ struct file *h_file; -+ struct super_block *sb; -+ struct dentry *root; -+ struct au_branch *br; -+ struct aufs_wbr_fd wbrfd = { -+ .oflags = au_dir_roflags, -+ .brid = -1 -+ }; -+ const int valid = O_RDONLY | O_NONBLOCK | O_LARGEFILE | O_DIRECTORY -+ | O_NOATIME | O_CLOEXEC; -+ -+ AuDebugOn(wbrfd.oflags & ~valid); -+ -+ if (arg) { -+ err = copy_from_user(&wbrfd, arg, sizeof(wbrfd)); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ goto out; -+ } -+ -+ err = -EINVAL; -+ AuDbg("wbrfd{0%o, %d}\n", wbrfd.oflags, wbrfd.brid); -+ wbrfd.oflags |= au_dir_roflags; -+ AuDbg("0%o\n", wbrfd.oflags); -+ if (unlikely(wbrfd.oflags & ~valid)) -+ goto out; -+ } -+ -+ fd = get_unused_fd_flags(0); -+ err = fd; -+ if (unlikely(fd < 0)) -+ goto out; -+ -+ h_file = ERR_PTR(-EINVAL); -+ wbi = 0; -+ br = NULL; -+ sb = path->dentry->d_sb; -+ root = sb->s_root; -+ aufs_read_lock(root, AuLock_IR); -+ bbot = au_sbbot(sb); -+ if (wbrfd.brid >= 0) { -+ wbi = au_br_index(sb, wbrfd.brid); -+ if (unlikely(wbi < 0 || wbi > bbot)) -+ goto out_unlock; -+ } -+ -+ h_file = ERR_PTR(-ENOENT); -+ br = au_sbr(sb, wbi); -+ if (!au_br_writable(br->br_perm)) { -+ if (arg) -+ goto out_unlock; -+ -+ bindex = wbi + 1; -+ wbi = -1; -+ for (; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (au_br_writable(br->br_perm)) { -+ wbi = bindex; -+ br = au_sbr(sb, wbi); -+ break; -+ } -+ } -+ } -+ AuDbg("wbi %d\n", wbi); -+ if (wbi >= 0) -+ h_file = au_h_open(root, wbi, wbrfd.oflags, NULL, -+ /*force_wr*/0); -+ -+out_unlock: -+ aufs_read_unlock(root, AuLock_IR); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out_fd; -+ -+ au_lcnt_dec(&br->br_nfiles); /* cf. au_h_open() */ -+ fd_install(fd, h_file); -+ err = fd; -+ goto out; /* success */ -+ -+out_fd: -+ put_unused_fd(fd); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ long err; -+ struct dentry *dentry; -+ -+ switch (cmd) { -+ case AUFS_CTL_RDU: -+ case AUFS_CTL_RDU_INO: -+ err = au_rdu_ioctl(file, cmd, arg); -+ break; -+ -+ case AUFS_CTL_WBR_FD: -+ err = au_wbr_fd(&file->f_path, (void __user *)arg); -+ break; -+ -+ case AUFS_CTL_IBUSY: -+ err = au_ibusy_ioctl(file, arg); -+ break; -+ -+ case AUFS_CTL_BRINFO: -+ err = au_brinfo_ioctl(file, arg); -+ break; -+ -+ case AUFS_CTL_FHSM_FD: -+ dentry = file->f_path.dentry; -+ if (IS_ROOT(dentry)) -+ err = au_fhsm_fd(dentry->d_sb, arg); -+ else -+ err = -ENOTTY; -+ break; -+ -+ default: -+ /* do not call the lower */ -+ AuDbg("0x%x\n", cmd); -+ err = -ENOTTY; -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ long err; -+ -+ switch (cmd) { -+ case AUFS_CTL_MVDOWN: -+ err = au_mvdown(file->f_path.dentry, (void __user *)arg); -+ break; -+ -+ case AUFS_CTL_WBR_FD: -+ err = au_wbr_fd(&file->f_path, (void __user *)arg); -+ break; -+ -+ default: -+ /* do not call the lower */ -+ AuDbg("0x%x\n", cmd); -+ err = -ENOTTY; -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+#ifdef CONFIG_COMPAT -+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd, -+ unsigned long arg) -+{ -+ long err; -+ -+ switch (cmd) { -+ case AUFS_CTL_RDU: -+ case AUFS_CTL_RDU_INO: -+ err = au_rdu_compat_ioctl(file, cmd, arg); -+ break; -+ -+ case AUFS_CTL_IBUSY: -+ err = au_ibusy_compat_ioctl(file, arg); -+ break; -+ -+ case AUFS_CTL_BRINFO: -+ err = au_brinfo_compat_ioctl(file, arg); -+ break; -+ -+ default: -+ err = aufs_ioctl_dir(file, cmd, arg); -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd, -+ unsigned long arg) -+{ -+ return aufs_ioctl_nondir(file, cmd, (unsigned long)compat_ptr(arg)); -+} -+#endif -diff -Naur null/fs/aufs/i_op_add.c linux-6.6.63/fs/aufs/i_op_add.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/i_op_add.c 2024-12-18 15:12:59.297519563 +0300 -@@ -0,0 +1,971 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * inode operations (add entry) -+ */ -+ -+#include -+#include "aufs.h" -+ -+/* -+ * final procedure of adding a new entry, except link(2). -+ * remove whiteout, instantiate, copyup the parent dir's times and size -+ * and update version. -+ * if it failed, re-create the removed whiteout. -+ */ -+static int epilog(struct inode *dir, aufs_bindex_t bindex, -+ struct dentry *wh_dentry, struct dentry *dentry) -+{ -+ int err, rerr; -+ aufs_bindex_t bwh; -+ struct path h_path; -+ struct super_block *sb; -+ struct inode *inode, *h_dir; -+ struct dentry *wh; -+ -+ bwh = -1; -+ sb = dir->i_sb; -+ if (wh_dentry) { -+ 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); -+ h_path.dentry = wh_dentry; -+ h_path.mnt = au_sbr_mnt(sb, bindex); -+ err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, -+ dentry); -+ if (unlikely(err)) -+ goto out; -+ } -+ -+ inode = au_new_inode(dentry, /*must_new*/1); -+ if (!IS_ERR(inode)) { -+ d_instantiate(dentry, inode); -+ dir = d_inode(dentry->d_parent); /* dir inode is locked */ -+ IMustLock(dir); -+ au_dir_ts(dir, bindex); -+ inode_inc_iversion(dir); -+ au_fhsm_wrote(sb, bindex, /*force*/0); -+ return 0; /* success */ -+ } -+ -+ err = PTR_ERR(inode); -+ if (!wh_dentry) -+ goto out; -+ -+ /* revert */ -+ /* dir inode is locked */ -+ wh = au_wh_create(dentry, bwh, wh_dentry->d_parent); -+ rerr = PTR_ERR(wh); -+ if (IS_ERR(wh)) { -+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n", -+ dentry, err, rerr); -+ err = -EIO; -+ } else -+ dput(wh); -+ -+out: -+ return err; -+} -+ -+static int au_d_may_add(struct dentry *dentry) -+{ -+ int err; -+ -+ err = 0; -+ if (unlikely(d_unhashed(dentry))) -+ err = -ENOENT; -+ if (unlikely(d_really_is_positive(dentry))) -+ err = -EEXIST; -+ return err; -+} -+ -+/* -+ * simple tests for the adding inode operations. -+ * following the checks in vfs, plus the parent-child relationship. -+ */ -+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex, -+ struct dentry *h_parent, int isdir) -+{ -+ int err; -+ umode_t h_mode; -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ -+ err = -ENAMETOOLONG; -+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN)) -+ goto out; -+ -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (d_really_is_negative(dentry)) { -+ err = -EEXIST; -+ if (unlikely(d_is_positive(h_dentry))) -+ goto out; -+ } else { -+ /* rename(2) case */ -+ err = -EIO; -+ if (unlikely(d_is_negative(h_dentry))) -+ goto out; -+ h_inode = d_inode(h_dentry); -+ if (unlikely(!vfsub_inode_nlink(h_inode, AU_I_BRANCH))) -+ goto out; -+ -+ h_mode = h_inode->i_mode; -+ if (!isdir) { -+ err = -EISDIR; -+ if (unlikely(S_ISDIR(h_mode))) -+ goto out; -+ } else if (unlikely(!S_ISDIR(h_mode))) { -+ err = -ENOTDIR; -+ goto out; -+ } -+ } -+ -+ err = 0; -+ /* expected parent dir is locked */ -+ if (unlikely(h_parent != h_dentry->d_parent)) -+ err = -EIO; -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* -+ * initial procedure of adding a new entry. -+ * prepare writable branch and the parent dir, lock it, -+ * and lookup whiteout for the new entry. -+ */ -+static struct dentry* -+lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt, -+ struct dentry *src_dentry, struct au_pin *pin, -+ struct au_wr_dir_args *wr_dir_args) -+{ -+ struct dentry *wh_dentry, *h_parent; -+ struct super_block *sb; -+ struct au_branch *br; -+ int err; -+ unsigned int udba; -+ aufs_bindex_t bcpup; -+ -+ AuDbg("%pd\n", dentry); -+ -+ err = au_wr_dir(dentry, src_dentry, wr_dir_args); -+ bcpup = err; -+ wh_dentry = ERR_PTR(err); -+ if (unlikely(err < 0)) -+ goto out; -+ -+ sb = dentry->d_sb; -+ udba = au_opt_udba(sb); -+ err = au_pin(pin, dentry, bcpup, udba, -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ wh_dentry = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out; -+ -+ h_parent = au_pinned_h_parent(pin); -+ if (udba != AuOpt_UDBA_NONE -+ && au_dbtop(dentry) == bcpup) -+ err = au_may_add(dentry, bcpup, h_parent, -+ au_ftest_wrdir(wr_dir_args->flags, ISDIR)); -+ else if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN)) -+ err = -ENAMETOOLONG; -+ wh_dentry = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out_unpin; -+ -+ br = au_sbr(sb, bcpup); -+ if (dt) { -+ struct path tmp = { -+ .dentry = h_parent, -+ .mnt = au_br_mnt(br) -+ }; -+ au_dtime_store(dt, au_pinned_parent(pin), &tmp); -+ } -+ -+ wh_dentry = NULL; -+ 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: -+ if (IS_ERR(wh_dentry)) -+ au_unpin(pin); -+out: -+ return wh_dentry; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+enum { Mknod, Symlink, Creat }; -+struct simple_arg { -+ int type; -+ union { -+ struct { -+ umode_t mode; -+ bool want_excl; -+ bool try_aopen; -+ struct vfsub_aopen_args *aopen; -+ } c; -+ struct { -+ const char *symname; -+ } s; -+ struct { -+ umode_t mode; -+ dev_t dev; -+ } m; -+ } u; -+}; -+ -+static int add_simple(struct inode *dir, struct dentry *dentry, -+ struct simple_arg *arg) -+{ -+ int err, rerr; -+ aufs_bindex_t btop; -+ unsigned char created; -+ const unsigned char try_aopen -+ = (arg->type == Creat && arg->u.c.try_aopen); -+ struct vfsub_aopen_args *aopen = arg->u.c.aopen; -+ struct dentry *wh_dentry, *parent; -+ struct inode *h_dir; -+ struct super_block *sb; -+ struct au_branch *br; -+ /* to reduce stack size */ -+ struct { -+ struct au_dtime dt; -+ struct au_pin pin; -+ struct path h_path; -+ struct au_wr_dir_args wr_dir_args; -+ } *a; -+ -+ AuDbg("%pd\n", dentry); -+ IMustLock(dir); -+ -+ err = -ENOMEM; -+ a = kmalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ a->wr_dir_args.force_btgt = -1; -+ a->wr_dir_args.flags = AuWrDir_ADD_ENTRY; -+ -+ parent = dentry->d_parent; /* dir inode is locked */ -+ 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; -+ 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); -+ if (IS_ERR(wh_dentry)) -+ goto out_parent; -+ -+ btop = au_dbtop(dentry); -+ sb = dentry->d_sb; -+ br = au_sbr(sb, btop); -+ a->h_path.dentry = au_h_dptr(dentry, btop); -+ a->h_path.mnt = au_br_mnt(br); -+ h_dir = au_pinned_h_dir(&a->pin); -+ switch (arg->type) { -+ case Creat: -+ 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); -+ created = !err; -+ if (!err && try_aopen) -+ aopen->file->f_mode |= FMODE_CREATED; -+ } else { -+ aopen->br = br; -+ err = vfsub_atomic_open(h_dir, a->h_path.dentry, aopen); -+ AuDbg("err %d\n", err); -+ AuDbgFile(aopen->file); -+ created = err >= 0 -+ && !!(aopen->file->f_mode & FMODE_CREATED); -+ } -+ break; -+ case Symlink: -+ err = vfsub_symlink(h_dir, &a->h_path, arg->u.s.symname); -+ created = !err; -+ break; -+ case Mknod: -+ err = vfsub_mknod(h_dir, &a->h_path, arg->u.m.mode, -+ arg->u.m.dev); -+ created = !err; -+ break; -+ default: -+ BUG(); -+ } -+ if (unlikely(err < 0)) -+ goto out_unpin; -+ -+ err = epilog(dir, btop, wh_dentry, dentry); -+ if (!err) -+ goto out_unpin; /* success */ -+ -+ /* revert */ -+ if (created /* && 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); -+ if (rerr) { -+ AuIOErr("%pd revert failure(%d, %d)\n", -+ dentry, err, rerr); -+ err = -EIO; -+ } -+ au_dtime_revert(&a->dt); -+ } -+ if (try_aopen && h_dir->i_op->atomic_open -+ && (aopen->file->f_mode & FMODE_OPENED)) -+ /* aopen->file is still opened */ -+ au_lcnt_dec(&aopen->br->br_nfiles); -+ -+out_unpin: -+ au_unpin(&a->pin); -+ dput(wh_dentry); -+out_parent: -+ if (!try_aopen) -+ di_write_unlock(parent); -+out_unlock: -+ if (unlikely(err)) { -+ au_update_dbtop(dentry); -+ d_drop(dentry); -+ } -+ if (!try_aopen) -+ aufs_read_unlock(dentry, AuLock_DW); -+out_free: -+ au_kfree_rcu(a); -+out: -+ return err; -+} -+ -+int aufs_mknod(struct mnt_idmap *idmap, struct inode *dir, -+ struct dentry *dentry, umode_t mode, dev_t dev) -+{ -+ struct simple_arg arg = { -+ .type = Mknod, -+ .u.m = { -+ .mode = mode, -+ .dev = dev -+ } -+ }; -+ return add_simple(dir, dentry, &arg); -+} -+ -+int aufs_symlink(struct mnt_idmap *idmap, struct inode *dir, -+ struct dentry *dentry, const char *symname) -+{ -+ struct simple_arg arg = { -+ .type = Symlink, -+ .u.s.symname = symname -+ }; -+ return add_simple(dir, dentry, &arg); -+} -+ -+int aufs_create(struct mnt_idmap *idmap, struct inode *dir, -+ struct dentry *dentry, umode_t mode, bool want_excl) -+{ -+ struct simple_arg arg = { -+ .type = Creat, -+ .u.c = { -+ .mode = mode, -+ .want_excl = want_excl -+ } -+ }; -+ 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 mnt_idmap *idmap, struct inode *dir, -+ struct file *file, umode_t mode) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ struct path h_ppath; -+ struct super_block *sb; -+ struct au_branch *br; -+ struct dentry *dentry, *parent, *h_parent, *h_dentry; -+ struct inode *h_dir, *inode; -+ struct vfsmount *h_mnt; -+ struct mnt_idmap *h_idmap; -+ struct file *h_file; -+ struct au_wr_dir_args wr_dir_args = { -+ .force_btgt = -1, -+ .flags = AuWrDir_TMPFILE -+ }; -+ -+ /* copy-up may happen */ -+ inode_lock(dir); -+ -+ h_file = NULL; -+ sb = dir->i_sb; -+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (unlikely(err)) -+ goto out; -+ -+ dentry = file->f_path.dentry; -+ err = au_di_init(dentry); -+ if (unlikely(err)) -+ goto out_si; -+ -+ err = -EBUSY; -+ parent = d_find_any_alias(dir); -+ AuDebugOn(!parent); -+ di_write_lock_parent(parent); -+ if (unlikely(d_inode(parent) != dir)) -+ goto out_parent; -+ -+ err = au_digen_test(parent, au_sigen(sb)); -+ if (unlikely(err)) -+ goto out_parent; -+ -+ bindex = au_dbtop(parent); -+ au_set_dbtop(dentry, bindex); -+ au_set_dbbot(dentry, bindex); -+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args); -+ bindex = err; -+ if (unlikely(err < 0)) -+ goto out_parent; -+ -+ err = -EOPNOTSUPP; -+ h_dir = au_h_iptr(dir, bindex); -+ if (unlikely(!h_dir->i_op->tmpfile)) -+ goto out_parent; -+ -+ br = au_sbr(sb, bindex); -+ h_mnt = au_br_mnt(br); -+ err = vfsub_mnt_want_write(h_mnt); -+ if (unlikely(err)) -+ goto out_parent; -+ -+ h_idmap = mnt_idmap(h_mnt); -+ h_parent = au_h_dptr(parent, bindex); -+ h_ppath.mnt = h_mnt; -+ h_ppath.dentry = h_parent; -+ h_file = kernel_tmpfile_open(h_idmap, &h_ppath, mode, /*open_flag*/0, -+ current_cred()); -+ if (IS_ERR(h_file)) { -+ err = PTR_ERR(h_file); -+ h_file = NULL; -+ goto out_mnt; -+ } -+ -+ h_dentry = h_file->f_path.dentry; -+ au_set_dbtop(dentry, bindex); -+ au_set_dbbot(dentry, bindex); -+ au_set_h_dptr(dentry, bindex, dget(h_dentry)); -+ inode = au_new_inode(dentry, /*must_new*/1); -+ if (IS_ERR(inode)) { -+ err = PTR_ERR(inode); -+ au_set_h_dptr(dentry, bindex, NULL); -+ au_set_dbtop(dentry, -1); -+ au_set_dbbot(dentry, -1); -+ goto out_h_file; -+ } -+ -+ vfsub_inode_nlink_init(inode, 1); -+ d_tmpfile(file, inode); -+ au_di(dentry)->di_tmpfile = 1; -+ get_file(h_file); -+ au_di(dentry)->di_htmpfile = h_file; -+ -+ /* update without i_mutex */ -+ if (au_ibtop(dir) == au_dbtop(dentry)) -+ au_cpup_attr_timesizes(dir); -+ -+out_h_file: -+ fput(h_file); -+out_mnt: -+ vfsub_mnt_drop_write(h_mnt); -+out_parent: -+ di_write_unlock(parent); -+ dput(parent); -+ di_write_unlock(dentry); -+ if (!err) -+ goto out_si; -+ if (h_file) -+ fput(h_file); -+ au_di(dentry)->di_htmpfile = NULL; -+ au_di_fin(dentry); -+ dentry->d_fsdata = NULL; -+out_si: -+ si_read_unlock(sb); -+ if (!err && h_file) { -+ /* finally... */ -+ err = finish_open_simple(file, err); -+ if (!err) -+ au_lcnt_inc(&br->br_nfiles); -+ else { -+ fput(h_file); -+ au_di(dentry)->di_htmpfile = NULL; -+ au_di_fin(dentry); -+ dentry->d_fsdata = NULL; -+ } -+ } -+out: -+ inode_unlock(dir); -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_link_args { -+ aufs_bindex_t bdst, bsrc; -+ struct au_pin pin; -+ struct path h_path; -+ struct dentry *src_parent, *parent; -+}; -+ -+static int au_cpup_before_link(struct dentry *src_dentry, -+ struct au_link_args *a) -+{ -+ int err; -+ struct dentry *h_src_dentry; -+ struct au_cp_generic cpg = { -+ .dentry = src_dentry, -+ .bdst = a->bdst, -+ .bsrc = a->bsrc, -+ .len = -1, -+ .pin = &a->pin, -+ .flags = AuCpup_DTIME | AuCpup_HOPEN /* | AuCpup_KEEPLINO */ -+ }; -+ -+ di_read_lock_parent(a->src_parent, AuLock_IR); -+ err = au_test_and_cpup_dirs(src_dentry, a->bdst); -+ if (unlikely(err)) -+ goto out; -+ -+ h_src_dentry = au_h_dptr(src_dentry, a->bsrc); -+ err = au_pin(&a->pin, src_dentry, a->bdst, -+ au_opt_udba(src_dentry->d_sb), -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ if (unlikely(err)) -+ goto out; -+ -+ err = au_sio_cpup_simple(&cpg); -+ au_unpin(&a->pin); -+ -+out: -+ di_read_unlock(a->src_parent, AuLock_IR); -+ return err; -+} -+ -+static int au_cpup_or_link(struct dentry *src_dentry, struct dentry *dentry, -+ struct au_link_args *a) -+{ -+ int err; -+ unsigned char plink; -+ aufs_bindex_t bbot; -+ struct dentry *h_src_dentry; -+ struct inode *h_inode, *inode, *delegated; -+ struct super_block *sb; -+ struct file *h_file; -+ -+ plink = 0; -+ h_inode = NULL; -+ sb = src_dentry->d_sb; -+ inode = d_inode(src_dentry); -+ if (au_ibtop(inode) <= a->bdst) -+ h_inode = au_h_iptr(inode, a->bdst); -+ if (!h_inode || !vfsub_inode_nlink(h_inode, AU_I_BRANCH)) { -+ /* copyup src_dentry as the name of dentry. */ -+ bbot = au_dbbot(dentry); -+ if (bbot < a->bsrc) -+ au_set_dbbot(dentry, a->bsrc); -+ au_set_h_dptr(dentry, a->bsrc, -+ dget(au_h_dptr(src_dentry, a->bsrc))); -+ dget(a->h_path.dentry); -+ au_set_h_dptr(dentry, a->bdst, NULL); -+ AuDbg("temporary d_inode...\n"); -+ spin_lock(&dentry->d_lock); -+ 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)) -+ err = PTR_ERR(h_file); -+ else { -+ struct au_cp_generic cpg = { -+ .dentry = dentry, -+ .bdst = a->bdst, -+ .bsrc = -1, -+ .len = -1, -+ .pin = &a->pin, -+ .flags = AuCpup_KEEPLINO -+ }; -+ err = au_sio_cpup_simple(&cpg); -+ au_h_open_post(dentry, a->bsrc, h_file); -+ if (!err) { -+ dput(a->h_path.dentry); -+ a->h_path.dentry = au_h_dptr(dentry, a->bdst); -+ } else -+ au_set_h_dptr(dentry, a->bdst, -+ a->h_path.dentry); -+ } -+ spin_lock(&dentry->d_lock); -+ dentry->d_inode = NULL; /* restore */ -+ spin_unlock(&dentry->d_lock); -+ AuDbg("temporary d_inode...done\n"); -+ au_set_h_dptr(dentry, a->bsrc, NULL); -+ au_set_dbbot(dentry, bbot); -+ } else { -+ /* the inode of src_dentry already exists on a.bdst branch */ -+ h_src_dentry = d_find_alias(h_inode); -+ if (!h_src_dentry && au_plink_test(inode)) { -+ plink = 1; -+ h_src_dentry = au_plink_lkup(inode, a->bdst); -+ err = PTR_ERR(h_src_dentry); -+ if (IS_ERR(h_src_dentry)) -+ goto out; -+ -+ if (unlikely(d_is_negative(h_src_dentry))) { -+ dput(h_src_dentry); -+ h_src_dentry = NULL; -+ } -+ -+ } -+ if (h_src_dentry) { -+ delegated = NULL; -+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin), -+ &a->h_path, &delegated); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal link\n"); -+ iput(delegated); -+ } -+ dput(h_src_dentry); -+ } else { -+ AuIOErr("no dentry found for hi%lu on b%d\n", -+ h_inode->i_ino, a->bdst); -+ err = -EIO; -+ } -+ } -+ -+ if (!err && !plink) -+ au_plink_append(inode, a->bdst, a->h_path.dentry); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+int aufs_link(struct dentry *src_dentry, struct inode *dir, -+ struct dentry *dentry) -+{ -+ int err, rerr; -+ struct au_dtime dt; -+ struct au_link_args *a; -+ struct dentry *wh_dentry, *h_src_dentry; -+ struct inode *inode, *delegated; -+ struct super_block *sb; -+ struct au_wr_dir_args wr_dir_args = { -+ /* .force_btgt = -1, */ -+ .flags = AuWrDir_ADD_ENTRY -+ }; -+ -+ IMustLock(dir); -+ inode = d_inode(src_dentry); -+ IMustLock(inode); -+ -+ err = -ENOMEM; -+ a = kzalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ -+ a->parent = dentry->d_parent; /* dir inode is locked */ -+ err = aufs_read_and_write_lock2(dentry, src_dentry, -+ AuLock_NOPLM | AuLock_GEN); -+ if (unlikely(err)) -+ goto out_kfree; -+ err = au_d_linkable(src_dentry); -+ if (unlikely(err)) -+ goto out_unlock; -+ err = au_d_may_add(dentry); -+ if (unlikely(err)) -+ goto out_unlock; -+ -+ a->src_parent = dget_parent(src_dentry); -+ wr_dir_args.force_btgt = au_ibtop(inode); -+ -+ di_write_lock_parent(a->parent); -+ wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt); -+ wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin, -+ &wr_dir_args); -+ err = PTR_ERR(wh_dentry); -+ if (IS_ERR(wh_dentry)) -+ goto out_parent; -+ -+ err = 0; -+ sb = dentry->d_sb; -+ a->bdst = au_dbtop(dentry); -+ a->h_path.dentry = au_h_dptr(dentry, a->bdst); -+ a->h_path.mnt = au_sbr_mnt(sb, a->bdst); -+ a->bsrc = au_ibtop(inode); -+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc); -+ if (!h_src_dentry && au_di(src_dentry)->di_tmpfile) -+ h_src_dentry = dget(au_hi_wh(inode, a->bsrc)); -+ if (!h_src_dentry) { -+ a->bsrc = au_dbtop(src_dentry); -+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc); -+ AuDebugOn(!h_src_dentry); -+ } else if (IS_ERR(h_src_dentry)) { -+ err = PTR_ERR(h_src_dentry); -+ goto out_parent; -+ } -+ -+ /* -+ * aufs doesn't touch the credential so -+ * security_dentry_create_files_as() is unnecessary. -+ */ -+ if (au_opt_test(au_mntflags(sb), PLINK)) { -+ if (a->bdst < a->bsrc -+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) -+ err = au_cpup_or_link(src_dentry, dentry, a); -+ else { -+ delegated = NULL; -+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin), -+ &a->h_path, &delegated); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal link\n"); -+ iput(delegated); -+ } -+ } -+ dput(h_src_dentry); -+ } else { -+ /* -+ * copyup src_dentry to the branch we process, -+ * and then link(2) to it. -+ */ -+ dput(h_src_dentry); -+ if (a->bdst < a->bsrc -+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) { -+ au_unpin(&a->pin); -+ di_write_unlock(a->parent); -+ err = au_cpup_before_link(src_dentry, a); -+ di_write_lock_parent(a->parent); -+ if (!err) -+ err = au_pin(&a->pin, dentry, a->bdst, -+ au_opt_udba(sb), -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ if (unlikely(err)) -+ goto out_wh; -+ } -+ if (!err) { -+ h_src_dentry = au_h_dptr(src_dentry, a->bdst); -+ err = -ENOENT; -+ if (h_src_dentry && d_is_positive(h_src_dentry)) { -+ delegated = NULL; -+ err = vfsub_link(h_src_dentry, -+ au_pinned_h_dir(&a->pin), -+ &a->h_path, &delegated); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry" -+ " for NFSv4 delegation" -+ " for an internal link\n"); -+ iput(delegated); -+ } -+ } -+ } -+ } -+ if (unlikely(err)) -+ goto out_unpin; -+ -+ if (wh_dentry) { -+ a->h_path.dentry = wh_dentry; -+ err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path, -+ dentry); -+ if (unlikely(err)) -+ goto out_revert; -+ } -+ -+ au_dir_ts(dir, a->bdst); -+ inode_inc_iversion(dir); -+ vfsub_inc_nlink(inode); -+ inode_set_ctime_to_ts(inode, inode_get_ctime(dir)); -+ d_instantiate(dentry, au_igrab(inode)); -+ if (d_unhashed(a->h_path.dentry)) -+ /* some filesystem calls d_drop() */ -+ d_drop(dentry); -+ /* some filesystems consume an inode even hardlink */ -+ au_fhsm_wrote(sb, a->bdst, /*force*/0); -+ goto out_unpin; /* success */ -+ -+out_revert: -+ /* no delegation since it is just created */ -+ rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path, -+ /*delegated*/NULL, /*force*/0); -+ if (unlikely(rerr)) { -+ AuIOErr("%pd reverting failed(%d, %d)\n", dentry, err, rerr); -+ err = -EIO; -+ } -+ au_dtime_revert(&dt); -+out_unpin: -+ au_unpin(&a->pin); -+out_wh: -+ dput(wh_dentry); -+out_parent: -+ di_write_unlock(a->parent); -+ dput(a->src_parent); -+out_unlock: -+ if (unlikely(err)) { -+ au_update_dbtop(dentry); -+ d_drop(dentry); -+ } -+ aufs_read_and_write_unlock2(dentry, src_dentry); -+out_kfree: -+ au_kfree_rcu(a); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+int aufs_mkdir(struct mnt_idmap *idmap, struct inode *dir, -+ struct dentry *dentry, umode_t mode) -+{ -+ int err, rerr; -+ aufs_bindex_t bindex; -+ unsigned char diropq; -+ struct path h_path; -+ struct dentry *wh_dentry, *parent, *opq_dentry; -+ struct inode *h_inode; -+ struct super_block *sb; -+ struct { -+ struct au_pin pin; -+ struct au_dtime dt; -+ } *a; /* reduce the stack usage */ -+ struct au_wr_dir_args wr_dir_args = { -+ .force_btgt = -1, -+ .flags = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR -+ }; -+ -+ IMustLock(dir); -+ -+ err = -ENOMEM; -+ a = kmalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ -+ 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; -+ -+ parent = dentry->d_parent; /* dir inode is locked */ -+ di_write_lock_parent(parent); -+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL, -+ &a->pin, &wr_dir_args); -+ err = PTR_ERR(wh_dentry); -+ if (IS_ERR(wh_dentry)) -+ goto out_parent; -+ -+ sb = dentry->d_sb; -+ bindex = au_dbtop(dentry); -+ h_path.dentry = au_h_dptr(dentry, bindex); -+ h_path.mnt = au_sbr_mnt(sb, bindex); -+ err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode); -+ if (unlikely(err)) -+ goto out_unpin; -+ -+ /* make the dir opaque */ -+ diropq = 0; -+ h_inode = d_inode(h_path.dentry); -+ if (wh_dentry -+ || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) { -+ inode_lock_nested(h_inode, AuLsc_I_CHILD); -+ opq_dentry = au_diropq_create(dentry, bindex); -+ inode_unlock(h_inode); -+ err = PTR_ERR(opq_dentry); -+ if (IS_ERR(opq_dentry)) -+ goto out_dir; -+ dput(opq_dentry); -+ diropq = 1; -+ } -+ -+ err = epilog(dir, bindex, wh_dentry, dentry); -+ if (!err) { -+ vfsub_inc_nlink(dir); -+ goto out_unpin; /* success */ -+ } -+ -+ /* revert */ -+ if (diropq) { -+ AuLabel(revert opq); -+ inode_lock_nested(h_inode, AuLsc_I_CHILD); -+ rerr = au_diropq_remove(dentry, bindex); -+ inode_unlock(h_inode); -+ if (rerr) { -+ AuIOErr("%pd reverting diropq failed(%d, %d)\n", -+ dentry, err, rerr); -+ err = -EIO; -+ } -+ } -+ -+out_dir: -+ AuLabel(revert dir); -+ rerr = vfsub_rmdir(au_pinned_h_dir(&a->pin), &h_path); -+ if (rerr) { -+ AuIOErr("%pd reverting dir failed(%d, %d)\n", -+ dentry, err, rerr); -+ err = -EIO; -+ } -+ au_dtime_revert(&a->dt); -+out_unpin: -+ au_unpin(&a->pin); -+ dput(wh_dentry); -+out_parent: -+ di_write_unlock(parent); -+out_unlock: -+ if (unlikely(err)) { -+ au_update_dbtop(dentry); -+ d_drop(dentry); -+ } -+ aufs_read_unlock(dentry, AuLock_DW); -+out_free: -+ au_kfree_rcu(a); -+out: -+ return err; -+} -diff -Naur null/fs/aufs/i_op.c linux-6.6.63/fs/aufs/i_op.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/i_op.c 2024-12-18 15:12:59.297519563 +0300 -@@ -0,0 +1,1520 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * inode operations (except add/del/rename) -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include "aufs.h" -+ -+static int h_permission(struct inode *h_inode, int mask, -+ struct path *h_path, int brperm) -+{ -+ int err; -+ const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND)); -+ struct mnt_idmap *h_idmap; -+ -+ err = -EPERM; -+ if (write_mask && IS_IMMUTABLE(h_inode)) -+ goto out; -+ -+ err = -EACCES; -+ if (((mask & MAY_EXEC) -+ && S_ISREG(h_inode->i_mode) -+ && (path_noexec(h_path) -+ || !(h_inode->i_mode & 0111)))) -+ goto out; -+ -+ /* -+ * - 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 SB_POSIXACL regardless its mount option 'noacl.' -+ * in this case, generic_permission() returns -EOPNOTSUPP. -+ */ -+ h_idmap = mnt_idmap(h_path->mnt); -+ 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_inode_acl %ps\n", -+ h_inode->i_op->get_inode_acl); */ -+ err = generic_permission(h_idmap, h_inode, mask); -+ if (err == -EOPNOTSUPP && au_test_nfs_noacl(h_inode)) -+ err = h_inode->i_op->permission(h_idmap, h_inode, -+ mask); -+ AuTraceErr(err); -+ } else { -+ /* AuLabel(h_inode->permission); */ -+ err = h_inode->i_op->permission(h_idmap, h_inode, mask); -+ AuTraceErr(err); -+ } -+ -+ if (!err) -+ err = devcgroup_inode_permission(h_inode, mask); -+ if (!err) -+ err = security_inode_permission(h_inode, mask); -+ -+out: -+ return err; -+} -+ -+static int aufs_permission(struct mnt_idmap *idmap, struct inode *inode, -+ int mask) -+{ -+ int err; -+ aufs_bindex_t bindex, bbot; -+ const unsigned char isdir = !!S_ISDIR(inode->i_mode), -+ write_mask = !!(mask & (MAY_WRITE | MAY_APPEND)); -+ struct inode *h_inode; -+ struct super_block *sb; -+ struct au_branch *br; -+ -+ /* todo: support rcu-walk? */ -+ if (mask & MAY_NOT_BLOCK) -+ return -ECHILD; -+ -+ sb = inode->i_sb; -+ si_read_lock(sb, AuLock_FLUSH); -+ ii_read_lock_child(inode); -+#if 0 /* reserved for future use */ -+ /* -+ * This test may be rather 'too much' since the test is essentially done -+ * in the aufs_lookup(). Theoretically it is possible that the inode -+ * generation doesn't match to the superblock's here. But it isn't a -+ * big deal I suppose. -+ */ -+ err = au_iigen_test(inode, au_sigen(sb)); -+ if (unlikely(err)) -+ goto out; -+#endif -+ -+ if (!isdir -+ || write_mask -+ || au_opt_test(au_mntflags(sb), DIRPERM1)) { -+ err = au_busy_or_stale(); -+ h_inode = au_h_iptr(inode, au_ibtop(inode)); -+ if (unlikely(!h_inode -+ || (h_inode->i_mode & S_IFMT) -+ != (inode->i_mode & S_IFMT))) -+ goto out; -+ -+ err = 0; -+ bindex = au_ibtop(inode); -+ br = au_sbr(sb, bindex); -+ err = h_permission(h_inode, mask, &br->br_path, br->br_perm); -+ if (write_mask -+ && !err -+ && !special_file(h_inode->i_mode)) { -+ /* test whether the upper writable branch exists */ -+ err = -EROFS; -+ for (; bindex >= 0; bindex--) -+ if (!au_br_rdonly(au_sbr(sb, bindex))) { -+ err = 0; -+ break; -+ } -+ } -+ goto out; -+ } -+ -+ /* non-write to dir */ -+ err = 0; -+ bbot = au_ibbot(inode); -+ for (bindex = au_ibtop(inode); !err && bindex <= bbot; bindex++) { -+ h_inode = au_h_iptr(inode, bindex); -+ if (h_inode) { -+ err = au_busy_or_stale(); -+ if (unlikely(!S_ISDIR(h_inode->i_mode))) -+ break; -+ -+ br = au_sbr(sb, bindex); -+ err = h_permission(h_inode, mask, &br->br_path, -+ br->br_perm); -+ } -+ } -+ -+out: -+ ii_read_unlock(inode); -+ si_read_unlock(sb); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry, -+ unsigned int flags) -+{ -+ struct dentry *ret, *parent; -+ struct inode *inode; -+ struct super_block *sb; -+ int err, npositive; -+ -+ IMustLock(dir); -+ -+ /* todo: support rcu-walk? */ -+ ret = ERR_PTR(-ECHILD); -+ if (flags & LOOKUP_RCU) -+ goto out; -+ -+ ret = ERR_PTR(-ENAMETOOLONG); -+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN)) -+ goto out; -+ -+ sb = dir->i_sb; -+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ ret = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out; -+ -+ err = au_di_init(dentry); -+ ret = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out_si; -+ -+ inode = NULL; -+ npositive = 0; /* suppress a warning */ -+ parent = dentry->d_parent; /* dir inode is locked */ -+ di_read_lock_parent(parent, AuLock_IR); -+ err = au_alive_dir(parent); -+ if (!err) -+ err = au_digen_test(parent, au_sigen(sb)); -+ if (!err) { -+ /* regardless LOOKUP_CREATE, always ALLOW_NEG */ -+ npositive = au_lkup_dentry(dentry, au_dbtop(parent), -+ AuLkup_ALLOW_NEG); -+ err = npositive; -+ } -+ di_read_unlock(parent, AuLock_IR); -+ ret = ERR_PTR(err); -+ if (unlikely(err < 0)) -+ goto out_unlock; -+ -+ if (npositive) { -+ inode = au_new_inode(dentry, /*must_new*/0); -+ if (IS_ERR(inode)) { -+ ret = (void *)inode; -+ inode = NULL; -+ goto out_unlock; -+ } -+ } -+ -+ if (inode) -+ atomic_inc(&inode->i_count); -+ ret = d_splice_alias(inode, dentry); -+#if 0 /* reserved for future use */ -+ if (unlikely(d_need_lookup(dentry))) { -+ spin_lock(&dentry->d_lock); -+ dentry->d_flags &= ~DCACHE_NEED_LOOKUP; -+ spin_unlock(&dentry->d_lock); -+ } else -+#endif -+ if (inode) { -+ if (!IS_ERR(ret)) { -+ iput(inode); -+ if (ret && ret != dentry) -+ ii_write_unlock(inode); -+ } else { -+ ii_write_unlock(inode); -+ iput(inode); -+ inode = NULL; -+ } -+ } -+ -+out_unlock: -+ di_write_unlock(dentry); -+out_si: -+ si_read_unlock(sb); -+out: -+ return ret; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * very dirty and complicated aufs ->atomic_open(). -+ * aufs_atomic_open() -+ * + au_aopen_or_create() -+ * + add_simple() -+ * + vfsub_atomic_open() -+ * + branch fs ->atomic_open() -+ * may call the actual 'open' for h_file -+ * + inc br_nfiles only if opened -+ * + au_aopen_no_open() or au_aopen_do_open() -+ * -+ * au_aopen_do_open() -+ * + finish_open() -+ * + au_do_aopen() -+ * + au_do_open() the body of all 'open' -+ * + au_do_open_nondir() -+ * set the passed h_file -+ * -+ * au_aopen_no_open() -+ * + finish_no_open() -+ */ -+ -+struct aopen_node { -+ struct hlist_bl_node hblist; -+ struct file *file, *h_file; -+}; -+ -+static int au_do_aopen(struct inode *inode, struct file *file) -+{ -+ struct hlist_bl_head *aopen; -+ struct hlist_bl_node *pos; -+ struct aopen_node *node; -+ struct au_do_open_args args = { -+ .aopen = 1, -+ .open = au_do_open_nondir -+ }; -+ -+ aopen = &au_sbi(inode->i_sb)->si_aopen; -+ hlist_bl_lock(aopen); -+ hlist_bl_for_each_entry(node, pos, aopen, hblist) -+ if (node->file == file) { -+ args.h_file = node->h_file; -+ break; -+ } -+ hlist_bl_unlock(aopen); -+ /* AuDebugOn(!args.h_file); */ -+ -+ return au_do_open(file, &args); -+} -+ -+static int au_aopen_do_open(struct file *file, struct dentry *dentry, -+ struct aopen_node *aopen_node) -+{ -+ int err; -+ struct hlist_bl_head *aopen; -+ -+ AuLabel(here); -+ aopen = &au_sbi(dentry->d_sb)->si_aopen; -+ au_hbl_add(&aopen_node->hblist, aopen); -+ err = finish_open(file, dentry, au_do_aopen); -+ au_hbl_del(&aopen_node->hblist, aopen); -+ /* AuDbgFile(file); */ -+ AuDbg("%pd%s%s\n", dentry, -+ (file->f_mode & FMODE_CREATED) ? " created" : "", -+ (file->f_mode & FMODE_OPENED) ? " opened" : ""); -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_aopen_no_open(struct file *file, struct dentry *dentry) -+{ -+ int err; -+ -+ AuLabel(here); -+ dget(dentry); -+ err = finish_no_open(file, dentry); -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+static int aufs_atomic_open(struct inode *dir, struct dentry *dentry, -+ struct file *file, unsigned int open_flag, -+ umode_t create_mode) -+{ -+ int err, did_open; -+ unsigned int lkup_flags; -+ aufs_bindex_t bindex; -+ struct super_block *sb; -+ struct dentry *parent, *d; -+ struct vfsub_aopen_args args = { -+ .open_flag = open_flag, -+ .create_mode = create_mode -+ }; -+ struct aopen_node aopen_node = { -+ .file = file -+ }; -+ -+ IMustLock(dir); -+ AuDbg("open_flag 0%o\n", open_flag); -+ AuDbgDentry(dentry); -+ -+ err = 0; -+ if (!au_di(dentry)) { -+ lkup_flags = LOOKUP_OPEN; -+ if (open_flag & O_CREAT) -+ lkup_flags |= LOOKUP_CREATE; -+ d = aufs_lookup(dir, dentry, lkup_flags); -+ if (IS_ERR(d)) { -+ err = PTR_ERR(d); -+ AuTraceErr(err); -+ goto out; -+ } else if (d) { -+ /* -+ * obsoleted dentry found. -+ * another error will be returned later. -+ */ -+ d_drop(d); -+ AuDbgDentry(d); -+ dput(d); -+ } -+ AuDbgDentry(dentry); -+ } -+ -+ if (d_is_positive(dentry) -+ || d_unhashed(dentry) -+ || d_unlinked(dentry) -+ || !(open_flag & O_CREAT)) { -+ err = au_aopen_no_open(file, dentry); -+ goto out; /* success */ -+ } -+ -+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN); -+ if (unlikely(err)) -+ goto out; -+ -+ sb = dentry->d_sb; -+ parent = dentry->d_parent; /* dir is locked */ -+ di_write_lock_parent(parent); -+ err = au_lkup_dentry(dentry, /*btop*/0, AuLkup_ALLOW_NEG); -+ if (unlikely(err < 0)) -+ goto out_parent; -+ -+ AuDbgDentry(dentry); -+ if (d_is_positive(dentry)) { -+ err = au_aopen_no_open(file, dentry); -+ goto out_parent; /* success */ -+ } -+ -+ args.file = alloc_empty_file(file->f_flags, current_cred()); -+ err = PTR_ERR(args.file); -+ if (IS_ERR(args.file)) -+ goto out_parent; -+ -+ bindex = au_dbtop(dentry); -+ err = au_aopen_or_create(dir, dentry, &args); -+ AuTraceErr(err); -+ AuDbgFile(args.file); -+ file->f_mode = args.file->f_mode & ~FMODE_OPENED; -+ did_open = !!(args.file->f_mode & FMODE_OPENED); -+ if (!did_open) { -+ fput(args.file); -+ args.file = NULL; -+ } -+ di_write_unlock(parent); -+ di_write_unlock(dentry); -+ if (unlikely(err < 0)) { -+ if (args.file) -+ fput(args.file); -+ goto out_sb; -+ } -+ -+ if (!did_open) -+ err = au_aopen_no_open(file, dentry); -+ else { -+ aopen_node.h_file = args.file; -+ err = au_aopen_do_open(file, dentry, &aopen_node); -+ } -+ if (unlikely(err < 0)) { -+ if (args.file) -+ fput(args.file); -+ if (did_open) -+ au_lcnt_dec(&args.br->br_nfiles); -+ } -+ goto out_sb; /* success */ -+ -+out_parent: -+ di_write_unlock(parent); -+ di_write_unlock(dentry); -+out_sb: -+ si_read_unlock(sb); -+out: -+ AuTraceErr(err); -+ AuDbgFile(file); -+ 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 btop) -+{ -+ int err; -+ struct dentry *h_parent; -+ struct inode *h_dir; -+ -+ if (add_entry) -+ IMustLock(d_inode(parent)); -+ else -+ di_write_lock_parent(parent); -+ -+ err = 0; -+ if (!au_h_dptr(parent, bcpup)) { -+ if (btop > bcpup) -+ err = au_cpup_dirs(dentry, bcpup); -+ else if (btop < bcpup) -+ err = au_cpdown_dirs(dentry, bcpup); -+ else -+ BUG(); -+ } -+ if (!err && add_entry && !au_ftest_wrdir(add_entry, TMPFILE)) { -+ h_parent = au_h_dptr(parent, bcpup); -+ h_dir = d_inode(h_parent); -+ inode_lock_shared_nested(h_dir, AuLsc_I_PARENT); -+ err = au_lkup_neg(dentry, bcpup, /*wh*/0); -+ /* todo: no unlock here */ -+ inode_unlock_shared(h_dir); -+ -+ AuDbg("bcpup %d\n", bcpup); -+ if (!err) { -+ if (d_really_is_negative(dentry)) -+ au_set_h_dptr(dentry, btop, NULL); -+ au_update_dbrange(dentry, /*do_put_zero*/0); -+ } -+ } -+ -+ if (!add_entry) -+ di_write_unlock(parent); -+ if (!err) -+ err = bcpup; /* success */ -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+/* -+ * decide the branch and the parent dir where we will create a new entry. -+ * returns new bindex or an error. -+ * copyup the parent dir if needed. -+ */ -+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry, -+ struct au_wr_dir_args *args) -+{ -+ int err; -+ unsigned int flags; -+ aufs_bindex_t bcpup, btop, src_btop; -+ const unsigned char add_entry -+ = au_ftest_wrdir(args->flags, ADD_ENTRY) -+ | au_ftest_wrdir(args->flags, TMPFILE); -+ struct super_block *sb; -+ struct dentry *parent; -+ struct au_sbinfo *sbinfo; -+ -+ sb = dentry->d_sb; -+ sbinfo = au_sbi(sb); -+ parent = dget_parent(dentry); -+ btop = au_dbtop(dentry); -+ bcpup = btop; -+ if (args->force_btgt < 0) { -+ if (src_dentry) { -+ src_btop = au_dbtop(src_dentry); -+ if (src_btop < btop) -+ bcpup = src_btop; -+ } else if (add_entry) { -+ flags = 0; -+ if (au_ftest_wrdir(args->flags, ISDIR)) -+ au_fset_wbr(flags, DIR); -+ err = AuWbrCreate(sbinfo, dentry, flags); -+ bcpup = err; -+ } -+ -+ if (bcpup < 0 || au_test_ro(sb, bcpup, d_inode(dentry))) { -+ if (add_entry) -+ err = AuWbrCopyup(sbinfo, dentry); -+ else { -+ if (!IS_ROOT(dentry)) { -+ di_read_lock_parent(parent, !AuLock_IR); -+ err = AuWbrCopyup(sbinfo, dentry); -+ di_read_unlock(parent, !AuLock_IR); -+ } else -+ err = AuWbrCopyup(sbinfo, dentry); -+ } -+ bcpup = err; -+ if (unlikely(err < 0)) -+ goto out; -+ } -+ } else { -+ bcpup = args->force_btgt; -+ AuDebugOn(au_test_ro(sb, bcpup, d_inode(dentry))); -+ } -+ -+ AuDbg("btop %d, bcpup %d\n", btop, bcpup); -+ err = bcpup; -+ if (bcpup == btop) -+ goto out; /* success */ -+ -+ /* copyup the new parent into the branch we process */ -+ err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, btop); -+ if (err >= 0) { -+ if (d_really_is_negative(dentry)) { -+ au_set_h_dptr(dentry, btop, NULL); -+ au_set_dbtop(dentry, bcpup); -+ au_set_dbbot(dentry, bcpup); -+ } -+ AuDebugOn(add_entry -+ && !au_ftest_wrdir(args->flags, TMPFILE) -+ && !au_h_dptr(dentry, bcpup)); -+ } -+ -+out: -+ dput(parent); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void au_pin_hdir_unlock(struct au_pin *p) -+{ -+ if (p->hdir) -+ au_hn_inode_unlock(p->hdir); -+} -+ -+int au_pin_hdir_lock(struct au_pin *p) -+{ -+ int err; -+ -+ err = 0; -+ if (!p->hdir) -+ goto out; -+ -+ /* even if an error happens later, keep this lock */ -+ au_hn_inode_lock_nested(p->hdir, p->lsc_hi); -+ -+ err = -EBUSY; -+ if (unlikely(p->hdir->hi_inode != d_inode(p->h_parent))) -+ goto out; -+ -+ err = 0; -+ if (p->h_dentry) -+ err = au_h_verify(p->h_dentry, p->udba, p->hdir->hi_inode, -+ p->h_parent, p->br); -+ -+out: -+ return err; -+} -+ -+int au_pin_hdir_relock(struct au_pin *p) -+{ -+ int err, i; -+ struct inode *h_i; -+ struct dentry *h_d[] = { -+ p->h_dentry, -+ p->h_parent -+ }; -+ -+ err = au_pin_hdir_lock(p); -+ if (unlikely(err)) -+ goto out; -+ -+ for (i = 0; !err && i < sizeof(h_d)/sizeof(*h_d); i++) { -+ if (!h_d[i]) -+ continue; -+ if (d_is_positive(h_d[i])) { -+ h_i = d_inode(h_d[i]); -+ err = !vfsub_inode_nlink(h_i, AU_I_BRANCH); -+ } -+ } -+ -+out: -+ return err; -+} -+ -+static void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task) -+{ -+ atomic_long_set(&p->hdir->hi_inode->i_rwsem.owner, (long)task); -+} -+ -+void au_pin_hdir_acquire_nest(struct au_pin *p) -+{ -+ if (p->hdir) { -+ rwsem_acquire_nest(&p->hdir->hi_inode->i_rwsem.dep_map, -+ p->lsc_hi, 0, NULL, _RET_IP_); -+ au_pin_hdir_set_owner(p, current); -+ } -+} -+ -+void au_pin_hdir_release(struct au_pin *p) -+{ -+ if (p->hdir) { -+ au_pin_hdir_set_owner(p, p->task); -+ rwsem_release(&p->hdir->hi_inode->i_rwsem.dep_map, _RET_IP_); -+ } -+} -+ -+struct dentry *au_pinned_h_parent(struct au_pin *pin) -+{ -+ if (pin && pin->parent) -+ return au_h_dptr(pin->parent, pin->bindex); -+ return NULL; -+} -+ -+void au_unpin(struct au_pin *p) -+{ -+ if (p->hdir) -+ au_pin_hdir_unlock(p); -+ if (p->h_mnt && au_ftest_pin(p->flags, MNT_WRITE)) -+ vfsub_mnt_drop_write(p->h_mnt); -+ if (!p->hdir) -+ return; -+ -+ if (!au_ftest_pin(p->flags, DI_LOCKED)) -+ di_read_unlock(p->parent, AuLock_IR); -+ iput(p->hdir->hi_inode); -+ dput(p->parent); -+ p->parent = NULL; -+ p->hdir = NULL; -+ p->h_mnt = NULL; -+ /* do not clear p->task */ -+} -+ -+int au_do_pin(struct au_pin *p) -+{ -+ int err; -+ struct super_block *sb; -+ struct inode *h_dir; -+ -+ err = 0; -+ sb = p->dentry->d_sb; -+ p->br = au_sbr(sb, p->bindex); -+ if (IS_ROOT(p->dentry)) { -+ if (au_ftest_pin(p->flags, MNT_WRITE)) { -+ p->h_mnt = au_br_mnt(p->br); -+ err = vfsub_mnt_want_write(p->h_mnt); -+ if (unlikely(err)) { -+ au_fclr_pin(p->flags, MNT_WRITE); -+ goto out_err; -+ } -+ } -+ goto out; -+ } -+ -+ p->h_dentry = NULL; -+ if (p->bindex <= au_dbbot(p->dentry)) -+ p->h_dentry = au_h_dptr(p->dentry, p->bindex); -+ -+ p->parent = dget_parent(p->dentry); -+ if (!au_ftest_pin(p->flags, DI_LOCKED)) -+ di_read_lock(p->parent, AuLock_IR, p->lsc_di); -+ -+ h_dir = NULL; -+ p->h_parent = au_h_dptr(p->parent, p->bindex); -+ p->hdir = au_hi(d_inode(p->parent), p->bindex); -+ if (p->hdir) -+ h_dir = p->hdir->hi_inode; -+ -+ /* -+ * udba case, or -+ * if DI_LOCKED is not set, then p->parent may be different -+ * and h_parent can be NULL. -+ */ -+ if (unlikely(!p->hdir || !h_dir || !p->h_parent)) { -+ err = -EBUSY; -+ if (!au_ftest_pin(p->flags, DI_LOCKED)) -+ di_read_unlock(p->parent, AuLock_IR); -+ dput(p->parent); -+ p->parent = NULL; -+ goto out_err; -+ } -+ -+ if (au_ftest_pin(p->flags, MNT_WRITE)) { -+ p->h_mnt = au_br_mnt(p->br); -+ err = vfsub_mnt_want_write(p->h_mnt); -+ if (unlikely(err)) { -+ au_fclr_pin(p->flags, MNT_WRITE); -+ if (!au_ftest_pin(p->flags, DI_LOCKED)) -+ di_read_unlock(p->parent, AuLock_IR); -+ dput(p->parent); -+ p->parent = NULL; -+ goto out_err; -+ } -+ } -+ -+ au_igrab(h_dir); -+ err = au_pin_hdir_lock(p); -+ if (!err) -+ goto out; /* success */ -+ -+ au_unpin(p); -+ -+out_err: -+ pr_err("err %d\n", err); -+ err = au_busy_or_stale(); -+out: -+ return err; -+} -+ -+void au_pin_init(struct au_pin *p, struct dentry *dentry, -+ aufs_bindex_t bindex, int lsc_di, int lsc_hi, -+ unsigned int udba, unsigned char flags) -+{ -+ p->dentry = dentry; -+ p->udba = udba; -+ p->lsc_di = lsc_di; -+ p->lsc_hi = lsc_hi; -+ p->flags = flags; -+ p->bindex = bindex; -+ -+ p->parent = NULL; -+ p->hdir = NULL; -+ p->h_mnt = NULL; -+ -+ p->h_dentry = NULL; -+ p->h_parent = NULL; -+ p->br = NULL; -+ p->task = current; -+} -+ -+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex, -+ unsigned int udba, unsigned char flags) -+{ -+ au_pin_init(pin, dentry, bindex, AuLsc_DI_PARENT, AuLsc_I_PARENT2, -+ udba, flags); -+ return au_do_pin(pin); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * ->setattr() and ->getattr() are called in various cases. -+ * chmod, stat: dentry is revalidated. -+ * fchmod, fstat: file and dentry are not revalidated, additionally they may be -+ * unhashed. -+ * for ->setattr(), ia->ia_file is passed from ftruncate only. -+ */ -+/* todo: consolidate with do_refresh() and simple_reval_dpath() */ -+int au_reval_for_attr(struct dentry *dentry, unsigned int sigen) -+{ -+ int err; -+ struct dentry *parent; -+ -+ err = 0; -+ if (au_digen_test(dentry, sigen)) { -+ parent = dget_parent(dentry); -+ di_read_lock_parent(parent, AuLock_IR); -+ err = au_refresh_dentry(dentry, parent); -+ di_read_unlock(parent, AuLock_IR); -+ dput(parent); -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia, -+ struct au_icpup_args *a) -+{ -+ int err; -+ loff_t sz; -+ aufs_bindex_t btop, ibtop; -+ struct dentry *hi_wh, *parent; -+ struct inode *inode; -+ struct au_wr_dir_args wr_dir_args = { -+ .force_btgt = -1, -+ .flags = 0 -+ }; -+ -+ if (d_is_dir(dentry)) -+ au_fset_wrdir(wr_dir_args.flags, ISDIR); -+ /* plink or hi_wh() case */ -+ btop = au_dbtop(dentry); -+ inode = d_inode(dentry); -+ ibtop = au_ibtop(inode); -+ if (btop != ibtop && !au_test_ro(inode->i_sb, ibtop, inode)) -+ wr_dir_args.force_btgt = ibtop; -+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args); -+ if (unlikely(err < 0)) -+ goto out; -+ a->btgt = err; -+ if (err != btop) -+ au_fset_icpup(a->flags, DID_CPUP); -+ -+ err = 0; -+ a->pin_flags = AuPin_MNT_WRITE; -+ parent = NULL; -+ if (!IS_ROOT(dentry)) { -+ au_fset_pin(a->pin_flags, DI_LOCKED); -+ parent = dget_parent(dentry); -+ di_write_lock_parent(parent); -+ } -+ -+ err = au_pin(&a->pin, dentry, a->btgt, a->udba, a->pin_flags); -+ if (unlikely(err)) -+ goto out_parent; -+ -+ sz = -1; -+ a->h_path.dentry = au_h_dptr(dentry, btop); -+ a->h_inode = d_inode(a->h_path.dentry); -+ if (ia && (ia->ia_valid & ATTR_SIZE)) { -+ inode_lock_shared_nested(a->h_inode, AuLsc_I_CHILD); -+ if (ia->ia_size < i_size_read(a->h_inode)) -+ sz = ia->ia_size; -+ inode_unlock_shared(a->h_inode); -+ } -+ -+ hi_wh = NULL; -+ if (au_ftest_icpup(a->flags, DID_CPUP) && d_unlinked(dentry)) { -+ hi_wh = au_hi_wh(inode, a->btgt); -+ if (!hi_wh) { -+ struct au_cp_generic cpg = { -+ .dentry = dentry, -+ .bdst = a->btgt, -+ .bsrc = -1, -+ .len = sz, -+ .pin = &a->pin -+ }; -+ err = au_sio_cpup_wh(&cpg, /*file*/NULL); -+ if (unlikely(err)) -+ goto out_unlock; -+ hi_wh = au_hi_wh(inode, a->btgt); -+ /* todo: revalidate hi_wh? */ -+ } -+ } -+ -+ if (parent) { -+ au_pin_set_parent_lflag(&a->pin, /*lflag*/0); -+ di_downgrade_lock(parent, AuLock_IR); -+ dput(parent); -+ parent = NULL; -+ } -+ if (!au_ftest_icpup(a->flags, DID_CPUP)) -+ goto out; /* success */ -+ -+ if (!d_unhashed(dentry)) { -+ struct au_cp_generic cpg = { -+ .dentry = dentry, -+ .bdst = a->btgt, -+ .bsrc = btop, -+ .len = sz, -+ .pin = &a->pin, -+ .flags = AuCpup_DTIME | AuCpup_HOPEN -+ }; -+ err = au_sio_cpup_simple(&cpg); -+ if (!err) -+ a->h_path.dentry = au_h_dptr(dentry, a->btgt); -+ } else if (!hi_wh) -+ a->h_path.dentry = au_h_dptr(dentry, a->btgt); -+ else -+ a->h_path.dentry = hi_wh; /* do not dget here */ -+ -+out_unlock: -+ a->h_inode = d_inode(a->h_path.dentry); -+ if (!err) -+ goto out; /* success */ -+ au_unpin(&a->pin); -+out_parent: -+ if (parent) { -+ di_write_unlock(parent); -+ dput(parent); -+ } -+out: -+ if (!err) -+ inode_lock_nested(a->h_inode, AuLsc_I_CHILD); -+ return err; -+} -+ -+static int aufs_setattr(struct mnt_idmap *idmap, struct dentry *dentry, -+ struct iattr *ia) -+{ -+ int err; -+ struct inode *inode, *delegated; -+ struct super_block *sb; -+ struct file *file; -+ struct au_icpup_args *a; -+ struct mnt_idmap *h_idmap; -+ -+ inode = d_inode(dentry); -+ IMustLock(inode); -+ -+ err = setattr_prepare(idmap, dentry, ia); -+ if (unlikely(err)) -+ goto out; -+ -+ err = -ENOMEM; -+ a = kzalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ -+ if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) -+ ia->ia_valid &= ~ATTR_MODE; -+ -+ file = NULL; -+ sb = dentry->d_sb; -+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (unlikely(err)) -+ goto out_kfree; -+ -+ if (ia->ia_valid & ATTR_FILE) { -+ /* currently ftruncate(2) only */ -+ AuDebugOn(!d_is_reg(dentry)); -+ file = ia->ia_file; -+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1, -+ /*fi_lsc*/0); -+ if (unlikely(err)) -+ goto out_si; -+ ia->ia_file = au_hf_top(file); -+ a->udba = AuOpt_UDBA_NONE; -+ } else { -+ /* fchmod() doesn't pass ia_file */ -+ a->udba = au_opt_udba(sb); -+ di_write_lock_child(dentry); -+ /* no d_unlinked(), to set UDBA_NONE for root */ -+ if (d_unhashed(dentry)) -+ a->udba = AuOpt_UDBA_NONE; -+ if (a->udba != AuOpt_UDBA_NONE) { -+ AuDebugOn(IS_ROOT(dentry)); -+ err = au_reval_for_attr(dentry, au_sigen(sb)); -+ if (unlikely(err)) -+ goto out_dentry; -+ } -+ } -+ -+ err = au_pin_and_icpup(dentry, ia, a); -+ if (unlikely(err < 0)) -+ goto out_dentry; -+ if (au_ftest_icpup(a->flags, DID_CPUP)) { -+ ia->ia_file = NULL; -+ ia->ia_valid &= ~ATTR_FILE; -+ } -+ -+ a->h_path.mnt = au_sbr_mnt(sb, a->btgt); -+ if ((ia->ia_valid & (ATTR_MODE | ATTR_CTIME)) -+ == (ATTR_MODE | ATTR_CTIME)) { -+ err = security_path_chmod(&a->h_path, ia->ia_mode); -+ if (unlikely(err)) -+ goto out_unlock; -+ } else if ((ia->ia_valid & (ATTR_UID | ATTR_GID)) -+ && (ia->ia_valid & ATTR_CTIME)) { -+ err = security_path_chown(&a->h_path, ia->ia_uid, ia->ia_gid); -+ if (unlikely(err)) -+ goto out_unlock; -+ } -+ -+ if (ia->ia_valid & ATTR_SIZE) { -+ struct file *f; -+ -+ if (ia->ia_size < i_size_read(inode)) -+ /* unmap only */ -+ truncate_setsize(inode, ia->ia_size); -+ -+ f = NULL; -+ if (ia->ia_valid & ATTR_FILE) -+ f = ia->ia_file; -+ inode_unlock(a->h_inode); -+ err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f); -+ inode_lock_nested(a->h_inode, AuLsc_I_CHILD); -+ } else { -+ delegated = NULL; -+ while (1) { -+ err = vfsub_notify_change(&a->h_path, ia, &delegated); -+ if (delegated) { -+ err = break_deleg_wait(&delegated); -+ if (!err) -+ continue; -+ } -+ break; -+ } -+ } -+ /* -+ * regardless aufs 'acl' option setting. -+ * why don't all acl-aware fs call this func from their ->setattr()? -+ */ -+ if (!err && (ia->ia_valid & ATTR_MODE)) { -+ h_idmap = mnt_idmap(a->h_path.mnt); -+ err = vfsub_acl_chmod(h_idmap, a->h_path.dentry, ia->ia_mode); -+ } -+ if (!err) -+ au_cpup_attr_changeable(inode); -+ -+out_unlock: -+ inode_unlock(a->h_inode); -+ au_unpin(&a->pin); -+ if (unlikely(err)) -+ au_update_dbtop(dentry); -+out_dentry: -+ di_write_unlock(dentry); -+ if (file) { -+ fi_write_unlock(file); -+ ia->ia_file = file; -+ ia->ia_valid |= ATTR_FILE; -+ } -+out_si: -+ si_read_unlock(sb); -+out_kfree: -+ au_kfree_rcu(a); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL) -+static int au_h_path_to_set_attr(struct dentry *dentry, -+ struct au_icpup_args *a, struct path *h_path) -+{ -+ int err; -+ struct super_block *sb; -+ -+ sb = dentry->d_sb; -+ a->udba = au_opt_udba(sb); -+ /* no d_unlinked(), to set UDBA_NONE for root */ -+ if (d_unhashed(dentry)) -+ a->udba = AuOpt_UDBA_NONE; -+ if (a->udba != AuOpt_UDBA_NONE) { -+ AuDebugOn(IS_ROOT(dentry)); -+ err = au_reval_for_attr(dentry, au_sigen(sb)); -+ if (unlikely(err)) -+ goto out; -+ } -+ err = au_pin_and_icpup(dentry, /*ia*/NULL, a); -+ if (unlikely(err < 0)) -+ goto out; -+ -+ h_path->dentry = a->h_path.dentry; -+ h_path->mnt = au_sbr_mnt(sb, a->btgt); -+ -+out: -+ return err; -+} -+ -+ssize_t au_sxattr(struct dentry *dentry, struct inode *inode, -+ struct au_sxattr *arg) -+{ -+ int err; -+ struct path h_path; -+ struct super_block *sb; -+ struct au_icpup_args *a; -+ struct inode *h_inode; -+ struct mnt_idmap *h_idmap; -+ -+ IMustLock(inode); -+ -+ err = -ENOMEM; -+ a = kzalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ -+ sb = dentry->d_sb; -+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (unlikely(err)) -+ goto out_kfree; -+ -+ h_path.dentry = NULL; /* silence gcc */ -+ di_write_lock_child(dentry); -+ err = au_h_path_to_set_attr(dentry, a, &h_path); -+ if (unlikely(err)) -+ goto out_di; -+ h_idmap = mnt_idmap(h_path.mnt); -+ -+ inode_unlock(a->h_inode); -+ switch (arg->type) { -+ case AU_XATTR_SET: -+ AuDebugOn(d_is_negative(h_path.dentry)); -+ err = vfsub_setxattr(h_idmap, h_path.dentry, -+ arg->u.set.name, arg->u.set.value, -+ arg->u.set.size, arg->u.set.flags); -+ break; -+ case AU_ACL_SET: -+ err = -EOPNOTSUPP; -+ h_inode = d_inode(h_path.dentry); -+ if (h_inode->i_op->set_acl) { -+ /* this will call posix_acl_update_mode */ -+ err = h_inode->i_op->set_acl(h_idmap, h_path.dentry, -+ arg->u.acl_set.acl, -+ arg->u.acl_set.type); -+ } -+ break; -+ } -+ if (!err) -+ au_cpup_attr_timesizes(inode); -+ -+ au_unpin(&a->pin); -+ if (unlikely(err)) -+ au_update_dbtop(dentry); -+ -+out_di: -+ di_write_unlock(dentry); -+ si_read_unlock(sb); -+out_kfree: -+ au_kfree_rcu(a); -+out: -+ AuTraceErr(err); -+ return err; -+} -+#endif -+ -+static void au_refresh_iattr(struct inode *inode, struct kstat *st, -+ unsigned int nlink) -+{ -+ unsigned int n; -+ -+ inode->i_mode = st->mode; -+ /* don't i_[ug]id_write() here */ -+ inode->i_uid = st->uid; -+ inode->i_gid = st->gid; -+ inode->i_atime = st->atime; -+ inode->i_mtime = st->mtime; -+ inode_set_ctime_to_ts(inode, st->ctime); -+ -+ au_cpup_attr_nlink(inode, /*force*/0); -+ if (S_ISDIR(inode->i_mode)) { -+ n = vfsub_inode_nlink(inode, AU_I_AUFS); -+ n -= nlink; -+ n += st->nlink; -+ /* 0 can happen */ -+ vfsub_set_nlink(inode, n); -+ } -+ -+ spin_lock(&inode->i_lock); -+ inode->i_blocks = st->blocks; -+ i_size_write(inode, st->size); -+ spin_unlock(&inode->i_lock); -+} -+ -+/* -+ * common routine for aufs_getattr() and au_getxattr(). -+ * returns zero or negative (an error). -+ * @dentry will be read-locked in success. -+ */ -+int au_h_path_getattr(struct dentry *dentry, struct inode *inode, int force, -+ struct path *h_path, int locked) -+{ -+ int err; -+ unsigned int mnt_flags, sigen; -+ unsigned char udba_none; -+ aufs_bindex_t bindex; -+ struct super_block *sb, *h_sb; -+ -+ h_path->mnt = NULL; -+ h_path->dentry = NULL; -+ -+ err = 0; -+ sb = dentry->d_sb; -+ mnt_flags = au_mntflags(sb); -+ udba_none = !!au_opt_test(mnt_flags, UDBA_NONE); -+ -+ if (unlikely(locked)) -+ goto body; /* skip locking dinfo */ -+ -+ /* support fstat(2) */ -+ if (!d_unlinked(dentry) && !udba_none) { -+ sigen = au_sigen(sb); -+ err = au_digen_test(dentry, sigen); -+ if (!err) { -+ di_read_lock_child(dentry, AuLock_IR); -+ err = au_dbrange_test(dentry); -+ if (unlikely(err)) { -+ di_read_unlock(dentry, AuLock_IR); -+ goto out; -+ } -+ } else { -+ AuDebugOn(IS_ROOT(dentry)); -+ di_write_lock_child(dentry); -+ err = au_dbrange_test(dentry); -+ if (!err) -+ err = au_reval_for_attr(dentry, sigen); -+ if (!err) -+ di_downgrade_lock(dentry, AuLock_IR); -+ else { -+ di_write_unlock(dentry); -+ goto out; -+ } -+ } -+ } else -+ di_read_lock_child(dentry, AuLock_IR); -+ -+body: -+ if (!inode) { -+ inode = d_inode(dentry); -+ if (unlikely(!inode)) -+ goto out; -+ } -+ bindex = au_ibtop(inode); -+ h_path->mnt = au_sbr_mnt(sb, bindex); -+ h_sb = h_path->mnt->mnt_sb; -+ if (!force -+ && !au_test_fs_bad_iattr(h_sb) -+ && udba_none) -+ goto out; /* success */ -+ -+ if (au_dbtop(dentry) == bindex) -+ h_path->dentry = au_h_dptr(dentry, bindex); -+ else if (au_opt_test(mnt_flags, PLINK) && au_plink_test(inode)) { -+ h_path->dentry = au_plink_lkup(inode, bindex); -+ if (IS_ERR(h_path->dentry)) -+ /* pretending success */ -+ h_path->dentry = NULL; -+ else -+ dput(h_path->dentry); -+ } -+ -+out: -+ return err; -+} -+ -+static int aufs_getattr(struct mnt_idmap *idmap, const struct path *path, -+ struct kstat *st, u32 request, unsigned int query) -+{ -+ int err; -+ unsigned char positive; -+ struct path h_path; -+ struct dentry *dentry; -+ struct inode *inode; -+ struct super_block *sb; -+ -+ dentry = path->dentry; -+ inode = d_inode(dentry); -+ sb = dentry->d_sb; -+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (unlikely(err)) -+ goto out; -+ err = au_h_path_getattr(dentry, /*inode*/NULL, /*force*/0, &h_path, -+ /*locked*/0); -+ if (unlikely(err)) -+ goto out_si; -+ if (unlikely(!h_path.dentry)) -+ /* illegally overlapped or something */ -+ goto out_fill; /* pretending success */ -+ -+ positive = d_is_positive(h_path.dentry); -+ if (positive) { -+ /* no vfsub version */ -+ if (query & AT_GETATTR_NOSEC) -+ err = vfs_getattr_nosec(&h_path, st, request, query); -+ else -+ err = vfs_getattr(&h_path, st, request, query); -+ } -+ if (!err) { -+ if (positive) -+ au_refresh_iattr(inode, st, -+ vfsub_inode_nlink(d_inode(h_path.dentry), -+ AU_I_BRANCH)); -+ goto out_fill; /* success */ -+ } -+ AuTraceErr(err); -+ goto out_di; -+ -+out_fill: -+ generic_fillattr(idmap, request, inode, st); -+out_di: -+ di_read_unlock(dentry, AuLock_IR); -+out_si: -+ si_read_unlock(sb); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static const char *aufs_get_link(struct dentry *dentry, struct inode *inode, -+ struct delayed_call *done) -+{ -+ const char *ret; -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ int err; -+ aufs_bindex_t bindex; -+ -+ ret = NULL; /* suppress a warning */ -+ err = -ECHILD; -+ if (!dentry) -+ goto out; -+ -+ err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN); -+ if (unlikely(err)) -+ goto out; -+ -+ err = au_d_hashed_positive(dentry); -+ if (unlikely(err)) -+ goto out_unlock; -+ -+ err = -EINVAL; -+ inode = d_inode(dentry); -+ bindex = au_ibtop(inode); -+ h_inode = au_h_iptr(inode, bindex); -+ if (unlikely(!h_inode->i_op->get_link)) -+ goto out_unlock; -+ -+ err = -EBUSY; -+ h_dentry = NULL; -+ if (au_dbtop(dentry) <= bindex) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (h_dentry) -+ dget(h_dentry); -+ } -+ if (!h_dentry) { -+ h_dentry = d_find_any_alias(h_inode); -+ if (IS_ERR(h_dentry)) { -+ err = PTR_ERR(h_dentry); -+ goto out_unlock; -+ } -+ } -+ if (unlikely(!h_dentry)) -+ goto out_unlock; -+ -+ err = 0; -+ AuDbg("%ps\n", h_inode->i_op->get_link); -+ AuDbgDentry(h_dentry); -+ ret = vfs_get_link(h_dentry, done); -+ dput(h_dentry); -+ if (IS_ERR(ret)) -+ err = PTR_ERR(ret); -+ -+out_unlock: -+ aufs_read_unlock(dentry, AuLock_IR); -+out: -+ if (unlikely(err)) -+ ret = ERR_PTR(err); -+ AuTraceErrPtr(ret); -+ return ret; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_is_special(struct inode *inode) -+{ -+ return (inode->i_mode & (S_IFBLK | S_IFCHR | S_IFIFO | S_IFSOCK)); -+} -+ -+static int aufs_update_time(struct inode *inode, int flags) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ struct super_block *sb; -+ struct inode *h_inode; -+ struct vfsmount *h_mnt; -+ -+ sb = inode->i_sb; -+ WARN_ONCE((flags & S_ATIME) && !IS_NOATIME(inode), -+ "unexpected s_flags 0x%lx", sb->s_flags); -+ -+ /* mmap_sem might be acquired already, cf. aufs_mmap() */ -+ lockdep_off(); -+ si_read_lock(sb, AuLock_FLUSH); -+ ii_write_lock_child(inode); -+ -+ err = 0; -+ bindex = au_ibtop(inode); -+ h_inode = au_h_iptr(inode, bindex); -+ if (!au_test_ro(sb, bindex, inode)) { -+ h_mnt = au_sbr_mnt(sb, bindex); -+ err = vfsub_mnt_want_write(h_mnt); -+ if (!err) { -+ err = vfsub_update_time(h_inode, flags); -+ vfsub_mnt_drop_write(h_mnt); -+ } -+ } else if (au_is_special(h_inode)) { -+ /* -+ * Never copy-up here. -+ * These special files may already be opened and used for -+ * communicating. If we copied it up, then the communication -+ * would be corrupted. -+ */ -+ AuWarn1("timestamps for i%lu are ignored " -+ "since it is on readonly branch (hi%lu).\n", -+ inode->i_ino, h_inode->i_ino); -+ } else if (flags & ~S_ATIME) { -+ err = -EIO; -+ AuIOErr1("unexpected flags 0x%x\n", flags); -+ AuDebugOn(1); -+ } -+ -+ if (!err) -+ au_cpup_attr_timesizes(inode); -+ ii_write_unlock(inode); -+ si_read_unlock(sb); -+ lockdep_on(); -+ -+ if (!err && (flags & S_VERSION)) -+ inode_inc_iversion(inode); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* no getattr version will be set by module.c:aufs_init() */ -+struct inode_operations aufs_iop_nogetattr[AuIop_Last], -+ aufs_iop[] = { -+ [AuIop_SYMLINK] = { -+ .permission = aufs_permission, -+#ifdef CONFIG_FS_POSIX_ACL -+ .get_inode_acl = aufs_get_inode_acl, -+ .get_acl = aufs_get_acl, -+ .set_acl = aufs_set_acl, /* unsupport for symlink? */ -+#endif -+ -+ .setattr = aufs_setattr, -+ .getattr = aufs_getattr, -+ -+#ifdef CONFIG_AUFS_XATTR -+ .listxattr = aufs_listxattr, -+#endif -+ -+ .get_link = aufs_get_link -+ -+ /* .update_time = aufs_update_time */ -+ }, -+ [AuIop_DIR] = { -+ .create = aufs_create, -+ .lookup = aufs_lookup, -+ .link = aufs_link, -+ .unlink = aufs_unlink, -+ .symlink = aufs_symlink, -+ .mkdir = aufs_mkdir, -+ .rmdir = aufs_rmdir, -+ .mknod = aufs_mknod, -+ .rename = aufs_rename, -+ -+ .permission = aufs_permission, -+#ifdef CONFIG_FS_POSIX_ACL -+ .get_inode_acl = aufs_get_inode_acl, -+ .get_acl = aufs_get_acl, -+ .set_acl = aufs_set_acl, -+#endif -+ -+ .setattr = aufs_setattr, -+ .getattr = aufs_getattr, -+ -+#ifdef CONFIG_AUFS_XATTR -+ .listxattr = aufs_listxattr, -+#endif -+ -+ .update_time = aufs_update_time, -+ .atomic_open = aufs_atomic_open, -+ .tmpfile = aufs_tmpfile -+ }, -+ [AuIop_OTHER] = { -+ .permission = aufs_permission, -+#ifdef CONFIG_FS_POSIX_ACL -+ .get_inode_acl = aufs_get_inode_acl, -+ .get_acl = aufs_get_acl, -+ .set_acl = aufs_set_acl, -+#endif -+ -+ .setattr = aufs_setattr, -+ .getattr = aufs_getattr, -+ -+#ifdef CONFIG_AUFS_XATTR -+ .listxattr = aufs_listxattr, -+#endif -+ -+ .update_time = aufs_update_time -+ } -+}; -diff -Naur null/fs/aufs/i_op_del.c linux-6.6.63/fs/aufs/i_op_del.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/i_op_del.c 2024-12-18 15:12:59.297519563 +0300 -@@ -0,0 +1,523 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * inode operations (del entry) -+ */ -+ -+#include -+#include "aufs.h" -+ -+/* -+ * decide if a new whiteout for @dentry is necessary or not. -+ * when it is necessary, prepare the parent dir for the upper branch whose -+ * branch index is @bcpup for creation. the actual creation of the whiteout will -+ * be done by caller. -+ * return value: -+ * 0: wh is unnecessary -+ * plus: wh is necessary -+ * minus: error -+ */ -+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup) -+{ -+ int need_wh, err; -+ aufs_bindex_t btop; -+ struct super_block *sb; -+ -+ sb = dentry->d_sb; -+ btop = au_dbtop(dentry); -+ if (*bcpup < 0) { -+ *bcpup = btop; -+ if (au_test_ro(sb, btop, d_inode(dentry))) { -+ err = AuWbrCopyup(au_sbi(sb), dentry); -+ *bcpup = err; -+ if (unlikely(err < 0)) -+ goto out; -+ } -+ } else -+ AuDebugOn(btop < *bcpup -+ || au_test_ro(sb, *bcpup, d_inode(dentry))); -+ AuDbg("bcpup %d, btop %d\n", *bcpup, btop); -+ -+ if (*bcpup != btop) { -+ err = au_cpup_dirs(dentry, *bcpup); -+ if (unlikely(err)) -+ goto out; -+ need_wh = 1; -+ } else { -+ struct au_dinfo *dinfo, *tmp; -+ -+ need_wh = -ENOMEM; -+ dinfo = au_di(dentry); -+ tmp = au_di_alloc(sb, AuLsc_DI_TMP); -+ if (tmp) { -+ au_di_cp(tmp, dinfo); -+ au_di_swap(tmp, dinfo); -+ /* returns the number of positive dentries */ -+ need_wh = au_lkup_dentry(dentry, btop + 1, -+ /* AuLkup_IGNORE_PERM */ 0); -+ au_di_swap(tmp, dinfo); -+ au_rw_write_unlock(&tmp->di_rwsem); -+ au_di_free(tmp); -+ } -+ } -+ AuDbg("need_wh %d\n", need_wh); -+ err = need_wh; -+ -+out: -+ return err; -+} -+ -+/* -+ * simple tests for the del-entry operations. -+ * following the checks in vfs, plus the parent-child relationship. -+ */ -+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex, -+ struct dentry *h_parent, int isdir) -+{ -+ int err; -+ umode_t h_mode; -+ struct dentry *h_dentry, *h_latest; -+ struct inode *h_inode; -+ struct path h_ppath; -+ struct super_block *sb; -+ struct au_branch *br; -+ struct mnt_idmap *h_idmap; -+ -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (d_really_is_positive(dentry)) { -+ err = -ENOENT; -+ if (unlikely(d_is_negative(h_dentry))) -+ goto out; -+ h_inode = d_inode(h_dentry); -+ if (unlikely(!vfsub_inode_nlink(h_inode, AU_I_BRANCH))) -+ goto out; -+ -+ h_mode = h_inode->i_mode; -+ if (!isdir) { -+ err = -EISDIR; -+ if (unlikely(S_ISDIR(h_mode))) -+ goto out; -+ } else if (unlikely(!S_ISDIR(h_mode))) { -+ err = -ENOTDIR; -+ goto out; -+ } -+ } else { -+ /* rename(2) case */ -+ err = -EIO; -+ if (unlikely(d_is_positive(h_dentry))) -+ goto out; -+ } -+ -+ err = -ENOENT; -+ /* expected parent dir is locked */ -+ if (unlikely(h_parent != h_dentry->d_parent)) -+ goto out; -+ err = 0; -+ -+ /* -+ * rmdir a dir may break the consistency on some filesystem. -+ * let's try heavy test. -+ */ -+ err = -EACCES; -+ sb = dentry->d_sb; -+ br = au_sbr(sb, bindex); -+ h_idmap = au_br_idmap(br); -+ if (unlikely(!au_opt_test(au_mntflags(sb), DIRPERM1) -+ && au_test_h_perm(h_idmap, d_inode(h_parent), -+ MAY_EXEC | MAY_WRITE))) -+ goto out; -+ -+ h_ppath.dentry = h_parent; -+ h_ppath.mnt = au_br_mnt(br); -+ h_latest = au_sio_lkup_one(h_idmap, &dentry->d_name, &h_ppath); -+ err = -EIO; -+ if (IS_ERR(h_latest)) -+ goto out; -+ if (h_latest == h_dentry) -+ err = 0; -+ dput(h_latest); -+ -+out: -+ return err; -+} -+ -+/* -+ * decide the branch where we operate for @dentry. the branch index will be set -+ * @rbcpup. after deciding it, 'pin' it and store the timestamps of the parent -+ * dir for reverting. -+ * when a new whiteout is necessary, create it. -+ */ -+static struct dentry* -+lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup, -+ struct au_dtime *dt, struct au_pin *pin) -+{ -+ struct dentry *wh_dentry; -+ struct super_block *sb; -+ struct path h_path; -+ int err, need_wh; -+ unsigned int udba; -+ aufs_bindex_t bcpup; -+ -+ need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup); -+ wh_dentry = ERR_PTR(need_wh); -+ if (unlikely(need_wh < 0)) -+ goto out; -+ -+ sb = dentry->d_sb; -+ udba = au_opt_udba(sb); -+ bcpup = *rbcpup; -+ err = au_pin(pin, dentry, bcpup, udba, -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ wh_dentry = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out; -+ -+ h_path.dentry = au_pinned_h_parent(pin); -+ if (udba != AuOpt_UDBA_NONE -+ && au_dbtop(dentry) == bcpup) { -+ err = au_may_del(dentry, bcpup, h_path.dentry, isdir); -+ wh_dentry = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out_unpin; -+ } -+ -+ h_path.mnt = au_sbr_mnt(sb, bcpup); -+ au_dtime_store(dt, au_pinned_parent(pin), &h_path); -+ wh_dentry = NULL; -+ if (!need_wh) -+ goto out; /* success, no need to create whiteout */ -+ -+ wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry); -+ if (IS_ERR(wh_dentry)) -+ goto out_unpin; -+ -+ /* returns with the parent is locked and wh_dentry is dget-ed */ -+ goto out; /* success */ -+ -+out_unpin: -+ au_unpin(pin); -+out: -+ return wh_dentry; -+} -+ -+/* -+ * when removing a dir, rename it to a unique temporary whiteout-ed name first -+ * in order to be revertible and save time for removing many child whiteouts -+ * under the dir. -+ * returns 1 when there are too many child whiteout and caller should remove -+ * them asynchronously. returns 0 when the number of children is enough small to -+ * remove now or the branch fs is a remote fs. -+ * otherwise return an error. -+ */ -+static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex, -+ struct au_nhash *whlist, struct inode *dir) -+{ -+ int rmdir_later, err, dirwh; -+ struct dentry *h_dentry; -+ struct super_block *sb; -+ struct inode *inode; -+ -+ sb = dentry->d_sb; -+ SiMustAnyLock(sb); -+ h_dentry = au_h_dptr(dentry, bindex); -+ err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex)); -+ if (unlikely(err)) -+ goto out; -+ -+ /* stop monitoring */ -+ 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; -+ rmdir_later = (dirwh <= 1); -+ if (!rmdir_later) -+ rmdir_later = au_nhash_test_longer_wh(whlist, bindex, -+ dirwh); -+ if (rmdir_later) -+ return rmdir_later; -+ } -+ -+ err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist); -+ if (unlikely(err)) { -+ AuIOErr("rmdir %pd, b%d failed, %d. ignored\n", -+ h_dentry, bindex, err); -+ err = 0; -+ } -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* -+ * final procedure for deleting a entry. -+ * maintain dentry and iattr. -+ */ -+static void epilog(struct inode *dir, struct dentry *dentry, -+ aufs_bindex_t bindex) -+{ -+ struct inode *inode; -+ -+ inode = d_inode(dentry); -+ d_drop(dentry); -+ inode_set_ctime_to_ts(inode, inode_get_ctime(dir)); -+ -+ au_dir_ts(dir, bindex); -+ inode_inc_iversion(dir); -+} -+ -+/* -+ * when an error happened, remove the created whiteout and revert everything. -+ */ -+static int do_revert(int err, struct inode *dir, aufs_bindex_t bindex, -+ aufs_bindex_t bwh, struct dentry *wh_dentry, -+ struct dentry *dentry, struct au_dtime *dt) -+{ -+ int rerr; -+ struct path h_path = { -+ .dentry = wh_dentry, -+ .mnt = au_sbr_mnt(dir->i_sb, bindex) -+ }; -+ -+ rerr = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, dentry); -+ if (!rerr) { -+ au_set_dbwh(dentry, bwh); -+ au_dtime_revert(dt); -+ return 0; -+ } -+ -+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n", dentry, err, rerr); -+ return -EIO; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int aufs_unlink(struct inode *dir, struct dentry *dentry) -+{ -+ int err; -+ aufs_bindex_t bwh, bindex, btop; -+ struct inode *inode, *h_dir, *delegated, *h_inode; -+ struct dentry *parent, *wh_dentry; -+ /* to reduce stack size */ -+ struct { -+ struct au_dtime dt; -+ struct au_pin pin; -+ struct path h_path; -+ } *a; -+ -+ IMustLock(dir); -+ -+ err = -ENOMEM; -+ a = kmalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ -+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN); -+ if (unlikely(err)) -+ goto out_free; -+ err = au_d_hashed_positive(dentry); -+ if (unlikely(err)) -+ goto out_unlock; -+ inode = d_inode(dentry); -+ IMustLock(inode); -+ err = -EISDIR; -+ if (unlikely(d_is_dir(dentry))) -+ goto out_unlock; /* possible? */ -+ -+ btop = au_dbtop(dentry); -+ bwh = au_dbwh(dentry); -+ bindex = -1; -+ parent = dentry->d_parent; /* dir inode is locked */ -+ di_write_lock_parent(parent); -+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &a->dt, -+ &a->pin); -+ err = PTR_ERR(wh_dentry); -+ if (IS_ERR(wh_dentry)) -+ goto out_parent; -+ -+ a->h_path.mnt = au_sbr_mnt(dentry->d_sb, btop); -+ a->h_path.dentry = au_h_dptr(dentry, btop); -+ dget(a->h_path.dentry); -+ if (bindex == btop) { -+ h_dir = au_pinned_h_dir(&a->pin); -+ delegated = NULL; -+ err = vfsub_unlink(h_dir, &a->h_path, &delegated, /*force*/0); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal unlink\n"); -+ iput(delegated); -+ } -+ } else { -+ /* dir inode is locked */ -+ h_dir = d_inode(wh_dentry->d_parent); -+ IMustLock(h_dir); -+ err = 0; -+ } -+ -+ if (!err) { -+ vfsub_drop_nlink(inode); -+ epilog(dir, dentry, bindex); -+ -+ /* update target timestamps */ -+ if (bindex == btop) { -+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); -+ /*ignore*/ -+ h_inode = d_inode(a->h_path.dentry); -+ inode_set_ctime_to_ts(inode, inode_get_ctime(h_inode)); -+ } else -+ /* todo: this timestamp may be reverted later */ -+ inode_set_ctime_to_ts(inode, inode_get_ctime(h_dir)); -+ goto out_unpin; /* success */ -+ } -+ -+ /* revert */ -+ if (wh_dentry) { -+ int rerr; -+ -+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry, -+ &a->dt); -+ if (rerr) -+ err = rerr; -+ } -+ -+out_unpin: -+ au_unpin(&a->pin); -+ dput(wh_dentry); -+ dput(a->h_path.dentry); -+out_parent: -+ di_write_unlock(parent); -+out_unlock: -+ aufs_read_unlock(dentry, AuLock_DW); -+out_free: -+ au_kfree_rcu(a); -+out: -+ return err; -+} -+ -+int aufs_rmdir(struct inode *dir, struct dentry *dentry) -+{ -+ int err, rmdir_later; -+ aufs_bindex_t bwh, bindex, btop; -+ struct inode *inode; -+ struct dentry *parent, *wh_dentry, *h_dentry; -+ struct au_whtmp_rmdir *args; -+ /* to reduce stack size */ -+ struct { -+ struct au_dtime dt; -+ struct au_pin pin; -+ } *a; -+ -+ IMustLock(dir); -+ -+ err = -ENOMEM; -+ a = kmalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ -+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN); -+ if (unlikely(err)) -+ goto out_free; -+ err = au_alive_dir(dentry); -+ if (unlikely(err)) -+ goto out_unlock; -+ inode = d_inode(dentry); -+ IMustLock(inode); -+ err = -ENOTDIR; -+ if (unlikely(!d_is_dir(dentry))) -+ goto out_unlock; /* possible? */ -+ -+ err = -ENOMEM; -+ args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS); -+ if (unlikely(!args)) -+ goto out_unlock; -+ -+ parent = dentry->d_parent; /* dir inode is locked */ -+ di_write_lock_parent(parent); -+ err = au_test_empty(dentry, &args->whlist); -+ if (unlikely(err)) -+ goto out_parent; -+ -+ btop = au_dbtop(dentry); -+ bwh = au_dbwh(dentry); -+ bindex = -1; -+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &a->dt, -+ &a->pin); -+ err = PTR_ERR(wh_dentry); -+ if (IS_ERR(wh_dentry)) -+ goto out_parent; -+ -+ h_dentry = au_h_dptr(dentry, btop); -+ dget(h_dentry); -+ rmdir_later = 0; -+ if (bindex == btop) { -+ err = renwh_and_rmdir(dentry, btop, &args->whlist, dir); -+ if (err > 0) { -+ rmdir_later = err; -+ err = 0; -+ } -+ } else { -+ /* stop monitoring */ -+ au_hn_free(au_hi(inode, btop)); -+ -+ /* dir inode is locked */ -+ IMustLock(d_inode(wh_dentry->d_parent)); -+ err = 0; -+ } -+ -+ if (!err) { -+ vfsub_dead_dir(inode); -+ au_set_dbdiropq(dentry, -1); -+ epilog(dir, dentry, bindex); -+ -+ if (rmdir_later) { -+ au_whtmp_kick_rmdir(dir, btop, h_dentry, args); -+ args = NULL; -+ } -+ -+ goto out_unpin; /* success */ -+ } -+ -+ /* revert */ -+ AuLabel(revert); -+ if (wh_dentry) { -+ int rerr; -+ -+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry, -+ &a->dt); -+ if (rerr) -+ err = rerr; -+ } -+ -+out_unpin: -+ au_unpin(&a->pin); -+ dput(wh_dentry); -+ dput(h_dentry); -+out_parent: -+ di_write_unlock(parent); -+ if (args) -+ au_whtmp_rmdir_free(args); -+out_unlock: -+ aufs_read_unlock(dentry, AuLock_DW); -+out_free: -+ au_kfree_rcu(a); -+out: -+ AuTraceErr(err); -+ return err; -+} -diff -Naur null/fs/aufs/i_op_ren.c linux-6.6.63/fs/aufs/i_op_ren.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/i_op_ren.c 2024-12-18 15:12:59.297519563 +0300 -@@ -0,0 +1,1260 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * inode operation (rename entry) -+ * todo: this is crazy monster -+ */ -+ -+#include -+#include "aufs.h" -+ -+enum { AuSRC, AuDST, AuSrcDst }; -+enum { AuPARENT, AuCHILD, AuParentChild }; -+ -+#define AuRen_ISDIR_SRC 1 -+#define AuRen_ISDIR_DST (1 << 1) -+#define AuRen_ISSAMEDIR (1 << 2) -+#define AuRen_WHSRC (1 << 3) -+#define AuRen_WHDST (1 << 4) -+#define AuRen_MNT_WRITE (1 << 5) -+#define AuRen_DT_DSTDIR (1 << 6) -+#define AuRen_DIROPQ_SRC (1 << 7) -+#define AuRen_DIROPQ_DST (1 << 8) -+#define AuRen_DIRREN (1 << 9) -+#define AuRen_DROPPED_SRC (1 << 10) -+#define AuRen_DROPPED_DST (1 << 11) -+#define au_ftest_ren(flags, name) ((flags) & AuRen_##name) -+#define au_fset_ren(flags, name) \ -+ do { (flags) |= AuRen_##name; } while (0) -+#define au_fclr_ren(flags, name) \ -+ do { (flags) &= ~AuRen_##name; } while (0) -+ -+#ifndef CONFIG_AUFS_DIRREN -+#undef AuRen_DIRREN -+#define AuRen_DIRREN 0 -+#endif -+ -+struct au_ren_args { -+ struct { -+ struct dentry *dentry, *h_dentry, *parent, *h_parent, -+ *wh_dentry; -+ struct inode *dir, *inode; -+ struct au_hinode *hdir, *hinode; -+ struct au_dtime dt[AuParentChild]; -+ aufs_bindex_t btop, bdiropq; -+ } sd[AuSrcDst]; -+ -+#define src_dentry sd[AuSRC].dentry -+#define src_dir sd[AuSRC].dir -+#define src_inode sd[AuSRC].inode -+#define src_h_dentry sd[AuSRC].h_dentry -+#define src_parent sd[AuSRC].parent -+#define src_h_parent sd[AuSRC].h_parent -+#define src_wh_dentry sd[AuSRC].wh_dentry -+#define src_hdir sd[AuSRC].hdir -+#define src_hinode sd[AuSRC].hinode -+#define src_h_dir sd[AuSRC].hdir->hi_inode -+#define src_dt sd[AuSRC].dt -+#define src_btop sd[AuSRC].btop -+#define src_bdiropq sd[AuSRC].bdiropq -+ -+#define dst_dentry sd[AuDST].dentry -+#define dst_dir sd[AuDST].dir -+#define dst_inode sd[AuDST].inode -+#define dst_h_dentry sd[AuDST].h_dentry -+#define dst_parent sd[AuDST].parent -+#define dst_h_parent sd[AuDST].h_parent -+#define dst_wh_dentry sd[AuDST].wh_dentry -+#define dst_hdir sd[AuDST].hdir -+#define dst_hinode sd[AuDST].hinode -+#define dst_h_dir sd[AuDST].hdir->hi_inode -+#define dst_dt sd[AuDST].dt -+#define dst_btop sd[AuDST].btop -+#define dst_bdiropq sd[AuDST].bdiropq -+ -+ struct dentry *h_trap; -+ struct au_branch *br; -+ struct path h_path; -+ struct au_nhash whlist; -+ aufs_bindex_t btgt, src_bwh; -+ -+ struct { -+ unsigned short auren_flags; -+ unsigned char flags; /* syscall parameter */ -+ unsigned char exchange; -+ } __packed; -+ -+ struct au_whtmp_rmdir *thargs; -+ struct dentry *h_dst; -+ struct au_hinode *h_root; -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * functions for reverting. -+ * when an error happened in a single rename systemcall, we should revert -+ * everything as if nothing happened. -+ * we don't need to revert the copied-up/down the parent dir since they are -+ * harmless. -+ */ -+ -+#define RevertFailure(fmt, ...) do { \ -+ AuIOErr("revert failure: " fmt " (%d, %d)\n", \ -+ ##__VA_ARGS__, err, rerr); \ -+ err = -EIO; \ -+} while (0) -+ -+static void au_ren_do_rev_diropq(int err, struct au_ren_args *a, int idx) -+{ -+ int rerr; -+ struct dentry *d; -+#define src_or_dst(member) a->sd[idx].member -+ -+ d = src_or_dst(dentry); /* {src,dst}_dentry */ -+ au_hn_inode_lock_nested(src_or_dst(hinode), AuLsc_I_CHILD); -+ rerr = au_diropq_remove(d, a->btgt); -+ au_hn_inode_unlock(src_or_dst(hinode)); -+ au_set_dbdiropq(d, src_or_dst(bdiropq)); -+ if (rerr) -+ RevertFailure("remove diropq %pd", d); -+ -+#undef src_or_dst_ -+} -+ -+static void au_ren_rev_diropq(int err, struct au_ren_args *a) -+{ -+ if (au_ftest_ren(a->auren_flags, DIROPQ_SRC)) -+ au_ren_do_rev_diropq(err, a, AuSRC); -+ if (au_ftest_ren(a->auren_flags, DIROPQ_DST)) -+ au_ren_do_rev_diropq(err, a, AuDST); -+} -+ -+static void au_ren_rev_rename(int err, struct au_ren_args *a) -+{ -+ int rerr; -+ struct inode *delegated; -+ struct path h_ppath = { -+ .dentry = a->src_h_parent, -+ .mnt = a->h_path.mnt -+ }; -+ -+ a->h_path.dentry = vfsub_lkup_one(&a->src_dentry->d_name, &h_ppath); -+ rerr = PTR_ERR(a->h_path.dentry); -+ if (IS_ERR(a->h_path.dentry)) { -+ RevertFailure("lkup one %pd", a->src_dentry); -+ return; -+ } -+ -+ delegated = NULL; -+ rerr = vfsub_rename(a->dst_h_dir, -+ au_h_dptr(a->src_dentry, a->btgt), -+ a->src_h_dir, &a->h_path, &delegated, a->flags); -+ if (unlikely(rerr == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal rename\n"); -+ iput(delegated); -+ } -+ d_drop(a->h_path.dentry); -+ dput(a->h_path.dentry); -+ /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */ -+ if (rerr) -+ RevertFailure("rename %pd", a->src_dentry); -+} -+ -+static void au_ren_rev_whtmp(int err, struct au_ren_args *a) -+{ -+ int rerr; -+ struct inode *delegated; -+ struct path h_ppath = { -+ .dentry = a->dst_h_parent, -+ .mnt = a->h_path.mnt -+ }; -+ -+ a->h_path.dentry = vfsub_lkup_one(&a->dst_dentry->d_name, &h_ppath); -+ rerr = PTR_ERR(a->h_path.dentry); -+ if (IS_ERR(a->h_path.dentry)) { -+ RevertFailure("lkup one %pd", a->dst_dentry); -+ return; -+ } -+ if (d_is_positive(a->h_path.dentry)) { -+ d_drop(a->h_path.dentry); -+ dput(a->h_path.dentry); -+ return; -+ } -+ -+ delegated = NULL; -+ rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path, -+ &delegated, a->flags); -+ if (unlikely(rerr == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal rename\n"); -+ iput(delegated); -+ } -+ d_drop(a->h_path.dentry); -+ dput(a->h_path.dentry); -+ if (!rerr) -+ au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst)); -+ else -+ RevertFailure("rename %pd", a->h_dst); -+} -+ -+static void au_ren_rev_whsrc(int err, struct au_ren_args *a) -+{ -+ int rerr; -+ -+ a->h_path.dentry = a->src_wh_dentry; -+ rerr = au_wh_unlink_dentry(a->src_h_dir, &a->h_path, a->src_dentry); -+ au_set_dbwh(a->src_dentry, a->src_bwh); -+ if (rerr) -+ RevertFailure("unlink %pd", a->src_wh_dentry); -+} -+#undef RevertFailure -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * when we have to copyup the renaming entry, do it with the rename-target name -+ * in order to minimize the cost (the later actual rename is unnecessary). -+ * otherwise rename it on the target branch. -+ */ -+static int au_ren_or_cpup(struct au_ren_args *a) -+{ -+ int err; -+ struct dentry *d; -+ struct inode *delegated; -+ -+ d = a->src_dentry; -+ if (au_dbtop(d) == a->btgt) { -+ a->h_path.dentry = a->dst_h_dentry; -+ AuDebugOn(au_dbtop(d) != a->btgt); -+ delegated = NULL; -+ err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt), -+ a->dst_h_dir, &a->h_path, &delegated, -+ a->flags); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal rename\n"); -+ iput(delegated); -+ } -+ } else -+ BUG(); -+ -+ if (!err && a->h_dst) -+ /* it will be set to dinfo later */ -+ dget(a->h_dst); -+ -+ return err; -+} -+ -+/* cf. aufs_rmdir() */ -+static int au_ren_del_whtmp(struct au_ren_args *a) -+{ -+ int err; -+ struct inode *dir; -+ -+ dir = a->dst_dir; -+ SiMustAnyLock(dir->i_sb); -+ if (!au_nhash_test_longer_wh(&a->whlist, a->btgt, -+ au_sbi(dir->i_sb)->si_dirwh) -+ || au_test_fs_remote(a->h_dst->d_sb)) { -+ err = au_whtmp_rmdir(dir, a->btgt, a->h_dst, &a->whlist); -+ if (unlikely(err)) -+ pr_warn("failed removing whtmp dir %pd (%d), " -+ "ignored.\n", a->h_dst, err); -+ } else { -+ au_nhash_wh_free(&a->thargs->whlist); -+ a->thargs->whlist = a->whlist; -+ a->whlist.nh_num = 0; -+ au_whtmp_kick_rmdir(dir, a->btgt, a->h_dst, a->thargs); -+ dput(a->h_dst); -+ a->thargs = NULL; -+ } -+ -+ return 0; -+} -+ -+/* make it 'opaque' dir. */ -+static int au_ren_do_diropq(struct au_ren_args *a, int idx) -+{ -+ int err; -+ struct dentry *d, *diropq; -+#define src_or_dst(member) a->sd[idx].member -+ -+ err = 0; -+ d = src_or_dst(dentry); /* {src,dst}_dentry */ -+ src_or_dst(bdiropq) = au_dbdiropq(d); -+ src_or_dst(hinode) = au_hi(src_or_dst(inode), a->btgt); -+ au_hn_inode_lock_nested(src_or_dst(hinode), AuLsc_I_CHILD); -+ diropq = au_diropq_create(d, a->btgt); -+ au_hn_inode_unlock(src_or_dst(hinode)); -+ if (IS_ERR(diropq)) -+ err = PTR_ERR(diropq); -+ else -+ dput(diropq); -+ -+#undef src_or_dst_ -+ return err; -+} -+ -+static int au_ren_diropq(struct au_ren_args *a) -+{ -+ int err; -+ unsigned char always; -+ struct dentry *d; -+ -+ err = 0; -+ d = a->dst_dentry; /* already renamed on the branch */ -+ always = !!au_opt_test(au_mntflags(d->d_sb), ALWAYS_DIROPQ); -+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC) -+ && !au_ftest_ren(a->auren_flags, DIRREN) -+ && a->btgt != au_dbdiropq(a->src_dentry) -+ && (a->dst_wh_dentry -+ || a->btgt <= au_dbdiropq(d) -+ /* hide the lower to keep xino */ -+ /* the lowers may not be a dir, but we hide them anyway */ -+ || a->btgt < au_dbbot(d) -+ || always)) { -+ AuDbg("here\n"); -+ err = au_ren_do_diropq(a, AuSRC); -+ if (unlikely(err)) -+ goto out; -+ au_fset_ren(a->auren_flags, DIROPQ_SRC); -+ } -+ if (!a->exchange) -+ goto out; /* success */ -+ -+ d = a->src_dentry; /* already renamed on the branch */ -+ if (au_ftest_ren(a->auren_flags, ISDIR_DST) -+ && a->btgt != au_dbdiropq(a->dst_dentry) -+ && (a->btgt < au_dbdiropq(d) -+ || a->btgt < au_dbbot(d) -+ || always)) { -+ AuDbgDentry(a->src_dentry); -+ AuDbgDentry(a->dst_dentry); -+ err = au_ren_do_diropq(a, AuDST); -+ if (unlikely(err)) -+ goto out_rev_src; -+ au_fset_ren(a->auren_flags, DIROPQ_DST); -+ } -+ goto out; /* success */ -+ -+out_rev_src: -+ AuDbg("err %d, reverting src\n", err); -+ au_ren_rev_diropq(err, a); -+out: -+ return err; -+} -+ -+static int do_rename(struct au_ren_args *a) -+{ -+ int err; -+ struct dentry *d, *h_d; -+ struct inode *h_inode; -+ -+ if (!a->exchange) { -+ /* prepare workqueue args for asynchronous rmdir */ -+ h_d = a->dst_h_dentry; -+ if (au_ftest_ren(a->auren_flags, ISDIR_DST) -+ /* && !au_ftest_ren(a->auren_flags, DIRREN) */ -+ && d_is_positive(h_d)) { -+ err = -ENOMEM; -+ a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb, -+ GFP_NOFS); -+ if (unlikely(!a->thargs)) -+ goto out; -+ a->h_dst = dget(h_d); -+ } -+ -+ /* create whiteout for src_dentry */ -+ if (au_ftest_ren(a->auren_flags, WHSRC)) { -+ a->src_bwh = au_dbwh(a->src_dentry); -+ AuDebugOn(a->src_bwh >= 0); -+ a->src_wh_dentry = au_wh_create(a->src_dentry, a->btgt, -+ a->src_h_parent); -+ err = PTR_ERR(a->src_wh_dentry); -+ if (IS_ERR(a->src_wh_dentry)) -+ goto out_thargs; -+ } -+ -+ /* lookup whiteout for dentry */ -+ if (au_ftest_ren(a->auren_flags, WHDST)) { -+ h_d = au_wh_lkup(a->dst_h_parent, -+ &a->dst_dentry->d_name, a->br); -+ err = PTR_ERR(h_d); -+ if (IS_ERR(h_d)) -+ goto out_whsrc; -+ if (d_is_negative(h_d)) -+ dput(h_d); -+ else -+ a->dst_wh_dentry = h_d; -+ } -+ -+ /* rename dentry to tmpwh */ -+ if (a->thargs) { -+ err = au_whtmp_ren(a->dst_h_dentry, a->br); -+ if (unlikely(err)) -+ goto out_whdst; -+ -+ d = a->dst_dentry; -+ au_set_h_dptr(d, a->btgt, NULL); -+ err = au_lkup_neg(d, a->btgt, /*wh*/0); -+ if (unlikely(err)) -+ goto out_whtmp; -+ a->dst_h_dentry = au_h_dptr(d, a->btgt); -+ } -+ } -+ -+ BUG_ON(d_is_positive(a->dst_h_dentry) && a->src_btop != a->btgt); -+#if 0 /* debugging */ -+ BUG_ON(!au_ftest_ren(a->auren_flags, DIRREN) -+ && d_is_positive(a->dst_h_dentry) -+ && a->src_btop != a->btgt); -+#endif -+ -+ /* rename by vfs_rename or cpup */ -+ err = au_ren_or_cpup(a); -+ if (unlikely(err)) -+ /* leave the copied-up one */ -+ goto out_whtmp; -+ -+ /* make dir opaque */ -+ err = au_ren_diropq(a); -+ if (unlikely(err)) -+ goto out_rename; -+ -+ /* update target timestamps */ -+ if (a->exchange) { -+ AuDebugOn(au_dbtop(a->dst_dentry) != a->btgt); -+ a->h_path.dentry = au_h_dptr(a->dst_dentry, a->btgt); -+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/ -+ h_inode = d_inode(a->h_path.dentry); -+ inode_set_ctime_to_ts(a->dst_inode, inode_get_ctime(h_inode)); -+ } -+ AuDebugOn(au_dbtop(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*/ -+ h_inode = d_inode(a->h_path.dentry); -+ inode_set_ctime_to_ts(a->src_inode, inode_get_ctime(h_inode)); -+ -+ if (!a->exchange) { -+ /* remove whiteout for dentry */ -+ if (a->dst_wh_dentry) { -+ a->h_path.dentry = a->dst_wh_dentry; -+ err = au_wh_unlink_dentry(a->dst_h_dir, &a->h_path, -+ a->dst_dentry); -+ if (unlikely(err)) -+ goto out_diropq; -+ } -+ -+ /* remove whtmp */ -+ if (a->thargs) -+ au_ren_del_whtmp(a); /* ignore this error */ -+ -+ au_fhsm_wrote(a->src_dentry->d_sb, a->btgt, /*force*/0); -+ } -+ err = 0; -+ goto out_success; -+ -+out_diropq: -+ au_ren_rev_diropq(err, a); -+out_rename: -+ au_ren_rev_rename(err, a); -+ dput(a->h_dst); -+out_whtmp: -+ if (a->thargs) -+ au_ren_rev_whtmp(err, a); -+out_whdst: -+ dput(a->dst_wh_dentry); -+ a->dst_wh_dentry = NULL; -+out_whsrc: -+ if (a->src_wh_dentry) -+ au_ren_rev_whsrc(err, a); -+out_success: -+ dput(a->src_wh_dentry); -+ dput(a->dst_wh_dentry); -+out_thargs: -+ if (a->thargs) { -+ dput(a->h_dst); -+ au_whtmp_rmdir_free(a->thargs); -+ a->thargs = NULL; -+ } -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * test if @dentry dir can be rename destination or not. -+ * success means, it is a logically empty dir. -+ */ -+static int may_rename_dstdir(struct dentry *dentry, struct au_nhash *whlist) -+{ -+ return au_test_empty(dentry, whlist); -+} -+ -+/* -+ * test if @a->src_dentry dir can be rename source or not. -+ * if it can, return 0. -+ * success means, -+ * - it is a logically empty dir. -+ * - or, it exists on writable branch and has no children including whiteouts -+ * on the lower branch unless DIRREN is on. -+ */ -+static int may_rename_srcdir(struct au_ren_args *a) -+{ -+ int err; -+ unsigned int rdhash; -+ aufs_bindex_t btop, btgt; -+ struct dentry *dentry; -+ struct super_block *sb; -+ struct au_sbinfo *sbinfo; -+ -+ dentry = a->src_dentry; -+ sb = dentry->d_sb; -+ sbinfo = au_sbi(sb); -+ if (au_opt_test(sbinfo->si_mntflags, DIRREN)) -+ au_fset_ren(a->auren_flags, DIRREN); -+ -+ btgt = a->btgt; -+ btop = au_dbtop(dentry); -+ if (btop != btgt) { -+ struct au_nhash whlist; -+ -+ SiMustAnyLock(sb); -+ rdhash = sbinfo->si_rdhash; -+ if (!rdhash) -+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, -+ dentry)); -+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS); -+ if (unlikely(err)) -+ goto out; -+ err = au_test_empty(dentry, &whlist); -+ au_nhash_wh_free(&whlist); -+ goto out; -+ } -+ -+ if (btop == au_dbtaildir(dentry)) -+ return 0; /* success */ -+ -+ err = au_test_empty_lower(dentry); -+ -+out: -+ if (err == -ENOTEMPTY) { -+ if (au_ftest_ren(a->auren_flags, DIRREN)) { -+ err = 0; -+ } else { -+ AuWarn1("renaming dir who has child(ren) on multiple " -+ "branches, is not supported\n"); -+ err = -EXDEV; -+ } -+ } -+ return err; -+} -+ -+/* side effect: sets whlist and h_dentry */ -+static int au_ren_may_dir(struct au_ren_args *a) -+{ -+ int err; -+ unsigned int rdhash; -+ struct dentry *d; -+ -+ d = a->dst_dentry; -+ SiMustAnyLock(d->d_sb); -+ -+ err = 0; -+ if (au_ftest_ren(a->auren_flags, ISDIR_DST) && a->dst_inode) { -+ rdhash = au_sbi(d->d_sb)->si_rdhash; -+ if (!rdhash) -+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, d)); -+ err = au_nhash_alloc(&a->whlist, rdhash, GFP_NOFS); -+ if (unlikely(err)) -+ goto out; -+ -+ if (!a->exchange) { -+ au_set_dbtop(d, a->dst_btop); -+ err = may_rename_dstdir(d, &a->whlist); -+ au_set_dbtop(d, a->btgt); -+ } else -+ err = may_rename_srcdir(a); -+ } -+ a->dst_h_dentry = au_h_dptr(d, au_dbtop(d)); -+ if (unlikely(err)) -+ goto out; -+ -+ d = a->src_dentry; -+ a->src_h_dentry = au_h_dptr(d, au_dbtop(d)); -+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC)) { -+ err = may_rename_srcdir(a); -+ if (unlikely(err)) { -+ au_nhash_wh_free(&a->whlist); -+ a->whlist.nh_num = 0; -+ } -+ } -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * simple tests for rename. -+ * following the checks in vfs, plus the parent-child relationship. -+ */ -+static int au_may_ren(struct au_ren_args *a) -+{ -+ int err, isdir; -+ struct inode *h_inode; -+ -+ if (a->src_btop == a->btgt) { -+ err = au_may_del(a->src_dentry, a->btgt, a->src_h_parent, -+ au_ftest_ren(a->auren_flags, ISDIR_SRC)); -+ if (unlikely(err)) -+ goto out; -+ err = -EINVAL; -+ if (unlikely(a->src_h_dentry == a->h_trap)) -+ goto out; -+ } -+ -+ err = 0; -+ if (a->dst_btop != a->btgt) -+ goto out; -+ -+ err = -ENOTEMPTY; -+ if (unlikely(a->dst_h_dentry == a->h_trap)) -+ goto out; -+ -+ err = -EIO; -+ isdir = !!au_ftest_ren(a->auren_flags, ISDIR_DST); -+ 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(d_is_negative(a->dst_h_dentry))) -+ goto out; -+ h_inode = d_inode(a->dst_h_dentry); -+ if (vfsub_inode_nlink(h_inode, AU_I_BRANCH)) -+ err = au_may_del(a->dst_dentry, a->btgt, -+ a->dst_h_parent, isdir); -+ } -+ -+out: -+ if (unlikely(err == -ENOENT || err == -EEXIST)) -+ err = -EIO; -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * locking order -+ * (VFS) -+ * - src_dir and dir by lock_rename() -+ * - inode if exists -+ * (aufs) -+ * - lock all -+ * + src_dentry and dentry by aufs_read_and_write_lock2() which calls, -+ * + si_read_lock -+ * + di_write_lock2_child() -+ * + di_write_lock_child() -+ * + ii_write_lock_child() -+ * + di_write_lock_child2() -+ * + ii_write_lock_child2() -+ * + src_parent and parent -+ * + di_write_lock_parent() -+ * + ii_write_lock_parent() -+ * + di_write_lock_parent2() -+ * + ii_write_lock_parent2() -+ * + lower src_dir and dir by vfsub_lock_rename() -+ * + verify the every relationships between child and parent. if any -+ * of them failed, unlock all and return -EBUSY. -+ */ -+static void au_ren_unlock(struct au_ren_args *a) -+{ -+ vfsub_unlock_rename(a->src_h_parent, a->src_hdir, -+ a->dst_h_parent, a->dst_hdir); -+ if (au_ftest_ren(a->auren_flags, DIRREN) -+ && a->h_root) -+ au_hn_inode_unlock(a->h_root); -+ if (au_ftest_ren(a->auren_flags, MNT_WRITE)) -+ vfsub_mnt_drop_write(au_br_mnt(a->br)); -+} -+ -+static int au_ren_lock(struct au_ren_args *a) -+{ -+ int err; -+ unsigned int udba; -+ -+ err = 0; -+ a->src_h_parent = au_h_dptr(a->src_parent, a->btgt); -+ a->src_hdir = au_hi(a->src_dir, a->btgt); -+ a->dst_h_parent = au_h_dptr(a->dst_parent, a->btgt); -+ a->dst_hdir = au_hi(a->dst_dir, a->btgt); -+ -+ err = vfsub_mnt_want_write(au_br_mnt(a->br)); -+ if (unlikely(err)) -+ goto out; -+ au_fset_ren(a->auren_flags, MNT_WRITE); -+ if (au_ftest_ren(a->auren_flags, DIRREN)) { -+ struct dentry *root; -+ struct inode *dir; -+ -+ /* -+ * sbinfo is already locked, so this ii_read_lock is -+ * unnecessary. but our debugging feature checks it. -+ */ -+ root = a->src_inode->i_sb->s_root; -+ if (root != a->src_parent && root != a->dst_parent) { -+ dir = d_inode(root); -+ ii_read_lock_parent3(dir); -+ a->h_root = au_hi(dir, a->btgt); -+ ii_read_unlock(dir); -+ au_hn_inode_lock_nested(a->h_root, AuLsc_I_PARENT3); -+ } -+ } -+ 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 != 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_dbtop(a->src_dentry) == a->btgt) -+ err = au_h_verify(a->src_h_dentry, udba, -+ d_inode(a->src_h_parent), a->src_h_parent, -+ a->br); -+ if (!err && au_dbtop(a->dst_dentry) == a->btgt) -+ err = au_h_verify(a->dst_h_dentry, udba, -+ d_inode(a->dst_h_parent), a->dst_h_parent, -+ a->br); -+ if (!err) -+ goto out; /* success */ -+ -+ err = au_busy_or_stale(); -+ au_ren_unlock(a); -+ -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void au_ren_refresh_dir(struct au_ren_args *a) -+{ -+ struct inode *dir; -+ -+ dir = a->dst_dir; -+ inode_inc_iversion(dir); -+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC)) { -+ /* is this updating defined in POSIX? */ -+ au_cpup_attr_timesizes(a->src_inode); -+ au_cpup_attr_nlink(dir, /*force*/1); -+ } -+ au_dir_ts(dir, a->btgt); -+ -+ if (a->exchange) { -+ dir = a->src_dir; -+ inode_inc_iversion(dir); -+ if (au_ftest_ren(a->auren_flags, ISDIR_DST)) { -+ /* is this updating defined in POSIX? */ -+ au_cpup_attr_timesizes(a->dst_inode); -+ au_cpup_attr_nlink(dir, /*force*/1); -+ } -+ au_dir_ts(dir, a->btgt); -+ } -+ -+ if (au_ftest_ren(a->auren_flags, ISSAMEDIR)) -+ return; -+ -+ dir = a->src_dir; -+ inode_inc_iversion(dir); -+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC)) -+ au_cpup_attr_nlink(dir, /*force*/1); -+ au_dir_ts(dir, a->btgt); -+} -+ -+static void au_ren_refresh(struct au_ren_args *a) -+{ -+ aufs_bindex_t bbot, bindex; -+ struct dentry *d, *h_d; -+ struct inode *i, *h_i; -+ struct super_block *sb; -+ -+ d = a->dst_dentry; -+ d_drop(d); -+ if (a->h_dst) -+ /* already dget-ed by au_ren_or_cpup() */ -+ au_set_h_dptr(d, a->btgt, a->h_dst); -+ -+ i = a->dst_inode; -+ if (i) { -+ if (!a->exchange) { -+ if (!au_ftest_ren(a->auren_flags, ISDIR_DST)) -+ vfsub_drop_nlink(i); -+ else { -+ vfsub_dead_dir(i); -+ au_cpup_attr_timesizes(i); -+ } -+ au_update_dbrange(d, /*do_put_zero*/1); -+ } else -+ au_cpup_attr_nlink(i, /*force*/1); -+ } else { -+ bbot = a->btgt; -+ for (bindex = au_dbtop(d); bindex < bbot; bindex++) -+ au_set_h_dptr(d, bindex, NULL); -+ bbot = au_dbbot(d); -+ for (bindex = a->btgt + 1; bindex <= bbot; bindex++) -+ au_set_h_dptr(d, bindex, NULL); -+ au_update_dbrange(d, /*do_put_zero*/0); -+ } -+ -+ if (a->exchange -+ || au_ftest_ren(a->auren_flags, DIRREN)) { -+ d_drop(a->src_dentry); -+ if (au_ftest_ren(a->auren_flags, DIRREN)) -+ au_set_dbwh(a->src_dentry, -1); -+ return; -+ } -+ -+ d = a->src_dentry; -+ au_set_dbwh(d, -1); -+ bbot = au_dbbot(d); -+ for (bindex = a->btgt + 1; bindex <= bbot; bindex++) { -+ h_d = au_h_dptr(d, bindex); -+ if (h_d) -+ au_set_h_dptr(d, bindex, NULL); -+ } -+ au_set_dbbot(d, a->btgt); -+ -+ sb = d->d_sb; -+ i = a->src_inode; -+ if (au_opt_test(au_mntflags(sb), PLINK) && au_plink_test(i)) -+ return; /* success */ -+ -+ bbot = au_ibbot(i); -+ for (bindex = a->btgt + 1; bindex <= bbot; bindex++) { -+ h_i = au_h_iptr(i, bindex); -+ if (h_i) { -+ au_xino_write(sb, bindex, h_i->i_ino, /*ino*/0); -+ /* ignore this error */ -+ au_set_h_iptr(i, bindex, NULL, 0); -+ } -+ } -+ au_set_ibbot(i, a->btgt); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* mainly for link(2) and rename(2) */ -+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt) -+{ -+ aufs_bindex_t bdiropq, bwh; -+ struct dentry *parent; -+ struct au_branch *br; -+ -+ parent = dentry->d_parent; -+ IMustLock(d_inode(parent)); /* dir is locked */ -+ -+ bdiropq = au_dbdiropq(parent); -+ bwh = au_dbwh(dentry); -+ br = au_sbr(dentry->d_sb, btgt); -+ if (au_br_rdonly(br) -+ || (0 <= bdiropq && bdiropq < btgt) -+ || (0 <= bwh && bwh < btgt)) -+ btgt = -1; -+ -+ AuDbg("btgt %d\n", btgt); -+ return btgt; -+} -+ -+/* sets src_btop, dst_btop and btgt */ -+static int au_ren_wbr(struct au_ren_args *a) -+{ -+ int err; -+ struct au_wr_dir_args wr_dir_args = { -+ /* .force_btgt = -1, */ -+ .flags = AuWrDir_ADD_ENTRY -+ }; -+ -+ a->src_btop = au_dbtop(a->src_dentry); -+ a->dst_btop = au_dbtop(a->dst_dentry); -+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC) -+ || au_ftest_ren(a->auren_flags, ISDIR_DST)) -+ au_fset_wrdir(wr_dir_args.flags, ISDIR); -+ wr_dir_args.force_btgt = a->src_btop; -+ if (a->dst_inode && a->dst_btop < a->src_btop) -+ wr_dir_args.force_btgt = a->dst_btop; -+ wr_dir_args.force_btgt = au_wbr(a->dst_dentry, wr_dir_args.force_btgt); -+ err = au_wr_dir(a->dst_dentry, a->src_dentry, &wr_dir_args); -+ a->btgt = err; -+ if (a->exchange) -+ au_update_dbtop(a->dst_dentry); -+ -+ return err; -+} -+ -+static void au_ren_dt(struct au_ren_args *a) -+{ -+ a->h_path.dentry = a->src_h_parent; -+ au_dtime_store(a->src_dt + AuPARENT, a->src_parent, &a->h_path); -+ if (!au_ftest_ren(a->auren_flags, ISSAMEDIR)) { -+ a->h_path.dentry = a->dst_h_parent; -+ au_dtime_store(a->dst_dt + AuPARENT, a->dst_parent, &a->h_path); -+ } -+ -+ au_fclr_ren(a->auren_flags, DT_DSTDIR); -+ if (!au_ftest_ren(a->auren_flags, ISDIR_SRC) -+ && !a->exchange) -+ return; -+ -+ a->h_path.dentry = a->src_h_dentry; -+ au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path); -+ if (d_is_positive(a->dst_h_dentry)) { -+ au_fset_ren(a->auren_flags, DT_DSTDIR); -+ a->h_path.dentry = a->dst_h_dentry; -+ au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path); -+ } -+} -+ -+static void au_ren_rev_dt(int err, struct au_ren_args *a) -+{ -+ struct dentry *h_d; -+ struct inode *h_inode; -+ -+ au_dtime_revert(a->src_dt + AuPARENT); -+ if (!au_ftest_ren(a->auren_flags, ISSAMEDIR)) -+ au_dtime_revert(a->dst_dt + AuPARENT); -+ -+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC) && err != -EIO) { -+ h_d = a->src_dt[AuCHILD].dt_h_path.dentry; -+ h_inode = d_inode(h_d); -+ inode_lock_nested(h_inode, AuLsc_I_CHILD); -+ au_dtime_revert(a->src_dt + AuCHILD); -+ inode_unlock(h_inode); -+ -+ if (au_ftest_ren(a->auren_flags, DT_DSTDIR)) { -+ h_d = a->dst_dt[AuCHILD].dt_h_path.dentry; -+ h_inode = d_inode(h_d); -+ inode_lock_nested(h_inode, AuLsc_I_CHILD); -+ au_dtime_revert(a->dst_dt + AuCHILD); -+ inode_unlock(h_inode); -+ } -+ } -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int aufs_rename(struct mnt_idmap *idmap, -+ struct inode *_src_dir, struct dentry *_src_dentry, -+ struct inode *_dst_dir, struct dentry *_dst_dentry, -+ unsigned int _flags) -+{ -+ int err, lock_flags; -+ void *rev; -+ /* reduce stack space */ -+ struct au_ren_args *a; -+ struct au_pin pin; -+ -+ AuDbg("%pd, %pd, 0x%x\n", _src_dentry, _dst_dentry, _flags); -+ IMustLock(_src_dir); -+ IMustLock(_dst_dir); -+ -+ err = -EINVAL; -+ if (unlikely(_flags & RENAME_WHITEOUT)) -+ goto out; -+ -+ err = -ENOMEM; -+ BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE); -+ a = kzalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ -+ a->flags = _flags; -+ BUILD_BUG_ON(sizeof(a->exchange) == sizeof(u8) -+ && RENAME_EXCHANGE > U8_MAX); -+ a->exchange = _flags & RENAME_EXCHANGE; -+ a->src_dir = _src_dir; -+ a->src_dentry = _src_dentry; -+ 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 = 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) { -+ /* -+ * if EXCHANGE && src is non-dir && dst is dir, -+ * dst is not locked. -+ */ -+ /* IMustLock(a->dst_inode); */ -+ au_igrab(a->dst_inode); -+ } -+ -+ err = -ENOTDIR; -+ lock_flags = AuLock_FLUSH | AuLock_NOPLM | AuLock_GEN; -+ if (d_is_dir(a->src_dentry)) { -+ au_fset_ren(a->auren_flags, ISDIR_SRC); -+ if (unlikely(!a->exchange -+ && d_really_is_positive(a->dst_dentry) -+ && !d_is_dir(a->dst_dentry))) -+ goto out_free; -+ lock_flags |= AuLock_DIRS; -+ } -+ if (a->dst_inode && d_is_dir(a->dst_dentry)) { -+ au_fset_ren(a->auren_flags, ISDIR_DST); -+ if (unlikely(!a->exchange -+ && d_really_is_positive(a->src_dentry) -+ && !d_is_dir(a->src_dentry))) -+ goto out_free; -+ lock_flags |= AuLock_DIRS; -+ } -+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry, -+ lock_flags); -+ if (unlikely(err)) -+ goto out_free; -+ -+ err = au_d_hashed_positive(a->src_dentry); -+ if (unlikely(err)) -+ goto out_unlock; -+ err = -ENOENT; -+ if (a->dst_inode) { -+ /* -+ * If it is a dir, VFS unhash it before this -+ * function. It means we cannot rely upon d_unhashed(). -+ */ -+ if (unlikely(!vfsub_inode_nlink(a->dst_inode, AU_I_AUFS))) -+ goto out_unlock; -+ if (!au_ftest_ren(a->auren_flags, ISDIR_DST)) { -+ err = au_d_hashed_positive(a->dst_dentry); -+ if (unlikely(err && !a->exchange)) -+ goto out_unlock; -+ } else if (unlikely(IS_DEADDIR(a->dst_inode))) -+ goto out_unlock; -+ } else if (unlikely(d_unhashed(a->dst_dentry))) -+ goto out_unlock; -+ -+ /* -+ * is it possible? -+ * yes, it happened (in linux-3.3-rcN) but I don't know why. -+ * there may exist a problem somewhere else. -+ */ -+ err = -EINVAL; -+ if (unlikely(d_inode(a->dst_parent) == d_inode(a->src_dentry))) -+ goto out_unlock; -+ -+ au_fset_ren(a->auren_flags, ISSAMEDIR); /* temporary */ -+ di_write_lock_parent(a->dst_parent); -+ -+ /* which branch we process */ -+ err = au_ren_wbr(a); -+ if (unlikely(err < 0)) -+ goto out_parent; -+ a->br = au_sbr(a->dst_dentry->d_sb, a->btgt); -+ a->h_path.mnt = au_br_mnt(a->br); -+ -+ /* are they available to be renamed */ -+ err = au_ren_may_dir(a); -+ if (unlikely(err)) -+ goto out_children; -+ -+ /* prepare the writable parent dir on the same branch */ -+ if (a->dst_btop == a->btgt) { -+ au_fset_ren(a->auren_flags, WHDST); -+ } else { -+ err = au_cpup_dirs(a->dst_dentry, a->btgt); -+ if (unlikely(err)) -+ goto out_children; -+ } -+ -+ err = 0; -+ if (!a->exchange) { -+ if (a->src_dir != a->dst_dir) { -+ /* -+ * this temporary unlock is safe, -+ * because both dir->i_mutex are locked. -+ */ -+ di_write_unlock(a->dst_parent); -+ di_write_lock_parent(a->src_parent); -+ err = au_wr_dir_need_wh(a->src_dentry, -+ au_ftest_ren(a->auren_flags, -+ ISDIR_SRC), -+ &a->btgt); -+ di_write_unlock(a->src_parent); -+ di_write_lock2_parent(a->src_parent, a->dst_parent, -+ /*isdir*/1); -+ au_fclr_ren(a->auren_flags, ISSAMEDIR); -+ } else -+ err = au_wr_dir_need_wh(a->src_dentry, -+ au_ftest_ren(a->auren_flags, -+ ISDIR_SRC), -+ &a->btgt); -+ } -+ if (unlikely(err < 0)) -+ goto out_children; -+ if (err) -+ au_fset_ren(a->auren_flags, WHSRC); -+ -+ /* cpup src */ -+ if (a->src_btop != a->btgt) { -+ err = au_pin(&pin, a->src_dentry, a->btgt, -+ au_opt_udba(a->src_dentry->d_sb), -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ if (!err) { -+ struct au_cp_generic cpg = { -+ .dentry = a->src_dentry, -+ .bdst = a->btgt, -+ .bsrc = a->src_btop, -+ .len = -1, -+ .pin = &pin, -+ .flags = AuCpup_DTIME | AuCpup_HOPEN -+ }; -+ AuDebugOn(au_dbtop(a->src_dentry) != a->src_btop); -+ err = au_sio_cpup_simple(&cpg); -+ au_unpin(&pin); -+ } -+ if (unlikely(err)) -+ goto out_children; -+ a->src_btop = a->btgt; -+ a->src_h_dentry = au_h_dptr(a->src_dentry, a->btgt); -+ if (!a->exchange) -+ au_fset_ren(a->auren_flags, WHSRC); -+ } -+ -+ /* cpup dst */ -+ if (a->exchange && a->dst_inode -+ && a->dst_btop != a->btgt) { -+ err = au_pin(&pin, a->dst_dentry, a->btgt, -+ au_opt_udba(a->dst_dentry->d_sb), -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ if (!err) { -+ struct au_cp_generic cpg = { -+ .dentry = a->dst_dentry, -+ .bdst = a->btgt, -+ .bsrc = a->dst_btop, -+ .len = -1, -+ .pin = &pin, -+ .flags = AuCpup_DTIME | AuCpup_HOPEN -+ }; -+ err = au_sio_cpup_simple(&cpg); -+ au_unpin(&pin); -+ } -+ if (unlikely(err)) -+ goto out_children; -+ a->dst_btop = a->btgt; -+ a->dst_h_dentry = au_h_dptr(a->dst_dentry, a->btgt); -+ } -+ -+ /* lock them all */ -+ err = au_ren_lock(a); -+ if (unlikely(err)) -+ /* leave the copied-up one */ -+ goto out_children; -+ -+ if (!a->exchange) { -+ if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE)) -+ err = au_may_ren(a); -+ else if (unlikely(a->dst_dentry->d_name.len > AUFS_MAX_NAMELEN)) -+ err = -ENAMETOOLONG; -+ if (unlikely(err)) -+ goto out_hdir; -+ } -+ -+ /* store timestamps to be revertible */ -+ au_ren_dt(a); -+ -+ /* store dirren info */ -+ if (au_ftest_ren(a->auren_flags, DIRREN)) { -+ err = au_dr_rename(a->src_dentry, a->btgt, -+ &a->dst_dentry->d_name, &rev); -+ AuTraceErr(err); -+ if (unlikely(err)) -+ goto out_dt; -+ } -+ -+ /* here we go */ -+ err = do_rename(a); -+ if (unlikely(err)) -+ goto out_dirren; -+ -+ if (au_ftest_ren(a->auren_flags, DIRREN)) -+ au_dr_rename_fin(a->src_dentry, a->btgt, rev); -+ -+ /* update dir attributes */ -+ au_ren_refresh_dir(a); -+ -+ /* dput/iput all lower dentries */ -+ au_ren_refresh(a); -+ -+ goto out_hdir; /* success */ -+ -+out_dirren: -+ if (au_ftest_ren(a->auren_flags, DIRREN)) -+ au_dr_rename_rev(a->src_dentry, a->btgt, rev); -+out_dt: -+ au_ren_rev_dt(err, a); -+out_hdir: -+ au_ren_unlock(a); -+out_children: -+ au_nhash_wh_free(&a->whlist); -+ if (err && a->dst_inode && a->dst_btop != a->btgt) { -+ AuDbg("btop %d, btgt %d\n", a->dst_btop, a->btgt); -+ au_set_h_dptr(a->dst_dentry, a->btgt, NULL); -+ au_set_dbtop(a->dst_dentry, a->dst_btop); -+ } -+out_parent: -+ if (!err) { -+ if (d_unhashed(a->src_dentry)) -+ au_fset_ren(a->auren_flags, DROPPED_SRC); -+ if (d_unhashed(a->dst_dentry)) -+ au_fset_ren(a->auren_flags, DROPPED_DST); -+ if (!a->exchange) -+ d_move(a->src_dentry, a->dst_dentry); -+ else { -+ d_exchange(a->src_dentry, a->dst_dentry); -+ if (au_ftest_ren(a->auren_flags, DROPPED_DST)) -+ d_drop(a->dst_dentry); -+ } -+ if (au_ftest_ren(a->auren_flags, DROPPED_SRC)) -+ d_drop(a->src_dentry); -+ } else { -+ au_update_dbtop(a->dst_dentry); -+ if (!a->dst_inode) -+ d_drop(a->dst_dentry); -+ } -+ if (au_ftest_ren(a->auren_flags, ISSAMEDIR)) -+ di_write_unlock(a->dst_parent); -+ else -+ di_write_unlock2(a->src_parent, a->dst_parent); -+out_unlock: -+ aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry); -+out_free: -+ iput(a->dst_inode); -+ if (a->thargs) -+ au_whtmp_rmdir_free(a->thargs); -+ au_kfree_rcu(a); -+out: -+ AuTraceErr(err); -+ return err; -+} -diff -Naur null/fs/aufs/Kconfig linux-6.6.63/fs/aufs/Kconfig ---- /dev/null -+++ linux-6.6.63/fs/aufs/Kconfig 2024-12-18 15:12:59.292519626 +0300 -@@ -0,0 +1,199 @@ -+# SPDX-License-Identifier: GPL-2.0 -+config AUFS_FS -+ tristate "Aufs (Advanced multi layered unification filesystem) support" -+ help -+ Aufs is a stackable unification filesystem such as Unionfs, -+ which unifies several directories and provides a merged single -+ directory. -+ In the early days, aufs was entirely re-designed and -+ re-implemented Unionfs Version 1.x series. Introducing many -+ original ideas, approaches and improvements, it becomes totally -+ different from Unionfs while keeping the basic features. -+ -+if AUFS_FS -+choice -+ prompt "Maximum number of branches" -+ default AUFS_BRANCH_MAX_127 -+ help -+ Specifies the maximum number of branches (or member directories) -+ in a single aufs. The larger value consumes more system -+ resources and has a minor impact to performance. -+config AUFS_BRANCH_MAX_127 -+ bool "127" -+ help -+ Specifies the maximum number of branches (or member directories) -+ in a single aufs. The larger value consumes more system -+ resources and has a minor impact to performance. -+config AUFS_BRANCH_MAX_511 -+ bool "511" -+ help -+ Specifies the maximum number of branches (or member directories) -+ in a single aufs. The larger value consumes more system -+ resources and has a minor impact to performance. -+config AUFS_BRANCH_MAX_1023 -+ bool "1023" -+ help -+ Specifies the maximum number of branches (or member directories) -+ in a single aufs. The larger value consumes more system -+ resources and has a minor impact to performance. -+config AUFS_BRANCH_MAX_32767 -+ bool "32767" -+ help -+ Specifies the maximum number of branches (or member directories) -+ in a single aufs. The larger value consumes more system -+ resources and has a minor impact to performance. -+endchoice -+ -+config AUFS_SBILIST -+ bool -+ depends on AUFS_MAGIC_SYSRQ || PROC_FS -+ default y -+ help -+ Automatic configuration for internal use. -+ When aufs supports Magic SysRq or /proc, enabled automatically. -+ -+config AUFS_HNOTIFY -+ bool "Detect direct branch access (bypassing aufs)" -+ help -+ If you want to modify files on branches directly, eg. bypassing aufs, -+ and want aufs to detect the changes of them fully, then enable this -+ option and use 'udba=notify' mount option. -+ Currently there is only one available configuration, "fsnotify". -+ It will have a negative impact to the performance. -+ See detail in aufs.5. -+ -+choice -+ prompt "method" if AUFS_HNOTIFY -+ default AUFS_HFSNOTIFY -+config AUFS_HFSNOTIFY -+ bool "fsnotify" -+ select FSNOTIFY -+endchoice -+ -+config AUFS_EXPORT -+ bool "NFS-exportable aufs" -+ depends on EXPORTFS -+ help -+ If you want to export your mounted aufs via NFS, then enable this -+ option. There are several requirements for this configuration. -+ See detail in aufs.5. -+ -+config AUFS_INO_T_64 -+ bool -+ depends on AUFS_EXPORT -+ depends on 64BIT && !(ALPHA || S390) -+ default y -+ help -+ Automatic configuration for internal use. -+ /* typedef unsigned long/int __kernel_ino_t */ -+ /* alpha and s390x are int */ -+ -+config AUFS_XATTR -+ bool "support for XATTR/EA (including Security Labels)" -+ help -+ If your branch fs supports XATTR/EA and you want to make them -+ available in aufs too, then enable this opsion and specify the -+ branch attributes for EA. -+ See detail in aufs.5. -+ -+config AUFS_FHSM -+ bool "File-based Hierarchical Storage Management" -+ help -+ Hierarchical Storage Management (or HSM) is a well-known feature -+ in the storage world. Aufs provides this feature as file-based. -+ with multiple branches. -+ These multiple branches are prioritized, ie. the topmost one -+ should be the fastest drive and be used heavily. -+ -+config AUFS_RDU -+ bool "Readdir in userspace" -+ help -+ Aufs has two methods to provide a merged view for a directory, -+ by a user-space library and by kernel-space natively. The latter -+ is always enabled but sometimes large and slow. -+ If you enable this option, install the library in aufs2-util -+ package, and set some environment variables for your readdir(3), -+ then the work will be handled in user-space which generally -+ shows better performance in most cases. -+ See detail in aufs.5. -+ -+config AUFS_DIRREN -+ bool "Workaround for rename(2)-ing a directory" -+ help -+ By default, aufs returns EXDEV error in renameing a dir who has -+ his child on the lower branch, since it is a bad idea to issue -+ rename(2) internally for every lower branch. But user may not -+ accept this behaviour. So here is a workaround to allow such -+ rename(2) and store some extra information on the writable -+ branch. Obviously this costs high (and I don't like it). -+ To use this feature, you need to enable this configuration AND -+ to specify the mount option `dirren.' -+ See details in aufs.5 and the design documents. -+ -+config AUFS_SHWH -+ bool "Show whiteouts" -+ help -+ If you want to make the whiteouts in aufs visible, then enable -+ this option and specify 'shwh' mount option. Although it may -+ sounds like philosophy or something, but in technically it -+ simply shows the name of whiteout with keeping its behaviour. -+ -+config AUFS_BR_RAMFS -+ bool "Ramfs (initramfs/rootfs) as an aufs branch" -+ help -+ If you want to use ramfs as an aufs branch fs, then enable this -+ option. Generally tmpfs is recommended. -+ Aufs prohibited them to be a branch fs by default, because -+ initramfs becomes unusable after switch_root or something -+ generally. If you sets initramfs as an aufs branch and boot your -+ system by switch_root, you will meet a problem easily since the -+ files in initramfs may be inaccessible. -+ Unless you are going to use ramfs as an aufs branch fs without -+ switch_root or something, leave it N. -+ -+config AUFS_BR_FUSE -+ bool "Fuse fs as an aufs branch" -+ depends on FUSE_FS -+ select AUFS_POLL -+ help -+ If you want to use fuse-based userspace filesystem as an aufs -+ branch fs, then enable this option. -+ It implements the internal poll(2) operation which is -+ implemented by fuse only (curretnly). -+ -+config AUFS_POLL -+ bool -+ help -+ Automatic configuration for internal use. -+ -+config AUFS_BR_HFSPLUS -+ bool "Hfsplus as an aufs branch" -+ depends on HFSPLUS_FS -+ default y -+ help -+ If you want to use hfsplus fs as an aufs branch fs, then enable -+ this option. This option introduces a small overhead at -+ copying-up a file on hfsplus. -+ -+config AUFS_BDEV_LOOP -+ bool -+ depends on BLK_DEV_LOOP -+ default y -+ help -+ Automatic configuration for internal use. -+ Convert =[ym] into =y. -+ -+config AUFS_DEBUG -+ bool "Debug aufs" -+ help -+ Enable this to compile aufs internal debug code. -+ It will have a negative impact to the performance. -+ -+config AUFS_MAGIC_SYSRQ -+ bool -+ depends on AUFS_DEBUG && MAGIC_SYSRQ -+ default y -+ help -+ Automatic configuration for internal use. -+ When aufs supports Magic SysRq, enabled automatically. -+endif -diff -Naur null/fs/aufs/lcnt.h linux-6.6.63/fs/aufs/lcnt.h ---- /dev/null -+++ linux-6.6.63/fs/aufs/lcnt.h 2024-12-18 15:12:59.298519551 +0300 -@@ -0,0 +1,186 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2018-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * simple long counter wrapper -+ */ -+ -+#ifndef __AUFS_LCNT_H__ -+#define __AUFS_LCNT_H__ -+ -+#ifdef __KERNEL__ -+ -+#include "debug.h" -+ -+#define AuLCntATOMIC 1 -+#define AuLCntPCPUCNT 2 -+/* -+ * why does percpu_refcount require extra synchronize_rcu()s in -+ * au_br_do_free() -+ */ -+#define AuLCntPCPUREF 3 -+ -+/* #define AuLCntChosen AuLCntATOMIC */ -+#define AuLCntChosen AuLCntPCPUCNT -+/* #define AuLCntChosen AuLCntPCPUREF */ -+ -+#if AuLCntChosen == AuLCntATOMIC -+#include -+ -+typedef atomic_long_t au_lcnt_t; -+ -+static inline int au_lcnt_init(au_lcnt_t *cnt, void *release __maybe_unused) -+{ -+ atomic_long_set(cnt, 0); -+ return 0; -+} -+ -+static inline void au_lcnt_wait_for_fin(au_lcnt_t *cnt __maybe_unused) -+{ -+ /* empty */ -+} -+ -+static inline void au_lcnt_fin(au_lcnt_t *cnt __maybe_unused, -+ int do_sync __maybe_unused) -+{ -+ /* empty */ -+} -+ -+static inline void au_lcnt_inc(au_lcnt_t *cnt) -+{ -+ atomic_long_inc(cnt); -+} -+ -+static inline void au_lcnt_dec(au_lcnt_t *cnt) -+{ -+ atomic_long_dec(cnt); -+} -+ -+static inline long au_lcnt_read(au_lcnt_t *cnt, int do_rev __maybe_unused) -+{ -+ return atomic_long_read(cnt); -+} -+#endif -+ -+#if AuLCntChosen == AuLCntPCPUCNT -+#include -+ -+typedef struct percpu_counter au_lcnt_t; -+ -+static inline int au_lcnt_init(au_lcnt_t *cnt, void *release __maybe_unused) -+{ -+ return percpu_counter_init(cnt, 0, GFP_NOFS); -+} -+ -+static inline void au_lcnt_wait_for_fin(au_lcnt_t *cnt __maybe_unused) -+{ -+ /* empty */ -+} -+ -+static inline void au_lcnt_fin(au_lcnt_t *cnt, int do_sync __maybe_unused) -+{ -+ percpu_counter_destroy(cnt); -+} -+ -+static inline void au_lcnt_inc(au_lcnt_t *cnt) -+{ -+ percpu_counter_inc(cnt); -+} -+ -+static inline void au_lcnt_dec(au_lcnt_t *cnt) -+{ -+ percpu_counter_dec(cnt); -+} -+ -+static inline long au_lcnt_read(au_lcnt_t *cnt, int do_rev __maybe_unused) -+{ -+ s64 n; -+ -+ n = percpu_counter_sum(cnt); -+ BUG_ON(n < 0); -+ if (LONG_MAX != LLONG_MAX -+ && n > LONG_MAX) -+ AuWarn1("%s\n", "wrap-around"); -+ -+ return n; -+} -+#endif -+ -+#if AuLCntChosen == AuLCntPCPUREF -+#include -+ -+typedef struct percpu_ref au_lcnt_t; -+ -+static inline int au_lcnt_init(au_lcnt_t *cnt, percpu_ref_func_t *release) -+{ -+ if (!release) -+ release = percpu_ref_exit; -+ return percpu_ref_init(cnt, release, /*percpu mode*/0, GFP_NOFS); -+} -+ -+static inline void au_lcnt_wait_for_fin(au_lcnt_t *cnt __maybe_unused) -+{ -+ synchronize_rcu(); -+} -+ -+static inline void au_lcnt_fin(au_lcnt_t *cnt, int do_sync) -+{ -+ percpu_ref_kill(cnt); -+ if (do_sync) -+ au_lcnt_wait_for_fin(cnt); -+} -+ -+static inline void au_lcnt_inc(au_lcnt_t *cnt) -+{ -+ percpu_ref_get(cnt); -+} -+ -+static inline void au_lcnt_dec(au_lcnt_t *cnt) -+{ -+ percpu_ref_put(cnt); -+} -+ -+/* -+ * avoid calling this func as possible. -+ */ -+static inline long au_lcnt_read(au_lcnt_t *cnt, int do_rev) -+{ -+ long l; -+ -+ percpu_ref_switch_to_atomic_sync(cnt); -+ l = atomic_long_read(&cnt->count); -+ if (do_rev) -+ percpu_ref_switch_to_percpu(cnt); -+ -+ /* percpu_ref is initialized by 1 instead of 0 */ -+ return l - 1; -+} -+#endif -+ -+#ifdef CONFIG_AUFS_DEBUG -+#define AuLCntZero(val) do { \ -+ long l = val; \ -+ if (l) \ -+ AuDbg("%s = %ld\n", #val, l); \ -+} while (0) -+#else -+AuStubVoid(AuLCntZero, long val __maybe_unused); -+#endif -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_LCNT_H__ */ -diff -Naur null/fs/aufs/loop.c linux-6.6.63/fs/aufs/loop.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/loop.c 2024-12-18 15:12:59.298519551 +0300 -@@ -0,0 +1,148 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * support for loopback block device as a branch -+ */ -+ -+#include "aufs.h" -+ -+/* added into drivers/block/loop.c */ -+static struct file *(*backing_file_func)(struct super_block *sb); -+ -+/* -+ * test if two lower dentries have overlapping branches. -+ */ -+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding) -+{ -+ struct super_block *h_sb; -+ struct file *backing_file; -+ -+ if (unlikely(!backing_file_func)) { -+ /* don't load "loop" module here */ -+ backing_file_func = symbol_get(loop_backing_file); -+ if (unlikely(!backing_file_func)) -+ /* "loop" module is not loaded */ -+ return 0; -+ } -+ -+ h_sb = h_adding->d_sb; -+ backing_file = backing_file_func(h_sb); -+ if (!backing_file) -+ return 0; -+ -+ h_adding = backing_file->f_path.dentry; -+ /* -+ * h_adding can be local NFS. -+ * in this case aufs cannot detect the loop. -+ */ -+ if (unlikely(h_adding->d_sb == sb)) -+ return 1; -+ return !!au_test_subdir(h_adding, sb->s_root); -+} -+ -+/* true if a kernel thread named 'loop[0-9].*' accesses a file */ -+int au_test_loopback_kthread(void) -+{ -+ int ret; -+ struct task_struct *tsk = current; -+ char c, comm[sizeof(tsk->comm)]; -+ -+ ret = 0; -+ if (tsk->flags & PF_KTHREAD) { -+ get_task_comm(comm, tsk); -+ c = comm[4]; -+ ret = ('0' <= c && c <= '9' -+ && !strncmp(comm, "loop", 4)); -+ } -+ -+ return ret; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+#define au_warn_loopback_step 16 -+static int au_warn_loopback_nelem = au_warn_loopback_step; -+static unsigned long *au_warn_loopback_array; -+ -+void au_warn_loopback(struct super_block *h_sb) -+{ -+ int i, new_nelem; -+ unsigned long *a, magic; -+ static DEFINE_SPINLOCK(spin); -+ -+ magic = h_sb->s_magic; -+ spin_lock(&spin); -+ a = au_warn_loopback_array; -+ for (i = 0; i < au_warn_loopback_nelem && *a; i++) -+ if (a[i] == magic) { -+ spin_unlock(&spin); -+ return; -+ } -+ -+ /* h_sb is new to us, print it */ -+ if (i < au_warn_loopback_nelem) { -+ a[i] = magic; -+ goto pr; -+ } -+ -+ /* expand the array */ -+ new_nelem = au_warn_loopback_nelem + au_warn_loopback_step; -+ a = au_kzrealloc(au_warn_loopback_array, -+ au_warn_loopback_nelem * sizeof(unsigned long), -+ new_nelem * sizeof(unsigned long), GFP_ATOMIC, -+ /*may_shrink*/0); -+ if (a) { -+ au_warn_loopback_nelem = new_nelem; -+ au_warn_loopback_array = a; -+ a[i] = magic; -+ goto pr; -+ } -+ -+ spin_unlock(&spin); -+ AuWarn1("realloc failed, ignored\n"); -+ return; -+ -+pr: -+ spin_unlock(&spin); -+ pr_warn("you may want to try another patch for loopback file " -+ "on %s(0x%lx) branch\n", au_sbtype(h_sb), magic); -+} -+ -+int au_loopback_init(void) -+{ -+ int err; -+ struct super_block *sb __maybe_unused; -+ -+ BUILD_BUG_ON(sizeof(sb->s_magic) != sizeof(*au_warn_loopback_array)); -+ -+ err = 0; -+ au_warn_loopback_array = kcalloc(au_warn_loopback_step, -+ sizeof(unsigned long), GFP_NOFS); -+ if (unlikely(!au_warn_loopback_array)) -+ err = -ENOMEM; -+ -+ return err; -+} -+ -+void au_loopback_fin(void) -+{ -+ if (backing_file_func) -+ symbol_put(loop_backing_file); -+ au_kfree_try_rcu(au_warn_loopback_array); -+} -diff -Naur null/fs/aufs/loop.h linux-6.6.63/fs/aufs/loop.h ---- /dev/null -+++ linux-6.6.63/fs/aufs/loop.h 2024-12-18 15:12:59.298519551 +0300 -@@ -0,0 +1,55 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * support for loopback mount as a branch -+ */ -+ -+#ifndef __AUFS_LOOP_H__ -+#define __AUFS_LOOP_H__ -+ -+#ifdef __KERNEL__ -+ -+struct dentry; -+struct super_block; -+ -+#ifdef CONFIG_AUFS_BDEV_LOOP -+/* drivers/block/loop.c */ -+struct file *loop_backing_file(struct super_block *sb); -+ -+/* loop.c */ -+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding); -+int au_test_loopback_kthread(void); -+void au_warn_loopback(struct super_block *h_sb); -+ -+int au_loopback_init(void); -+void au_loopback_fin(void); -+#else -+AuStub(struct file *, loop_backing_file, return NULL, struct super_block *sb) -+ -+AuStubInt0(au_test_loopback_overlap, struct super_block *sb, -+ struct dentry *h_adding) -+AuStubInt0(au_test_loopback_kthread, void) -+AuStubVoid(au_warn_loopback, struct super_block *h_sb) -+ -+AuStubInt0(au_loopback_init, void) -+AuStubVoid(au_loopback_fin, void) -+#endif /* BLK_DEV_LOOP */ -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_LOOP_H__ */ -diff -Naur null/fs/aufs/magic.mk linux-6.6.63/fs/aufs/magic.mk ---- /dev/null -+++ linux-6.6.63/fs/aufs/magic.mk 2024-12-18 15:12:59.298519551 +0300 -@@ -0,0 +1,31 @@ -+# SPDX-License-Identifier: GPL-2.0 -+ -+# defined in ${srctree}/fs/fuse/inode.c -+# tristate -+ifdef CONFIG_FUSE_FS -+ccflags-y += -DFUSE_SUPER_MAGIC=0x65735546 -+endif -+ -+# defined in ${srctree}/fs/xfs/xfs_sb.h -+# tristate -+ifdef CONFIG_XFS_FS -+ccflags-y += -DXFS_SB_MAGIC=0x58465342 -+endif -+ -+# defined in ${srctree}/fs/configfs/mount.c -+# tristate -+ifdef CONFIG_CONFIGFS_FS -+ccflags-y += -DCONFIGFS_MAGIC=0x62656570 -+endif -+ -+# defined in ${srctree}/fs/ubifs/ubifs.h -+# tristate -+ifdef CONFIG_UBIFS_FS -+ccflags-y += -DUBIFS_SUPER_MAGIC=0x24051905 -+endif -+ -+# defined in ${srctree}/fs/hfsplus/hfsplus_raw.h -+# tristate -+ifdef CONFIG_HFSPLUS_FS -+ccflags-y += -DHFSPLUS_SUPER_MAGIC=0x482b -+endif -diff -Naur null/fs/aufs/Makefile linux-6.6.63/fs/aufs/Makefile ---- /dev/null -+++ linux-6.6.63/fs/aufs/Makefile 2024-12-18 15:12:59.293519613 +0300 -@@ -0,0 +1,46 @@ -+# SPDX-License-Identifier: GPL-2.0 -+ -+include ${src}/magic.mk -+ifeq (${CONFIG_AUFS_FS},m) -+include ${src}/conf.mk -+endif -+-include ${src}/priv_def.mk -+ -+# cf. include/linux/kernel.h -+# enable pr_debug -+ccflags-y += -DDEBUG -+# sparse requires the full pathname -+ifdef M -+ccflags-y += -include ${M}/../../include/uapi/linux/aufs_type.h -+else -+ccflags-y += -include ${srctree}/include/uapi/linux/aufs_type.h -+endif -+ -+obj-$(CONFIG_AUFS_FS) += aufs.o -+aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o fsctx.o \ -+ wkq.o vfsub.o dcsub.o \ -+ cpup.o whout.o wbr_policy.o \ -+ dinfo.o dentry.o \ -+ dynop.o \ -+ finfo.o file.o f_op.o \ -+ dir.o vdir.o \ -+ iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \ -+ mvdown.o ioctl.o -+ -+# all are boolean -+aufs-$(CONFIG_PROC_FS) += procfs.o plink.o -+aufs-$(CONFIG_SYSFS) += sysfs.o -+aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o -+aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o -+aufs-$(CONFIG_AUFS_HNOTIFY) += hnotify.o -+aufs-$(CONFIG_AUFS_HFSNOTIFY) += hfsnotify.o -+aufs-$(CONFIG_AUFS_EXPORT) += export.o -+aufs-$(CONFIG_AUFS_XATTR) += xattr.o -+aufs-$(CONFIG_FS_POSIX_ACL) += posix_acl.o -+aufs-$(CONFIG_AUFS_DIRREN) += dirren.o -+aufs-$(CONFIG_AUFS_FHSM) += fhsm.o -+aufs-$(CONFIG_AUFS_POLL) += poll.o -+aufs-$(CONFIG_AUFS_RDU) += rdu.o -+aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o -+aufs-$(CONFIG_AUFS_DEBUG) += debug.o -+aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o -diff -Naur null/fs/aufs/module.c linux-6.6.63/fs/aufs/module.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/module.c 2024-12-18 15:12:59.298519551 +0300 -@@ -0,0 +1,273 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * module global variables and operations -+ */ -+ -+#include -+#include -+#include "aufs.h" -+ -+/* shrinkable realloc */ -+void *au_krealloc(void *p, unsigned int new_sz, gfp_t gfp, int may_shrink) -+{ -+ size_t sz; -+ int diff; -+ -+ sz = 0; -+ diff = -1; -+ if (p) { -+#if 0 /* unused */ -+ if (!new_sz) { -+ au_kfree_rcu(p); -+ p = NULL; -+ goto out; -+ } -+#else -+ AuDebugOn(!new_sz); -+#endif -+ sz = ksize(p); -+ diff = au_kmidx_sub(sz, new_sz); -+ } -+ if (sz && !diff) -+ goto out; -+ -+ if (sz < new_sz) -+ /* expand or SLOB */ -+ p = krealloc(p, new_sz, gfp); -+ else if (new_sz < sz && may_shrink) { -+ /* shrink */ -+ void *q; -+ -+ q = kmalloc(new_sz, gfp); -+ if (q) { -+ if (p) { -+ memcpy(q, p, new_sz); -+ au_kfree_try_rcu(p); -+ } -+ p = q; -+ } else -+ p = NULL; -+ } -+ -+out: -+ return p; -+} -+ -+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp, -+ int may_shrink) -+{ -+ p = au_krealloc(p, new_sz, gfp, may_shrink); -+ if (p && new_sz > nused) -+ memset(p + nused, 0, new_sz - nused); -+ return p; -+} -+ -+/* ---------------------------------------------------------------------- */ -+/* -+ * aufs caches -+ */ -+struct kmem_cache *au_cache[AuCache_Last]; -+ -+static void au_cache_fin(void) -+{ -+ int i; -+ -+ /* -+ * Make sure all delayed rcu free inodes are flushed before we -+ * destroy cache. -+ */ -+ rcu_barrier(); -+ -+ /* excluding AuCache_HNOTIFY */ -+ BUILD_BUG_ON(AuCache_HNOTIFY + 1 != AuCache_Last); -+ for (i = 0; i < AuCache_HNOTIFY; i++) { -+ kmem_cache_destroy(au_cache[i]); -+ au_cache[i] = NULL; -+ } -+} -+ -+static int __init au_cache_init(void) -+{ -+ au_cache[AuCache_DINFO] = AuCacheCtor(au_dinfo, au_di_init_once); -+ if (au_cache[AuCache_DINFO]) -+ /* SLAB_DESTROY_BY_RCU */ -+ au_cache[AuCache_ICNTNR] = AuCacheCtor(au_icntnr, -+ au_icntnr_init_once); -+ if (au_cache[AuCache_ICNTNR]) -+ au_cache[AuCache_FINFO] = AuCacheCtor(au_finfo, -+ au_fi_init_once); -+ if (au_cache[AuCache_FINFO]) -+ au_cache[AuCache_VDIR] = AuCache(au_vdir); -+ if (au_cache[AuCache_VDIR]) -+ au_cache[AuCache_DEHSTR] = AuCache(au_vdir_dehstr); -+ if (au_cache[AuCache_DEHSTR]) -+ return 0; -+ -+ au_cache_fin(); -+ return -ENOMEM; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_dir_roflags; -+ -+#ifdef CONFIG_AUFS_SBILIST -+/* -+ * iterate_supers_type() doesn't protect us from -+ * remounting (branch management) -+ */ -+struct hlist_bl_head au_sbilist; -+#endif -+ -+/* -+ * functions for module interface. -+ */ -+MODULE_LICENSE("GPL"); -+/* MODULE_LICENSE("GPL v2"); */ -+MODULE_AUTHOR("Junjiro R. Okajima "); -+MODULE_DESCRIPTION(AUFS_NAME -+ " -- Advanced multi layered unification filesystem"); -+MODULE_VERSION(AUFS_VERSION); -+MODULE_ALIAS_FS(AUFS_NAME); -+ -+/* this module parameter has no meaning when SYSFS is disabled */ -+int sysaufs_brs = 1; -+MODULE_PARM_DESC(brs, "use /fs/aufs/si_*/brN"); -+module_param_named(brs, sysaufs_brs, int, 0444); -+ -+/* this module parameter has no meaning when USER_NS is disabled */ -+bool au_userns; -+MODULE_PARM_DESC(allow_userns, "allow unprivileged to mount under userns"); -+module_param_named(allow_userns, au_userns, bool, 0444); -+ -+/* ---------------------------------------------------------------------- */ -+ -+static char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */ -+ -+int au_seq_path(struct seq_file *seq, struct path *path) -+{ -+ int err; -+ -+ err = seq_path(seq, path, au_esc_chars); -+ if (err >= 0) -+ err = 0; -+ else -+ err = -ENOMEM; -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int __init aufs_init(void) -+{ -+ int err, i; -+ char *p; -+ -+ p = au_esc_chars; -+ for (i = 1; i <= ' '; i++) -+ *p++ = i; -+ *p++ = '\\'; -+ *p++ = '\x7f'; -+ *p = 0; -+ -+ au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE); -+ -+ memcpy(aufs_iop_nogetattr, aufs_iop, sizeof(aufs_iop)); -+ for (i = 0; i < AuIop_Last; i++) -+ aufs_iop_nogetattr[i].getattr = NULL; -+ -+ memset(au_cache, 0, sizeof(au_cache)); /* including hnotify */ -+ -+ au_sbilist_init(); -+ sysaufs_brs_init(); -+ au_debug_init(); -+ au_dy_init(); -+ err = sysaufs_init(); -+ if (unlikely(err)) -+ goto out; -+ err = dbgaufs_init(); -+ if (unlikely(err)) -+ goto out_sysaufs; -+ err = au_procfs_init(); -+ if (unlikely(err)) -+ goto out_dbgaufs; -+ err = au_wkq_init(); -+ if (unlikely(err)) -+ goto out_procfs; -+ err = au_loopback_init(); -+ if (unlikely(err)) -+ goto out_wkq; -+ err = au_hnotify_init(); -+ if (unlikely(err)) -+ goto out_loopback; -+ err = au_sysrq_init(); -+ if (unlikely(err)) -+ goto out_hin; -+ err = au_cache_init(); -+ if (unlikely(err)) -+ goto out_sysrq; -+ -+ aufs_fs_type.fs_flags |= au_userns ? FS_USERNS_MOUNT : 0; -+ err = register_filesystem(&aufs_fs_type); -+ if (unlikely(err)) -+ goto out_cache; -+ -+ /* since we define pr_fmt, call printk directly */ -+ printk(KERN_INFO AUFS_NAME " " AUFS_VERSION "\n"); -+ goto out; /* success */ -+ -+out_cache: -+ au_cache_fin(); -+out_sysrq: -+ au_sysrq_fin(); -+out_hin: -+ au_hnotify_fin(); -+out_loopback: -+ au_loopback_fin(); -+out_wkq: -+ au_wkq_fin(); -+out_procfs: -+ au_procfs_fin(); -+out_dbgaufs: -+ dbgaufs_fin(); -+out_sysaufs: -+ sysaufs_fin(); -+ au_dy_fin(); -+out: -+ return err; -+} -+ -+static void __exit aufs_exit(void) -+{ -+ unregister_filesystem(&aufs_fs_type); -+ au_cache_fin(); -+ au_sysrq_fin(); -+ au_hnotify_fin(); -+ au_loopback_fin(); -+ au_wkq_fin(); -+ au_procfs_fin(); -+ dbgaufs_fin(); -+ sysaufs_fin(); -+ au_dy_fin(); -+} -+ -+module_init(aufs_init); -+module_exit(aufs_exit); -diff -Naur null/fs/aufs/module.h linux-6.6.63/fs/aufs/module.h ---- /dev/null -+++ linux-6.6.63/fs/aufs/module.h 2024-12-18 15:12:59.298519551 +0300 -@@ -0,0 +1,180 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * module initialization and module-global -+ */ -+ -+#ifndef __AUFS_MODULE_H__ -+#define __AUFS_MODULE_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include "debug.h" -+#include "dentry.h" -+#include "dir.h" -+#include "file.h" -+#include "inode.h" -+ -+struct path; -+struct seq_file; -+ -+/* module parameters */ -+extern int sysaufs_brs; -+extern bool au_userns; -+ -+/* ---------------------------------------------------------------------- */ -+ -+extern int au_dir_roflags; -+ -+void *au_krealloc(void *p, unsigned int new_sz, gfp_t gfp, int may_shrink); -+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp, -+ int may_shrink); -+ -+/* -+ * Comparing the size of the object with sizeof(struct rcu_head) -+ * case 1: object is always larger -+ * --> au_kfree_rcu() or au_kfree_do_rcu() -+ * case 2: object is always smaller -+ * --> au_kfree_small() -+ * case 3: object can be any size -+ * --> au_kfree_try_rcu() -+ */ -+ -+static inline void au_kfree_do_rcu(const void *p) -+{ -+ struct { -+ struct rcu_head rcu; -+ } *a = (void *)p; -+ -+ kfree_rcu(a, rcu); -+} -+ -+#define au_kfree_rcu(_p) do { \ -+ typeof(_p) p = (_p); \ -+ BUILD_BUG_ON(sizeof(*p) < sizeof(struct rcu_head)); \ -+ if (p) \ -+ au_kfree_do_rcu(p); \ -+ } while (0) -+ -+#define au_kfree_do_sz_test(sz) (sz >= sizeof(struct rcu_head)) -+#define au_kfree_sz_test(p) (p && au_kfree_do_sz_test(ksize(p))) -+ -+static inline void au_kfree_try_rcu(const void *p) -+{ -+ if (!p) -+ return; -+ if (au_kfree_sz_test(p)) -+ au_kfree_do_rcu(p); -+ else -+ kfree(p); -+} -+ -+static inline void au_kfree_small(const void *p) -+{ -+ if (!p) -+ return; -+ AuDebugOn(au_kfree_sz_test(p)); -+ kfree(p); -+} -+ -+static inline int au_kmidx_sub(size_t sz, size_t new_sz) -+{ -+#ifndef CONFIG_SLOB -+ return __kmalloc_index(sz, false) - __kmalloc_index(new_sz, false); -+#else -+ return -1; /* SLOB is untested */ -+#endif -+} -+ -+int au_seq_path(struct seq_file *seq, struct path *path); -+ -+#ifdef CONFIG_PROC_FS -+/* procfs.c */ -+int __init au_procfs_init(void); -+void au_procfs_fin(void); -+#else -+AuStubInt0(au_procfs_init, void); -+AuStubVoid(au_procfs_fin, void); -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* kmem cache */ -+enum { -+ AuCache_DINFO, -+ AuCache_ICNTNR, -+ AuCache_FINFO, -+ AuCache_VDIR, -+ AuCache_DEHSTR, -+ AuCache_HNOTIFY, /* must be last */ -+ AuCache_Last -+}; -+ -+extern struct kmem_cache *au_cache[AuCache_Last]; -+ -+#define AuCacheFlags (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD) -+#define AuCache(type) KMEM_CACHE(type, AuCacheFlags) -+#define AuCacheCtor(type, ctor) \ -+ kmem_cache_create(#type, sizeof(struct type), \ -+ __alignof__(struct type), AuCacheFlags, ctor) -+ -+#define AuCacheFuncAlloc(name, index) \ -+ static inline struct au_##name *au_cache_alloc_##name(void) \ -+ { return kmem_cache_alloc(au_cache[AuCache_##index], GFP_NOFS); } -+ -+#define AuCacheFuncs(name, index) \ -+ static inline void au_cache_free_##name##_norcu(struct au_##name *p) \ -+ { kmem_cache_free(au_cache[AuCache_##index], p); } \ -+ \ -+ static inline void au_cache_free_##name##_rcu_cb(struct rcu_head *rcu) \ -+ { void *p = rcu; \ -+ p -= offsetof(struct au_##name, rcu); \ -+ kmem_cache_free(au_cache[AuCache_##index], p); } \ -+ static inline void au_cache_free_##name##_rcu(struct au_##name *p) \ -+ { BUILD_BUG_ON(sizeof(struct au_##name) < sizeof(struct rcu_head)); \ -+ call_rcu(&p->rcu, au_cache_free_##name##_rcu_cb); } \ -+ \ -+ static inline void au_cache_free_##name(struct au_##name *p) \ -+ { /* au_cache_free_##name##_norcu(p); */ \ -+ au_cache_free_##name##_rcu(p); } -+ -+AuCacheFuncs(dinfo, DINFO); -+AuCacheFuncAlloc(dinfo, DINFO); -+ -+AuCacheFuncs(icntnr, ICNTNR); -+static inline struct au_icntnr *au_cache_alloc_icntnr(struct super_block *sb) -+{ return alloc_inode_sb(sb, au_cache[AuCache_ICNTNR], GFP_NOFS); } -+ -+AuCacheFuncs(finfo, FINFO); -+AuCacheFuncAlloc(finfo, FINFO); -+ -+AuCacheFuncs(vdir, VDIR); -+AuCacheFuncAlloc(vdir, VDIR); -+ -+AuCacheFuncs(vdir_dehstr, DEHSTR); -+AuCacheFuncAlloc(vdir_dehstr, DEHSTR); -+ -+#ifdef CONFIG_AUFS_HNOTIFY -+AuCacheFuncs(hnotify, HNOTIFY); -+AuCacheFuncAlloc(hnotify, HNOTIFY); -+#endif -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_MODULE_H__ */ -diff -Naur null/fs/aufs/mvdown.c linux-6.6.63/fs/aufs/mvdown.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/mvdown.c 2024-12-18 15:12:59.298519551 +0300 -@@ -0,0 +1,707 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2011-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * move-down, opposite of copy-up -+ */ -+ -+#include "aufs.h" -+ -+struct au_mvd_args { -+ struct { -+ struct super_block *h_sb; -+ struct dentry *h_parent; -+ struct au_hinode *hdir; -+ struct inode *h_dir, *h_inode; -+ struct au_pin pin; -+ } info[AUFS_MVDOWN_NARRAY]; -+ -+ struct aufs_mvdown mvdown; -+ struct dentry *dentry, *parent; -+ struct inode *inode, *dir; -+ struct super_block *sb; -+ aufs_bindex_t bopq, bwh, bfound; -+ unsigned char rename_lock; -+}; -+ -+#define mvd_errno mvdown.au_errno -+#define mvd_bsrc mvdown.stbr[AUFS_MVDOWN_UPPER].bindex -+#define mvd_src_brid mvdown.stbr[AUFS_MVDOWN_UPPER].brid -+#define mvd_bdst mvdown.stbr[AUFS_MVDOWN_LOWER].bindex -+#define mvd_dst_brid mvdown.stbr[AUFS_MVDOWN_LOWER].brid -+ -+#define mvd_h_src_sb info[AUFS_MVDOWN_UPPER].h_sb -+#define mvd_h_src_parent info[AUFS_MVDOWN_UPPER].h_parent -+#define mvd_hdir_src info[AUFS_MVDOWN_UPPER].hdir -+#define mvd_h_src_dir info[AUFS_MVDOWN_UPPER].h_dir -+#define mvd_h_src_inode info[AUFS_MVDOWN_UPPER].h_inode -+#define mvd_pin_src info[AUFS_MVDOWN_UPPER].pin -+ -+#define mvd_h_dst_sb info[AUFS_MVDOWN_LOWER].h_sb -+#define mvd_h_dst_parent info[AUFS_MVDOWN_LOWER].h_parent -+#define mvd_hdir_dst info[AUFS_MVDOWN_LOWER].hdir -+#define mvd_h_dst_dir info[AUFS_MVDOWN_LOWER].h_dir -+#define mvd_h_dst_inode info[AUFS_MVDOWN_LOWER].h_inode -+#define mvd_pin_dst info[AUFS_MVDOWN_LOWER].pin -+ -+#define AU_MVD_PR(flag, ...) do { \ -+ if (flag) \ -+ pr_err(__VA_ARGS__); \ -+ } while (0) -+ -+static int find_lower_writable(struct au_mvd_args *a) -+{ -+ struct super_block *sb; -+ aufs_bindex_t bindex, bbot; -+ struct au_branch *br; -+ -+ sb = a->sb; -+ bindex = a->mvd_bsrc; -+ bbot = au_sbbot(sb); -+ if (a->mvdown.flags & AUFS_MVDOWN_FHSM_LOWER) -+ for (bindex++; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (au_br_fhsm(br->br_perm) -+ && !sb_rdonly(au_br_sb(br))) -+ return bindex; -+ } -+ else if (!(a->mvdown.flags & AUFS_MVDOWN_ROLOWER)) -+ for (bindex++; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (!au_br_rdonly(br)) -+ return bindex; -+ } -+ else -+ for (bindex++; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (!sb_rdonly(au_br_sb(br))) { -+ if (au_br_rdonly(br)) -+ a->mvdown.flags -+ |= AUFS_MVDOWN_ROLOWER_R; -+ return bindex; -+ } -+ } -+ -+ return -1; -+} -+ -+/* make the parent dir on bdst */ -+static int au_do_mkdir(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ int err; -+ -+ err = 0; -+ a->mvd_hdir_src = au_hi(a->dir, a->mvd_bsrc); -+ a->mvd_hdir_dst = au_hi(a->dir, a->mvd_bdst); -+ a->mvd_h_src_parent = au_h_dptr(a->parent, a->mvd_bsrc); -+ a->mvd_h_dst_parent = NULL; -+ if (au_dbbot(a->parent) >= a->mvd_bdst) -+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst); -+ if (!a->mvd_h_dst_parent) { -+ err = au_cpdown_dirs(a->dentry, a->mvd_bdst); -+ if (unlikely(err)) { -+ AU_MVD_PR(dmsg, "cpdown_dirs failed\n"); -+ goto out; -+ } -+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst); -+ } -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* lock them all */ -+static int au_do_lock(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ int err; -+ struct dentry *h_trap; -+ -+ a->mvd_h_src_sb = au_sbr_sb(a->sb, a->mvd_bsrc); -+ a->mvd_h_dst_sb = au_sbr_sb(a->sb, a->mvd_bdst); -+ err = au_pin(&a->mvd_pin_dst, a->dentry, a->mvd_bdst, -+ au_opt_udba(a->sb), -+ AuPin_MNT_WRITE | AuPin_DI_LOCKED); -+ AuTraceErr(err); -+ if (unlikely(err)) { -+ AU_MVD_PR(dmsg, "pin_dst failed\n"); -+ goto out; -+ } -+ -+ if (a->mvd_h_src_sb != a->mvd_h_dst_sb) { -+ a->rename_lock = 0; -+ au_pin_init(&a->mvd_pin_src, a->dentry, a->mvd_bsrc, -+ AuLsc_DI_PARENT, AuLsc_I_PARENT3, -+ au_opt_udba(a->sb), -+ AuPin_MNT_WRITE | AuPin_DI_LOCKED); -+ err = au_do_pin(&a->mvd_pin_src); -+ AuTraceErr(err); -+ 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; -+ } -+ goto out; /* success */ -+ } -+ -+ a->rename_lock = 1; -+ au_pin_hdir_unlock(&a->mvd_pin_dst); -+ err = au_pin(&a->mvd_pin_src, a->dentry, a->mvd_bsrc, -+ au_opt_udba(a->sb), -+ AuPin_MNT_WRITE | AuPin_DI_LOCKED); -+ AuTraceErr(err); -+ 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); -+ goto out_dst; -+ } -+ au_pin_hdir_unlock(&a->mvd_pin_src); -+ h_trap = vfsub_lock_rename(a->mvd_h_src_parent, a->mvd_hdir_src, -+ a->mvd_h_dst_parent, a->mvd_hdir_dst); -+ if (h_trap) { -+ err = (h_trap != a->mvd_h_src_parent); -+ if (err) -+ err = (h_trap != a->mvd_h_dst_parent); -+ } -+ BUG_ON(err); /* it should never happen */ -+ if (unlikely(a->mvd_h_src_dir != au_pinned_h_dir(&a->mvd_pin_src))) { -+ err = -EBUSY; -+ AuTraceErr(err); -+ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src, -+ a->mvd_h_dst_parent, a->mvd_hdir_dst); -+ au_pin_hdir_lock(&a->mvd_pin_src); -+ au_unpin(&a->mvd_pin_src); -+ au_pin_hdir_lock(&a->mvd_pin_dst); -+ goto out_dst; -+ } -+ goto out; /* success */ -+ -+out_dst: -+ au_unpin(&a->mvd_pin_dst); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static void au_do_unlock(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ if (!a->rename_lock) -+ au_unpin(&a->mvd_pin_src); -+ else { -+ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src, -+ a->mvd_h_dst_parent, a->mvd_hdir_dst); -+ au_pin_hdir_lock(&a->mvd_pin_src); -+ au_unpin(&a->mvd_pin_src); -+ au_pin_hdir_lock(&a->mvd_pin_dst); -+ } -+ au_unpin(&a->mvd_pin_dst); -+} -+ -+/* copy-down the file */ -+static int au_do_cpdown(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ int err; -+ struct au_cp_generic cpg = { -+ .dentry = a->dentry, -+ .bdst = a->mvd_bdst, -+ .bsrc = a->mvd_bsrc, -+ .len = -1, -+ .pin = &a->mvd_pin_dst, -+ .flags = AuCpup_DTIME | AuCpup_HOPEN -+ }; -+ -+ AuDbg("b%d, b%d\n", cpg.bsrc, cpg.bdst); -+ if (a->mvdown.flags & AUFS_MVDOWN_OWLOWER) -+ au_fset_cpup(cpg.flags, OVERWRITE); -+ if (a->mvdown.flags & AUFS_MVDOWN_ROLOWER) -+ au_fset_cpup(cpg.flags, RWDST); -+ err = au_sio_cpdown_simple(&cpg); -+ if (unlikely(err)) -+ AU_MVD_PR(dmsg, "cpdown failed\n"); -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+/* -+ * unlink the whiteout on bdst if exist which may be created by UDBA while we -+ * were sleeping -+ */ -+static int au_do_unlink_wh(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ int err; -+ struct path h_path; -+ struct au_branch *br; -+ struct inode *delegated; -+ -+ br = au_sbr(a->sb, a->mvd_bdst); -+ h_path.dentry = au_wh_lkup(a->mvd_h_dst_parent, &a->dentry->d_name, br); -+ err = PTR_ERR(h_path.dentry); -+ if (IS_ERR(h_path.dentry)) { -+ AU_MVD_PR(dmsg, "wh_lkup failed\n"); -+ goto out; -+ } -+ -+ err = 0; -+ if (d_is_positive(h_path.dentry)) { -+ h_path.mnt = au_br_mnt(br); -+ delegated = NULL; -+ 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" -+ " for an internal unlink\n"); -+ iput(delegated); -+ } -+ if (unlikely(err)) -+ AU_MVD_PR(dmsg, "wh_unlink failed\n"); -+ } -+ dput(h_path.dentry); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* -+ * unlink the topmost h_dentry -+ */ -+static int au_do_unlink(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ int err; -+ struct path h_path; -+ struct inode *delegated; -+ -+ h_path.mnt = au_sbr_mnt(a->sb, a->mvd_bsrc); -+ h_path.dentry = au_h_dptr(a->dentry, a->mvd_bsrc); -+ delegated = NULL; -+ err = vfsub_unlink(a->mvd_h_src_dir, &h_path, &delegated, /*force*/0); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal unlink\n"); -+ iput(delegated); -+ } -+ if (unlikely(err)) -+ AU_MVD_PR(dmsg, "unlink failed\n"); -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+/* Since mvdown succeeded, we ignore an error of this function */ -+static void au_do_stfs(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ int err; -+ struct au_branch *br; -+ -+ a->mvdown.flags |= AUFS_MVDOWN_STFS_FAILED; -+ br = au_sbr(a->sb, a->mvd_bsrc); -+ err = au_br_stfs(br, &a->mvdown.stbr[AUFS_MVDOWN_UPPER].stfs); -+ if (!err) { -+ br = au_sbr(a->sb, a->mvd_bdst); -+ a->mvdown.stbr[AUFS_MVDOWN_LOWER].brid = br->br_id; -+ err = au_br_stfs(br, &a->mvdown.stbr[AUFS_MVDOWN_LOWER].stfs); -+ } -+ if (!err) -+ a->mvdown.flags &= ~AUFS_MVDOWN_STFS_FAILED; -+ else -+ AU_MVD_PR(dmsg, "statfs failed (%d), ignored\n", err); -+} -+ -+/* -+ * copy-down the file and unlink the bsrc file. -+ * - unlink the bdst whout if exist -+ * - copy-down the file (with whtmp name and rename) -+ * - unlink the bsrc file -+ */ -+static int au_do_mvdown(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ int err; -+ -+ err = au_do_mkdir(dmsg, a); -+ if (!err) -+ err = au_do_lock(dmsg, a); -+ if (unlikely(err)) -+ goto out; -+ -+ /* -+ * do not revert the activities we made on bdst since they should be -+ * harmless in aufs. -+ */ -+ -+ err = au_do_cpdown(dmsg, a); -+ if (!err) -+ err = au_do_unlink_wh(dmsg, a); -+ if (!err && !(a->mvdown.flags & AUFS_MVDOWN_KUPPER)) -+ err = au_do_unlink(dmsg, a); -+ if (unlikely(err)) -+ goto out_unlock; -+ -+ AuDbg("%pd2, 0x%x, %d --> %d\n", -+ a->dentry, a->mvdown.flags, a->mvd_bsrc, a->mvd_bdst); -+ if (find_lower_writable(a) < 0) -+ a->mvdown.flags |= AUFS_MVDOWN_BOTTOM; -+ -+ if (a->mvdown.flags & AUFS_MVDOWN_STFS) -+ au_do_stfs(dmsg, a); -+ -+ /* maintain internal array */ -+ if (!(a->mvdown.flags & AUFS_MVDOWN_KUPPER)) { -+ au_set_h_dptr(a->dentry, a->mvd_bsrc, NULL); -+ au_set_dbtop(a->dentry, a->mvd_bdst); -+ au_set_h_iptr(a->inode, a->mvd_bsrc, NULL, /*flags*/0); -+ au_set_ibtop(a->inode, a->mvd_bdst); -+ } else { -+ /* hide the lower */ -+ au_set_h_dptr(a->dentry, a->mvd_bdst, NULL); -+ au_set_dbbot(a->dentry, a->mvd_bsrc); -+ au_set_h_iptr(a->inode, a->mvd_bdst, NULL, /*flags*/0); -+ au_set_ibbot(a->inode, a->mvd_bsrc); -+ } -+ if (au_dbbot(a->dentry) < a->mvd_bdst) -+ au_set_dbbot(a->dentry, a->mvd_bdst); -+ if (au_ibbot(a->inode) < a->mvd_bdst) -+ au_set_ibbot(a->inode, a->mvd_bdst); -+ -+out_unlock: -+ au_do_unlock(dmsg, a); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* make sure the file is idle */ -+static int au_mvd_args_busy(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ int err, plinked; -+ -+ err = 0; -+ plinked = !!au_opt_test(au_mntflags(a->sb), PLINK); -+ if (au_dbtop(a->dentry) == a->mvd_bsrc -+ && au_dcount(a->dentry) == 1 -+ && atomic_read(&a->inode->i_count) == 1 -+ /* && a->mvd_h_src_inode->i_nlink == 1 */ -+ && (!plinked || !au_plink_test(a->inode)) -+ && vfsub_inode_nlink(a->inode, AU_I_AUFS) == 1) -+ goto out; -+ -+ err = -EBUSY; -+ AU_MVD_PR(dmsg, -+ "b%d, d{b%d, c%d?}, i{c%d?, l%u}, hi{l%u}, p{%d, %d}\n", -+ a->mvd_bsrc, au_dbtop(a->dentry), au_dcount(a->dentry), -+ atomic_read(&a->inode->i_count), -+ vfsub_inode_nlink(a->inode, AU_I_AUFS), -+ vfsub_inode_nlink(a->mvd_h_src_inode, AU_I_BRANCH), -+ plinked, plinked ? au_plink_test(a->inode) : 0); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* make sure the parent dir is fine */ -+static int au_mvd_args_parent(const unsigned char dmsg, -+ struct au_mvd_args *a) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ -+ err = 0; -+ if (unlikely(au_alive_dir(a->parent))) { -+ err = -ENOENT; -+ AU_MVD_PR(dmsg, "parent dir is dead\n"); -+ goto out; -+ } -+ -+ a->bopq = au_dbdiropq(a->parent); -+ bindex = au_wbr_nonopq(a->dentry, a->mvd_bdst); -+ AuDbg("b%d\n", bindex); -+ if (unlikely((bindex >= 0 && bindex < a->mvd_bdst) -+ || (a->bopq != -1 && a->bopq < a->mvd_bdst))) { -+ err = -EINVAL; -+ a->mvd_errno = EAU_MVDOWN_OPAQUE; -+ AU_MVD_PR(dmsg, "ancestor is opaque b%d, b%d\n", -+ a->bopq, a->mvd_bdst); -+ } -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_mvd_args_intermediate(const unsigned char dmsg, -+ struct au_mvd_args *a) -+{ -+ int err; -+ struct au_dinfo *dinfo, *tmp; -+ -+ /* lookup the next lower positive entry */ -+ err = -ENOMEM; -+ tmp = au_di_alloc(a->sb, AuLsc_DI_TMP); -+ if (unlikely(!tmp)) -+ goto out; -+ -+ a->bfound = -1; -+ a->bwh = -1; -+ dinfo = au_di(a->dentry); -+ au_di_cp(tmp, dinfo); -+ au_di_swap(tmp, dinfo); -+ -+ /* returns the number of positive dentries */ -+ err = au_lkup_dentry(a->dentry, a->mvd_bsrc + 1, -+ /* AuLkup_IGNORE_PERM */ 0); -+ if (!err) -+ a->bwh = au_dbwh(a->dentry); -+ else if (err > 0) -+ a->bfound = au_dbtop(a->dentry); -+ -+ au_di_swap(tmp, dinfo); -+ au_rw_write_unlock(&tmp->di_rwsem); -+ au_di_free(tmp); -+ if (unlikely(err < 0)) -+ AU_MVD_PR(dmsg, "failed look-up lower\n"); -+ -+ /* -+ * here, we have these cases. -+ * bfound == -1 -+ * no positive dentry under bsrc. there are more sub-cases. -+ * bwh < 0 -+ * there no whiteout, we can safely move-down. -+ * bwh <= bsrc -+ * impossible -+ * bsrc < bwh && bwh < bdst -+ * there is a whiteout on RO branch. cannot proceed. -+ * bwh == bdst -+ * there is a whiteout on the RW target branch. it should -+ * be removed. -+ * bdst < bwh -+ * there is a whiteout somewhere unrelated branch. -+ * -1 < bfound && bfound <= bsrc -+ * impossible. -+ * bfound < bdst -+ * found, but it is on RO branch between bsrc and bdst. cannot -+ * proceed. -+ * bfound == bdst -+ * found, replace it if AUFS_MVDOWN_FORCE is set. otherwise return -+ * error. -+ * bdst < bfound -+ * found, after we create the file on bdst, it will be hidden. -+ */ -+ -+ AuDebugOn(a->bfound == -1 -+ && a->bwh != -1 -+ && a->bwh <= a->mvd_bsrc); -+ AuDebugOn(-1 < a->bfound -+ && a->bfound <= a->mvd_bsrc); -+ -+ err = -EINVAL; -+ if (a->bfound == -1 -+ && a->mvd_bsrc < a->bwh -+ && a->bwh != -1 -+ && a->bwh < a->mvd_bdst) { -+ a->mvd_errno = EAU_MVDOWN_WHITEOUT; -+ AU_MVD_PR(dmsg, "bsrc %d, bdst %d, bfound %d, bwh %d\n", -+ a->mvd_bsrc, a->mvd_bdst, a->bfound, a->bwh); -+ goto out; -+ } else if (a->bfound != -1 && a->bfound < a->mvd_bdst) { -+ a->mvd_errno = EAU_MVDOWN_UPPER; -+ AU_MVD_PR(dmsg, "bdst %d, bfound %d\n", -+ a->mvd_bdst, a->bfound); -+ goto out; -+ } -+ -+ err = 0; /* success */ -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_mvd_args_exist(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ int err; -+ -+ err = 0; -+ if (!(a->mvdown.flags & AUFS_MVDOWN_OWLOWER) -+ && a->bfound == a->mvd_bdst) -+ err = -EEXIST; -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_mvd_args(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ int err; -+ struct au_branch *br; -+ -+ err = -EISDIR; -+ if (unlikely(S_ISDIR(a->inode->i_mode))) -+ goto out; -+ -+ err = -EINVAL; -+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_UPPER)) -+ a->mvd_bsrc = au_ibtop(a->inode); -+ else { -+ a->mvd_bsrc = au_br_index(a->sb, a->mvd_src_brid); -+ if (unlikely(a->mvd_bsrc < 0 -+ || (a->mvd_bsrc < au_dbtop(a->dentry) -+ || au_dbbot(a->dentry) < a->mvd_bsrc -+ || !au_h_dptr(a->dentry, a->mvd_bsrc)) -+ || (a->mvd_bsrc < au_ibtop(a->inode) -+ || au_ibbot(a->inode) < a->mvd_bsrc -+ || !au_h_iptr(a->inode, a->mvd_bsrc)))) { -+ a->mvd_errno = EAU_MVDOWN_NOUPPER; -+ AU_MVD_PR(dmsg, "no upper\n"); -+ goto out; -+ } -+ } -+ if (unlikely(a->mvd_bsrc == au_sbbot(a->sb))) { -+ a->mvd_errno = EAU_MVDOWN_BOTTOM; -+ AU_MVD_PR(dmsg, "on the bottom\n"); -+ goto out; -+ } -+ a->mvd_h_src_inode = au_h_iptr(a->inode, a->mvd_bsrc); -+ br = au_sbr(a->sb, a->mvd_bsrc); -+ err = au_br_rdonly(br); -+ if (!(a->mvdown.flags & AUFS_MVDOWN_ROUPPER)) { -+ if (unlikely(err)) -+ goto out; -+ } else if (!(vfsub_native_ro(a->mvd_h_src_inode) -+ || IS_APPEND(a->mvd_h_src_inode))) { -+ if (err) -+ a->mvdown.flags |= AUFS_MVDOWN_ROUPPER_R; -+ /* go on */ -+ } else -+ goto out; -+ -+ err = -EINVAL; -+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_LOWER)) { -+ a->mvd_bdst = find_lower_writable(a); -+ if (unlikely(a->mvd_bdst < 0)) { -+ a->mvd_errno = EAU_MVDOWN_BOTTOM; -+ AU_MVD_PR(dmsg, "no writable lower branch\n"); -+ goto out; -+ } -+ } else { -+ a->mvd_bdst = au_br_index(a->sb, a->mvd_dst_brid); -+ if (unlikely(a->mvd_bdst < 0 -+ || au_sbbot(a->sb) < a->mvd_bdst)) { -+ a->mvd_errno = EAU_MVDOWN_NOLOWERBR; -+ AU_MVD_PR(dmsg, "no lower brid\n"); -+ goto out; -+ } -+ } -+ -+ err = au_mvd_args_busy(dmsg, a); -+ if (!err) -+ err = au_mvd_args_parent(dmsg, a); -+ if (!err) -+ err = au_mvd_args_intermediate(dmsg, a); -+ if (!err) -+ err = au_mvd_args_exist(dmsg, a); -+ if (!err) -+ AuDbg("b%d, b%d\n", a->mvd_bsrc, a->mvd_bdst); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *uarg) -+{ -+ int err, e; -+ unsigned char dmsg; -+ struct au_mvd_args *args; -+ struct inode *inode; -+ -+ inode = d_inode(dentry); -+ err = -EPERM; -+ if (unlikely(!capable(CAP_SYS_ADMIN))) -+ goto out; -+ -+ err = -ENOMEM; -+ args = kmalloc(sizeof(*args), GFP_NOFS); -+ if (unlikely(!args)) -+ goto out; -+ -+ err = copy_from_user(&args->mvdown, uarg, sizeof(args->mvdown)); -+ if (!err) -+ /* VERIFY_WRITE */ -+ err = !access_ok(uarg, sizeof(*uarg)); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ AuTraceErr(err); -+ goto out_free; -+ } -+ AuDbg("flags 0x%x\n", args->mvdown.flags); -+ args->mvdown.flags &= ~(AUFS_MVDOWN_ROLOWER_R | AUFS_MVDOWN_ROUPPER_R); -+ args->mvdown.au_errno = 0; -+ args->dentry = dentry; -+ args->inode = inode; -+ args->sb = dentry->d_sb; -+ -+ err = -ENOENT; -+ dmsg = !!(args->mvdown.flags & AUFS_MVDOWN_DMSG); -+ args->parent = dget_parent(dentry); -+ args->dir = d_inode(args->parent); -+ inode_lock_nested(args->dir, I_MUTEX_PARENT); -+ dput(args->parent); -+ if (unlikely(args->parent != dentry->d_parent)) { -+ AU_MVD_PR(dmsg, "parent dir is moved\n"); -+ goto out_dir; -+ } -+ -+ inode_lock_nested(inode, I_MUTEX_CHILD); -+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_NOPLMW); -+ if (unlikely(err)) -+ goto out_inode; -+ -+ di_write_lock_parent(args->parent); -+ err = au_mvd_args(dmsg, args); -+ if (unlikely(err)) -+ goto out_parent; -+ -+ err = au_do_mvdown(dmsg, args); -+ if (unlikely(err)) -+ goto out_parent; -+ -+ au_cpup_attr_timesizes(args->dir); -+ au_cpup_attr_timesizes(inode); -+ if (!(args->mvdown.flags & AUFS_MVDOWN_KUPPER)) -+ au_cpup_igen(inode, au_h_iptr(inode, args->mvd_bdst)); -+ /* au_digen_dec(dentry); */ -+ -+out_parent: -+ di_write_unlock(args->parent); -+ aufs_read_unlock(dentry, AuLock_DW); -+out_inode: -+ inode_unlock(inode); -+out_dir: -+ inode_unlock(args->dir); -+out_free: -+ e = copy_to_user(uarg, &args->mvdown, sizeof(args->mvdown)); -+ if (unlikely(e)) -+ err = -EFAULT; -+ au_kfree_rcu(args); -+out: -+ AuTraceErr(err); -+ return err; -+} -diff -Naur null/fs/aufs/opts.c linux-6.6.63/fs/aufs/opts.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/opts.c 2024-12-18 15:12:59.298519551 +0300 -@@ -0,0 +1,1032 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * mount options/flags -+ */ -+ -+#include /* a distribution requires */ -+#include -+#include "aufs.h" -+ -+/* ---------------------------------------------------------------------- */ -+ -+static const char *au_parser_pattern(int val, match_table_t tbl) -+{ -+ struct match_token *p; -+ -+ p = tbl; -+ while (p->pattern) { -+ if (p->token == val) -+ return p->pattern; -+ p++; -+ } -+ BUG(); -+ return "??"; -+} -+ -+static const char *au_optstr(int *val, match_table_t tbl) -+{ -+ struct match_token *p; -+ int v; -+ -+ v = *val; -+ if (!v) -+ goto out; -+ p = tbl; -+ while (p->pattern) { -+ if (p->token -+ && (v & p->token) == p->token) { -+ *val &= ~p->token; -+ return p->pattern; -+ } -+ p++; -+ } -+ -+out: -+ return NULL; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static match_table_t brperm = { -+ {AuBrPerm_RO, AUFS_BRPERM_RO}, -+ {AuBrPerm_RR, AUFS_BRPERM_RR}, -+ {AuBrPerm_RW, AUFS_BRPERM_RW}, -+ {0, NULL} -+}; -+ -+static match_table_t brattr = { -+ /* general */ -+ {AuBrAttr_COO_REG, AUFS_BRATTR_COO_REG}, -+ {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}, -+ -+ /* rw branch */ -+ {AuBrWAttr_MOO, AUFS_BRWATTR_MOO}, -+ {AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH}, -+ -+ {0, NULL} -+}; -+ -+static int br_attr_val(char *str, match_table_t table, substring_t args[]) -+{ -+ int attr, v; -+ char *p; -+ -+ attr = 0; -+ do { -+ p = strchr(str, '+'); -+ if (p) -+ *p = 0; -+ v = match_token(str, table, args); -+ if (v) { -+ if (v & AuBrAttr_CMOO_Mask) -+ attr &= ~AuBrAttr_CMOO_Mask; -+ attr |= v; -+ } else { -+ if (p) -+ *p = '+'; -+ pr_warn("ignored branch attribute %s\n", str); -+ break; -+ } -+ if (p) -+ str = p + 1; -+ } while (p); -+ -+ return attr; -+} -+ -+static int au_do_optstr_br_attr(au_br_perm_str_t *str, int perm) -+{ -+ int sz; -+ const char *p; -+ char *q; -+ -+ q = str->a; -+ *q = 0; -+ p = au_optstr(&perm, brattr); -+ if (p) { -+ sz = strlen(p); -+ memcpy(q, p, sz + 1); -+ q += sz; -+ } else -+ goto out; -+ -+ do { -+ p = au_optstr(&perm, brattr); -+ if (p) { -+ *q++ = '+'; -+ sz = strlen(p); -+ memcpy(q, p, sz + 1); -+ q += sz; -+ } -+ } while (p); -+ -+out: -+ return q - str->a; -+} -+ -+int au_br_perm_val(char *perm) -+{ -+ int val, bad, sz; -+ char *p; -+ substring_t args[MAX_OPT_ARGS]; -+ au_br_perm_str_t attr; -+ -+ p = strchr(perm, '+'); -+ if (p) -+ *p = 0; -+ val = match_token(perm, brperm, args); -+ if (!val) { -+ if (p) -+ *p = '+'; -+ pr_warn("ignored branch permission %s\n", perm); -+ val = AuBrPerm_RO; -+ goto out; -+ } -+ if (!p) -+ goto out; -+ -+ val |= br_attr_val(p + 1, brattr, args); -+ -+ bad = 0; -+ switch (val & AuBrPerm_Mask) { -+ case AuBrPerm_RO: -+ case AuBrPerm_RR: -+ bad = val & AuBrWAttr_Mask; -+ val &= ~AuBrWAttr_Mask; -+ break; -+ case AuBrPerm_RW: -+ bad = val & AuBrRAttr_Mask; -+ val &= ~AuBrRAttr_Mask; -+ break; -+ } -+ -+ /* -+ * 'unpin' attrib becomes meaningless since linux-3.18-rc1, but aufs -+ * does not treat it as an error, just warning. -+ * this is a tiny guard for the user operation. -+ */ -+ if (val & AuBrAttr_UNPIN) { -+ bad |= AuBrAttr_UNPIN; -+ val &= ~AuBrAttr_UNPIN; -+ } -+ -+ if (unlikely(bad)) { -+ sz = au_do_optstr_br_attr(&attr, bad); -+ AuDebugOn(!sz); -+ pr_warn("ignored branch attribute %s\n", attr.a); -+ } -+ -+out: -+ return val; -+} -+ -+void au_optstr_br_perm(au_br_perm_str_t *str, int perm) -+{ -+ au_br_perm_str_t attr; -+ const char *p; -+ char *q; -+ int sz; -+ -+ q = str->a; -+ p = au_optstr(&perm, brperm); -+ AuDebugOn(!p || !*p); -+ sz = strlen(p); -+ memcpy(q, p, sz + 1); -+ q += sz; -+ -+ sz = au_do_optstr_br_attr(&attr, perm); -+ if (sz) { -+ *q++ = '+'; -+ memcpy(q, attr.a, sz + 1); -+ } -+ -+ AuDebugOn(strlen(str->a) >= sizeof(str->a)); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static match_table_t udbalevel = { -+ {AuOpt_UDBA_REVAL, "reval"}, -+ {AuOpt_UDBA_NONE, "none"}, -+#ifdef CONFIG_AUFS_HNOTIFY -+ {AuOpt_UDBA_HNOTIFY, "notify"}, /* abstraction */ -+#ifdef CONFIG_AUFS_HFSNOTIFY -+ {AuOpt_UDBA_HNOTIFY, "fsnotify"}, -+#endif -+#endif -+ {-1, NULL} -+}; -+ -+int au_udba_val(char *str) -+{ -+ substring_t args[MAX_OPT_ARGS]; -+ -+ return match_token(str, udbalevel, args); -+} -+ -+const char *au_optstr_udba(int udba) -+{ -+ return au_parser_pattern(udba, udbalevel); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static match_table_t au_wbr_create_policy = { -+ {AuWbrCreate_TDP, "tdp"}, -+ {AuWbrCreate_TDP, "top-down-parent"}, -+ {AuWbrCreate_RR, "rr"}, -+ {AuWbrCreate_RR, "round-robin"}, -+ {AuWbrCreate_MFS, "mfs"}, -+ {AuWbrCreate_MFS, "most-free-space"}, -+ {AuWbrCreate_MFSV, "mfs:%d"}, -+ {AuWbrCreate_MFSV, "most-free-space:%d"}, -+ -+ /* top-down regardless the parent, and then mfs */ -+ {AuWbrCreate_TDMFS, "tdmfs:%d"}, -+ {AuWbrCreate_TDMFSV, "tdmfs:%d:%d"}, -+ -+ {AuWbrCreate_MFSRR, "mfsrr:%d"}, -+ {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"}, -+ {AuWbrCreate_PMFS, "pmfs"}, -+ {AuWbrCreate_PMFSV, "pmfs:%d"}, -+ {AuWbrCreate_PMFSRR, "pmfsrr:%d"}, -+ {AuWbrCreate_PMFSRRV, "pmfsrr:%d:%d"}, -+ -+ {-1, NULL} -+}; -+ -+static int au_wbr_mfs_wmark(substring_t *arg, char *str, -+ struct au_opt_wbr_create *create) -+{ -+ int err; -+ unsigned long long ull; -+ -+ err = 0; -+ if (!match_u64(arg, &ull)) -+ create->mfsrr_watermark = ull; -+ else { -+ pr_err("bad integer in %s\n", str); -+ err = -EINVAL; -+ } -+ -+ return err; -+} -+ -+static int au_wbr_mfs_sec(substring_t *arg, char *str, -+ struct au_opt_wbr_create *create) -+{ -+ int n, err; -+ -+ err = 0; -+ if (!match_int(arg, &n) && 0 <= n && n <= AUFS_MFS_MAX_SEC) -+ create->mfs_second = n; -+ else { -+ pr_err("bad integer in %s\n", str); -+ err = -EINVAL; -+ } -+ -+ return err; -+} -+ -+int au_wbr_create_val(char *str, struct au_opt_wbr_create *create) -+{ -+ int err, e; -+ substring_t args[MAX_OPT_ARGS]; -+ -+ err = match_token(str, au_wbr_create_policy, args); -+ create->wbr_create = err; -+ switch (err) { -+ case AuWbrCreate_MFSRRV: -+ case AuWbrCreate_TDMFSV: -+ case AuWbrCreate_PMFSRRV: -+ e = au_wbr_mfs_wmark(&args[0], str, create); -+ if (!e) -+ e = au_wbr_mfs_sec(&args[1], str, create); -+ if (unlikely(e)) -+ err = e; -+ break; -+ case AuWbrCreate_MFSRR: -+ case AuWbrCreate_TDMFS: -+ case AuWbrCreate_PMFSRR: -+ e = au_wbr_mfs_wmark(&args[0], str, create); -+ if (unlikely(e)) { -+ err = e; -+ break; -+ } -+ fallthrough; -+ case AuWbrCreate_MFS: -+ case AuWbrCreate_PMFS: -+ create->mfs_second = AUFS_MFS_DEF_SEC; -+ break; -+ case AuWbrCreate_MFSV: -+ case AuWbrCreate_PMFSV: -+ e = au_wbr_mfs_sec(&args[0], str, create); -+ if (unlikely(e)) -+ err = e; -+ break; -+ } -+ -+ return err; -+} -+ -+const char *au_optstr_wbr_create(int wbr_create) -+{ -+ return au_parser_pattern(wbr_create, au_wbr_create_policy); -+} -+ -+static match_table_t au_wbr_copyup_policy = { -+ {AuWbrCopyup_TDP, "tdp"}, -+ {AuWbrCopyup_TDP, "top-down-parent"}, -+ {AuWbrCopyup_BUP, "bup"}, -+ {AuWbrCopyup_BUP, "bottom-up-parent"}, -+ {AuWbrCopyup_BU, "bu"}, -+ {AuWbrCopyup_BU, "bottom-up"}, -+ {-1, NULL} -+}; -+ -+int au_wbr_copyup_val(char *str) -+{ -+ substring_t args[MAX_OPT_ARGS]; -+ -+ return match_token(str, au_wbr_copyup_policy, args); -+} -+ -+const char *au_optstr_wbr_copyup(int wbr_copyup) -+{ -+ return au_parser_pattern(wbr_copyup, au_wbr_copyup_policy); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags, -+ aufs_bindex_t bindex) -+{ -+ int err; -+ struct au_opt_add *add = &opt->add; -+ char *p; -+ -+ add->bindex = bindex; -+ add->perm = AuBrPerm_RO; -+ add->pathname = opt_str; -+ p = strchr(opt_str, '='); -+ if (p) { -+ *p++ = 0; -+ if (*p) -+ add->perm = au_br_perm_val(p); -+ } -+ -+ err = vfsub_kern_path(add->pathname, AuOpt_LkupDirFlags, &add->path); -+ if (!err) { -+ if (!p) { -+ add->perm = AuBrPerm_RO; -+ if (au_test_fs_rr(add->path.dentry->d_sb)) -+ add->perm = AuBrPerm_RR; -+ else if (!bindex && !(sb_flags & SB_RDONLY)) -+ add->perm = AuBrPerm_RW; -+ } -+ opt->type = Opt_add; -+ goto out; -+ } -+ pr_err("lookup failed %s (%d)\n", add->pathname, err); -+ err = -EINVAL; -+ -+out: -+ return err; -+} -+ -+static int au_opt_wbr_create(struct super_block *sb, -+ struct au_opt_wbr_create *create) -+{ -+ int err; -+ struct au_sbinfo *sbinfo; -+ -+ SiMustWriteLock(sb); -+ -+ err = 1; /* handled */ -+ sbinfo = au_sbi(sb); -+ if (sbinfo->si_wbr_create_ops->fin) { -+ err = sbinfo->si_wbr_create_ops->fin(sb); -+ if (!err) -+ err = 1; -+ } -+ -+ sbinfo->si_wbr_create = create->wbr_create; -+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create; -+ switch (create->wbr_create) { -+ case AuWbrCreate_MFSRRV: -+ case AuWbrCreate_MFSRR: -+ case AuWbrCreate_TDMFS: -+ case AuWbrCreate_TDMFSV: -+ case AuWbrCreate_PMFSRR: -+ case AuWbrCreate_PMFSRRV: -+ sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark; -+ fallthrough; -+ case AuWbrCreate_MFS: -+ case AuWbrCreate_MFSV: -+ case AuWbrCreate_PMFS: -+ case AuWbrCreate_PMFSV: -+ sbinfo->si_wbr_mfs.mfs_expire -+ = msecs_to_jiffies(create->mfs_second * MSEC_PER_SEC); -+ break; -+ } -+ -+ if (sbinfo->si_wbr_create_ops->init) -+ sbinfo->si_wbr_create_ops->init(sb); /* ignore */ -+ -+ return err; -+} -+ -+/* -+ * returns, -+ * plus: processed without an error -+ * zero: unprocessed -+ */ -+static int au_opt_simple(struct super_block *sb, struct au_opt *opt, -+ struct au_opts *opts) -+{ -+ int err; -+ struct au_sbinfo *sbinfo; -+ -+ SiMustWriteLock(sb); -+ -+ err = 1; /* handled */ -+ sbinfo = au_sbi(sb); -+ switch (opt->type) { -+ case Opt_udba: -+ sbinfo->si_mntflags &= ~AuOptMask_UDBA; -+ sbinfo->si_mntflags |= opt->udba; -+ opts->given_udba |= opt->udba; -+ break; -+ -+ case Opt_plink: -+ if (opt->tf) -+ au_opt_set(sbinfo->si_mntflags, PLINK); -+ else { -+ if (au_opt_test(sbinfo->si_mntflags, PLINK)) -+ au_plink_put(sb, /*verbose*/1); -+ au_opt_clr(sbinfo->si_mntflags, PLINK); -+ } -+ break; -+ case Opt_list_plink: -+ if (au_opt_test(sbinfo->si_mntflags, PLINK)) -+ au_plink_list(sb); -+ break; -+ -+ case Opt_dio: -+ if (opt->tf) { -+ au_opt_set(sbinfo->si_mntflags, DIO); -+ au_fset_opts(opts->flags, REFRESH_DYAOP); -+ } else { -+ au_opt_clr(sbinfo->si_mntflags, DIO); -+ au_fset_opts(opts->flags, REFRESH_DYAOP); -+ } -+ break; -+ -+ case Opt_fhsm_sec: -+ au_fhsm_set(sbinfo, opt->fhsm_second); -+ break; -+ -+ case Opt_diropq_a: -+ au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ); -+ break; -+ case Opt_diropq_w: -+ au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ); -+ break; -+ -+ case Opt_warn_perm: -+ if (opt->tf) -+ au_opt_set(sbinfo->si_mntflags, WARN_PERM); -+ else -+ au_opt_clr(sbinfo->si_mntflags, WARN_PERM); -+ break; -+ -+ case Opt_verbose: -+ if (opt->tf) -+ au_opt_set(sbinfo->si_mntflags, VERBOSE); -+ else -+ au_opt_clr(sbinfo->si_mntflags, VERBOSE); -+ break; -+ -+ case Opt_sum: -+ if (opt->tf) -+ au_opt_set(sbinfo->si_mntflags, SUM); -+ else { -+ au_opt_clr(sbinfo->si_mntflags, SUM); -+ au_opt_clr(sbinfo->si_mntflags, SUM_W); -+ } -+ break; -+ case Opt_wsum: -+ au_opt_clr(sbinfo->si_mntflags, SUM); -+ au_opt_set(sbinfo->si_mntflags, SUM_W); -+ break; -+ -+ case Opt_wbr_create: -+ err = au_opt_wbr_create(sb, &opt->wbr_create); -+ break; -+ case Opt_wbr_copyup: -+ sbinfo->si_wbr_copyup = opt->wbr_copyup; -+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup; -+ break; -+ -+ case Opt_dirwh: -+ sbinfo->si_dirwh = opt->dirwh; -+ break; -+ -+ case Opt_rdcache: -+ sbinfo->si_rdcache -+ = msecs_to_jiffies(opt->rdcache * MSEC_PER_SEC); -+ break; -+ case Opt_rdblk: -+ sbinfo->si_rdblk = opt->rdblk; -+ break; -+ case Opt_rdhash: -+ sbinfo->si_rdhash = opt->rdhash; -+ break; -+ -+ case Opt_shwh: -+ if (opt->tf) -+ au_opt_set(sbinfo->si_mntflags, SHWH); -+ else -+ au_opt_clr(sbinfo->si_mntflags, SHWH); -+ break; -+ -+ case Opt_dirperm1: -+ if (opt->tf) -+ au_opt_set(sbinfo->si_mntflags, DIRPERM1); -+ else -+ au_opt_clr(sbinfo->si_mntflags, DIRPERM1); -+ break; -+ -+ case Opt_trunc_xino: -+ if (opt->tf) -+ au_opt_set(sbinfo->si_mntflags, TRUNC_XINO); -+ else -+ au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO); -+ break; -+ -+ case Opt_trunc_xino_path: -+ case Opt_itrunc_xino: -+ err = au_xino_trunc(sb, opt->xino_itrunc.bindex, -+ /*idx_begin*/0); -+ if (!err) -+ err = 1; -+ break; -+ -+ case Opt_trunc_xib: -+ if (opt->tf) -+ au_fset_opts(opts->flags, TRUNC_XIB); -+ else -+ au_fclr_opts(opts->flags, TRUNC_XIB); -+ break; -+ -+ case Opt_dirren: -+ err = 1; -+ if (opt->tf) { -+ if (!au_opt_test(sbinfo->si_mntflags, DIRREN)) { -+ err = au_dr_opt_set(sb); -+ if (!err) -+ err = 1; -+ } -+ if (err == 1) -+ au_opt_set(sbinfo->si_mntflags, DIRREN); -+ } else { -+ if (au_opt_test(sbinfo->si_mntflags, DIRREN)) { -+ err = au_dr_opt_clr(sb, au_ftest_opts(opts->flags, -+ DR_FLUSHED)); -+ if (!err) -+ err = 1; -+ } -+ if (err == 1) -+ au_opt_clr(sbinfo->si_mntflags, DIRREN); -+ } -+ break; -+ -+ case Opt_acl: -+ if (opt->tf) -+ sb->s_flags |= SB_POSIXACL; -+ else -+ sb->s_flags &= ~SB_POSIXACL; -+ break; -+ -+ default: -+ err = 0; -+ break; -+ } -+ -+ return err; -+} -+ -+/* -+ * returns tri-state. -+ * plus: processed without an error -+ * zero: unprocessed -+ * minus: error -+ */ -+static int au_opt_br(struct super_block *sb, struct au_opt *opt, -+ struct au_opts *opts) -+{ -+ int err, do_refresh; -+ -+ err = 0; -+ switch (opt->type) { -+ case Opt_append: -+ opt->add.bindex = au_sbbot(sb) + 1; -+ if (opt->add.bindex < 0) -+ opt->add.bindex = 0; -+ goto add; -+ /* Always goto add, not fallthrough */ -+ case Opt_prepend: -+ opt->add.bindex = 0; -+ fallthrough; -+ case Opt_add: -+ add: /* indented label */ -+ err = au_br_add(sb, &opt->add, -+ au_ftest_opts(opts->flags, REMOUNT)); -+ if (!err) { -+ err = 1; -+ au_fset_opts(opts->flags, REFRESH); -+ } -+ break; -+ -+ case Opt_del: -+ case Opt_idel: -+ err = au_br_del(sb, &opt->del, -+ au_ftest_opts(opts->flags, REMOUNT)); -+ if (!err) { -+ err = 1; -+ au_fset_opts(opts->flags, TRUNC_XIB); -+ au_fset_opts(opts->flags, REFRESH); -+ } -+ break; -+ -+ case Opt_mod: -+ case Opt_imod: -+ err = au_br_mod(sb, &opt->mod, -+ au_ftest_opts(opts->flags, REMOUNT), -+ &do_refresh); -+ if (!err) { -+ err = 1; -+ if (do_refresh) -+ au_fset_opts(opts->flags, REFRESH); -+ } -+ break; -+ } -+ return err; -+} -+ -+static int au_opt_xino(struct super_block *sb, struct au_opt *opt, -+ struct au_opt_xino **opt_xino, -+ struct au_opts *opts) -+{ -+ int err; -+ -+ err = 0; -+ switch (opt->type) { -+ case Opt_xino: -+ err = au_xino_set(sb, &opt->xino, -+ !!au_ftest_opts(opts->flags, REMOUNT)); -+ if (!err) -+ *opt_xino = &opt->xino; -+ break; -+ case Opt_noxino: -+ au_xino_clr(sb); -+ *opt_xino = (void *)-1; -+ break; -+ } -+ -+ return err; -+} -+ -+int au_opts_verify(struct super_block *sb, unsigned long sb_flags, -+ unsigned int pending) -+{ -+ int err, fhsm; -+ aufs_bindex_t bindex, bbot; -+ unsigned char do_plink, skip, do_free, can_no_dreval; -+ struct au_branch *br; -+ struct au_wbr *wbr; -+ struct dentry *root, *dentry; -+ struct inode *dir, *h_dir; -+ struct au_sbinfo *sbinfo; -+ struct au_hinode *hdir; -+ -+ SiMustAnyLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA)); -+ -+ if (!(sb_flags & SB_RDONLY)) { -+ if (unlikely(!au_br_writable(au_sbr_perm(sb, 0)))) -+ pr_warn("first branch should be rw\n"); -+ if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH))) -+ pr_warn_once("shwh should be used with ro\n"); -+ } -+ -+ if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HNOTIFY) -+ && !au_opt_test(sbinfo->si_mntflags, XINO)) -+ pr_warn_once("udba=*notify requires xino\n"); -+ -+ if (au_opt_test(sbinfo->si_mntflags, DIRPERM1)) -+ pr_warn_once("dirperm1 breaks the protection" -+ " by the permission bits on the lower branch\n"); -+ -+ err = 0; -+ fhsm = 0; -+ root = sb->s_root; -+ dir = d_inode(root); -+ do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK); -+ can_no_dreval = !!au_opt_test((sbinfo->si_mntflags | pending), -+ UDBA_NONE); -+ bbot = au_sbbot(sb); -+ for (bindex = 0; !err && bindex <= bbot; bindex++) { -+ skip = 0; -+ h_dir = au_h_iptr(dir, bindex); -+ br = au_sbr(sb, bindex); -+ -+ if ((br->br_perm & AuBrAttr_ICEX) -+ && !h_dir->i_op->listxattr) -+ br->br_perm &= ~AuBrAttr_ICEX; -+#if 0 /* untested */ -+ if ((br->br_perm & AuBrAttr_ICEX_SEC) -+ && (au_br_sb(br)->s_flags & SB_NOSEC)) -+ br->br_perm &= ~AuBrAttr_ICEX_SEC; -+#endif -+ -+ do_free = 0; -+ wbr = br->br_wbr; -+ if (wbr) -+ wbr_wh_read_lock(wbr); -+ -+ if (!au_br_writable(br->br_perm)) { -+ do_free = !!wbr; -+ skip = (!wbr -+ || (!wbr->wbr_whbase -+ && !wbr->wbr_plink -+ && !wbr->wbr_orph)); -+ } else if (!au_br_wh_linkable(br->br_perm)) { -+ /* skip = (!br->br_whbase && !br->br_orph); */ -+ skip = (!wbr || !wbr->wbr_whbase); -+ if (skip && wbr) { -+ if (do_plink) -+ skip = !!wbr->wbr_plink; -+ else -+ skip = !wbr->wbr_plink; -+ } -+ } else { -+ /* skip = (br->br_whbase && br->br_ohph); */ -+ skip = (wbr && wbr->wbr_whbase); -+ if (skip) { -+ if (do_plink) -+ skip = !!wbr->wbr_plink; -+ else -+ skip = !wbr->wbr_plink; -+ } -+ } -+ if (wbr) -+ wbr_wh_read_unlock(wbr); -+ -+ if (can_no_dreval) { -+ dentry = br->br_path.dentry; -+ spin_lock(&dentry->d_lock); -+ if (dentry->d_flags & -+ (DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE)) -+ can_no_dreval = 0; -+ spin_unlock(&dentry->d_lock); -+ } -+ -+ if (au_br_fhsm(br->br_perm)) { -+ fhsm++; -+ AuDebugOn(!br->br_fhsm); -+ } -+ -+ if (skip) -+ continue; -+ -+ hdir = au_hi(dir, bindex); -+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT); -+ if (wbr) -+ wbr_wh_write_lock(wbr); -+ err = au_wh_init(br, sb); -+ if (wbr) -+ wbr_wh_write_unlock(wbr); -+ au_hn_inode_unlock(hdir); -+ -+ if (!err && do_free) { -+ au_kfree_rcu(wbr); -+ br->br_wbr = NULL; -+ } -+ } -+ -+ if (can_no_dreval) -+ au_fset_si(sbinfo, NO_DREVAL); -+ else -+ au_fclr_si(sbinfo, NO_DREVAL); -+ -+ if (fhsm >= 2) { -+ au_fset_si(sbinfo, FHSM); -+ for (bindex = bbot; bindex >= 0; bindex--) { -+ br = au_sbr(sb, bindex); -+ if (au_br_fhsm(br->br_perm)) { -+ au_fhsm_set_bottom(sb, bindex); -+ break; -+ } -+ } -+ } else { -+ au_fclr_si(sbinfo, FHSM); -+ au_fhsm_set_bottom(sb, -1); -+ } -+ -+ return err; -+} -+ -+int au_opts_mount(struct super_block *sb, struct au_opts *opts) -+{ -+ int err; -+ unsigned int tmp; -+ aufs_bindex_t bindex, bbot; -+ struct au_opt *opt; -+ struct au_opt_xino *opt_xino, xino; -+ struct au_sbinfo *sbinfo; -+ struct au_branch *br; -+ struct inode *dir; -+ -+ SiMustWriteLock(sb); -+ -+ err = 0; -+ opt_xino = NULL; -+ opt = opts->opt; -+ while (err >= 0 && opt->type != Opt_tail) -+ err = au_opt_simple(sb, opt++, opts); -+ if (err > 0) -+ err = 0; -+ else if (unlikely(err < 0)) -+ goto out; -+ -+ /* disable xino and udba temporary */ -+ sbinfo = au_sbi(sb); -+ tmp = sbinfo->si_mntflags; -+ au_opt_clr(sbinfo->si_mntflags, XINO); -+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL); -+ -+ opt = opts->opt; -+ while (err >= 0 && opt->type != Opt_tail) -+ err = au_opt_br(sb, opt++, opts); -+ if (err > 0) -+ err = 0; -+ else if (unlikely(err < 0)) -+ goto out; -+ -+ bbot = au_sbbot(sb); -+ if (unlikely(bbot < 0)) { -+ err = -EINVAL; -+ pr_err("no branches\n"); -+ goto out; -+ } -+ -+ if (au_opt_test(tmp, XINO)) -+ au_opt_set(sbinfo->si_mntflags, XINO); -+ opt = opts->opt; -+ while (!err && opt->type != Opt_tail) -+ err = au_opt_xino(sb, opt++, &opt_xino, opts); -+ if (unlikely(err)) -+ goto out; -+ -+ err = au_opts_verify(sb, sb->s_flags, tmp); -+ if (unlikely(err)) -+ goto out; -+ -+ /* restore xino */ -+ if (au_opt_test(tmp, XINO) && !opt_xino) { -+ xino.file = au_xino_def(sb); -+ err = PTR_ERR(xino.file); -+ if (IS_ERR(xino.file)) -+ goto out; -+ -+ err = au_xino_set(sb, &xino, /*remount*/0); -+ fput(xino.file); -+ if (unlikely(err)) -+ goto out; -+ } -+ -+ /* restore udba */ -+ tmp &= AuOptMask_UDBA; -+ sbinfo->si_mntflags &= ~AuOptMask_UDBA; -+ sbinfo->si_mntflags |= tmp; -+ bbot = au_sbbot(sb); -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ err = au_hnotify_reset_br(tmp, br, br->br_perm); -+ if (unlikely(err)) -+ AuIOErr("hnotify failed on br %d, %d, ignored\n", -+ bindex, err); -+ /* go on even if err */ -+ } -+ if (au_opt_test(tmp, UDBA_HNOTIFY)) { -+ dir = d_inode(sb->s_root); -+ au_hn_reset(dir, au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO); -+ } -+ -+out: -+ return err; -+} -+ -+int au_opts_remount(struct super_block *sb, struct au_opts *opts) -+{ -+ int err, rerr; -+ unsigned char no_dreval; -+ struct inode *dir; -+ struct au_opt_xino *opt_xino; -+ struct au_opt *opt; -+ struct au_sbinfo *sbinfo; -+ -+ SiMustWriteLock(sb); -+ -+ err = au_dr_opt_flush(sb); -+ if (unlikely(err)) -+ goto out; -+ au_fset_opts(opts->flags, DR_FLUSHED); -+ -+ dir = d_inode(sb->s_root); -+ sbinfo = au_sbi(sb); -+ opt_xino = NULL; -+ opt = opts->opt; -+ while (err >= 0 && opt->type != Opt_tail) { -+ err = au_opt_simple(sb, opt, opts); -+ if (!err) -+ err = au_opt_br(sb, opt, opts); -+ if (!err) -+ err = au_opt_xino(sb, opt, &opt_xino, opts); -+ opt++; -+ } -+ if (err > 0) -+ err = 0; -+ AuTraceErr(err); -+ /* go on even err */ -+ -+ no_dreval = !!au_ftest_si(sbinfo, NO_DREVAL); -+ rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0); -+ if (unlikely(rerr && !err)) -+ err = rerr; -+ -+ if (no_dreval != !!au_ftest_si(sbinfo, NO_DREVAL)) -+ au_fset_opts(opts->flags, REFRESH_IDOP); -+ -+ if (au_ftest_opts(opts->flags, TRUNC_XIB)) { -+ rerr = au_xib_trunc(sb); -+ if (unlikely(rerr && !err)) -+ err = rerr; -+ } -+ -+ /* will be handled by the caller */ -+ if (!au_ftest_opts(opts->flags, REFRESH) -+ && (opts->given_udba -+ || au_opt_test(sbinfo->si_mntflags, XINO) -+ || au_ftest_opts(opts->flags, REFRESH_IDOP) -+ )) -+ au_fset_opts(opts->flags, REFRESH); -+ -+ AuDbg("status 0x%x\n", opts->flags); -+ -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+unsigned int au_opt_udba(struct super_block *sb) -+{ -+ return au_mntflags(sb) & AuOptMask_UDBA; -+} -diff -Naur null/fs/aufs/opts.h linux-6.6.63/fs/aufs/opts.h ---- /dev/null -+++ linux-6.6.63/fs/aufs/opts.h 2024-12-18 15:12:59.298519551 +0300 -@@ -0,0 +1,263 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * mount options/flags -+ */ -+ -+#ifndef __AUFS_OPTS_H__ -+#define __AUFS_OPTS_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+#include -+ -+enum { -+ Opt_br, -+ Opt_add, Opt_del, Opt_mod, Opt_append, Opt_prepend, -+ Opt_idel, Opt_imod, -+ Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash, -+ Opt_xino, Opt_noxino, -+ Opt_trunc_xino, Opt_trunc_xino_v, -+ Opt_trunc_xino_path, Opt_itrunc_xino, -+ Opt_trunc_xib, -+ Opt_shwh, -+ Opt_plink, Opt_list_plink, -+ Opt_udba, -+ Opt_dio, -+ Opt_diropq, Opt_diropq_a, Opt_diropq_w, -+ Opt_warn_perm, -+ Opt_wbr_copyup, Opt_wbr_create, -+ Opt_fhsm_sec, -+ Opt_verbose, Opt_noverbose, -+ Opt_sum, Opt_wsum, -+ Opt_dirperm1, -+ Opt_dirren, -+ Opt_acl, -+ Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* mount flags */ -+#define AuOpt_XINO 1 /* external inode number bitmap -+ and translation table */ -+#define AuOpt_TRUNC_XINO (1 << 1) /* truncate xino files */ -+#define AuOpt_UDBA_NONE (1 << 2) /* users direct branch access */ -+#define AuOpt_UDBA_REVAL (1 << 3) -+#define AuOpt_UDBA_HNOTIFY (1 << 4) -+#define AuOpt_SHWH (1 << 5) /* show whiteout */ -+#define AuOpt_PLINK (1 << 6) /* pseudo-link */ -+#define AuOpt_DIRPERM1 (1 << 7) /* ignore the lower dir's perm -+ bits */ -+#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 */ -+#define AuOpt_WARN_PERM (1 << 12) /* warn when add-branch */ -+#define AuOpt_VERBOSE (1 << 13) /* print the cause of error */ -+#define AuOpt_DIO (1 << 14) /* direct io */ -+#define AuOpt_DIRREN (1 << 15) /* directory rename */ -+ -+#ifndef CONFIG_AUFS_HNOTIFY -+#undef AuOpt_UDBA_HNOTIFY -+#define AuOpt_UDBA_HNOTIFY 0 -+#endif -+#ifndef CONFIG_AUFS_DIRREN -+#undef AuOpt_DIRREN -+#define AuOpt_DIRREN 0 -+#endif -+#ifndef CONFIG_AUFS_SHWH -+#undef AuOpt_SHWH -+#define AuOpt_SHWH 0 -+#endif -+ -+#define AuOpt_Def (AuOpt_XINO \ -+ | AuOpt_UDBA_REVAL \ -+ | AuOpt_PLINK \ -+ /* | AuOpt_DIRPERM1 */ \ -+ | AuOpt_WARN_PERM) -+#define AuOptMask_UDBA (AuOpt_UDBA_NONE \ -+ | AuOpt_UDBA_REVAL \ -+ | AuOpt_UDBA_HNOTIFY) -+ -+#define AuOpt_LkupDirFlags (LOOKUP_FOLLOW | LOOKUP_DIRECTORY) -+ -+#define au_opt_test(flags, name) (flags & AuOpt_##name) -+#define au_opt_set(flags, name) do { \ -+ BUILD_BUG_ON(AuOpt_##name & AuOptMask_UDBA); \ -+ ((flags) |= AuOpt_##name); \ -+} while (0) -+#define au_opt_set_udba(flags, name) do { \ -+ (flags) &= ~AuOptMask_UDBA; \ -+ ((flags) |= AuOpt_##name); \ -+} while (0) -+#define au_opt_clr(flags, name) do { \ -+ ((flags) &= ~AuOpt_##name); \ -+} while (0) -+ -+static inline unsigned int au_opts_plink(unsigned int mntflags) -+{ -+#ifdef CONFIG_PROC_FS -+ return mntflags; -+#else -+ return mntflags & ~AuOpt_PLINK; -+#endif -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* policies to select one among multiple writable branches */ -+enum { -+ AuWbrCreate_TDP, /* top down parent */ -+ AuWbrCreate_RR, /* round robin */ -+ AuWbrCreate_MFS, /* most free space */ -+ AuWbrCreate_MFSV, /* mfs with seconds */ -+ AuWbrCreate_MFSRR, /* mfs then rr */ -+ AuWbrCreate_MFSRRV, /* mfs then rr with seconds */ -+ AuWbrCreate_TDMFS, /* top down regardless parent and mfs */ -+ AuWbrCreate_TDMFSV, /* top down regardless parent and mfs */ -+ AuWbrCreate_PMFS, /* parent and mfs */ -+ AuWbrCreate_PMFSV, /* parent and mfs with seconds */ -+ AuWbrCreate_PMFSRR, /* parent, mfs and round-robin */ -+ AuWbrCreate_PMFSRRV, /* plus seconds */ -+ -+ AuWbrCreate_Def = AuWbrCreate_TDP -+}; -+ -+enum { -+ AuWbrCopyup_TDP, /* top down parent */ -+ AuWbrCopyup_BUP, /* bottom up parent */ -+ AuWbrCopyup_BU, /* bottom up */ -+ -+ AuWbrCopyup_Def = AuWbrCopyup_TDP -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct file; -+ -+struct au_opt_add { -+ aufs_bindex_t bindex; -+ char *pathname; -+ int perm; -+ struct path path; -+}; -+ -+struct au_opt_del { -+ char *pathname; -+ struct path h_path; -+}; -+ -+struct au_opt_mod { -+ char *path; -+ int perm; -+ struct dentry *h_root; -+}; -+ -+struct au_opt_xino { -+ char *path; -+ struct file *file; -+}; -+ -+struct au_opt_xino_itrunc { -+ aufs_bindex_t bindex; -+}; -+ -+struct au_opt_wbr_create { -+ int wbr_create; -+ int mfs_second; -+ unsigned long long mfsrr_watermark; -+}; -+ -+struct au_opt { -+ int type; -+ union { -+ struct au_opt_xino xino; -+ struct au_opt_xino_itrunc xino_itrunc; -+ struct au_opt_add add; -+ struct au_opt_del del; -+ struct au_opt_mod mod; -+ int dirwh; -+ int rdcache; -+ unsigned int rdblk; -+ unsigned int rdhash; -+ int udba; -+ struct au_opt_wbr_create wbr_create; -+ int wbr_copyup; -+ unsigned int fhsm_second; -+ bool tf; /* generic flag, true or false */ -+ }; -+}; -+ -+/* opts flags */ -+#define AuOpts_REMOUNT 1 -+#define AuOpts_REFRESH (1 << 1) -+#define AuOpts_TRUNC_XIB (1 << 2) -+#define AuOpts_REFRESH_DYAOP (1 << 3) -+#define AuOpts_REFRESH_IDOP (1 << 4) -+#define AuOpts_DR_FLUSHED (1 << 5) -+#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name) -+#define au_fset_opts(flags, name) \ -+ do { (flags) |= AuOpts_##name; } while (0) -+#define au_fclr_opts(flags, name) \ -+ do { (flags) &= ~AuOpts_##name; } while (0) -+ -+#ifndef CONFIG_AUFS_DIRREN -+#undef AuOpts_DR_FLUSHED -+#define AuOpts_DR_FLUSHED 0 -+#endif -+ -+struct au_opts { -+ struct au_opt *opt; -+ int max_opt; -+ -+ unsigned int given_udba; -+ unsigned int flags; -+ unsigned long sb_flags; -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* opts.c */ -+int au_br_perm_val(char *perm); -+void au_optstr_br_perm(au_br_perm_str_t *str, int perm); -+int au_udba_val(char *str); -+const char *au_optstr_udba(int udba); -+int au_wbr_create_val(char *str, struct au_opt_wbr_create *create); -+const char *au_optstr_wbr_create(int wbr_create); -+int au_wbr_copyup_val(char *str); -+const char *au_optstr_wbr_copyup(int wbr_copyup); -+ -+int au_opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags, -+ aufs_bindex_t bindex); -+struct super_block; -+int au_opts_verify(struct super_block *sb, unsigned long sb_flags, -+ unsigned int pending); -+int au_opts_mount(struct super_block *sb, struct au_opts *opts); -+int au_opts_remount(struct super_block *sb, struct au_opts *opts); -+ -+unsigned int au_opt_udba(struct super_block *sb); -+ -+/* fsctx.c */ -+int aufs_fsctx_init(struct fs_context *fc); -+extern const struct fs_parameter_spec aufs_fsctx_paramspec[]; -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_OPTS_H__ */ -diff -Naur null/fs/aufs/plink.c linux-6.6.63/fs/aufs/plink.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/plink.c 2024-12-18 15:12:59.299519538 +0300 -@@ -0,0 +1,516 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * pseudo-link -+ */ -+ -+#include "aufs.h" -+ -+/* -+ * the pseudo-link maintenance mode. -+ * during a user process maintains the pseudo-links, -+ * prohibit adding a new plink and branch manipulation. -+ * -+ * Flags -+ * NOPLM: -+ * For entry functions which will handle plink, and i_mutex is already held -+ * in VFS. -+ * They cannot wait and should return an error at once. -+ * Callers has to check the error. -+ * NOPLMW: -+ * For entry functions which will handle plink, but i_mutex is not held -+ * in VFS. -+ * They can wait the plink maintenance mode to finish. -+ * -+ * They behave like F_SETLK and F_SETLKW. -+ * If the caller never handle plink, then both flags are unnecessary. -+ */ -+ -+int au_plink_maint(struct super_block *sb, int flags) -+{ -+ int err; -+ pid_t pid, ppid; -+ struct task_struct *parent, *prev; -+ struct au_sbinfo *sbi; -+ -+ SiMustAnyLock(sb); -+ -+ err = 0; -+ if (!au_opt_test(au_mntflags(sb), PLINK)) -+ goto out; -+ -+ sbi = au_sbi(sb); -+ pid = sbi->si_plink_maint_pid; -+ if (!pid || pid == current->pid) -+ goto out; -+ -+ /* todo: it highly depends upon /sbin/mount.aufs */ -+ prev = NULL; -+ parent = current; -+ ppid = 0; -+ rcu_read_lock(); -+ while (1) { -+ parent = rcu_dereference(parent->real_parent); -+ if (parent == prev) -+ break; -+ ppid = task_pid_vnr(parent); -+ if (pid == ppid) { -+ rcu_read_unlock(); -+ goto out; -+ } -+ prev = parent; -+ } -+ rcu_read_unlock(); -+ -+ if (au_ftest_lock(flags, NOPLMW)) { -+ /* if there is no i_mutex lock in VFS, we don't need to wait */ -+ /* AuDebugOn(!lockdep_depth(current)); */ -+ while (sbi->si_plink_maint_pid) { -+ si_read_unlock(sb); -+ /* gave up wake_up_bit() */ -+ wait_event(sbi->si_plink_wq, !sbi->si_plink_maint_pid); -+ -+ if (au_ftest_lock(flags, FLUSH)) -+ au_nwt_flush(&sbi->si_nowait); -+ si_noflush_read_lock(sb); -+ } -+ } else if (au_ftest_lock(flags, NOPLM)) { -+ AuDbg("ppid %d, pid %d\n", ppid, pid); -+ err = -EAGAIN; -+ } -+ -+out: -+ return err; -+} -+ -+void au_plink_maint_leave(struct au_sbinfo *sbinfo) -+{ -+ spin_lock(&sbinfo->si_plink_maint_lock); -+ sbinfo->si_plink_maint_pid = 0; -+ spin_unlock(&sbinfo->si_plink_maint_lock); -+ wake_up_all(&sbinfo->si_plink_wq); -+} -+ -+int au_plink_maint_enter(struct super_block *sb) -+{ -+ int err; -+ struct au_sbinfo *sbinfo; -+ -+ err = 0; -+ sbinfo = au_sbi(sb); -+ /* make sure i am the only one in this fs */ -+ si_write_lock(sb, AuLock_FLUSH); -+ if (au_opt_test(au_mntflags(sb), PLINK)) { -+ spin_lock(&sbinfo->si_plink_maint_lock); -+ if (!sbinfo->si_plink_maint_pid) -+ sbinfo->si_plink_maint_pid = current->pid; -+ else -+ err = -EBUSY; -+ spin_unlock(&sbinfo->si_plink_maint_lock); -+ } -+ si_write_unlock(sb); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+#ifdef CONFIG_AUFS_DEBUG -+void au_plink_list(struct super_block *sb) -+{ -+ int i; -+ struct au_sbinfo *sbinfo; -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *pos; -+ struct au_icntnr *icntnr; -+ -+ SiMustAnyLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); -+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM)); -+ -+ for (i = 0; i < AuPlink_NHASH; i++) { -+ hbl = sbinfo->si_plink + i; -+ hlist_bl_lock(hbl); -+ hlist_bl_for_each_entry(icntnr, pos, hbl, plink) -+ AuDbg("%lu\n", icntnr->vfs_inode.i_ino); -+ hlist_bl_unlock(hbl); -+ } -+} -+#endif -+ -+/* is the inode pseudo-linked? */ -+int au_plink_test(struct inode *inode) -+{ -+ int found, i; -+ struct au_sbinfo *sbinfo; -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *pos; -+ struct au_icntnr *icntnr; -+ -+ sbinfo = au_sbi(inode->i_sb); -+ AuRwMustAnyLock(&sbinfo->si_rwsem); -+ AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK)); -+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM)); -+ -+ found = 0; -+ i = au_plink_hash(inode->i_ino); -+ hbl = sbinfo->si_plink + i; -+ hlist_bl_lock(hbl); -+ hlist_bl_for_each_entry(icntnr, pos, hbl, plink) -+ if (&icntnr->vfs_inode == inode) { -+ found = 1; -+ break; -+ } -+ hlist_bl_unlock(hbl); -+ return found; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * generate a name for plink. -+ * the file will be stored under AUFS_WH_PLINKDIR. -+ */ -+/* 20 is max digits length of ulong 64 */ -+#define PLINK_NAME_LEN ((20 + 1) * 2) -+ -+static int plink_name(char *name, int len, struct inode *inode, -+ aufs_bindex_t bindex) -+{ -+ int rlen; -+ struct inode *h_inode; -+ -+ h_inode = au_h_iptr(inode, bindex); -+ rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino); -+ return rlen; -+} -+ -+struct au_do_plink_lkup_args { -+ struct dentry **errp; -+ struct qstr *tgtname; -+ struct path *h_ppath; -+}; -+ -+static struct dentry *au_do_plink_lkup(struct qstr *tgtname, -+ struct path *h_ppath) -+{ -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ -+ h_inode = d_inode(h_ppath->dentry); -+ inode_lock_shared_nested(h_inode, AuLsc_I_CHILD2); -+ h_dentry = vfsub_lkup_one(tgtname, h_ppath); -+ inode_unlock_shared(h_inode); -+ -+ return h_dentry; -+} -+ -+static void au_call_do_plink_lkup(void *args) -+{ -+ struct au_do_plink_lkup_args *a = args; -+ *a->errp = au_do_plink_lkup(a->tgtname, a->h_ppath); -+} -+ -+/* lookup the plink-ed @inode under the branch at @bindex */ -+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex) -+{ -+ struct dentry *h_dentry; -+ struct au_branch *br; -+ struct path h_ppath; -+ int wkq_err; -+ char a[PLINK_NAME_LEN]; -+ struct qstr tgtname = QSTR_INIT(a, 0); -+ -+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM)); -+ -+ br = au_sbr(inode->i_sb, bindex); -+ h_ppath.dentry = br->br_wbr->wbr_plink; -+ h_ppath.mnt = au_br_mnt(br); -+ tgtname.len = plink_name(a, sizeof(a), inode, bindex); -+ -+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) { -+ struct au_do_plink_lkup_args args = { -+ .errp = &h_dentry, -+ .tgtname = &tgtname, -+ .h_ppath = &h_ppath -+ }; -+ -+ wkq_err = au_wkq_wait(au_call_do_plink_lkup, &args); -+ if (unlikely(wkq_err)) -+ h_dentry = ERR_PTR(wkq_err); -+ } else -+ h_dentry = au_do_plink_lkup(&tgtname, &h_ppath); -+ -+ return h_dentry; -+} -+ -+/* create a pseudo-link */ -+static int do_whplink(struct qstr *tgt, struct path *h_ppath, -+ struct dentry *h_dentry) -+{ -+ int err; -+ struct path h_path; -+ struct inode *h_dir, *delegated; -+ -+ h_dir = d_inode(h_ppath->dentry); -+ inode_lock_nested(h_dir, AuLsc_I_CHILD2); -+ h_path.mnt = h_ppath->mnt; -+again: -+ h_path.dentry = vfsub_lkup_one(tgt, h_ppath); -+ err = PTR_ERR(h_path.dentry); -+ if (IS_ERR(h_path.dentry)) -+ goto out; -+ -+ err = 0; -+ /* wh.plink dir is not monitored */ -+ /* todo: is it really safe? */ -+ 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)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal unlink\n"); -+ iput(delegated); -+ } -+ dput(h_path.dentry); -+ h_path.dentry = NULL; -+ if (!err) -+ goto again; -+ } -+ if (!err && d_is_negative(h_path.dentry)) { -+ delegated = NULL; -+ err = vfsub_link(h_dentry, h_dir, &h_path, &delegated); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal link\n"); -+ iput(delegated); -+ } -+ } -+ dput(h_path.dentry); -+ -+out: -+ inode_unlock(h_dir); -+ return err; -+} -+ -+struct do_whplink_args { -+ int *errp; -+ struct qstr *tgt; -+ struct path *h_ppath; -+ struct dentry *h_dentry; -+}; -+ -+static void call_do_whplink(void *args) -+{ -+ struct do_whplink_args *a = args; -+ *a->errp = do_whplink(a->tgt, a->h_ppath, a->h_dentry); -+} -+ -+static int whplink(struct dentry *h_dentry, struct inode *inode, -+ aufs_bindex_t bindex) -+{ -+ int err, wkq_err; -+ struct au_branch *br; -+ struct au_wbr *wbr; -+ struct path h_ppath; -+ char a[PLINK_NAME_LEN]; -+ struct qstr tgtname = QSTR_INIT(a, 0); -+ -+ br = au_sbr(inode->i_sb, bindex); -+ wbr = br->br_wbr; -+ h_ppath.dentry = wbr->wbr_plink; -+ h_ppath.mnt = au_br_mnt(br); -+ tgtname.len = plink_name(a, sizeof(a), inode, bindex); -+ -+ /* always superio. */ -+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) { -+ struct do_whplink_args args = { -+ .errp = &err, -+ .tgt = &tgtname, -+ .h_ppath = &h_ppath, -+ .h_dentry = h_dentry -+ }; -+ wkq_err = au_wkq_wait(call_do_whplink, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } else -+ err = do_whplink(&tgtname, &h_ppath, h_dentry); -+ -+ return err; -+} -+ -+/* -+ * create a new pseudo-link for @h_dentry on @bindex. -+ * the linked inode is held in aufs @inode. -+ */ -+void au_plink_append(struct inode *inode, aufs_bindex_t bindex, -+ struct dentry *h_dentry) -+{ -+ struct super_block *sb; -+ struct au_sbinfo *sbinfo; -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *pos; -+ struct au_icntnr *icntnr; -+ int found, err, cnt, i; -+ -+ sb = inode->i_sb; -+ sbinfo = au_sbi(sb); -+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); -+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM)); -+ -+ found = au_plink_test(inode); -+ if (found) -+ return; -+ -+ i = au_plink_hash(inode->i_ino); -+ hbl = sbinfo->si_plink + i; -+ au_igrab(inode); -+ -+ hlist_bl_lock(hbl); -+ hlist_bl_for_each_entry(icntnr, pos, hbl, plink) { -+ if (&icntnr->vfs_inode == inode) { -+ found = 1; -+ break; -+ } -+ } -+ if (!found) { -+ icntnr = container_of(inode, struct au_icntnr, vfs_inode); -+ hlist_bl_add_head(&icntnr->plink, hbl); -+ } -+ hlist_bl_unlock(hbl); -+ if (!found) { -+ cnt = au_hbl_count(hbl); -+#define msg "unexpectedly unbalanced or too many pseudo-links" -+ if (cnt > AUFS_PLINK_WARN) -+ AuWarn1(msg ", %d\n", cnt); -+#undef msg -+ err = whplink(h_dentry, inode, bindex); -+ if (unlikely(err)) { -+ pr_warn("err %d, damaged pseudo link.\n", err); -+ au_hbl_del(&icntnr->plink, hbl); -+ iput(&icntnr->vfs_inode); -+ } -+ } else -+ iput(&icntnr->vfs_inode); -+} -+ -+/* free all plinks */ -+void au_plink_put(struct super_block *sb, int verbose) -+{ -+ int i, warned; -+ struct au_sbinfo *sbinfo; -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *pos, *tmp; -+ struct au_icntnr *icntnr; -+ -+ SiMustWriteLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); -+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM)); -+ -+ /* no spin_lock since sbinfo is write-locked */ -+ warned = 0; -+ for (i = 0; i < AuPlink_NHASH; i++) { -+ hbl = sbinfo->si_plink + i; -+ if (!warned && verbose && !hlist_bl_empty(hbl)) { -+ pr_warn("pseudo-link is not flushed"); -+ warned = 1; -+ } -+ hlist_bl_for_each_entry_safe(icntnr, pos, tmp, hbl, plink) -+ iput(&icntnr->vfs_inode); -+ INIT_HLIST_BL_HEAD(hbl); -+ } -+} -+ -+void au_plink_clean(struct super_block *sb, int verbose) -+{ -+ struct dentry *root; -+ -+ root = sb->s_root; -+ aufs_write_lock(root); -+ if (au_opt_test(au_mntflags(sb), PLINK)) -+ au_plink_put(sb, verbose); -+ aufs_write_unlock(root); -+} -+ -+static int au_plink_do_half_refresh(struct inode *inode, aufs_bindex_t br_id) -+{ -+ int do_put; -+ aufs_bindex_t btop, bbot, bindex; -+ -+ do_put = 0; -+ btop = au_ibtop(inode); -+ bbot = au_ibbot(inode); -+ if (btop >= 0) { -+ for (bindex = btop; bindex <= bbot; bindex++) { -+ if (!au_h_iptr(inode, bindex) -+ || au_ii_br_id(inode, bindex) != br_id) -+ continue; -+ au_set_h_iptr(inode, bindex, NULL, 0); -+ do_put = 1; -+ break; -+ } -+ if (do_put) -+ for (bindex = btop; bindex <= bbot; bindex++) -+ if (au_h_iptr(inode, bindex)) { -+ do_put = 0; -+ break; -+ } -+ } else -+ do_put = 1; -+ -+ return do_put; -+} -+ -+/* free the plinks on a branch specified by @br_id */ -+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id) -+{ -+ struct au_sbinfo *sbinfo; -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *pos, *tmp; -+ struct au_icntnr *icntnr; -+ struct inode *inode; -+ int i, do_put; -+ -+ SiMustWriteLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); -+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM)); -+ -+ /* no bit_lock since sbinfo is write-locked */ -+ for (i = 0; i < AuPlink_NHASH; i++) { -+ hbl = sbinfo->si_plink + i; -+ hlist_bl_for_each_entry_safe(icntnr, pos, tmp, hbl, plink) { -+ inode = au_igrab(&icntnr->vfs_inode); -+ ii_write_lock_child(inode); -+ do_put = au_plink_do_half_refresh(inode, br_id); -+ if (do_put) { -+ hlist_bl_del(&icntnr->plink); -+ iput(inode); -+ } -+ ii_write_unlock(inode); -+ iput(inode); -+ } -+ } -+} -diff -Naur null/fs/aufs/poll.c linux-6.6.63/fs/aufs/poll.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/poll.c 2024-12-18 15:12:59.299519538 +0300 -@@ -0,0 +1,51 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * poll operation -+ * There is only one filesystem which implements ->poll operation, currently. -+ */ -+ -+#include "aufs.h" -+ -+__poll_t aufs_poll(struct file *file, struct poll_table_struct *pt) -+{ -+ __poll_t mask; -+ struct file *h_file; -+ struct super_block *sb; -+ -+ /* We should pretend an error happened. */ -+ mask = EPOLLERR /* | EPOLLIN | EPOLLOUT */; -+ sb = file->f_path.dentry->d_sb; -+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); -+ -+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0); -+ if (IS_ERR(h_file)) { -+ AuDbg("h_file %ld\n", PTR_ERR(h_file)); -+ goto out; -+ } -+ -+ mask = vfs_poll(h_file, pt); -+ fput(h_file); /* instead of au_read_post() */ -+ -+out: -+ si_read_unlock(sb); -+ if (mask & EPOLLERR) -+ AuDbg("mask 0x%x\n", mask); -+ return mask; -+} -diff -Naur null/fs/aufs/posix_acl.c linux-6.6.63/fs/aufs/posix_acl.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/posix_acl.c 2024-12-18 15:12:59.299519538 +0300 -@@ -0,0 +1,108 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2014-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * posix acl operations -+ */ -+ -+#include -+#include "aufs.h" -+ -+struct posix_acl *aufs_get_inode_acl(struct inode *inode, int type, bool rcu) -+{ -+ struct posix_acl *acl; -+ int err; -+ aufs_bindex_t bindex; -+ struct inode *h_inode; -+ struct super_block *sb; -+ -+ acl = ERR_PTR(-ECHILD); -+ if (rcu) -+ goto out; -+ -+ acl = NULL; -+ sb = inode->i_sb; -+ si_read_lock(sb, AuLock_FLUSH); -+ ii_read_lock_child(inode); -+ if (!(sb->s_flags & SB_POSIXACL)) -+ goto unlock; -+ -+ bindex = au_ibtop(inode); -+ h_inode = au_h_iptr(inode, bindex); -+ if (unlikely(!h_inode -+ || ((h_inode->i_mode & S_IFMT) -+ != (inode->i_mode & S_IFMT)))) { -+ err = au_busy_or_stale(); -+ acl = ERR_PTR(err); -+ goto unlock; -+ } -+ -+ /* always topmost only */ -+ acl = get_inode_acl(h_inode, type); -+ if (IS_ERR(acl)) -+ forget_cached_acl(inode, type); -+ else -+ set_cached_acl(inode, type, acl); -+ -+unlock: -+ ii_read_unlock(inode); -+ si_read_unlock(sb); -+ -+out: -+ AuTraceErrPtr(acl); -+ return acl; -+} -+ -+struct posix_acl *aufs_get_acl(struct mnt_idmap *idmap, -+ struct dentry *dentry, int type) -+{ -+ struct posix_acl *acl; -+ struct inode *inode; -+ -+ inode = d_inode(dentry); -+ acl = aufs_get_inode_acl(inode, type, /*rcu*/false); -+ -+ return acl; -+} -+ -+int aufs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry, -+ struct posix_acl *acl, int type) -+{ -+ int err; -+ ssize_t ssz; -+ struct inode *inode; -+ struct au_sxattr arg = { -+ .type = AU_ACL_SET, -+ .u.acl_set = { -+ .acl = acl, -+ .type = type -+ }, -+ }; -+ -+ inode = d_inode(dentry); -+ IMustLock(inode); -+ -+ ssz = au_sxattr(dentry, inode, &arg); -+ /* forget even it if succeeds since the branch might set differently */ -+ forget_cached_acl(inode, type); -+ err = ssz; -+ if (ssz >= 0) -+ err = 0; -+ -+ return err; -+} -diff -Naur null/fs/aufs/procfs.c linux-6.6.63/fs/aufs/procfs.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/procfs.c 2024-12-18 15:12:59.299519538 +0300 -@@ -0,0 +1,170 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2010-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * procfs interfaces -+ */ -+ -+#include -+#include "aufs.h" -+ -+static int au_procfs_plm_release(struct inode *inode, struct file *file) -+{ -+ struct au_sbinfo *sbinfo; -+ -+ sbinfo = file->private_data; -+ if (sbinfo) { -+ au_plink_maint_leave(sbinfo); -+ kobject_put(&sbinfo->si_kobj); -+ } -+ -+ return 0; -+} -+ -+static void au_procfs_plm_write_clean(struct file *file) -+{ -+ struct au_sbinfo *sbinfo; -+ -+ sbinfo = file->private_data; -+ if (sbinfo) -+ au_plink_clean(sbinfo->si_sb, /*verbose*/0); -+} -+ -+static int au_procfs_plm_write_si(struct file *file, unsigned long id) -+{ -+ int err; -+ struct super_block *sb; -+ struct au_sbinfo *sbinfo; -+ struct hlist_bl_node *pos; -+ -+ err = -EBUSY; -+ if (unlikely(file->private_data)) -+ goto out; -+ -+ sb = NULL; -+ /* don't use au_sbilist_lock() here */ -+ hlist_bl_lock(&au_sbilist); -+ hlist_bl_for_each_entry(sbinfo, pos, &au_sbilist, si_list) -+ if (id == sysaufs_si_id(sbinfo)) { -+ if (kobject_get_unless_zero(&sbinfo->si_kobj)) -+ sb = sbinfo->si_sb; -+ break; -+ } -+ hlist_bl_unlock(&au_sbilist); -+ -+ err = -EINVAL; -+ if (unlikely(!sb)) -+ goto out; -+ -+ err = au_plink_maint_enter(sb); -+ if (!err) -+ /* keep kobject_get() */ -+ file->private_data = sbinfo; -+ else -+ kobject_put(&sbinfo->si_kobj); -+out: -+ return err; -+} -+ -+/* -+ * Accept a valid "si=xxxx" only. -+ * Once it is accepted successfully, accept "clean" too. -+ */ -+static ssize_t au_procfs_plm_write(struct file *file, const char __user *ubuf, -+ size_t count, loff_t *ppos) -+{ -+ ssize_t err; -+ unsigned long id; -+ /* last newline is allowed */ -+ char buf[3 + sizeof(unsigned long) * 2 + 1]; -+ -+ err = -EACCES; -+ if (unlikely(!capable(CAP_SYS_ADMIN))) -+ goto out; -+ -+ err = -EINVAL; -+ if (unlikely(count > sizeof(buf))) -+ goto out; -+ -+ err = copy_from_user(buf, ubuf, count); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ goto out; -+ } -+ buf[count] = 0; -+ -+ err = -EINVAL; -+ if (!strcmp("clean", buf)) { -+ au_procfs_plm_write_clean(file); -+ goto out_success; -+ } else if (unlikely(strncmp("si=", buf, 3))) -+ goto out; -+ -+ err = kstrtoul(buf + 3, 16, &id); -+ if (unlikely(err)) -+ goto out; -+ -+ err = au_procfs_plm_write_si(file, id); -+ if (unlikely(err)) -+ goto out; -+ -+out_success: -+ err = count; /* success */ -+out: -+ return err; -+} -+ -+static const struct proc_ops au_procfs_plm_op = { -+ .proc_write = au_procfs_plm_write, -+ .proc_release = au_procfs_plm_release -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+static struct proc_dir_entry *au_procfs_dir; -+ -+void au_procfs_fin(void) -+{ -+ remove_proc_entry(AUFS_PLINK_MAINT_NAME, au_procfs_dir); -+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL); -+} -+ -+int __init au_procfs_init(void) -+{ -+ int err; -+ struct proc_dir_entry *entry; -+ -+ err = -ENOMEM; -+ au_procfs_dir = proc_mkdir(AUFS_PLINK_MAINT_DIR, NULL); -+ if (unlikely(!au_procfs_dir)) -+ goto out; -+ -+ entry = proc_create(AUFS_PLINK_MAINT_NAME, S_IFREG | 0200, -+ au_procfs_dir, &au_procfs_plm_op); -+ if (unlikely(!entry)) -+ goto out_dir; -+ -+ err = 0; -+ goto out; /* success */ -+ -+ -+out_dir: -+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL); -+out: -+ return err; -+} -diff -Naur null/fs/aufs/rdu.c linux-6.6.63/fs/aufs/rdu.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/rdu.c 2024-12-18 15:12:59.299519538 +0300 -@@ -0,0 +1,384 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * readdir in userspace. -+ */ -+ -+#include -+#include -+#include -+#include "aufs.h" -+ -+/* bits for struct aufs_rdu.flags */ -+#define AuRdu_CALLED 1 -+#define AuRdu_CONT (1 << 1) -+#define AuRdu_FULL (1 << 2) -+#define au_ftest_rdu(flags, name) ((flags) & AuRdu_##name) -+#define au_fset_rdu(flags, name) \ -+ do { (flags) |= AuRdu_##name; } while (0) -+#define au_fclr_rdu(flags, name) \ -+ do { (flags) &= ~AuRdu_##name; } while (0) -+ -+struct au_rdu_arg { -+ struct dir_context ctx; -+ struct aufs_rdu *rdu; -+ union au_rdu_ent_ul ent; -+ unsigned long end; -+ -+ struct super_block *sb; -+ int err; -+}; -+ -+static bool au_rdu_fill(struct dir_context *ctx, const char *name, int nlen, -+ loff_t offset, u64 h_ino, unsigned int d_type) -+{ -+ int err, len; -+ struct au_rdu_arg *arg = container_of(ctx, struct au_rdu_arg, ctx); -+ struct aufs_rdu *rdu = arg->rdu; -+ struct au_rdu_ent ent; -+ -+ err = 0; -+ arg->err = 0; -+ au_fset_rdu(rdu->cookie.flags, CALLED); -+ len = au_rdu_len(nlen); -+ if (arg->ent.ul + len < arg->end) { -+ ent.ino = h_ino; -+ ent.bindex = rdu->cookie.bindex; -+ ent.type = d_type; -+ ent.nlen = nlen; -+ if (unlikely(nlen > AUFS_MAX_NAMELEN)) -+ ent.type = DT_UNKNOWN; -+ -+ /* unnecessary to support mmap_sem since this is a dir */ -+ err = -EFAULT; -+ if (copy_to_user(arg->ent.e, &ent, sizeof(ent))) -+ goto out; -+ if (copy_to_user(arg->ent.e->name, name, nlen)) -+ goto out; -+ /* the terminating NULL */ -+ if (__put_user(0, arg->ent.e->name + nlen)) -+ goto out; -+ err = 0; -+ /* AuDbg("%p, %.*s\n", arg->ent.p, nlen, name); */ -+ arg->ent.ul += len; -+ rdu->rent++; -+ } else { -+ err = -EFAULT; -+ au_fset_rdu(rdu->cookie.flags, FULL); -+ rdu->full = 1; -+ rdu->tail = arg->ent; -+ } -+ -+out: -+ /* AuTraceErr(err); */ -+ return !err; -+} -+ -+static int au_rdu_do(struct file *h_file, struct au_rdu_arg *arg) -+{ -+ int err; -+ loff_t offset; -+ struct au_rdu_cookie *cookie = &arg->rdu->cookie; -+ -+ /* we don't have to care (FMODE_32BITHASH | FMODE_64BITHASH) for ext4 */ -+ offset = vfsub_llseek(h_file, cookie->h_pos, SEEK_SET); -+ err = offset; -+ if (unlikely(offset != cookie->h_pos)) -+ goto out; -+ -+ err = 0; -+ do { -+ arg->err = 0; -+ au_fclr_rdu(cookie->flags, CALLED); -+ /* smp_mb(); */ -+ err = vfsub_iterate_dir(h_file, &arg->ctx); -+ if (err >= 0) -+ err = arg->err; -+ } while (!err -+ && au_ftest_rdu(cookie->flags, CALLED) -+ && !au_ftest_rdu(cookie->flags, FULL)); -+ cookie->h_pos = h_file->f_pos; -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_rdu(struct file *file, struct aufs_rdu *rdu) -+{ -+ int err; -+ aufs_bindex_t bbot; -+ struct au_rdu_arg arg = { -+ .ctx = { -+ .actor = au_rdu_fill -+ } -+ }; -+ struct dentry *dentry; -+ struct inode *inode; -+ struct file *h_file; -+ struct au_rdu_cookie *cookie = &rdu->cookie; -+ -+ /* VERIFY_WRITE */ -+ err = !access_ok(rdu->ent.e, rdu->sz); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ AuTraceErr(err); -+ goto out; -+ } -+ rdu->rent = 0; -+ rdu->tail = rdu->ent; -+ rdu->full = 0; -+ arg.rdu = rdu; -+ arg.ent = rdu->ent; -+ arg.end = arg.ent.ul; -+ arg.end += rdu->sz; -+ -+ err = -ENOTDIR; -+ if (unlikely(!file->f_op->iterate_shared)) -+ goto out; -+ -+ err = security_file_permission(file, MAY_READ); -+ AuTraceErr(err); -+ if (unlikely(err)) -+ goto out; -+ -+ dentry = file->f_path.dentry; -+ inode = d_inode(dentry); -+ inode_lock_shared(inode); -+ -+ arg.sb = inode->i_sb; -+ err = si_read_lock(arg.sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (unlikely(err)) -+ goto out_mtx; -+ err = au_alive_dir(dentry); -+ if (unlikely(err)) -+ goto out_si; -+ /* todo: reval? */ -+ fi_read_lock(file); -+ -+ err = -EAGAIN; -+ if (unlikely(au_ftest_rdu(cookie->flags, CONT) -+ && cookie->generation != au_figen(file))) -+ goto out_unlock; -+ -+ err = 0; -+ if (!rdu->blk) { -+ rdu->blk = au_sbi(arg.sb)->si_rdblk; -+ if (!rdu->blk) -+ rdu->blk = au_dir_size(file, /*dentry*/NULL); -+ } -+ bbot = au_fbtop(file); -+ if (cookie->bindex < bbot) -+ cookie->bindex = bbot; -+ bbot = au_fbbot_dir(file); -+ /* AuDbg("b%d, b%d\n", cookie->bindex, bbot); */ -+ for (; !err && cookie->bindex <= bbot; -+ cookie->bindex++, cookie->h_pos = 0) { -+ h_file = au_hf_dir(file, cookie->bindex); -+ if (!h_file) -+ continue; -+ -+ au_fclr_rdu(cookie->flags, FULL); -+ err = au_rdu_do(h_file, &arg); -+ AuTraceErr(err); -+ if (unlikely(au_ftest_rdu(cookie->flags, FULL) || err)) -+ break; -+ } -+ AuDbg("rent %llu\n", rdu->rent); -+ -+ if (!err && !au_ftest_rdu(cookie->flags, CONT)) { -+ rdu->shwh = !!au_opt_test(au_sbi(arg.sb)->si_mntflags, SHWH); -+ au_fset_rdu(cookie->flags, CONT); -+ cookie->generation = au_figen(file); -+ } -+ -+ ii_read_lock_child(inode); -+ fsstack_copy_attr_atime(inode, au_h_iptr(inode, au_ibtop(inode))); -+ ii_read_unlock(inode); -+ -+out_unlock: -+ fi_read_unlock(file); -+out_si: -+ si_read_unlock(arg.sb); -+out_mtx: -+ inode_unlock_shared(inode); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_rdu_ino(struct file *file, struct aufs_rdu *rdu) -+{ -+ int err; -+ ino_t ino; -+ unsigned long long nent; -+ union au_rdu_ent_ul *u; -+ struct au_rdu_ent ent; -+ struct super_block *sb; -+ -+ err = 0; -+ nent = rdu->nent; -+ u = &rdu->ent; -+ sb = file->f_path.dentry->d_sb; -+ si_read_lock(sb, AuLock_FLUSH); -+ while (nent-- > 0) { -+ /* unnecessary to support mmap_sem since this is a dir */ -+ err = copy_from_user(&ent, u->e, sizeof(ent)); -+ if (!err) -+ /* VERIFY_WRITE */ -+ err = !access_ok(&u->e->ino, sizeof(ino)); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ AuTraceErr(err); -+ break; -+ } -+ -+ /* AuDbg("b%d, i%llu\n", ent.bindex, ent.ino); */ -+ if (!ent.wh) -+ err = au_ino(sb, ent.bindex, ent.ino, ent.type, &ino); -+ else -+ err = au_wh_ino(sb, ent.bindex, ent.ino, ent.type, -+ &ino); -+ if (unlikely(err)) { -+ AuTraceErr(err); -+ break; -+ } -+ -+ err = __put_user(ino, &u->e->ino); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ AuTraceErr(err); -+ break; -+ } -+ u->ul += au_rdu_len(ent.nlen); -+ } -+ si_read_unlock(sb); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_rdu_verify(struct aufs_rdu *rdu) -+{ -+ AuDbg("rdu{%llu, %p, %u | %u | %llu, %u, %u | " -+ "%llu, b%d, 0x%x, g%u}\n", -+ rdu->sz, rdu->ent.e, rdu->verify[AufsCtlRduV_SZ], -+ rdu->blk, -+ rdu->rent, rdu->shwh, rdu->full, -+ rdu->cookie.h_pos, rdu->cookie.bindex, rdu->cookie.flags, -+ rdu->cookie.generation); -+ -+ if (rdu->verify[AufsCtlRduV_SZ] == sizeof(*rdu)) -+ return 0; -+ -+ AuDbg("%u:%u\n", -+ rdu->verify[AufsCtlRduV_SZ], (unsigned int)sizeof(*rdu)); -+ return -EINVAL; -+} -+ -+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ long err, e; -+ struct aufs_rdu rdu; -+ void __user *p = (void __user *)arg; -+ -+ err = copy_from_user(&rdu, p, sizeof(rdu)); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ AuTraceErr(err); -+ goto out; -+ } -+ err = au_rdu_verify(&rdu); -+ if (unlikely(err)) -+ goto out; -+ -+ switch (cmd) { -+ case AUFS_CTL_RDU: -+ err = au_rdu(file, &rdu); -+ if (unlikely(err)) -+ break; -+ -+ e = copy_to_user(p, &rdu, sizeof(rdu)); -+ if (unlikely(e)) { -+ err = -EFAULT; -+ AuTraceErr(err); -+ } -+ break; -+ case AUFS_CTL_RDU_INO: -+ err = au_rdu_ino(file, &rdu); -+ break; -+ -+ default: -+ /* err = -ENOTTY; */ -+ err = -EINVAL; -+ } -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+#ifdef CONFIG_COMPAT -+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ long err, e; -+ struct aufs_rdu rdu; -+ void __user *p = compat_ptr(arg); -+ -+ /* todo: get_user()? */ -+ err = copy_from_user(&rdu, p, sizeof(rdu)); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ AuTraceErr(err); -+ goto out; -+ } -+ rdu.ent.e = compat_ptr(rdu.ent.ul); -+ err = au_rdu_verify(&rdu); -+ if (unlikely(err)) -+ goto out; -+ -+ switch (cmd) { -+ case AUFS_CTL_RDU: -+ err = au_rdu(file, &rdu); -+ if (unlikely(err)) -+ break; -+ -+ rdu.ent.ul = ptr_to_compat(rdu.ent.e); -+ rdu.tail.ul = ptr_to_compat(rdu.tail.e); -+ e = copy_to_user(p, &rdu, sizeof(rdu)); -+ if (unlikely(e)) { -+ err = -EFAULT; -+ AuTraceErr(err); -+ } -+ break; -+ case AUFS_CTL_RDU_INO: -+ err = au_rdu_ino(file, &rdu); -+ break; -+ -+ default: -+ /* err = -ENOTTY; */ -+ err = -EINVAL; -+ } -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+#endif -diff -Naur null/fs/aufs/rwsem.h linux-6.6.63/fs/aufs/rwsem.h ---- /dev/null -+++ linux-6.6.63/fs/aufs/rwsem.h 2024-12-18 15:12:59.299519538 +0300 -@@ -0,0 +1,85 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * simple read-write semaphore wrappers -+ */ -+ -+#ifndef __AUFS_RWSEM_H__ -+#define __AUFS_RWSEM_H__ -+ -+#ifdef __KERNEL__ -+ -+#include "debug.h" -+ -+/* in the future, the name 'au_rwsem' will be totally gone */ -+#define au_rwsem rw_semaphore -+ -+/* to debug easier, do not make them inlined functions */ -+#define AuRwMustNoWaiters(rw) AuDebugOn(rwsem_is_contended(rw)) -+ -+#ifdef CONFIG_LOCKDEP -+/* rwsem_is_locked() is unusable */ -+#define AuRwMustReadLock(rw) AuDebugOn(IS_ENABLED(CONFIG_LOCKDEP) \ -+ && !lockdep_recursing(current) \ -+ && debug_locks \ -+ && !lockdep_is_held_type(rw, 1)) -+#define AuRwMustWriteLock(rw) AuDebugOn(IS_ENABLED(CONFIG_LOCKDEP) \ -+ && !lockdep_recursing(current) \ -+ && debug_locks \ -+ && !lockdep_is_held_type(rw, 0)) -+#define AuRwMustAnyLock(rw) AuDebugOn(IS_ENABLED(CONFIG_LOCKDEP) \ -+ && !lockdep_recursing(current) \ -+ && debug_locks \ -+ && !lockdep_is_held(rw)) -+#define AuRwDestroy(rw) AuDebugOn(IS_ENABLED(CONFIG_LOCKDEP) \ -+ && !lockdep_recursing(current) \ -+ && debug_locks \ -+ && lockdep_is_held(rw)) -+#else -+AuStubVoid(AuRwMustReadLock, struct rw_semaphore *rw) -+AuStubVoid(AuRwMustWriteLock, struct rw_semaphore *rw) -+AuStubVoid(AuRwMustAnyLock, struct rw_semaphore *rw) -+AuStubVoid(AuRwDestroy, struct rw_semaphore *rw) -+#endif -+ -+#define au_rw_init(rw) init_rwsem(rw) -+ -+#define au_rw_init_wlock(rw) do { \ -+ au_rw_init(rw); \ -+ down_write(rw); \ -+ } while (0) -+ -+#define au_rw_init_wlock_nested(rw, lsc) do { \ -+ au_rw_init(rw); \ -+ down_write_nested(rw, lsc); \ -+ } while (0) -+ -+#define au_rw_read_lock(rw) down_read(rw) -+#define au_rw_read_lock_nested(rw, lsc) down_read_nested(rw, lsc) -+#define au_rw_read_unlock(rw) up_read(rw) -+#define au_rw_dgrade_lock(rw) downgrade_write(rw) -+#define au_rw_write_lock(rw) down_write(rw) -+#define au_rw_write_lock_nested(rw, lsc) down_write_nested(rw, lsc) -+#define au_rw_write_unlock(rw) up_write(rw) -+/* why is not _nested version defined? */ -+#define au_rw_read_trylock(rw) down_read_trylock(rw) -+#define au_rw_write_trylock(rw) down_write_trylock(rw) -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_RWSEM_H__ */ -diff -Naur null/fs/aufs/sbinfo.c linux-6.6.63/fs/aufs/sbinfo.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/sbinfo.c 2024-12-18 15:12:59.299519538 +0300 -@@ -0,0 +1,316 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * superblock private data -+ */ -+ -+#include -+#include "aufs.h" -+ -+/* -+ * they are necessary regardless sysfs is disabled. -+ */ -+void au_si_free(struct kobject *kobj) -+{ -+ int i; -+ struct au_sbinfo *sbinfo; -+ char *locked __maybe_unused; /* debug only */ -+ -+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj); -+ for (i = 0; i < AuPlink_NHASH; i++) -+ AuDebugOn(!hlist_bl_empty(sbinfo->si_plink + i)); -+ AuDebugOn(atomic_read(&sbinfo->si_nowait.nw_len)); -+ -+ AuLCntZero(au_lcnt_read(&sbinfo->si_ninodes, /*do_rev*/0)); -+ au_lcnt_fin(&sbinfo->si_ninodes, /*do_sync*/0); -+ AuLCntZero(au_lcnt_read(&sbinfo->si_nfiles, /*do_rev*/0)); -+ au_lcnt_fin(&sbinfo->si_nfiles, /*do_sync*/0); -+ -+ dbgaufs_si_fin(sbinfo); -+ au_rw_write_lock(&sbinfo->si_rwsem); -+ au_br_free(sbinfo); -+ au_rw_write_unlock(&sbinfo->si_rwsem); -+ -+ au_kfree_try_rcu(sbinfo->si_branch); -+ mutex_destroy(&sbinfo->si_xib_mtx); -+ AuRwDestroy(&sbinfo->si_rwsem); -+ -+ au_lcnt_wait_for_fin(&sbinfo->si_ninodes); -+ /* si_nfiles is waited too */ -+ au_kfree_rcu(sbinfo); -+} -+ -+struct au_sbinfo *au_si_alloc(struct super_block *sb) -+{ -+ struct au_sbinfo *sbinfo; -+ int err, i; -+ -+ err = -ENOMEM; -+ sbinfo = kzalloc(sizeof(*sbinfo), GFP_NOFS); -+ if (unlikely(!sbinfo)) -+ goto out; -+ -+ /* will be reallocated separately */ -+ sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS); -+ if (unlikely(!sbinfo->si_branch)) -+ goto out_sbinfo; -+ -+ err = sysaufs_si_init(sbinfo); -+ if (!err) { -+ dbgaufs_si_null(sbinfo); -+ err = dbgaufs_si_init(sbinfo); -+ if (unlikely(err)) -+ kobject_put(&sbinfo->si_kobj); -+ } -+ if (unlikely(err)) -+ goto out_br; -+ -+ au_nwt_init(&sbinfo->si_nowait); -+ au_rw_init_wlock(&sbinfo->si_rwsem); -+ -+ au_lcnt_init(&sbinfo->si_ninodes, /*release*/NULL); -+ au_lcnt_init(&sbinfo->si_nfiles, /*release*/NULL); -+ -+ sbinfo->si_bbot = -1; -+ sbinfo->si_last_br_id = AUFS_BRANCH_MAX / 2; -+ -+ sbinfo->si_wbr_copyup = AuWbrCopyup_Def; -+ sbinfo->si_wbr_create = AuWbrCreate_Def; -+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + sbinfo->si_wbr_copyup; -+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + sbinfo->si_wbr_create; -+ -+ au_fhsm_init(sbinfo); -+ -+ sbinfo->si_mntflags = au_opts_plink(AuOpt_Def); -+ -+ sbinfo->si_xino_jiffy = jiffies; -+ sbinfo->si_xino_expire -+ = msecs_to_jiffies(AUFS_XINO_DEF_SEC * MSEC_PER_SEC); -+ mutex_init(&sbinfo->si_xib_mtx); -+ /* leave si_xib_last_pindex and si_xib_next_bit */ -+ -+ INIT_HLIST_BL_HEAD(&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; -+ sbinfo->si_dirwh = AUFS_DIRWH_DEF; -+ -+ for (i = 0; i < AuPlink_NHASH; i++) -+ INIT_HLIST_BL_HEAD(sbinfo->si_plink + i); -+ init_waitqueue_head(&sbinfo->si_plink_wq); -+ spin_lock_init(&sbinfo->si_plink_maint_lock); -+ -+ INIT_HLIST_BL_HEAD(&sbinfo->si_files); -+ -+ /* with getattr by default */ -+ sbinfo->si_iop_array = aufs_iop; -+ -+ /* leave other members for sysaufs and si_mnt. */ -+ sbinfo->si_sb = sb; -+ if (sb) { -+ sb->s_fs_info = sbinfo; -+ si_pid_set(sb); -+ } -+ return sbinfo; /* success */ -+ -+out_br: -+ au_kfree_try_rcu(sbinfo->si_branch); -+out_sbinfo: -+ au_kfree_rcu(sbinfo); -+out: -+ return ERR_PTR(err); -+} -+ -+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr, int may_shrink) -+{ -+ int err, sz; -+ struct au_branch **brp; -+ -+ AuRwMustWriteLock(&sbinfo->si_rwsem); -+ -+ err = -ENOMEM; -+ sz = sizeof(*brp) * (sbinfo->si_bbot + 1); -+ if (unlikely(!sz)) -+ sz = sizeof(*brp); -+ brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS, -+ may_shrink); -+ if (brp) { -+ sbinfo->si_branch = brp; -+ err = 0; -+ } -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+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); -+ inode = d_inode(sb->s_root); -+ au_update_iigen(inode, /*half*/0); -+ inode_inc_iversion(inode); -+ return gen; -+} -+ -+aufs_bindex_t au_new_br_id(struct super_block *sb) -+{ -+ aufs_bindex_t br_id; -+ int i; -+ struct au_sbinfo *sbinfo; -+ -+ SiMustWriteLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ for (i = 0; i <= AUFS_BRANCH_MAX; i++) { -+ br_id = ++sbinfo->si_last_br_id; -+ AuDebugOn(br_id < 0); -+ if (br_id && au_br_index(sb, br_id) < 0) -+ return br_id; -+ } -+ -+ return -1; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* it is ok that new 'nwt' tasks are appended while we are sleeping */ -+int si_read_lock(struct super_block *sb, int flags) -+{ -+ int err; -+ -+ err = 0; -+ if (au_ftest_lock(flags, FLUSH)) -+ au_nwt_flush(&au_sbi(sb)->si_nowait); -+ -+ si_noflush_read_lock(sb); -+ err = au_plink_maint(sb, flags); -+ if (unlikely(err)) -+ si_read_unlock(sb); -+ -+ return err; -+} -+ -+int si_write_lock(struct super_block *sb, int flags) -+{ -+ int err; -+ -+ if (au_ftest_lock(flags, FLUSH)) -+ au_nwt_flush(&au_sbi(sb)->si_nowait); -+ -+ si_noflush_write_lock(sb); -+ err = au_plink_maint(sb, flags); -+ if (unlikely(err)) -+ si_write_unlock(sb); -+ -+ return err; -+} -+ -+/* dentry and super_block lock. call at entry point */ -+int aufs_read_lock(struct dentry *dentry, int flags) -+{ -+ int err; -+ struct super_block *sb; -+ -+ sb = dentry->d_sb; -+ err = si_read_lock(sb, flags); -+ if (unlikely(err)) -+ goto out; -+ -+ if (au_ftest_lock(flags, DW)) -+ di_write_lock_child(dentry); -+ else -+ di_read_lock_child(dentry, flags); -+ -+ if (au_ftest_lock(flags, GEN)) { -+ err = au_digen_test(dentry, au_sigen(sb)); -+ if (!au_opt_test(au_mntflags(sb), UDBA_NONE)) -+ AuDebugOn(!err && au_dbrange_test(dentry)); -+ else if (!err) -+ err = au_dbrange_test(dentry); -+ if (unlikely(err)) -+ aufs_read_unlock(dentry, flags); -+ } -+ -+out: -+ return err; -+} -+ -+void aufs_read_unlock(struct dentry *dentry, int flags) -+{ -+ if (au_ftest_lock(flags, DW)) -+ di_write_unlock(dentry); -+ else -+ di_read_unlock(dentry, flags); -+ si_read_unlock(dentry->d_sb); -+} -+ -+void aufs_write_lock(struct dentry *dentry) -+{ -+ si_write_lock(dentry->d_sb, AuLock_FLUSH | AuLock_NOPLMW); -+ di_write_lock_child(dentry); -+} -+ -+void aufs_write_unlock(struct dentry *dentry) -+{ -+ di_write_unlock(dentry); -+ si_write_unlock(dentry->d_sb); -+} -+ -+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags) -+{ -+ int err; -+ unsigned int sigen; -+ struct super_block *sb; -+ -+ sb = d1->d_sb; -+ err = si_read_lock(sb, flags); -+ if (unlikely(err)) -+ goto out; -+ -+ di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIRS)); -+ -+ if (au_ftest_lock(flags, GEN)) { -+ sigen = au_sigen(sb); -+ err = au_digen_test(d1, sigen); -+ AuDebugOn(!err && au_dbrange_test(d1)); -+ if (!err) { -+ err = au_digen_test(d2, sigen); -+ AuDebugOn(!err && au_dbrange_test(d2)); -+ } -+ if (unlikely(err)) -+ aufs_read_and_write_unlock2(d1, d2); -+ } -+ -+out: -+ return err; -+} -+ -+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2) -+{ -+ di_write_unlock2(d1, d2); -+ si_read_unlock(d1->d_sb); -+} -diff -Naur null/fs/aufs/super.c linux-6.6.63/fs/aufs/super.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/super.c 2024-12-18 15:12:59.299519538 +0300 -@@ -0,0 +1,871 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * mount and super_block operations -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include "aufs.h" -+ -+/* -+ * super_operations -+ */ -+static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused) -+{ -+ struct au_icntnr *c; -+ -+ c = au_cache_alloc_icntnr(sb); -+ if (c) { -+ au_icntnr_init(c); -+ inode_set_iversion(&c->vfs_inode, 1); /* sigen(sb); */ -+ c->iinfo.ii_hinode = NULL; -+ return &c->vfs_inode; -+ } -+ return NULL; -+} -+ -+static void aufs_destroy_inode(struct inode *inode) -+{ -+ if (!au_is_bad_inode(inode)) -+ au_iinfo_fin(inode); -+} -+ -+static void aufs_free_inode(struct inode *inode) -+{ -+ au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode)); -+} -+ -+struct inode *au_iget_locked(struct super_block *sb, ino_t ino) -+{ -+ struct inode *inode; -+ int err; -+ -+ inode = iget_locked(sb, ino); -+ if (unlikely(!inode)) { -+ inode = ERR_PTR(-ENOMEM); -+ goto out; -+ } -+ if (!(inode->i_state & I_NEW)) -+ goto out; -+ -+ err = au_xigen_new(inode); -+ if (!err) -+ err = au_iinfo_init(inode); -+ if (!err) -+ inode_inc_iversion(inode); -+ else { -+ iget_failed(inode); -+ inode = ERR_PTR(err); -+ } -+ -+out: -+ /* never return NULL */ -+ AuDebugOn(!inode); -+ AuTraceErrPtr(inode); -+ return inode; -+} -+ -+/* lock free root dinfo */ -+static int au_show_brs(struct seq_file *seq, struct super_block *sb) -+{ -+ int err; -+ aufs_bindex_t bindex, bbot; -+ struct path path; -+ struct au_hdentry *hdp; -+ struct au_branch *br; -+ au_br_perm_str_t perm; -+ -+ err = 0; -+ bbot = au_sbbot(sb); -+ bindex = 0; -+ hdp = au_hdentry(au_di(sb->s_root), bindex); -+ for (; !err && bindex <= bbot; bindex++, hdp++) { -+ br = au_sbr(sb, bindex); -+ path.mnt = au_br_mnt(br); -+ path.dentry = hdp->hd_dentry; -+ err = au_seq_path(seq, &path); -+ if (!err) { -+ au_optstr_br_perm(&perm, br->br_perm); -+ seq_printf(seq, "=%s", perm.a); -+ if (bindex != bbot) -+ seq_putc(seq, ':'); -+ } -+ } -+ if (unlikely(err || seq_has_overflowed(seq))) -+ err = -E2BIG; -+ -+ return err; -+} -+ -+static void au_gen_fmt(char *fmt, int len, const char *pat, -+ const char *append) -+{ -+ char *p; -+ -+ p = fmt; -+ while (*pat != ':') -+ *p++ = *pat++; -+ *p++ = *pat++; -+ strscpy(p, append, len - (p - fmt)); -+ AuDebugOn(strlen(fmt) >= len); -+} -+ -+static void au_show_wbr_create(struct seq_file *m, int v, -+ struct au_sbinfo *sbinfo) -+{ -+ const char *pat; -+ char fmt[32]; -+ struct au_wbr_mfs *mfs; -+ -+ AuRwMustAnyLock(&sbinfo->si_rwsem); -+ -+ seq_puts(m, ",create="); -+ pat = au_optstr_wbr_create(v); -+ mfs = &sbinfo->si_wbr_mfs; -+ switch (v) { -+ case AuWbrCreate_TDP: -+ case AuWbrCreate_RR: -+ case AuWbrCreate_MFS: -+ case AuWbrCreate_PMFS: -+ seq_puts(m, pat); -+ break; -+ case AuWbrCreate_MFSRR: -+ case AuWbrCreate_TDMFS: -+ case AuWbrCreate_PMFSRR: -+ au_gen_fmt(fmt, sizeof(fmt), pat, "%llu"); -+ seq_printf(m, fmt, mfs->mfsrr_watermark); -+ break; -+ case AuWbrCreate_MFSV: -+ case AuWbrCreate_PMFSV: -+ au_gen_fmt(fmt, sizeof(fmt), pat, "%lu"); -+ seq_printf(m, fmt, -+ jiffies_to_msecs(mfs->mfs_expire) -+ / MSEC_PER_SEC); -+ break; -+ case AuWbrCreate_MFSRRV: -+ case AuWbrCreate_TDMFSV: -+ case AuWbrCreate_PMFSRRV: -+ au_gen_fmt(fmt, sizeof(fmt), pat, "%llu:%lu"); -+ seq_printf(m, fmt, mfs->mfsrr_watermark, -+ jiffies_to_msecs(mfs->mfs_expire) / MSEC_PER_SEC); -+ break; -+ default: -+ BUG(); -+ } -+} -+ -+static int au_show_xino(struct seq_file *seq, struct super_block *sb) -+{ -+#ifdef CONFIG_SYSFS -+ return 0; -+#else -+ int err; -+ const int len = sizeof(AUFS_XINO_FNAME) - 1; -+ aufs_bindex_t bindex, brid; -+ struct qstr *name; -+ struct file *f; -+ struct dentry *d, *h_root; -+ struct au_branch *br; -+ -+ AuRwMustAnyLock(&sbinfo->si_rwsem); -+ -+ err = 0; -+ f = au_sbi(sb)->si_xib; -+ if (!f) -+ goto out; -+ -+ /* stop printing the default xino path on the first writable branch */ -+ h_root = NULL; -+ bindex = au_xi_root(sb, f->f_path.dentry); -+ if (bindex >= 0) { -+ br = au_sbr_sb(sb, bindex); -+ h_root = au_br_dentry(br); -+ } -+ -+ d = f->f_path.dentry; -+ name = &d->d_name; -+ /* safe ->d_parent because the file is unlinked */ -+ if (d->d_parent == h_root -+ && name->len == len -+ && !memcmp(name->name, AUFS_XINO_FNAME, len)) -+ goto out; -+ -+ seq_puts(seq, ",xino="); -+ err = au_xino_path(seq, f); -+ -+out: -+ return err; -+#endif -+} -+ -+/* seq_file will re-call me in case of too long string */ -+static int aufs_show_options(struct seq_file *m, struct dentry *dentry) -+{ -+ int err; -+ unsigned int mnt_flags, v; -+ struct super_block *sb; -+ struct au_sbinfo *sbinfo; -+ -+#define AuBool(name, str) do { \ -+ v = au_opt_test(mnt_flags, name); \ -+ if (v != au_opt_test(AuOpt_Def, name)) \ -+ seq_printf(m, ",%s" #str, v ? "" : "no"); \ -+} while (0) -+ -+#define AuStr(name, str) do { \ -+ v = mnt_flags & AuOptMask_##name; \ -+ if (v != (AuOpt_Def & AuOptMask_##name)) \ -+ seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \ -+} while (0) -+ -+#define AuUInt(name, str, val) do { \ -+ if (val != AUFS_##name##_DEF) \ -+ seq_printf(m, "," #str "=%u", val); \ -+} while (0) -+ -+ sb = dentry->d_sb; -+ if (sb->s_flags & SB_POSIXACL) -+ seq_puts(m, ",acl"); -+#if 0 /* reserved for future use */ -+ if (sb->s_flags & SB_I_VERSION) -+ seq_puts(m, ",i_version"); -+#endif -+ -+ /* lock free root dinfo */ -+ si_noflush_read_lock(sb); -+ sbinfo = au_sbi(sb); -+ seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo)); -+ -+ mnt_flags = au_mntflags(sb); -+ if (au_opt_test(mnt_flags, XINO)) { -+ err = au_show_xino(m, sb); -+ if (unlikely(err)) -+ goto out; -+ } else -+ seq_puts(m, ",noxino"); -+ -+ AuBool(TRUNC_XINO, trunc_xino); -+ AuStr(UDBA, udba); -+ AuBool(SHWH, shwh); -+ AuBool(PLINK, plink); -+ AuBool(DIO, dio); -+ AuBool(DIRPERM1, dirperm1); -+ -+ v = sbinfo->si_wbr_create; -+ if (v != AuWbrCreate_Def) -+ au_show_wbr_create(m, v, sbinfo); -+ -+ v = sbinfo->si_wbr_copyup; -+ if (v != AuWbrCopyup_Def) -+ seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v)); -+ -+ v = au_opt_test(mnt_flags, ALWAYS_DIROPQ); -+ if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ)) -+ seq_printf(m, ",diropq=%c", v ? 'a' : 'w'); -+ -+ AuUInt(DIRWH, dirwh, sbinfo->si_dirwh); -+ -+ v = jiffies_to_msecs(sbinfo->si_rdcache) / MSEC_PER_SEC; -+ AuUInt(RDCACHE, rdcache, v); -+ -+ AuUInt(RDBLK, rdblk, sbinfo->si_rdblk); -+ AuUInt(RDHASH, rdhash, sbinfo->si_rdhash); -+ -+ au_fhsm_show(m, sbinfo); -+ -+ AuBool(DIRREN, dirren); -+ AuBool(SUM, sum); -+ /* AuBool(SUM_W, wsum); */ -+ AuBool(WARN_PERM, warn_perm); -+ AuBool(VERBOSE, verbose); -+ -+out: -+ /* be sure to print "br:" last */ -+ if (!sysaufs_brs) { -+ seq_puts(m, ",br:"); -+ au_show_brs(m, sb); -+ } -+ si_read_unlock(sb); -+ return 0; -+ -+#undef AuBool -+#undef AuStr -+#undef AuUInt -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* sum mode which returns the summation for statfs(2) */ -+ -+static u64 au_add_till_max(u64 a, u64 b) -+{ -+ u64 old; -+ -+ old = a; -+ a += b; -+ if (old <= a) -+ return a; -+ return ULLONG_MAX; -+} -+ -+static u64 au_mul_till_max(u64 a, long mul) -+{ -+ u64 old; -+ -+ old = a; -+ a *= mul; -+ if (old <= a) -+ return a; -+ return ULLONG_MAX; -+} -+ -+static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf) -+{ -+ int err; -+ long bsize, factor; -+ u64 blocks, bfree, bavail, files, ffree; -+ aufs_bindex_t bbot, bindex, i; -+ unsigned char shared; -+ struct path h_path; -+ struct super_block *h_sb; -+ -+ err = 0; -+ bsize = LONG_MAX; -+ files = 0; -+ ffree = 0; -+ blocks = 0; -+ bfree = 0; -+ bavail = 0; -+ bbot = au_sbbot(sb); -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ h_path.mnt = au_sbr_mnt(sb, bindex); -+ h_sb = h_path.mnt->mnt_sb; -+ shared = 0; -+ for (i = 0; !shared && i < bindex; i++) -+ shared = (au_sbr_sb(sb, i) == h_sb); -+ if (shared) -+ continue; -+ -+ /* sb->s_root for NFS is unreliable */ -+ h_path.dentry = h_path.mnt->mnt_root; -+ err = vfs_statfs(&h_path, buf); -+ if (unlikely(err)) -+ goto out; -+ -+ if (bsize > buf->f_bsize) { -+ /* -+ * we will reduce bsize, so we have to expand blocks -+ * etc. to match them again -+ */ -+ factor = (bsize / buf->f_bsize); -+ blocks = au_mul_till_max(blocks, factor); -+ bfree = au_mul_till_max(bfree, factor); -+ bavail = au_mul_till_max(bavail, factor); -+ bsize = buf->f_bsize; -+ } -+ -+ factor = (buf->f_bsize / bsize); -+ blocks = au_add_till_max(blocks, -+ au_mul_till_max(buf->f_blocks, factor)); -+ bfree = au_add_till_max(bfree, -+ au_mul_till_max(buf->f_bfree, factor)); -+ bavail = au_add_till_max(bavail, -+ au_mul_till_max(buf->f_bavail, factor)); -+ files = au_add_till_max(files, buf->f_files); -+ ffree = au_add_till_max(ffree, buf->f_ffree); -+ } -+ -+ buf->f_bsize = bsize; -+ buf->f_blocks = blocks; -+ buf->f_bfree = bfree; -+ buf->f_bavail = bavail; -+ buf->f_files = files; -+ buf->f_ffree = ffree; -+ buf->f_frsize = 0; -+ -+out: -+ return err; -+} -+ -+static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf) -+{ -+ int err; -+ struct path h_path; -+ struct super_block *sb; -+ -+ /* lock free root dinfo */ -+ sb = dentry->d_sb; -+ si_noflush_read_lock(sb); -+ if (!au_opt_test(au_mntflags(sb), SUM)) { -+ /* sb->s_root for NFS is unreliable */ -+ h_path.mnt = au_sbr_mnt(sb, 0); -+ h_path.dentry = h_path.mnt->mnt_root; -+ err = vfs_statfs(&h_path, buf); -+ } else -+ err = au_statfs_sum(sb, buf); -+ si_read_unlock(sb); -+ -+ if (!err) { -+ buf->f_type = AUFS_SUPER_MAGIC; -+ buf->f_namelen = AUFS_MAX_NAMELEN; -+ memset(&buf->f_fsid, 0, sizeof(buf->f_fsid)); -+ } -+ /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */ -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int aufs_sync_fs(struct super_block *sb, int wait) -+{ -+ int err, e; -+ aufs_bindex_t bbot, bindex; -+ struct au_branch *br; -+ struct super_block *h_sb; -+ -+ err = 0; -+ si_noflush_read_lock(sb); -+ bbot = au_sbbot(sb); -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (!au_br_writable(br->br_perm)) -+ continue; -+ -+ h_sb = au_sbr_sb(sb, bindex); -+ e = vfsub_sync_filesystem(h_sb); -+ if (unlikely(e && !err)) -+ err = e; -+ /* go on even if an error happens */ -+ } -+ si_read_unlock(sb); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* final actions when unmounting a file system */ -+static void aufs_put_super(struct super_block *sb) -+{ -+ struct au_sbinfo *sbinfo; -+ -+ sbinfo = au_sbi(sb); -+ if (sbinfo) -+ kobject_put(&sbinfo->si_kobj); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, -+ struct super_block *sb, void *arg) -+{ -+ void *array; -+ unsigned long long n, sz; -+ -+ array = NULL; -+ n = 0; -+ if (!*hint) -+ goto out; -+ -+ if (*hint > ULLONG_MAX / sizeof(array)) { -+ array = ERR_PTR(-EMFILE); -+ pr_err("hint %llu\n", *hint); -+ goto out; -+ } -+ -+ sz = sizeof(array) * *hint; -+ array = kzalloc(sz, GFP_NOFS); -+ if (unlikely(!array)) -+ array = vzalloc(sz); -+ if (unlikely(!array)) { -+ array = ERR_PTR(-ENOMEM); -+ goto out; -+ } -+ -+ n = cb(sb, array, *hint, arg); -+ AuDebugOn(n > *hint); -+ -+out: -+ *hint = n; -+ return array; -+} -+ -+static unsigned long long au_iarray_cb(struct super_block *sb, void *a, -+ unsigned long long max __maybe_unused, -+ void *arg) -+{ -+ unsigned long long n; -+ struct inode **p, *inode; -+ struct list_head *head; -+ -+ n = 0; -+ p = a; -+ head = arg; -+ spin_lock(&sb->s_inode_list_lock); -+ list_for_each_entry(inode, head, i_sb_list) { -+ if (!au_is_bad_inode(inode) -+ && au_ii(inode)->ii_btop >= 0) { -+ spin_lock(&inode->i_lock); -+ if (atomic_read(&inode->i_count)) { -+ au_igrab(inode); -+ *p++ = inode; -+ n++; -+ AuDebugOn(n > max); -+ } -+ spin_unlock(&inode->i_lock); -+ } -+ } -+ spin_unlock(&sb->s_inode_list_lock); -+ -+ return n; -+} -+ -+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max) -+{ -+ struct au_sbinfo *sbi; -+ -+ sbi = au_sbi(sb); -+ *max = au_lcnt_read(&sbi->si_ninodes, /*do_rev*/1); -+ return au_array_alloc(max, au_iarray_cb, sb, &sb->s_inodes); -+} -+ -+void au_iarray_free(struct inode **a, unsigned long long max) -+{ -+ unsigned long long ull; -+ -+ for (ull = 0; ull < max; ull++) -+ iput(a[ull]); -+ kvfree(a); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * refresh dentry and inode at remount time. -+ */ -+/* todo: consolidate with simple_reval_dpath() and au_reval_for_attr() */ -+static int au_do_refresh(struct dentry *dentry, unsigned int dir_flags, -+ struct dentry *parent) -+{ -+ int err; -+ -+ di_write_lock_child(dentry); -+ di_read_lock_parent(parent, AuLock_IR); -+ err = au_refresh_dentry(dentry, parent); -+ if (!err && dir_flags) -+ au_hn_reset(d_inode(dentry), dir_flags); -+ di_read_unlock(parent, AuLock_IR); -+ di_write_unlock(dentry); -+ -+ return err; -+} -+ -+static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen, -+ struct au_sbinfo *sbinfo, -+ const unsigned int dir_flags, unsigned int do_idop) -+{ -+ int err; -+ struct dentry *parent; -+ -+ err = 0; -+ parent = dget_parent(dentry); -+ if (!au_digen_test(parent, sigen) && au_digen_test(dentry, sigen)) { -+ if (d_really_is_positive(dentry)) { -+ if (!d_is_dir(dentry)) -+ err = au_do_refresh(dentry, /*dir_flags*/0, -+ parent); -+ else { -+ err = au_do_refresh(dentry, dir_flags, parent); -+ if (unlikely(err)) -+ au_fset_si(sbinfo, FAILED_REFRESH_DIR); -+ } -+ } else -+ err = au_do_refresh(dentry, /*dir_flags*/0, parent); -+ AuDbgDentry(dentry); -+ } -+ dput(parent); -+ -+ if (!err) { -+ if (do_idop) -+ au_refresh_dop(dentry, /*force_reval*/0); -+ } else -+ au_refresh_dop(dentry, /*force_reval*/1); -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_refresh_d(struct super_block *sb, unsigned int do_idop) -+{ -+ int err, i, j, ndentry, e; -+ unsigned int sigen; -+ struct au_dcsub_pages dpages; -+ struct au_dpage *dpage; -+ struct dentry **dentries, *d; -+ struct au_sbinfo *sbinfo; -+ struct dentry *root = sb->s_root; -+ const unsigned int dir_flags = au_hi_flags(d_inode(root), /*isdir*/1); -+ -+ if (do_idop) -+ au_refresh_dop(root, /*force_reval*/0); -+ -+ err = au_dpages_init(&dpages, GFP_NOFS); -+ if (unlikely(err)) -+ goto out; -+ err = au_dcsub_pages(&dpages, root, NULL, NULL); -+ if (unlikely(err)) -+ goto out_dpages; -+ -+ sigen = au_sigen(sb); -+ sbinfo = au_sbi(sb); -+ for (i = 0; i < dpages.ndpage; i++) { -+ dpage = dpages.dpages + i; -+ dentries = dpage->dentries; -+ ndentry = dpage->ndentry; -+ for (j = 0; j < ndentry; j++) { -+ d = dentries[j]; -+ e = au_do_refresh_d(d, sigen, sbinfo, dir_flags, -+ do_idop); -+ if (unlikely(e && !err)) -+ err = e; -+ /* go on even err */ -+ } -+ } -+ -+out_dpages: -+ au_dpages_free(&dpages); -+out: -+ return err; -+} -+ -+static int au_refresh_i(struct super_block *sb, unsigned int do_idop) -+{ -+ int err, e; -+ unsigned int sigen; -+ unsigned long long max, ull; -+ struct inode *inode, **array; -+ -+ array = au_iarray_alloc(sb, &max); -+ err = PTR_ERR(array); -+ if (IS_ERR(array)) -+ goto out; -+ -+ err = 0; -+ sigen = au_sigen(sb); -+ for (ull = 0; ull < max; ull++) { -+ inode = array[ull]; -+ if (unlikely(!inode)) -+ break; -+ -+ e = 0; -+ ii_write_lock_child(inode); -+ if (au_iigen(inode, NULL) != sigen) { -+ e = au_refresh_hinode_self(inode); -+ if (unlikely(e)) { -+ au_refresh_iop(inode, /*force_getattr*/1); -+ pr_err("error %d, i%lu\n", e, inode->i_ino); -+ if (!err) -+ err = e; -+ /* go on even if err */ -+ } -+ } -+ if (!e && do_idop) -+ au_refresh_iop(inode, /*force_getattr*/0); -+ ii_write_unlock(inode); -+ } -+ -+ au_iarray_free(array, max); -+ -+out: -+ return err; -+} -+ -+void au_remount_refresh(struct super_block *sb, unsigned int do_idop) -+{ -+ int err, e; -+ unsigned int udba; -+ aufs_bindex_t bindex, bbot; -+ struct dentry *root; -+ struct inode *inode; -+ struct au_branch *br; -+ struct au_sbinfo *sbi; -+ -+ au_sigen_inc(sb); -+ sbi = au_sbi(sb); -+ au_fclr_si(sbi, FAILED_REFRESH_DIR); -+ -+ root = sb->s_root; -+ DiMustNoWaiters(root); -+ inode = d_inode(root); -+ IiMustNoWaiters(inode); -+ -+ udba = au_opt_udba(sb); -+ bbot = au_sbbot(sb); -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ err = au_hnotify_reset_br(udba, br, br->br_perm); -+ if (unlikely(err)) -+ AuIOErr("hnotify failed on br %d, %d, ignored\n", -+ bindex, err); -+ /* go on even if err */ -+ } -+ au_hn_reset(inode, au_hi_flags(inode, /*isdir*/1)); -+ -+ if (do_idop) { -+ if (au_ftest_si(sbi, NO_DREVAL)) { -+ AuDebugOn(sb->s_d_op == &aufs_dop_noreval); -+ sb->s_d_op = &aufs_dop_noreval; -+ AuDebugOn(sbi->si_iop_array == aufs_iop_nogetattr); -+ sbi->si_iop_array = aufs_iop_nogetattr; -+ } else { -+ AuDebugOn(sb->s_d_op == &aufs_dop); -+ sb->s_d_op = &aufs_dop; -+ AuDebugOn(sbi->si_iop_array == aufs_iop); -+ sbi->si_iop_array = aufs_iop; -+ } -+ pr_info("reset to %ps and %ps\n", -+ sb->s_d_op, sbi->si_iop_array); -+ } -+ -+ di_write_unlock(root); -+ err = au_refresh_d(sb, do_idop); -+ e = au_refresh_i(sb, do_idop); -+ if (unlikely(e && !err)) -+ err = e; -+ /* aufs_write_lock() calls ..._child() */ -+ di_write_lock_child(root); -+ -+ au_cpup_attr_all(inode, /*force*/1); -+ -+ if (unlikely(err)) -+ AuIOErr("refresh failed, ignored, %d\n", err); -+} -+ -+const struct super_operations aufs_sop = { -+ .alloc_inode = aufs_alloc_inode, -+ .destroy_inode = aufs_destroy_inode, -+ .free_inode = aufs_free_inode, -+ /* always deleting, no clearing */ -+ .drop_inode = generic_delete_inode, -+ .show_options = aufs_show_options, -+ .statfs = aufs_statfs, -+ .put_super = aufs_put_super, -+ .sync_fs = aufs_sync_fs -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_alloc_root(struct super_block *sb) -+{ -+ int err; -+ struct inode *inode; -+ struct dentry *root; -+ -+ err = -ENOMEM; -+ inode = au_iget_locked(sb, AUFS_ROOT_INO); -+ err = PTR_ERR(inode); -+ if (IS_ERR(inode)) -+ goto out; -+ -+ inode->i_op = aufs_iop + AuIop_DIR; /* with getattr by default */ -+ inode->i_fop = &aufs_dir_fop; -+ inode->i_mode = S_IFDIR; -+ vfsub_inode_nlink_init(inode, 2); -+ unlock_new_inode(inode); -+ -+ root = d_make_root(inode); -+ if (unlikely(!root)) -+ goto out; -+ err = PTR_ERR(root); -+ if (IS_ERR(root)) -+ goto out; -+ -+ err = au_di_init(root); -+ if (!err) { -+ sb->s_root = root; -+ return 0; /* success */ -+ } -+ dput(root); -+ -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void aufs_kill_sb(struct super_block *sb) -+{ -+ struct au_sbinfo *sbinfo; -+ struct dentry *root; -+ -+ sbinfo = au_sbi(sb); -+ if (!sbinfo) -+ goto out; -+ -+ au_sbilist_del(sb); -+ -+ root = sb->s_root; -+ if (root) -+ aufs_write_lock(root); -+ else -+ __si_write_lock(sb); -+ -+ au_fhsm_fin(sb); -+ if (sbinfo->si_wbr_create_ops->fin) -+ sbinfo->si_wbr_create_ops->fin(sb); -+ if (au_opt_test(sbinfo->si_mntflags, UDBA_HNOTIFY)) { -+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_NONE); -+ au_remount_refresh(sb, /*do_idop*/0); -+ } -+ if (au_opt_test(sbinfo->si_mntflags, PLINK)) -+ au_plink_put(sb, /*verbose*/1); -+ au_xino_clr(sb); -+ if (root) -+ au_dr_opt_flush(sb); -+ -+ if (root) -+ aufs_write_unlock(root); -+ else -+ __si_write_unlock(sb); -+ -+ sbinfo->si_sb = NULL; -+ au_nwt_flush(&sbinfo->si_nowait); -+ -+out: -+ kill_anon_super(sb); -+} -+ -+struct file_system_type aufs_fs_type = { -+ .name = AUFS_FSTYPE, -+ /* a race between rename and others */ -+ .fs_flags = FS_RENAME_DOES_D_MOVE -+ /* untested */ -+ /*| FS_ALLOW_IDMAP*/ -+ , -+ .init_fs_context = aufs_fsctx_init, -+ .parameters = aufs_fsctx_paramspec, -+ .kill_sb = aufs_kill_sb, -+ /* no need to __module_get() and module_put(). */ -+ .owner = THIS_MODULE, -+}; -diff -Naur null/fs/aufs/super.h linux-6.6.63/fs/aufs/super.h ---- /dev/null -+++ linux-6.6.63/fs/aufs/super.h 2024-12-18 15:12:59.299519538 +0300 -@@ -0,0 +1,592 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * super_block operations -+ */ -+ -+#ifndef __AUFS_SUPER_H__ -+#define __AUFS_SUPER_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+#include "hbl.h" -+#include "lcnt.h" -+#include "rwsem.h" -+#include "wkq.h" -+ -+/* policies to select one among multiple writable branches */ -+struct au_wbr_copyup_operations { -+ int (*copyup)(struct dentry *dentry); -+}; -+ -+#define AuWbr_DIR 1 /* target is a dir */ -+#define AuWbr_PARENT (1 << 1) /* always require a parent */ -+ -+#define au_ftest_wbr(flags, name) ((flags) & AuWbr_##name) -+#define au_fset_wbr(flags, name) { (flags) |= AuWbr_##name; } -+#define au_fclr_wbr(flags, name) { (flags) &= ~AuWbr_##name; } -+ -+struct au_wbr_create_operations { -+ int (*create)(struct dentry *dentry, unsigned int flags); -+ int (*init)(struct super_block *sb); -+ int (*fin)(struct super_block *sb); -+}; -+ -+struct au_wbr_mfs { -+ struct mutex mfs_lock; /* protect this structure */ -+ unsigned long mfs_jiffy; -+ unsigned long mfs_expire; -+ aufs_bindex_t mfs_bindex; -+ -+ unsigned long long mfsrr_bytes; -+ unsigned long long mfsrr_watermark; -+}; -+ -+#define AuPlink_NHASH 100 -+static inline int au_plink_hash(ino_t ino) -+{ -+ return ino % AuPlink_NHASH; -+} -+ -+/* File-based Hierarchical Storage Management */ -+struct au_fhsm { -+#ifdef CONFIG_AUFS_FHSM -+ /* allow only one process who can receive the notification */ -+ spinlock_t fhsm_spin; -+ pid_t fhsm_pid; -+ wait_queue_head_t fhsm_wqh; -+ atomic_t fhsm_readable; -+ -+ /* these are protected by si_rwsem */ -+ unsigned long fhsm_expire; -+ aufs_bindex_t fhsm_bottom; -+#endif -+}; -+ -+struct au_branch; -+struct au_sbinfo { -+ /* nowait tasks in the system-wide workqueue */ -+ struct au_nowait_tasks si_nowait; -+ -+ /* -+ * tried sb->s_umount, but failed due to the dependency between i_mutex. -+ * rwsem for au_sbinfo is necessary. -+ */ -+ struct au_rwsem si_rwsem; -+ -+ /* -+ * dirty approach to protect sb->sb_inodes and ->s_files (gone) from -+ * remount. -+ */ -+ au_lcnt_t si_ninodes, si_nfiles; -+ -+ /* branch management */ -+ unsigned int si_generation; -+ -+ /* see AuSi_ flags */ -+ unsigned char au_si_status; -+ -+ aufs_bindex_t si_bbot; -+ -+ /* dirty trick to keep br_id plus */ -+ unsigned int si_last_br_id : -+ sizeof(aufs_bindex_t) * BITS_PER_BYTE - 1; -+ struct au_branch **si_branch; -+ -+ /* policy to select a writable branch */ -+ unsigned char si_wbr_copyup; -+ unsigned char si_wbr_create; -+ struct au_wbr_copyup_operations *si_wbr_copyup_ops; -+ struct au_wbr_create_operations *si_wbr_create_ops; -+ -+ /* round robin */ -+ atomic_t si_wbr_rr_next; -+ -+ /* most free space */ -+ struct au_wbr_mfs si_wbr_mfs; -+ -+ /* File-based Hierarchical Storage Management */ -+ struct au_fhsm si_fhsm; -+ -+ /* mount flags */ -+ /* include/asm-ia64/siginfo.h defines a macro named si_flags */ -+ unsigned int si_mntflags; -+ -+ /* external inode number (bitmap and translation table) */ -+ loff_t si_ximaxent; /* max entries in a xino */ -+ -+ struct file *si_xib; -+ struct mutex si_xib_mtx; /* protect xib members */ -+ unsigned long *si_xib_buf; -+ unsigned long si_xib_last_pindex; -+ int si_xib_next_bit; -+ -+ unsigned long si_xino_jiffy; -+ unsigned long si_xino_expire; -+ /* reserved for future use */ -+ /* unsigned long long si_xib_limit; */ /* Max xib file size */ -+ -+#ifdef CONFIG_AUFS_EXPORT -+ /* i_generation */ -+ /* todo: make xigen file an array to support many inode numbers */ -+ struct file *si_xigen; -+ atomic_t si_xigen_next; -+#endif -+ -+ /* dirty trick to support atomic_open */ -+ struct hlist_bl_head si_aopen; -+ -+ /* vdir parameters */ -+ unsigned long si_rdcache; /* max cache time in jiffies */ -+ unsigned int si_rdblk; /* deblk size */ -+ unsigned int si_rdhash; /* hash size */ -+ -+ /* -+ * If the number of whiteouts are larger than si_dirwh, leave all of -+ * them after au_whtmp_ren to reduce the cost of rmdir(2). -+ * future fsck.aufs or kernel thread will remove them later. -+ * Otherwise, remove all whiteouts and the dir in rmdir(2). -+ */ -+ unsigned int si_dirwh; -+ -+ /* pseudo_link list */ -+ struct hlist_bl_head si_plink[AuPlink_NHASH]; -+ wait_queue_head_t si_plink_wq; -+ spinlock_t si_plink_maint_lock; -+ pid_t si_plink_maint_pid; -+ -+ /* file list */ -+ struct hlist_bl_head si_files; -+ -+ /* with/without getattr, brother of sb->s_d_op */ -+ const struct inode_operations *si_iop_array; -+ -+ /* -+ * sysfs and lifetime management. -+ * this is not a small structure and it may be a waste of memory in case -+ * of sysfs is disabled, particularly when many aufs-es are mounted. -+ * but using sysfs is majority. -+ */ -+ struct kobject si_kobj; -+#ifdef CONFIG_DEBUG_FS -+ struct dentry *si_dbgaufs; -+ struct dentry *si_dbgaufs_plink; -+ struct dentry *si_dbgaufs_xib; -+#ifdef CONFIG_AUFS_EXPORT -+ struct dentry *si_dbgaufs_xigen; -+#endif -+#endif -+ -+#ifdef CONFIG_AUFS_SBILIST -+ struct hlist_bl_node si_list; -+#endif -+ -+ /* dirty, necessary for unmounting, sysfs and sysrq */ -+ struct super_block *si_sb; -+}; -+ -+/* sbinfo status flags */ -+/* -+ * set true when refresh_dirs() failed at remount time. -+ * then try refreshing dirs at access time again. -+ * if it is false, refreshing dirs at access time is unnecessary -+ */ -+#define AuSi_FAILED_REFRESH_DIR 1 -+#define AuSi_FHSM (1 << 1) /* fhsm is active now */ -+#define AuSi_NO_DREVAL (1 << 2) /* disable all d_revalidate */ -+ -+#ifndef CONFIG_AUFS_FHSM -+#undef AuSi_FHSM -+#define AuSi_FHSM 0 -+#endif -+ -+static inline unsigned char au_do_ftest_si(struct au_sbinfo *sbi, -+ unsigned int flag) -+{ -+ AuRwMustAnyLock(&sbi->si_rwsem); -+ return sbi->au_si_status & flag; -+} -+#define au_ftest_si(sbinfo, name) au_do_ftest_si(sbinfo, AuSi_##name) -+#define au_fset_si(sbinfo, name) do { \ -+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \ -+ (sbinfo)->au_si_status |= AuSi_##name; \ -+} while (0) -+#define au_fclr_si(sbinfo, name) do { \ -+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \ -+ (sbinfo)->au_si_status &= ~AuSi_##name; \ -+} while (0) -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* policy to select one among writable branches */ -+#define AuWbrCopyup(sbinfo, ...) \ -+ ((sbinfo)->si_wbr_copyup_ops->copyup(__VA_ARGS__)) -+#define AuWbrCreate(sbinfo, ...) \ -+ ((sbinfo)->si_wbr_create_ops->create(__VA_ARGS__)) -+ -+/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */ -+#define AuLock_DW 1 /* write-lock dentry */ -+#define AuLock_IR (1 << 1) /* read-lock inode */ -+#define AuLock_IW (1 << 2) /* write-lock inode */ -+#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */ -+#define AuLock_DIRS (1 << 4) /* target is a pair of dirs */ -+ /* except RENAME_EXCHANGE */ -+#define AuLock_NOPLM (1 << 5) /* return err in plm mode */ -+#define AuLock_NOPLMW (1 << 6) /* wait for plm mode ends */ -+#define AuLock_GEN (1 << 7) /* test digen/iigen */ -+#define au_ftest_lock(flags, name) ((flags) & AuLock_##name) -+#define au_fset_lock(flags, name) \ -+ do { (flags) |= AuLock_##name; } while (0) -+#define au_fclr_lock(flags, name) \ -+ do { (flags) &= ~AuLock_##name; } while (0) -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* super.c */ -+struct inode *au_iget_locked(struct super_block *sb, ino_t ino); -+ -+typedef unsigned long long (*au_arraycb_t)(struct super_block *sb, void *array, -+ unsigned long long max, void *arg); -+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, -+ struct super_block *sb, void *arg); -+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max); -+void au_iarray_free(struct inode **a, unsigned long long max); -+ -+void au_remount_refresh(struct super_block *sb, unsigned int do_idop); -+extern const struct super_operations aufs_sop; -+int au_alloc_root(struct super_block *sb); -+extern struct file_system_type aufs_fs_type; -+ -+/* sbinfo.c */ -+void au_si_free(struct kobject *kobj); -+struct au_sbinfo *au_si_alloc(struct super_block *sb); -+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr, int may_shrink); -+ -+unsigned int au_sigen_inc(struct super_block *sb); -+aufs_bindex_t au_new_br_id(struct super_block *sb); -+ -+int si_read_lock(struct super_block *sb, int flags); -+int si_write_lock(struct super_block *sb, int flags); -+int aufs_read_lock(struct dentry *dentry, int flags); -+void aufs_read_unlock(struct dentry *dentry, int flags); -+void aufs_write_lock(struct dentry *dentry); -+void aufs_write_unlock(struct dentry *dentry); -+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags); -+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2); -+ -+/* wbr_policy.c */ -+extern struct au_wbr_copyup_operations au_wbr_copyup_ops[]; -+extern struct au_wbr_create_operations au_wbr_create_ops[]; -+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst); -+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex); -+int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t btop); -+ -+/* mvdown.c */ -+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *arg); -+ -+#ifdef CONFIG_AUFS_FHSM -+/* fhsm.c */ -+ -+static inline pid_t au_fhsm_pid(struct au_fhsm *fhsm) -+{ -+ pid_t pid; -+ -+ spin_lock(&fhsm->fhsm_spin); -+ pid = fhsm->fhsm_pid; -+ spin_unlock(&fhsm->fhsm_spin); -+ -+ return pid; -+} -+ -+void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force); -+void au_fhsm_wrote_all(struct super_block *sb, int force); -+int au_fhsm_fd(struct super_block *sb, int oflags); -+int au_fhsm_br_alloc(struct au_branch *br); -+void au_fhsm_set_bottom(struct super_block *sb, aufs_bindex_t bindex); -+void au_fhsm_fin(struct super_block *sb); -+void au_fhsm_init(struct au_sbinfo *sbinfo); -+void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec); -+void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo); -+#else -+AuStubVoid(au_fhsm_wrote, struct super_block *sb, aufs_bindex_t bindex, -+ int force) -+AuStubVoid(au_fhsm_wrote_all, struct super_block *sb, int force) -+AuStub(int, au_fhsm_fd, return -EOPNOTSUPP, struct super_block *sb, int oflags) -+AuStub(pid_t, au_fhsm_pid, return 0, struct au_fhsm *fhsm) -+AuStubInt0(au_fhsm_br_alloc, struct au_branch *br) -+AuStubVoid(au_fhsm_set_bottom, struct super_block *sb, aufs_bindex_t bindex) -+AuStubVoid(au_fhsm_fin, struct super_block *sb) -+AuStubVoid(au_fhsm_init, struct au_sbinfo *sbinfo) -+AuStubVoid(au_fhsm_set, struct au_sbinfo *sbinfo, unsigned int sec) -+AuStubVoid(au_fhsm_show, struct seq_file *seq, struct au_sbinfo *sbinfo) -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline struct au_sbinfo *au_sbi(struct super_block *sb) -+{ -+ return sb->s_fs_info; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+#ifdef CONFIG_AUFS_EXPORT -+int au_test_nfsd(void); -+void au_export_init(struct super_block *sb); -+void au_xigen_inc(struct inode *inode); -+int au_xigen_new(struct inode *inode); -+int au_xigen_set(struct super_block *sb, struct path *path); -+void au_xigen_clr(struct super_block *sb); -+ -+static inline int au_busy_or_stale(void) -+{ -+ if (!au_test_nfsd()) -+ return -EBUSY; -+ return -ESTALE; -+} -+#else -+AuStubInt0(au_test_nfsd, void) -+AuStubVoid(au_export_init, struct super_block *sb) -+AuStubVoid(au_xigen_inc, struct inode *inode) -+AuStubInt0(au_xigen_new, struct inode *inode) -+AuStubInt0(au_xigen_set, struct super_block *sb, struct path *path) -+AuStubVoid(au_xigen_clr, struct super_block *sb) -+AuStub(int, au_busy_or_stale, return -EBUSY, void) -+#endif /* CONFIG_AUFS_EXPORT */ -+ -+/* ---------------------------------------------------------------------- */ -+ -+#ifdef CONFIG_AUFS_SBILIST -+/* module.c */ -+extern struct hlist_bl_head au_sbilist; -+ -+static inline void au_sbilist_init(void) -+{ -+ INIT_HLIST_BL_HEAD(&au_sbilist); -+} -+ -+static inline void au_sbilist_add(struct super_block *sb) -+{ -+ au_hbl_add(&au_sbi(sb)->si_list, &au_sbilist); -+} -+ -+static inline void au_sbilist_del(struct super_block *sb) -+{ -+ au_hbl_del(&au_sbi(sb)->si_list, &au_sbilist); -+} -+ -+#ifdef CONFIG_AUFS_MAGIC_SYSRQ -+static inline void au_sbilist_lock(void) -+{ -+ hlist_bl_lock(&au_sbilist); -+} -+ -+static inline void au_sbilist_unlock(void) -+{ -+ hlist_bl_unlock(&au_sbilist); -+} -+#define AuGFP_SBILIST GFP_ATOMIC -+#else -+AuStubVoid(au_sbilist_lock, void) -+AuStubVoid(au_sbilist_unlock, void) -+#define AuGFP_SBILIST GFP_NOFS -+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */ -+#else -+AuStubVoid(au_sbilist_init, void) -+AuStubVoid(au_sbilist_add, struct super_block *sb) -+AuStubVoid(au_sbilist_del, struct super_block *sb) -+AuStubVoid(au_sbilist_lock, void) -+AuStubVoid(au_sbilist_unlock, void) -+#define AuGFP_SBILIST GFP_NOFS -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo) -+{ -+ /* -+ * This function is a dynamic '__init' function actually, -+ * so the tiny check for si_rwsem is unnecessary. -+ */ -+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */ -+#ifdef CONFIG_DEBUG_FS -+ sbinfo->si_dbgaufs = NULL; -+ sbinfo->si_dbgaufs_plink = NULL; -+ sbinfo->si_dbgaufs_xib = NULL; -+#ifdef CONFIG_AUFS_EXPORT -+ sbinfo->si_dbgaufs_xigen = NULL; -+#endif -+#endif -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* current->atomic_flags */ -+/* this value should never corrupt the ones defined in linux/sched.h */ -+#define PFA_AUFS 0x10 -+ -+TASK_PFA_TEST(AUFS, test_aufs) /* task_test_aufs */ -+TASK_PFA_SET(AUFS, aufs) /* task_set_aufs */ -+TASK_PFA_CLEAR(AUFS, aufs) /* task_clear_aufs */ -+ -+static inline int si_pid_test(struct super_block *sb) -+{ -+ return !!task_test_aufs(current); -+} -+ -+static inline void si_pid_clr(struct super_block *sb) -+{ -+ AuDebugOn(!task_test_aufs(current)); -+ task_clear_aufs(current); -+} -+ -+static inline void si_pid_set(struct super_block *sb) -+{ -+ AuDebugOn(task_test_aufs(current)); -+ task_set_aufs(current); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* lock superblock. mainly for entry point functions */ -+#define __si_read_lock(sb) au_rw_read_lock(&au_sbi(sb)->si_rwsem) -+#define __si_write_lock(sb) au_rw_write_lock(&au_sbi(sb)->si_rwsem) -+#define __si_read_trylock(sb) au_rw_read_trylock(&au_sbi(sb)->si_rwsem) -+#define __si_write_trylock(sb) au_rw_write_trylock(&au_sbi(sb)->si_rwsem) -+/* -+#define __si_read_trylock_nested(sb) \ -+ au_rw_read_trylock_nested(&au_sbi(sb)->si_rwsem) -+#define __si_write_trylock_nested(sb) \ -+ au_rw_write_trylock_nested(&au_sbi(sb)->si_rwsem) -+*/ -+ -+#define __si_read_unlock(sb) au_rw_read_unlock(&au_sbi(sb)->si_rwsem) -+#define __si_write_unlock(sb) au_rw_write_unlock(&au_sbi(sb)->si_rwsem) -+#define __si_downgrade_lock(sb) au_rw_dgrade_lock(&au_sbi(sb)->si_rwsem) -+ -+#define SiMustNoWaiters(sb) AuRwMustNoWaiters(&au_sbi(sb)->si_rwsem) -+#define SiMustAnyLock(sb) AuRwMustAnyLock(&au_sbi(sb)->si_rwsem) -+#define SiMustWriteLock(sb) AuRwMustWriteLock(&au_sbi(sb)->si_rwsem) -+ -+static inline void si_noflush_read_lock(struct super_block *sb) -+{ -+ __si_read_lock(sb); -+ si_pid_set(sb); -+} -+ -+static inline int si_noflush_read_trylock(struct super_block *sb) -+{ -+ int locked; -+ -+ locked = __si_read_trylock(sb); -+ if (locked) -+ si_pid_set(sb); -+ return locked; -+} -+ -+static inline void si_noflush_write_lock(struct super_block *sb) -+{ -+ __si_write_lock(sb); -+ si_pid_set(sb); -+} -+ -+static inline int si_noflush_write_trylock(struct super_block *sb) -+{ -+ int locked; -+ -+ locked = __si_write_trylock(sb); -+ if (locked) -+ si_pid_set(sb); -+ return locked; -+} -+ -+#if 0 /* reserved */ -+static inline int si_read_trylock(struct super_block *sb, int flags) -+{ -+ if (au_ftest_lock(flags, FLUSH)) -+ au_nwt_flush(&au_sbi(sb)->si_nowait); -+ return si_noflush_read_trylock(sb); -+} -+#endif -+ -+static inline void si_read_unlock(struct super_block *sb) -+{ -+ si_pid_clr(sb); -+ __si_read_unlock(sb); -+} -+ -+#if 0 /* reserved */ -+static inline int si_write_trylock(struct super_block *sb, int flags) -+{ -+ if (au_ftest_lock(flags, FLUSH)) -+ au_nwt_flush(&au_sbi(sb)->si_nowait); -+ return si_noflush_write_trylock(sb); -+} -+#endif -+ -+static inline void si_write_unlock(struct super_block *sb) -+{ -+ si_pid_clr(sb); -+ __si_write_unlock(sb); -+} -+ -+#if 0 /* reserved */ -+static inline void si_downgrade_lock(struct super_block *sb) -+{ -+ __si_downgrade_lock(sb); -+} -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline aufs_bindex_t au_sbbot(struct super_block *sb) -+{ -+ SiMustAnyLock(sb); -+ return au_sbi(sb)->si_bbot; -+} -+ -+static inline unsigned int au_mntflags(struct super_block *sb) -+{ -+ SiMustAnyLock(sb); -+ return au_sbi(sb)->si_mntflags; -+} -+ -+static inline unsigned int au_sigen(struct super_block *sb) -+{ -+ SiMustAnyLock(sb); -+ return au_sbi(sb)->si_generation; -+} -+ -+static inline struct au_branch *au_sbr(struct super_block *sb, -+ aufs_bindex_t bindex) -+{ -+ SiMustAnyLock(sb); -+ return au_sbi(sb)->si_branch[0 + bindex]; -+} -+ -+static inline loff_t au_xi_maxent(struct super_block *sb) -+{ -+ SiMustAnyLock(sb); -+ return au_sbi(sb)->si_ximaxent; -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_SUPER_H__ */ -diff -Naur null/fs/aufs/sysaufs.c linux-6.6.63/fs/aufs/sysaufs.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/sysaufs.c 2024-12-18 15:12:59.299519538 +0300 -@@ -0,0 +1,94 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * sysfs interface and lifetime management -+ * they are necessary regardless sysfs is disabled. -+ */ -+ -+#include -+#include "aufs.h" -+ -+unsigned long sysaufs_si_mask; -+struct kset *sysaufs_kset; -+ -+#define AuSiAttr(_name) { \ -+ .attr = { .name = __stringify(_name), .mode = 0444 }, \ -+ .show = sysaufs_si_##_name, \ -+} -+ -+static struct sysaufs_si_attr sysaufs_si_attr_xi_path = AuSiAttr(xi_path); -+struct attribute *sysaufs_si_attrs[] = { -+ &sysaufs_si_attr_xi_path.attr, -+ NULL, -+}; -+ATTRIBUTE_GROUPS(sysaufs_si); -+ -+static const struct sysfs_ops au_sbi_ops = { -+ .show = sysaufs_si_show -+}; -+ -+static const struct kobj_type au_sbi_ktype = { -+ .release = au_si_free, -+ .sysfs_ops = &au_sbi_ops, -+ .default_groups = sysaufs_si_groups -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+int sysaufs_si_init(struct au_sbinfo *sbinfo) -+{ -+ int err; -+ -+ sbinfo->si_kobj.kset = sysaufs_kset; -+ /* cf. sysaufs_name() */ -+ err = kobject_init_and_add -+ (&sbinfo->si_kobj, &au_sbi_ktype, /*&sysaufs_kset->kobj*/NULL, -+ SysaufsSiNamePrefix "%lx", sysaufs_si_id(sbinfo)); -+ -+ return err; -+} -+ -+void sysaufs_fin(void) -+{ -+ sysfs_remove_group(&sysaufs_kset->kobj, sysaufs_attr_group); -+ kset_unregister(sysaufs_kset); -+} -+ -+int __init sysaufs_init(void) -+{ -+ int err; -+ -+ do { -+ get_random_bytes(&sysaufs_si_mask, sizeof(sysaufs_si_mask)); -+ } while (!sysaufs_si_mask); -+ -+ err = -EINVAL; -+ sysaufs_kset = kset_create_and_add(AUFS_NAME, NULL, fs_kobj); -+ if (unlikely(!sysaufs_kset)) -+ goto out; -+ err = PTR_ERR(sysaufs_kset); -+ if (IS_ERR(sysaufs_kset)) -+ goto out; -+ err = sysfs_create_group(&sysaufs_kset->kobj, sysaufs_attr_group); -+ if (unlikely(err)) -+ kset_unregister(sysaufs_kset); -+ -+out: -+ return err; -+} -diff -Naur null/fs/aufs/sysaufs.h linux-6.6.63/fs/aufs/sysaufs.h ---- /dev/null -+++ linux-6.6.63/fs/aufs/sysaufs.h 2024-12-18 15:12:59.299519538 +0300 -@@ -0,0 +1,102 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * sysfs interface and mount lifetime management -+ */ -+ -+#ifndef __SYSAUFS_H__ -+#define __SYSAUFS_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include "module.h" -+ -+struct super_block; -+struct au_sbinfo; -+ -+struct sysaufs_si_attr { -+ struct attribute attr; -+ int (*show)(struct seq_file *seq, struct super_block *sb); -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* sysaufs.c */ -+extern unsigned long sysaufs_si_mask; -+extern struct kset *sysaufs_kset; -+extern struct attribute *sysaufs_si_attrs[]; -+int sysaufs_si_init(struct au_sbinfo *sbinfo); -+int __init sysaufs_init(void); -+void sysaufs_fin(void); -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* some people doesn't like to show a pointer in kernel */ -+static inline unsigned long sysaufs_si_id(struct au_sbinfo *sbinfo) -+{ -+ return sysaufs_si_mask ^ (unsigned long)sbinfo; -+} -+ -+#define SysaufsSiNamePrefix "si_" -+#define SysaufsSiNameLen (sizeof(SysaufsSiNamePrefix) + 16) -+static inline void sysaufs_name(struct au_sbinfo *sbinfo, char *name) -+{ -+ snprintf(name, SysaufsSiNameLen, SysaufsSiNamePrefix "%lx", -+ sysaufs_si_id(sbinfo)); -+} -+ -+struct au_branch; -+#ifdef CONFIG_SYSFS -+/* sysfs.c */ -+extern struct attribute_group *sysaufs_attr_group; -+ -+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb); -+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr, -+ char *buf); -+long au_brinfo_ioctl(struct file *file, unsigned long arg); -+#ifdef CONFIG_COMPAT -+long au_brinfo_compat_ioctl(struct file *file, unsigned long arg); -+#endif -+ -+void sysaufs_br_init(struct au_branch *br); -+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex); -+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex); -+ -+#define sysaufs_brs_init() do {} while (0) -+ -+#else -+#define sysaufs_attr_group NULL -+ -+AuStubInt0(sysaufs_si_xi_path, struct seq_file *seq, struct super_block *sb) -+AuStub(ssize_t, sysaufs_si_show, return 0, struct kobject *kobj, -+ struct attribute *attr, char *buf) -+AuStubVoid(sysaufs_br_init, struct au_branch *br) -+AuStubVoid(sysaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex) -+AuStubVoid(sysaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex) -+ -+static inline void sysaufs_brs_init(void) -+{ -+ sysaufs_brs = 0; -+} -+ -+#endif /* CONFIG_SYSFS */ -+ -+#endif /* __KERNEL__ */ -+#endif /* __SYSAUFS_H__ */ -diff -Naur null/fs/aufs/sysfs.c linux-6.6.63/fs/aufs/sysfs.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/sysfs.c 2024-12-18 15:12:59.299519538 +0300 -@@ -0,0 +1,374 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * sysfs interface -+ */ -+ -+#include -+#include -+#include "aufs.h" -+ -+#ifdef CONFIG_AUFS_FS_MODULE -+/* this entry violates the "one line per file" policy of sysfs */ -+static ssize_t config_show(struct kobject *kobj, struct kobj_attribute *attr, -+ char *buf) -+{ -+ ssize_t err; -+ static char *conf = -+/* this file is generated at compiling */ -+#include "conf.str" -+ ; -+ -+ err = snprintf(buf, PAGE_SIZE, conf); -+ if (unlikely(err >= PAGE_SIZE)) -+ err = -EFBIG; -+ return err; -+} -+ -+static struct kobj_attribute au_config_attr = __ATTR_RO(config); -+#endif -+ -+static struct attribute *au_attr[] = { -+#ifdef CONFIG_AUFS_FS_MODULE -+ &au_config_attr.attr, -+#endif -+ NULL, /* need to NULL terminate the list of attributes */ -+}; -+ -+static struct attribute_group sysaufs_attr_group_body = { -+ .attrs = au_attr -+}; -+ -+struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body; -+ -+/* ---------------------------------------------------------------------- */ -+ -+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb) -+{ -+ int err; -+ -+ SiMustAnyLock(sb); -+ -+ err = 0; -+ if (au_opt_test(au_mntflags(sb), XINO)) { -+ err = au_xino_path(seq, au_sbi(sb)->si_xib); -+ seq_putc(seq, '\n'); -+ } -+ return err; -+} -+ -+/* -+ * the lifetime of branch is independent from the entry under sysfs. -+ * sysfs handles the lifetime of the entry, and never call ->show() after it is -+ * unlinked. -+ */ -+static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb, -+ aufs_bindex_t bindex, int idx) -+{ -+ int err; -+ struct path path; -+ struct dentry *root; -+ struct au_branch *br; -+ au_br_perm_str_t perm; -+ -+ AuDbg("b%d\n", bindex); -+ -+ err = 0; -+ root = sb->s_root; -+ di_read_lock_parent(root, !AuLock_IR); -+ br = au_sbr(sb, bindex); -+ -+ switch (idx) { -+ case AuBrSysfs_BR: -+ path.mnt = au_br_mnt(br); -+ path.dentry = au_h_dptr(root, bindex); -+ err = au_seq_path(seq, &path); -+ if (!err) { -+ au_optstr_br_perm(&perm, br->br_perm); -+ seq_printf(seq, "=%s\n", perm.a); -+ } -+ break; -+ case AuBrSysfs_BRID: -+ seq_printf(seq, "%d\n", br->br_id); -+ break; -+ } -+ di_read_unlock(root, !AuLock_IR); -+ if (unlikely(err || seq_has_overflowed(seq))) -+ err = -E2BIG; -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static struct seq_file *au_seq(char *p, ssize_t len) -+{ -+ struct seq_file *seq; -+ -+ seq = kzalloc(sizeof(*seq), GFP_NOFS); -+ if (seq) { -+ /* mutex_init(&seq.lock); */ -+ seq->buf = p; -+ seq->size = len; -+ return seq; /* success */ -+ } -+ -+ seq = ERR_PTR(-ENOMEM); -+ return seq; -+} -+ -+#define SysaufsBr_PREFIX "br" -+#define SysaufsBrid_PREFIX "brid" -+ -+/* todo: file size may exceed PAGE_SIZE */ -+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr, -+ char *buf) -+{ -+ ssize_t err; -+ int idx; -+ long l; -+ aufs_bindex_t bbot; -+ struct au_sbinfo *sbinfo; -+ struct super_block *sb; -+ struct seq_file *seq; -+ char *name; -+ struct attribute **cattr; -+ -+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj); -+ sb = sbinfo->si_sb; -+ -+ /* -+ * prevent a race condition between sysfs and aufs. -+ * for instance, sysfs_file_read() calls sysfs_get_active_two() which -+ * prohibits maintaining the sysfs entries. -+ * hew we acquire read lock after sysfs_get_active_two(). -+ * on the other hand, the remount process may maintain the sysfs/aufs -+ * entries after acquiring write lock. -+ * it can cause a deadlock. -+ * simply we gave up processing read here. -+ */ -+ err = -EBUSY; -+ if (unlikely(!si_noflush_read_trylock(sb))) -+ goto out; -+ -+ seq = au_seq(buf, PAGE_SIZE); -+ err = PTR_ERR(seq); -+ if (IS_ERR(seq)) -+ goto out_unlock; -+ -+ name = (void *)attr->name; -+ cattr = sysaufs_si_attrs; -+ while (*cattr) { -+ if (!strcmp(name, (*cattr)->name)) { -+ err = container_of(*cattr, struct sysaufs_si_attr, attr) -+ ->show(seq, sb); -+ goto out_seq; -+ } -+ cattr++; -+ } -+ -+ if (!strncmp(name, SysaufsBrid_PREFIX, -+ sizeof(SysaufsBrid_PREFIX) - 1)) { -+ idx = AuBrSysfs_BRID; -+ name += sizeof(SysaufsBrid_PREFIX) - 1; -+ } else if (!strncmp(name, SysaufsBr_PREFIX, -+ sizeof(SysaufsBr_PREFIX) - 1)) { -+ idx = AuBrSysfs_BR; -+ name += sizeof(SysaufsBr_PREFIX) - 1; -+ } else -+ BUG(); -+ -+ err = kstrtol(name, 10, &l); -+ if (!err) { -+ bbot = au_sbbot(sb); -+ if (l <= bbot) -+ err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l, idx); -+ else -+ err = -ENOENT; -+ } -+ -+out_seq: -+ if (!err) { -+ err = seq->count; -+ /* sysfs limit */ -+ if (unlikely(err == PAGE_SIZE)) -+ err = -EFBIG; -+ } -+ au_kfree_rcu(seq); -+out_unlock: -+ si_read_unlock(sb); -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_brinfo(struct super_block *sb, union aufs_brinfo __user *arg) -+{ -+ int err; -+ int16_t brid; -+ aufs_bindex_t bindex, bbot; -+ size_t sz; -+ char *buf; -+ struct seq_file *seq; -+ struct au_branch *br; -+ -+ si_read_lock(sb, AuLock_FLUSH); -+ bbot = au_sbbot(sb); -+ err = bbot + 1; -+ if (!arg) -+ goto out; -+ -+ err = -ENOMEM; -+ buf = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!buf)) -+ goto out; -+ -+ seq = au_seq(buf, PAGE_SIZE); -+ err = PTR_ERR(seq); -+ if (IS_ERR(seq)) -+ goto out_buf; -+ -+ sz = sizeof(*arg) - offsetof(union aufs_brinfo, path); -+ for (bindex = 0; bindex <= bbot; bindex++, arg++) { -+ /* VERIFY_WRITE */ -+ err = !access_ok(arg, sizeof(*arg)); -+ if (unlikely(err)) -+ break; -+ -+ br = au_sbr(sb, bindex); -+ brid = br->br_id; -+ BUILD_BUG_ON(sizeof(brid) != sizeof(arg->id)); -+ err = __put_user(brid, &arg->id); -+ if (unlikely(err)) -+ break; -+ -+ BUILD_BUG_ON(sizeof(br->br_perm) != sizeof(arg->perm)); -+ err = __put_user(br->br_perm, &arg->perm); -+ if (unlikely(err)) -+ break; -+ -+ err = au_seq_path(seq, &br->br_path); -+ if (unlikely(err)) -+ break; -+ seq_putc(seq, '\0'); -+ if (!seq_has_overflowed(seq)) { -+ err = copy_to_user(arg->path, seq->buf, seq->count); -+ seq->count = 0; -+ if (unlikely(err)) -+ break; -+ } else { -+ err = -E2BIG; -+ goto out_seq; -+ } -+ } -+ if (unlikely(err)) -+ err = -EFAULT; -+ -+out_seq: -+ au_kfree_rcu(seq); -+out_buf: -+ free_page((unsigned long)buf); -+out: -+ si_read_unlock(sb); -+ return err; -+} -+ -+long au_brinfo_ioctl(struct file *file, unsigned long arg) -+{ -+ return au_brinfo(file->f_path.dentry->d_sb, (void __user *)arg); -+} -+ -+#ifdef CONFIG_COMPAT -+long au_brinfo_compat_ioctl(struct file *file, unsigned long arg) -+{ -+ return au_brinfo(file->f_path.dentry->d_sb, compat_ptr(arg)); -+} -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+void sysaufs_br_init(struct au_branch *br) -+{ -+ int i; -+ struct au_brsysfs *br_sysfs; -+ struct attribute *attr; -+ -+ br_sysfs = br->br_sysfs; -+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) { -+ attr = &br_sysfs->attr; -+ sysfs_attr_init(attr); -+ attr->name = br_sysfs->name; -+ attr->mode = 0444; -+ br_sysfs++; -+ } -+} -+ -+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ struct au_branch *br; -+ struct kobject *kobj; -+ struct au_brsysfs *br_sysfs; -+ int i; -+ aufs_bindex_t bbot; -+ -+ if (!sysaufs_brs) -+ return; -+ -+ kobj = &au_sbi(sb)->si_kobj; -+ bbot = au_sbbot(sb); -+ for (; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ br_sysfs = br->br_sysfs; -+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) { -+ sysfs_remove_file(kobj, &br_sysfs->attr); -+ br_sysfs++; -+ } -+ } -+} -+ -+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ int err, i; -+ aufs_bindex_t bbot; -+ struct kobject *kobj; -+ struct au_branch *br; -+ struct au_brsysfs *br_sysfs; -+ -+ if (!sysaufs_brs) -+ return; -+ -+ kobj = &au_sbi(sb)->si_kobj; -+ bbot = au_sbbot(sb); -+ for (; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ br_sysfs = br->br_sysfs; -+ snprintf(br_sysfs[AuBrSysfs_BR].name, sizeof(br_sysfs->name), -+ SysaufsBr_PREFIX "%d", bindex); -+ snprintf(br_sysfs[AuBrSysfs_BRID].name, sizeof(br_sysfs->name), -+ SysaufsBrid_PREFIX "%d", bindex); -+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) { -+ err = sysfs_create_file(kobj, &br_sysfs->attr); -+ if (unlikely(err)) -+ pr_warn("failed %s under sysfs(%d)\n", -+ br_sysfs->name, err); -+ br_sysfs++; -+ } -+ } -+} -diff -Naur null/fs/aufs/sysrq.c linux-6.6.63/fs/aufs/sysrq.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/sysrq.c 2024-12-18 15:12:59.299519538 +0300 -@@ -0,0 +1,149 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * magic sysrq handler -+ */ -+ -+/* #include */ -+#include -+#include "aufs.h" -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void sysrq_sb(struct super_block *sb) -+{ -+ char *plevel; -+ struct au_sbinfo *sbinfo; -+ struct file *file; -+ struct hlist_bl_head *files; -+ struct hlist_bl_node *pos; -+ struct au_finfo *finfo; -+ struct inode *i; -+ -+ plevel = au_plevel; -+ au_plevel = KERN_WARNING; -+ -+ /* since we define pr_fmt, call printk directly */ -+#define pr(str) printk(KERN_WARNING AUFS_NAME ": " str) -+ -+ sbinfo = au_sbi(sb); -+ printk(KERN_WARNING "si=%lx\n", sysaufs_si_id(sbinfo)); -+ pr("superblock\n"); -+ au_dpri_sb(sb); -+ -+#if 0 /* reserved */ -+ do { -+ int err, i, j, ndentry; -+ struct au_dcsub_pages dpages; -+ struct au_dpage *dpage; -+ -+ err = au_dpages_init(&dpages, GFP_ATOMIC); -+ if (unlikely(err)) -+ break; -+ err = au_dcsub_pages(&dpages, sb->s_root, NULL, NULL); -+ if (!err) -+ for (i = 0; i < dpages.ndpage; i++) { -+ dpage = dpages.dpages + i; -+ ndentry = dpage->ndentry; -+ for (j = 0; j < ndentry; j++) -+ au_dpri_dentry(dpage->dentries[j]); -+ } -+ au_dpages_free(&dpages); -+ } while (0); -+#endif -+ -+ pr("isolated inode\n"); -+ spin_lock(&sb->s_inode_list_lock); -+ list_for_each_entry(i, &sb->s_inodes, i_sb_list) { -+ spin_lock(&i->i_lock); -+ if (hlist_empty(&i->i_dentry)) -+ au_dpri_inode(i); -+ spin_unlock(&i->i_lock); -+ } -+ spin_unlock(&sb->s_inode_list_lock); -+ -+ pr("files\n"); -+ files = &au_sbi(sb)->si_files; -+ hlist_bl_lock(files); -+ hlist_bl_for_each_entry(finfo, pos, files, fi_hlist) { -+ umode_t mode; -+ -+ file = finfo->fi_file; -+ mode = file_inode(file)->i_mode; -+ if (!special_file(mode)) -+ au_dpri_file(file); -+ } -+ hlist_bl_unlock(files); -+ pr("done\n"); -+ -+#undef pr -+ au_plevel = plevel; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* module parameter */ -+static char *aufs_sysrq_key = "a"; -+module_param_named(sysrq, aufs_sysrq_key, charp, 0444); -+MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME); -+ -+static void au_sysrq(u8 key __maybe_unused) -+{ -+ struct au_sbinfo *sbinfo; -+ struct hlist_bl_node *pos; -+ -+ lockdep_off(); -+ au_sbilist_lock(); -+ hlist_bl_for_each_entry(sbinfo, pos, &au_sbilist, si_list) -+ sysrq_sb(sbinfo->si_sb); -+ au_sbilist_unlock(); -+ lockdep_on(); -+} -+ -+static struct sysrq_key_op au_sysrq_op = { -+ .handler = au_sysrq, -+ .help_msg = "Aufs", -+ .action_msg = "Aufs", -+ .enable_mask = SYSRQ_ENABLE_DUMP -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+int __init au_sysrq_init(void) -+{ -+ int err; -+ char key; -+ -+ err = -1; -+ key = *aufs_sysrq_key; -+ if ('a' <= key && key <= 'z') -+ err = register_sysrq_key(key, &au_sysrq_op); -+ if (unlikely(err)) -+ pr_err("err %d, sysrq=%c\n", err, key); -+ return err; -+} -+ -+void au_sysrq_fin(void) -+{ -+ int err; -+ -+ err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op); -+ if (unlikely(err)) -+ pr_err("err %d (ignored)\n", err); -+} -diff -Naur null/fs/aufs/vdir.c linux-6.6.63/fs/aufs/vdir.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/vdir.c 2024-12-18 15:12:59.300519526 +0300 -@@ -0,0 +1,896 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * virtual or vertical directory -+ */ -+ -+#include -+#include "aufs.h" -+ -+static unsigned int calc_size(int nlen) -+{ -+ return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t)); -+} -+ -+static int set_deblk_end(union au_vdir_deblk_p *p, -+ union au_vdir_deblk_p *deblk_end) -+{ -+ if (calc_size(0) <= deblk_end->deblk - p->deblk) { -+ p->de->de_str.len = 0; -+ /* smp_mb(); */ -+ return 0; -+ } -+ return -1; /* error */ -+} -+ -+/* returns true or false */ -+static int is_deblk_end(union au_vdir_deblk_p *p, -+ union au_vdir_deblk_p *deblk_end) -+{ -+ if (calc_size(0) <= deblk_end->deblk - p->deblk) -+ return !p->de->de_str.len; -+ return 1; -+} -+ -+static unsigned char *last_deblk(struct au_vdir *vdir) -+{ -+ return vdir->vd_deblk[vdir->vd_nblk - 1]; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* estimate the appropriate size for name hash table */ -+unsigned int au_rdhash_est(loff_t sz) -+{ -+ unsigned int n; -+ -+ n = UINT_MAX; -+ sz >>= 10; -+ if (sz < n) -+ n = sz; -+ if (sz < AUFS_RDHASH_DEF) -+ n = AUFS_RDHASH_DEF; -+ /* pr_info("n %u\n", n); */ -+ return n; -+} -+ -+/* -+ * the allocated memory has to be freed by -+ * au_nhash_wh_free() or au_nhash_de_free(). -+ */ -+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp) -+{ -+ struct hlist_head *head; -+ unsigned int u; -+ size_t sz; -+ -+ sz = sizeof(*nhash->nh_head) * num_hash; -+ head = kmalloc(sz, gfp); -+ if (head) { -+ nhash->nh_num = num_hash; -+ nhash->nh_head = head; -+ for (u = 0; u < num_hash; u++) -+ INIT_HLIST_HEAD(head++); -+ return 0; /* success */ -+ } -+ -+ return -ENOMEM; -+} -+ -+static void nhash_count(struct hlist_head *head) -+{ -+#if 0 /* debugging */ -+ unsigned long n; -+ struct hlist_node *pos; -+ -+ n = 0; -+ hlist_for_each(pos, head) -+ n++; -+ pr_info("%lu\n", n); -+#endif -+} -+ -+static void au_nhash_wh_do_free(struct hlist_head *head) -+{ -+ struct au_vdir_wh *pos; -+ struct hlist_node *node; -+ -+ hlist_for_each_entry_safe(pos, node, head, wh_hash) -+ au_kfree_rcu(pos); -+} -+ -+static void au_nhash_de_do_free(struct hlist_head *head) -+{ -+ struct au_vdir_dehstr *pos; -+ struct hlist_node *node; -+ -+ hlist_for_each_entry_safe(pos, node, head, hash) -+ au_cache_free_vdir_dehstr(pos); -+} -+ -+static void au_nhash_do_free(struct au_nhash *nhash, -+ void (*free)(struct hlist_head *head)) -+{ -+ unsigned int n; -+ struct hlist_head *head; -+ -+ n = nhash->nh_num; -+ if (!n) -+ return; -+ -+ head = nhash->nh_head; -+ while (n-- > 0) { -+ nhash_count(head); -+ free(head++); -+ } -+ au_kfree_try_rcu(nhash->nh_head); -+} -+ -+void au_nhash_wh_free(struct au_nhash *whlist) -+{ -+ au_nhash_do_free(whlist, au_nhash_wh_do_free); -+} -+ -+static void au_nhash_de_free(struct au_nhash *delist) -+{ -+ au_nhash_do_free(delist, au_nhash_de_do_free); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt, -+ int limit) -+{ -+ int num; -+ unsigned int u, n; -+ struct hlist_head *head; -+ struct au_vdir_wh *pos; -+ -+ num = 0; -+ n = whlist->nh_num; -+ head = whlist->nh_head; -+ for (u = 0; u < n; u++, head++) -+ hlist_for_each_entry(pos, head, wh_hash) -+ if (pos->wh_bindex == btgt && ++num > limit) -+ return 1; -+ return 0; -+} -+ -+static struct hlist_head *au_name_hash(struct au_nhash *nhash, -+ unsigned char *name, -+ unsigned int len) -+{ -+ unsigned int v; -+ /* const unsigned int magic_bit = 12; */ -+ -+ AuDebugOn(!nhash->nh_num || !nhash->nh_head); -+ -+ v = 0; -+ if (len > 8) -+ len = 8; -+ while (len--) -+ v += *name++; -+ /* v = hash_long(v, magic_bit); */ -+ v %= nhash->nh_num; -+ return nhash->nh_head + v; -+} -+ -+static int au_nhash_test_name(struct au_vdir_destr *str, const char *name, -+ int nlen) -+{ -+ return str->len == nlen && !memcmp(str->name, name, nlen); -+} -+ -+/* returns found or not */ -+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen) -+{ -+ struct hlist_head *head; -+ struct au_vdir_wh *pos; -+ struct au_vdir_destr *str; -+ -+ head = au_name_hash(whlist, name, nlen); -+ hlist_for_each_entry(pos, head, wh_hash) { -+ str = &pos->wh_str; -+ AuDbg("%.*s\n", str->len, str->name); -+ if (au_nhash_test_name(str, name, nlen)) -+ return 1; -+ } -+ return 0; -+} -+ -+/* returns found(true) or not */ -+static int test_known(struct au_nhash *delist, char *name, int nlen) -+{ -+ struct hlist_head *head; -+ struct au_vdir_dehstr *pos; -+ struct au_vdir_destr *str; -+ -+ head = au_name_hash(delist, name, nlen); -+ hlist_for_each_entry(pos, head, hash) { -+ str = pos->str; -+ AuDbg("%.*s\n", str->len, str->name); -+ if (au_nhash_test_name(str, name, nlen)) -+ return 1; -+ } -+ return 0; -+} -+ -+static void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino, -+ unsigned char d_type) -+{ -+#ifdef CONFIG_AUFS_SHWH -+ wh->wh_ino = ino; -+ wh->wh_type = d_type; -+#endif -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino, -+ unsigned int d_type, aufs_bindex_t bindex, -+ unsigned char shwh) -+{ -+ int err; -+ struct au_vdir_destr *str; -+ struct au_vdir_wh *wh; -+ -+ AuDbg("%.*s\n", nlen, name); -+ AuDebugOn(!whlist->nh_num || !whlist->nh_head); -+ -+ err = -ENOMEM; -+ wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS); -+ if (unlikely(!wh)) -+ goto out; -+ -+ err = 0; -+ wh->wh_bindex = bindex; -+ if (shwh) -+ au_shwh_init_wh(wh, ino, d_type); -+ str = &wh->wh_str; -+ str->len = nlen; -+ memcpy(str->name, name, nlen); -+ hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen)); -+ /* smp_mb(); */ -+ -+out: -+ return err; -+} -+ -+static int append_deblk(struct au_vdir *vdir) -+{ -+ int err; -+ unsigned long ul; -+ const unsigned int deblk_sz = vdir->vd_deblk_sz; -+ union au_vdir_deblk_p p, deblk_end; -+ unsigned char **o; -+ -+ err = -ENOMEM; -+ o = au_krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1), -+ GFP_NOFS, /*may_shrink*/0); -+ if (unlikely(!o)) -+ goto out; -+ -+ vdir->vd_deblk = o; -+ p.deblk = kmalloc(deblk_sz, GFP_NOFS); -+ if (p.deblk) { -+ ul = vdir->vd_nblk++; -+ vdir->vd_deblk[ul] = p.deblk; -+ vdir->vd_last.ul = ul; -+ vdir->vd_last.p.deblk = p.deblk; -+ deblk_end.deblk = p.deblk + deblk_sz; -+ err = set_deblk_end(&p, &deblk_end); -+ } -+ -+out: -+ return err; -+} -+ -+static int append_de(struct au_vdir *vdir, char *name, int nlen, ino_t ino, -+ unsigned int d_type, struct au_nhash *delist) -+{ -+ int err; -+ unsigned int sz; -+ const unsigned int deblk_sz = vdir->vd_deblk_sz; -+ union au_vdir_deblk_p p, *room, deblk_end; -+ struct au_vdir_dehstr *dehstr; -+ -+ p.deblk = last_deblk(vdir); -+ deblk_end.deblk = p.deblk + deblk_sz; -+ room = &vdir->vd_last.p; -+ AuDebugOn(room->deblk < p.deblk || deblk_end.deblk <= room->deblk -+ || !is_deblk_end(room, &deblk_end)); -+ -+ sz = calc_size(nlen); -+ if (unlikely(sz > deblk_end.deblk - room->deblk)) { -+ err = append_deblk(vdir); -+ if (unlikely(err)) -+ goto out; -+ -+ p.deblk = last_deblk(vdir); -+ deblk_end.deblk = p.deblk + deblk_sz; -+ /* smp_mb(); */ -+ AuDebugOn(room->deblk != p.deblk); -+ } -+ -+ err = -ENOMEM; -+ dehstr = au_cache_alloc_vdir_dehstr(); -+ if (unlikely(!dehstr)) -+ goto out; -+ -+ dehstr->str = &room->de->de_str; -+ hlist_add_head(&dehstr->hash, au_name_hash(delist, name, nlen)); -+ room->de->de_ino = ino; -+ room->de->de_type = d_type; -+ room->de->de_str.len = nlen; -+ memcpy(room->de->de_str.name, name, nlen); -+ -+ err = 0; -+ room->deblk += sz; -+ if (unlikely(set_deblk_end(room, &deblk_end))) -+ err = append_deblk(vdir); -+ /* smp_mb(); */ -+ -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void au_vdir_free(struct au_vdir *vdir) -+{ -+ unsigned char **deblk; -+ -+ deblk = vdir->vd_deblk; -+ while (vdir->vd_nblk--) -+ au_kfree_try_rcu(*deblk++); -+ au_kfree_try_rcu(vdir->vd_deblk); -+ au_cache_free_vdir(vdir); -+} -+ -+static struct au_vdir *alloc_vdir(struct file *file) -+{ -+ struct au_vdir *vdir; -+ struct super_block *sb; -+ int err; -+ -+ sb = file->f_path.dentry->d_sb; -+ SiMustAnyLock(sb); -+ -+ err = -ENOMEM; -+ vdir = au_cache_alloc_vdir(); -+ if (unlikely(!vdir)) -+ goto out; -+ -+ vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS); -+ if (unlikely(!vdir->vd_deblk)) -+ goto out_free; -+ -+ vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk; -+ if (!vdir->vd_deblk_sz) { -+ /* estimate the appropriate size for deblk */ -+ vdir->vd_deblk_sz = au_dir_size(file, /*dentry*/NULL); -+ /* pr_info("vd_deblk_sz %u\n", vdir->vd_deblk_sz); */ -+ } -+ vdir->vd_nblk = 0; -+ vdir->vd_version = 0; -+ vdir->vd_jiffy = 0; -+ err = append_deblk(vdir); -+ if (!err) -+ return vdir; /* success */ -+ -+ au_kfree_try_rcu(vdir->vd_deblk); -+ -+out_free: -+ au_cache_free_vdir(vdir); -+out: -+ vdir = ERR_PTR(err); -+ return vdir; -+} -+ -+static int reinit_vdir(struct au_vdir *vdir) -+{ -+ int err; -+ union au_vdir_deblk_p p, deblk_end; -+ -+ while (vdir->vd_nblk > 1) { -+ au_kfree_try_rcu(vdir->vd_deblk[vdir->vd_nblk - 1]); -+ /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */ -+ vdir->vd_nblk--; -+ } -+ p.deblk = vdir->vd_deblk[0]; -+ deblk_end.deblk = p.deblk + vdir->vd_deblk_sz; -+ err = set_deblk_end(&p, &deblk_end); -+ /* keep vd_dblk_sz */ -+ vdir->vd_last.ul = 0; -+ vdir->vd_last.p.deblk = vdir->vd_deblk[0]; -+ vdir->vd_version = 0; -+ vdir->vd_jiffy = 0; -+ /* smp_mb(); */ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+#define AuFillVdir_CALLED 1 -+#define AuFillVdir_WHABLE (1 << 1) -+#define AuFillVdir_SHWH (1 << 2) -+#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name) -+#define au_fset_fillvdir(flags, name) \ -+ do { (flags) |= AuFillVdir_##name; } while (0) -+#define au_fclr_fillvdir(flags, name) \ -+ do { (flags) &= ~AuFillVdir_##name; } while (0) -+ -+#ifndef CONFIG_AUFS_SHWH -+#undef AuFillVdir_SHWH -+#define AuFillVdir_SHWH 0 -+#endif -+ -+struct fillvdir_arg { -+ struct dir_context ctx; -+ struct file *file; -+ struct au_vdir *vdir; -+ struct au_nhash delist; -+ struct au_nhash whlist; -+ aufs_bindex_t bindex; -+ unsigned int flags; -+ int err; -+}; -+ -+static bool fillvdir(struct dir_context *ctx, const char *__name, int nlen, -+ loff_t offset __maybe_unused, u64 h_ino, -+ unsigned int d_type) -+{ -+ struct fillvdir_arg *arg = container_of(ctx, struct fillvdir_arg, ctx); -+ char *name = (void *)__name; -+ struct super_block *sb; -+ ino_t ino; -+ const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH); -+ -+ arg->err = 0; -+ sb = arg->file->f_path.dentry->d_sb; -+ au_fset_fillvdir(arg->flags, CALLED); -+ /* smp_mb(); */ -+ if (nlen <= AUFS_WH_PFX_LEN -+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) { -+ if (test_known(&arg->delist, name, nlen) -+ || au_nhash_test_known_wh(&arg->whlist, name, nlen)) -+ goto out; /* already exists or whiteouted */ -+ -+ arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino); -+ if (!arg->err) { -+ if (unlikely(nlen > AUFS_MAX_NAMELEN)) -+ d_type = DT_UNKNOWN; -+ arg->err = append_de(arg->vdir, name, nlen, ino, -+ d_type, &arg->delist); -+ } -+ } else if (au_ftest_fillvdir(arg->flags, WHABLE)) { -+ name += AUFS_WH_PFX_LEN; -+ nlen -= AUFS_WH_PFX_LEN; -+ if (au_nhash_test_known_wh(&arg->whlist, name, nlen)) -+ goto out; /* already whiteouted */ -+ -+ ino = 0; /* just to suppress a warning */ -+ if (shwh) -+ arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type, -+ &ino); -+ if (!arg->err) { -+ if (nlen <= AUFS_MAX_NAMELEN + AUFS_WH_PFX_LEN) -+ d_type = DT_UNKNOWN; -+ arg->err = au_nhash_append_wh -+ (&arg->whlist, name, nlen, ino, d_type, -+ arg->bindex, shwh); -+ } -+ } -+ -+out: -+ if (!arg->err) -+ arg->vdir->vd_jiffy = jiffies; -+ /* smp_mb(); */ -+ AuTraceErr(arg->err); -+ return !arg->err; -+} -+ -+static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir, -+ struct au_nhash *whlist, struct au_nhash *delist) -+{ -+#ifdef CONFIG_AUFS_SHWH -+ int err; -+ unsigned int nh, u; -+ struct hlist_head *head; -+ struct au_vdir_wh *pos; -+ struct hlist_node *n; -+ char *p, *o; -+ struct au_vdir_destr *destr; -+ -+ AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH)); -+ -+ err = -ENOMEM; -+ o = p = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!p)) -+ goto out; -+ -+ err = 0; -+ nh = whlist->nh_num; -+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN); -+ p += AUFS_WH_PFX_LEN; -+ for (u = 0; u < nh; u++) { -+ head = whlist->nh_head + u; -+ hlist_for_each_entry_safe(pos, n, head, wh_hash) { -+ destr = &pos->wh_str; -+ memcpy(p, destr->name, destr->len); -+ err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN, -+ pos->wh_ino, pos->wh_type, delist); -+ if (unlikely(err)) -+ break; -+ } -+ } -+ -+ free_page((unsigned long)o); -+ -+out: -+ AuTraceErr(err); -+ return err; -+#else -+ return 0; -+#endif -+} -+ -+static int au_do_read_vdir(struct fillvdir_arg *arg) -+{ -+ int err; -+ unsigned int rdhash; -+ loff_t offset; -+ aufs_bindex_t bbot, bindex, btop; -+ unsigned char shwh; -+ struct file *hf, *file; -+ struct super_block *sb; -+ -+ file = arg->file; -+ sb = file->f_path.dentry->d_sb; -+ SiMustAnyLock(sb); -+ -+ rdhash = au_sbi(sb)->si_rdhash; -+ if (!rdhash) -+ rdhash = au_rdhash_est(au_dir_size(file, /*dentry*/NULL)); -+ err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS); -+ if (unlikely(err)) -+ goto out; -+ err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS); -+ if (unlikely(err)) -+ goto out_delist; -+ -+ err = 0; -+ arg->flags = 0; -+ shwh = 0; -+ if (au_opt_test(au_mntflags(sb), SHWH)) { -+ shwh = 1; -+ au_fset_fillvdir(arg->flags, SHWH); -+ } -+ btop = au_fbtop(file); -+ bbot = au_fbbot_dir(file); -+ for (bindex = btop; !err && bindex <= bbot; bindex++) { -+ hf = au_hf_dir(file, bindex); -+ if (!hf) -+ continue; -+ -+ offset = vfsub_llseek(hf, 0, SEEK_SET); -+ err = offset; -+ if (unlikely(offset)) -+ break; -+ -+ arg->bindex = bindex; -+ au_fclr_fillvdir(arg->flags, WHABLE); -+ if (shwh -+ || (bindex != bbot -+ && au_br_whable(au_sbr_perm(sb, bindex)))) -+ au_fset_fillvdir(arg->flags, WHABLE); -+ do { -+ arg->err = 0; -+ au_fclr_fillvdir(arg->flags, CALLED); -+ /* smp_mb(); */ -+ err = vfsub_iterate_dir(hf, &arg->ctx); -+ if (err >= 0) -+ err = arg->err; -+ } while (!err && au_ftest_fillvdir(arg->flags, CALLED)); -+ -+ /* -+ * dir_relax() may be good for concurrency, but aufs should not -+ * use it since it will cause a lockdep problem. -+ */ -+ } -+ -+ if (!err && shwh) -+ err = au_handle_shwh(sb, arg->vdir, &arg->whlist, &arg->delist); -+ -+ au_nhash_wh_free(&arg->whlist); -+ -+out_delist: -+ au_nhash_de_free(&arg->delist); -+out: -+ return err; -+} -+ -+static int read_vdir(struct file *file, int may_read) -+{ -+ int err; -+ unsigned long expire; -+ unsigned char do_read; -+ struct fillvdir_arg arg = { -+ .ctx = { -+ .actor = fillvdir -+ } -+ }; -+ struct inode *inode; -+ struct au_vdir *vdir, *allocated; -+ -+ err = 0; -+ inode = file_inode(file); -+ IMustLock(inode); -+ IiMustWriteLock(inode); -+ SiMustAnyLock(inode->i_sb); -+ -+ allocated = NULL; -+ do_read = 0; -+ expire = au_sbi(inode->i_sb)->si_rdcache; -+ vdir = au_ivdir(inode); -+ if (!vdir) { -+ do_read = 1; -+ vdir = alloc_vdir(file); -+ err = PTR_ERR(vdir); -+ if (IS_ERR(vdir)) -+ goto out; -+ err = 0; -+ allocated = vdir; -+ } else if (may_read -+ && (!inode_eq_iversion(inode, vdir->vd_version) -+ || time_after(jiffies, vdir->vd_jiffy + expire))) { -+ do_read = 1; -+ err = reinit_vdir(vdir); -+ if (unlikely(err)) -+ goto out; -+ } -+ -+ if (!do_read) -+ return 0; /* success */ -+ -+ arg.file = file; -+ arg.vdir = vdir; -+ err = au_do_read_vdir(&arg); -+ if (!err) { -+ /* file->f_pos = 0; */ /* todo: ctx->pos? */ -+ vdir->vd_version = inode_query_iversion(inode); -+ vdir->vd_last.ul = 0; -+ vdir->vd_last.p.deblk = vdir->vd_deblk[0]; -+ if (allocated) -+ au_set_ivdir(inode, allocated); -+ } else if (allocated) -+ au_vdir_free(allocated); -+ -+out: -+ return err; -+} -+ -+static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src) -+{ -+ int err, rerr; -+ unsigned long ul, n; -+ const unsigned int deblk_sz = src->vd_deblk_sz; -+ -+ AuDebugOn(tgt->vd_nblk != 1); -+ -+ err = -ENOMEM; -+ if (tgt->vd_nblk < src->vd_nblk) { -+ unsigned char **p; -+ -+ p = au_krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk, -+ GFP_NOFS, /*may_shrink*/0); -+ if (unlikely(!p)) -+ goto out; -+ tgt->vd_deblk = p; -+ } -+ -+ if (tgt->vd_deblk_sz != deblk_sz) { -+ unsigned char *p; -+ -+ tgt->vd_deblk_sz = deblk_sz; -+ p = au_krealloc(tgt->vd_deblk[0], deblk_sz, GFP_NOFS, -+ /*may_shrink*/1); -+ if (unlikely(!p)) -+ goto out; -+ tgt->vd_deblk[0] = p; -+ } -+ memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz); -+ tgt->vd_version = src->vd_version; -+ tgt->vd_jiffy = src->vd_jiffy; -+ -+ n = src->vd_nblk; -+ for (ul = 1; ul < n; ul++) { -+ tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz, -+ GFP_NOFS); -+ if (unlikely(!tgt->vd_deblk[ul])) -+ goto out; -+ tgt->vd_nblk++; -+ } -+ tgt->vd_nblk = n; -+ tgt->vd_last.ul = tgt->vd_last.ul; -+ tgt->vd_last.p.deblk = tgt->vd_deblk[tgt->vd_last.ul]; -+ tgt->vd_last.p.deblk += src->vd_last.p.deblk -+ - src->vd_deblk[src->vd_last.ul]; -+ /* smp_mb(); */ -+ return 0; /* success */ -+ -+out: -+ rerr = reinit_vdir(tgt); -+ BUG_ON(rerr); -+ return err; -+} -+ -+int au_vdir_init(struct file *file) -+{ -+ int err; -+ struct inode *inode; -+ struct au_vdir *vdir_cache, *allocated; -+ -+ /* test file->f_pos here instead of ctx->pos */ -+ err = read_vdir(file, !file->f_pos); -+ if (unlikely(err)) -+ goto out; -+ -+ allocated = NULL; -+ vdir_cache = au_fvdir_cache(file); -+ if (!vdir_cache) { -+ vdir_cache = alloc_vdir(file); -+ err = PTR_ERR(vdir_cache); -+ if (IS_ERR(vdir_cache)) -+ goto out; -+ allocated = vdir_cache; -+ } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) { -+ /* test file->f_pos here instead of ctx->pos */ -+ err = reinit_vdir(vdir_cache); -+ if (unlikely(err)) -+ goto out; -+ } else -+ return 0; /* success */ -+ -+ inode = file_inode(file); -+ err = copy_vdir(vdir_cache, au_ivdir(inode)); -+ if (!err) { -+ file->f_version = inode_query_iversion(inode); -+ if (allocated) -+ au_set_fvdir_cache(file, allocated); -+ } else if (allocated) -+ au_vdir_free(allocated); -+ -+out: -+ return err; -+} -+ -+static loff_t calc_offset(struct au_vdir *vdir) -+{ -+ loff_t offset; -+ union au_vdir_deblk_p p; -+ -+ p.deblk = vdir->vd_deblk[vdir->vd_last.ul]; -+ offset = vdir->vd_last.p.deblk - p.deblk; -+ offset += vdir->vd_deblk_sz * vdir->vd_last.ul; -+ return offset; -+} -+ -+/* returns true or false */ -+static int seek_vdir(struct file *file, struct dir_context *ctx) -+{ -+ int valid; -+ unsigned int deblk_sz; -+ unsigned long ul, n; -+ loff_t offset; -+ union au_vdir_deblk_p p, deblk_end; -+ struct au_vdir *vdir_cache; -+ -+ valid = 1; -+ vdir_cache = au_fvdir_cache(file); -+ offset = calc_offset(vdir_cache); -+ AuDbg("offset %lld\n", offset); -+ if (ctx->pos == offset) -+ goto out; -+ -+ vdir_cache->vd_last.ul = 0; -+ vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0]; -+ if (!ctx->pos) -+ goto out; -+ -+ valid = 0; -+ deblk_sz = vdir_cache->vd_deblk_sz; -+ ul = div64_u64(ctx->pos, deblk_sz); -+ AuDbg("ul %lu\n", ul); -+ if (ul >= vdir_cache->vd_nblk) -+ goto out; -+ -+ n = vdir_cache->vd_nblk; -+ for (; ul < n; ul++) { -+ p.deblk = vdir_cache->vd_deblk[ul]; -+ deblk_end.deblk = p.deblk + deblk_sz; -+ offset = ul; -+ offset *= deblk_sz; -+ while (!is_deblk_end(&p, &deblk_end) && offset < ctx->pos) { -+ unsigned int l; -+ -+ l = calc_size(p.de->de_str.len); -+ offset += l; -+ p.deblk += l; -+ } -+ if (!is_deblk_end(&p, &deblk_end)) { -+ valid = 1; -+ vdir_cache->vd_last.ul = ul; -+ vdir_cache->vd_last.p = p; -+ break; -+ } -+ } -+ -+out: -+ /* smp_mb(); */ -+ if (!valid) -+ AuDbg("valid %d\n", !valid); -+ return valid; -+} -+ -+int au_vdir_fill_de(struct file *file, struct dir_context *ctx) -+{ -+ unsigned int l, deblk_sz; -+ union au_vdir_deblk_p deblk_end; -+ struct au_vdir *vdir_cache; -+ struct au_vdir_de *de; -+ -+ if (!seek_vdir(file, ctx)) -+ return 0; -+ -+ vdir_cache = au_fvdir_cache(file); -+ deblk_sz = vdir_cache->vd_deblk_sz; -+ while (1) { -+ deblk_end.deblk = vdir_cache->vd_deblk[vdir_cache->vd_last.ul]; -+ deblk_end.deblk += deblk_sz; -+ while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) { -+ de = vdir_cache->vd_last.p.de; -+ AuDbg("%.*s, off%lld, i%lu, dt%d\n", -+ de->de_str.len, de->de_str.name, ctx->pos, -+ (unsigned long)de->de_ino, de->de_type); -+ if (unlikely(!dir_emit(ctx, de->de_str.name, -+ de->de_str.len, de->de_ino, -+ de->de_type))) { -+ /* todo: ignore the error caused by udba? */ -+ /* return err; */ -+ return 0; -+ } -+ -+ l = calc_size(de->de_str.len); -+ vdir_cache->vd_last.p.deblk += l; -+ ctx->pos += l; -+ } -+ if (vdir_cache->vd_last.ul < vdir_cache->vd_nblk - 1) { -+ vdir_cache->vd_last.ul++; -+ vdir_cache->vd_last.p.deblk -+ = vdir_cache->vd_deblk[vdir_cache->vd_last.ul]; -+ ctx->pos = deblk_sz * vdir_cache->vd_last.ul; -+ continue; -+ } -+ break; -+ } -+ -+ /* smp_mb(); */ -+ return 0; -+} -diff -Naur null/fs/aufs/vfsub.c linux-6.6.63/fs/aufs/vfsub.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/vfsub.c 2024-12-18 15:12:59.300519526 +0300 -@@ -0,0 +1,964 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * sub-routines for VFS -+ */ -+ -+#include -+#include -+#include -+#include -+#include "aufs.h" -+ -+#ifdef CONFIG_AUFS_BR_FUSE -+int vfsub_test_mntns(struct vfsmount *mnt, struct super_block *h_sb) -+{ -+ if (!au_test_fuse(h_sb) || !au_userns) -+ return 0; -+ -+ return is_current_mnt_ns(mnt) ? 0 : -EACCES; -+} -+#endif -+ -+int vfsub_sync_filesystem(struct super_block *h_sb) -+{ -+ int err; -+ -+ lockdep_off(); -+ down_read(&h_sb->s_umount); -+ err = sync_filesystem(h_sb); -+ up_read(&h_sb->s_umount); -+ lockdep_on(); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+unsigned int vfsub_inode_nlink_aufs(struct inode *inode) -+{ -+ unsigned int nlink; -+ -+ au_nlink_lock(inode); -+ nlink = inode->i_nlink; -+ au_nlink_unlock(inode); -+ -+ return nlink; -+} -+ -+void vfsub_inc_nlink(struct inode *inode) -+{ -+ au_nlink_lock(inode); -+ inc_nlink(inode); -+ au_nlink_unlock(inode); -+} -+ -+void vfsub_drop_nlink(struct inode *inode) -+{ -+ au_nlink_lock(inode); -+ AuDebugOn(!inode->i_nlink); -+ drop_nlink(inode); -+ au_nlink_unlock(inode); -+} -+ -+void vfsub_clear_nlink(struct inode *inode) -+{ -+ au_nlink_lock(inode); -+ AuDebugOn(!inode->i_nlink); -+ clear_nlink(inode); -+ au_nlink_unlock(inode); -+} -+ -+void vfsub_set_nlink(struct inode *inode, unsigned int nlink) -+{ -+ /* -+ * stop setting the value equal to the current one, in order to stop -+ * a useless warning from vfs:destroy_inode() about sb->s_remove_count. -+ */ -+ au_nlink_lock(inode); -+ if (nlink != inode->i_nlink) -+ set_nlink(inode, nlink); -+ au_nlink_unlock(inode); -+} -+ -+int vfsub_update_h_iattr(struct path *h_path, int *did) -+{ -+ int err; -+ struct kstat st; -+ struct super_block *h_sb; -+ -+ /* -+ * Always needs h_path->mnt for LSM or FUSE branch. -+ */ -+ AuDebugOn(!h_path->mnt); -+ -+ /* for remote fs, leave work for its getattr or d_revalidate */ -+ /* for bad i_attr fs, handle them in aufs_getattr() */ -+ /* still some fs may acquire i_mutex. we need to skip them */ -+ err = 0; -+ if (!did) -+ did = &err; -+ h_sb = h_path->dentry->d_sb; -+ *did = (!au_test_fs_remote(h_sb) && au_test_fs_refresh_iattr(h_sb)); -+ if (*did) -+ err = vfsub_getattr(h_path, &st); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct file *vfsub_dentry_open(struct path *path, int flags) -+{ -+ return dentry_open(path, flags /* | __FMODE_NONOTIFY */, -+ current_cred()); -+} -+ -+struct file *vfsub_filp_open(const char *path, int oflags, int mode) -+{ -+ struct file *file; -+ -+ lockdep_off(); -+ file = filp_open(path, -+ oflags /* | __FMODE_NONOTIFY */, -+ mode); -+ lockdep_on(); -+ if (IS_ERR(file)) -+ goto out; -+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ -+ -+out: -+ 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) -+{ -+ int err; -+ struct au_branch *br = args->br; -+ 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; -+ -+ au_lcnt_inc(&br->br_nfiles); -+ file->f_path.dentry = DENTRY_NOT_SET; -+ file->f_path.mnt = au_br_mnt(br); -+ AuDbg("%ps\n", dir->i_op->atomic_open); -+ err = dir->i_op->atomic_open(dir, dentry, file, args->open_flag, -+ args->create_mode); -+ if (unlikely(err < 0)) { -+ au_lcnt_dec(&br->br_nfiles); -+ goto out; -+ } -+ -+ /* temporary workaround for nfsv4 branch */ -+ if (au_test_nfs(dir->i_sb)) -+ nfs_mark_for_revalidate(dir); -+ -+ if (file->f_mode & FMODE_CREATED) -+ fsnotify_create(dir, dentry); -+ if (!(file->f_mode & FMODE_OPENED)) { -+ au_lcnt_dec(&br->br_nfiles); -+ goto out; -+ } -+ -+ /* todo: call VFS:may_open() here */ -+ /* todo: ima_file_check() too? */ -+ if (!err && (args->open_flag & __FMODE_EXEC)) -+ err = deny_write_access(file); -+ if (!err) -+ fsnotify_open(file); -+ else -+ au_lcnt_dec(&br->br_nfiles); -+ /* note that the file is created and still opened */ -+ -+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 && d_is_positive(path->dentry)) -+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/ -+ return err; -+} -+ -+struct dentry *vfsub_lookup_one_len_unlocked(const char *name, -+ struct path *ppath, int len) -+{ -+ struct path path; -+ -+ path.dentry = lookup_one_len_unlocked(name, ppath->dentry, len); -+ if (IS_ERR(path.dentry)) -+ goto out; -+ if (d_is_positive(path.dentry)) { -+ path.mnt = ppath->mnt; -+ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/ -+ } -+ -+out: -+ AuTraceErrPtr(path.dentry); -+ return path.dentry; -+} -+ -+struct dentry *vfsub_lookup_one_len(const char *name, struct path *ppath, -+ int len) -+{ -+ struct path path; -+ -+ /* VFS checks it too, but by WARN_ON_ONCE() */ -+ IMustLock(d_inode(ppath->dentry)); -+ -+ path.dentry = lookup_one_len(name, ppath->dentry, len); -+ if (IS_ERR(path.dentry)) -+ goto out; -+ if (d_is_positive(path.dentry)) { -+ path.mnt = ppath->mnt; -+ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/ -+ } -+ -+out: -+ AuTraceErrPtr(path.dentry); -+ return path.dentry; -+} -+ -+void vfsub_call_lkup_one(void *args) -+{ -+ struct vfsub_lkup_one_args *a = args; -+ *a->errp = vfsub_lkup_one(a->name, a->ppath); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1, -+ struct dentry *d2, struct au_hinode *hdir2) -+{ -+ struct dentry *d; -+ -+ lockdep_off(); -+ d = lock_rename(d1, d2); -+ lockdep_on(); -+ au_hn_suspend(hdir1); -+ if (hdir1 != hdir2) -+ au_hn_suspend(hdir2); -+ -+ return d; -+} -+ -+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1, -+ struct dentry *d2, struct au_hinode *hdir2) -+{ -+ au_hn_resume(hdir1); -+ if (hdir1 != hdir2) -+ au_hn_resume(hdir2); -+ lockdep_off(); -+ unlock_rename(d1, d2); -+ lockdep_on(); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int vfsub_create(struct inode *dir, struct path *path, int mode, bool want_excl) -+{ -+ int err; -+ struct dentry *d; -+ struct mnt_idmap *idmap; -+ -+ IMustLock(dir); -+ -+ d = path->dentry; -+ path->dentry = d->d_parent; -+ err = security_path_mknod(path, d, mode, 0); -+ path->dentry = d; -+ if (unlikely(err)) -+ goto out; -+ idmap = mnt_idmap(path->mnt); -+ -+ lockdep_off(); -+ err = vfs_create(idmap, dir, path->dentry, mode, want_excl); -+ lockdep_on(); -+ if (!err) { -+ struct path tmp = *path; -+ int did; -+ -+ vfsub_update_h_iattr(&tmp, &did); -+ if (did) { -+ tmp.dentry = path->dentry->d_parent; -+ vfsub_update_h_iattr(&tmp, /*did*/NULL); -+ } -+ /*ignore*/ -+ } -+ -+out: -+ return err; -+} -+ -+int vfsub_symlink(struct inode *dir, struct path *path, const char *symname) -+{ -+ int err; -+ struct dentry *d; -+ struct mnt_idmap *idmap; -+ -+ IMustLock(dir); -+ -+ d = path->dentry; -+ path->dentry = d->d_parent; -+ err = security_path_symlink(path, d, symname); -+ path->dentry = d; -+ if (unlikely(err)) -+ goto out; -+ idmap = mnt_idmap(path->mnt); -+ -+ lockdep_off(); -+ err = vfs_symlink(idmap, dir, path->dentry, symname); -+ lockdep_on(); -+ if (!err) { -+ struct path tmp = *path; -+ int did; -+ -+ vfsub_update_h_iattr(&tmp, &did); -+ if (did) { -+ tmp.dentry = path->dentry->d_parent; -+ vfsub_update_h_iattr(&tmp, /*did*/NULL); -+ } -+ /*ignore*/ -+ } -+ -+out: -+ return err; -+} -+ -+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev) -+{ -+ int err; -+ struct dentry *d; -+ struct mnt_idmap *idmap; -+ -+ IMustLock(dir); -+ -+ d = path->dentry; -+ path->dentry = d->d_parent; -+ err = security_path_mknod(path, d, mode, new_encode_dev(dev)); -+ path->dentry = d; -+ if (unlikely(err)) -+ goto out; -+ idmap = mnt_idmap(path->mnt); -+ -+ lockdep_off(); -+ err = vfs_mknod(idmap, dir, path->dentry, mode, dev); -+ lockdep_on(); -+ if (!err) { -+ struct path tmp = *path; -+ int did; -+ -+ vfsub_update_h_iattr(&tmp, &did); -+ if (did) { -+ tmp.dentry = path->dentry->d_parent; -+ vfsub_update_h_iattr(&tmp, /*did*/NULL); -+ } -+ /*ignore*/ -+ } -+ -+out: -+ return err; -+} -+ -+static int au_test_nlink(struct inode *inode) -+{ -+ const unsigned int link_max = UINT_MAX >> 1; /* rough margin */ -+ -+ if (!au_test_fs_no_limit_nlink(inode->i_sb) -+ || vfsub_inode_nlink(inode, AU_I_BRANCH) < link_max) -+ return 0; -+ return -EMLINK; -+} -+ -+int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path, -+ struct inode **delegated_inode) -+{ -+ int err; -+ struct dentry *d; -+ struct mnt_idmap *idmap; -+ -+ IMustLock(dir); -+ -+ err = au_test_nlink(d_inode(src_dentry)); -+ if (unlikely(err)) -+ return err; -+ -+ /* we don't call may_linkat() */ -+ d = path->dentry; -+ path->dentry = d->d_parent; -+ err = security_path_link(src_dentry, path, d); -+ path->dentry = d; -+ if (unlikely(err)) -+ goto out; -+ idmap = mnt_idmap(path->mnt); -+ -+ lockdep_off(); -+ err = vfs_link(src_dentry, idmap, dir, path->dentry, delegated_inode); -+ lockdep_on(); -+ if (!err) { -+ struct path tmp = *path; -+ int did; -+ -+ /* fuse has different memory inode for the same inumber */ -+ vfsub_update_h_iattr(&tmp, &did); -+ if (did) { -+ tmp.dentry = path->dentry->d_parent; -+ vfsub_update_h_iattr(&tmp, /*did*/NULL); -+ tmp.dentry = src_dentry; -+ vfsub_update_h_iattr(&tmp, /*did*/NULL); -+ } -+ /*ignore*/ -+ } -+ -+out: -+ return err; -+} -+ -+int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry, -+ struct inode *dir, struct path *path, -+ struct inode **delegated_inode, unsigned int flags) -+{ -+ int err; -+ struct renamedata rd; -+ struct path tmp = { -+ .mnt = path->mnt -+ }; -+ struct dentry *d; -+ -+ IMustLock(dir); -+ IMustLock(src_dir); -+ -+ d = path->dentry; -+ path->dentry = d->d_parent; -+ tmp.dentry = src_dentry->d_parent; -+ err = security_path_rename(&tmp, src_dentry, path, d, /*flags*/0); -+ path->dentry = d; -+ if (unlikely(err)) -+ goto out; -+ -+ rd.old_mnt_idmap = mnt_idmap(path->mnt); -+ rd.old_dir = src_dir; -+ rd.old_dentry = src_dentry; -+ rd.new_mnt_idmap = rd.old_mnt_idmap; -+ rd.new_dir = dir; -+ rd.new_dentry = path->dentry; -+ rd.delegated_inode = delegated_inode; -+ rd.flags = flags; -+ lockdep_off(); -+ err = vfs_rename(&rd); -+ lockdep_on(); -+ if (!err) { -+ int did; -+ -+ tmp.dentry = d->d_parent; -+ vfsub_update_h_iattr(&tmp, &did); -+ if (did) { -+ tmp.dentry = src_dentry; -+ vfsub_update_h_iattr(&tmp, /*did*/NULL); -+ tmp.dentry = src_dentry->d_parent; -+ vfsub_update_h_iattr(&tmp, /*did*/NULL); -+ } -+ /*ignore*/ -+ } -+ -+out: -+ return err; -+} -+ -+int vfsub_mkdir(struct inode *dir, struct path *path, int mode) -+{ -+ int err; -+ struct dentry *d; -+ struct mnt_idmap *idmap; -+ -+ IMustLock(dir); -+ -+ d = path->dentry; -+ path->dentry = d->d_parent; -+ err = security_path_mkdir(path, d, mode); -+ path->dentry = d; -+ if (unlikely(err)) -+ goto out; -+ idmap = mnt_idmap(path->mnt); -+ -+ lockdep_off(); -+ err = vfs_mkdir(idmap, dir, path->dentry, mode); -+ lockdep_on(); -+ if (!err) { -+ struct path tmp = *path; -+ int did; -+ -+ vfsub_update_h_iattr(&tmp, &did); -+ if (did) { -+ tmp.dentry = path->dentry->d_parent; -+ vfsub_update_h_iattr(&tmp, /*did*/NULL); -+ } -+ /*ignore*/ -+ } -+ -+out: -+ return err; -+} -+ -+int vfsub_rmdir(struct inode *dir, struct path *path) -+{ -+ int err; -+ struct dentry *d; -+ struct mnt_idmap *idmap; -+ -+ IMustLock(dir); -+ -+ d = path->dentry; -+ path->dentry = d->d_parent; -+ err = security_path_rmdir(path, d); -+ path->dentry = d; -+ if (unlikely(err)) -+ goto out; -+ idmap = mnt_idmap(path->mnt); -+ -+ lockdep_off(); -+ err = vfs_rmdir(idmap, dir, path->dentry); -+ lockdep_on(); -+ if (!err) { -+ struct path tmp = { -+ .dentry = path->dentry->d_parent, -+ .mnt = path->mnt -+ }; -+ -+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/ -+ } -+ -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* todo: support mmap_sem? */ -+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count, -+ loff_t *ppos) -+{ -+ ssize_t err; -+ -+ lockdep_off(); -+ err = vfs_read(file, ubuf, count, ppos); -+ lockdep_on(); -+ if (err >= 0) -+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ -+ return err; -+} -+ -+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count, -+ loff_t *ppos) -+{ -+ ssize_t err; -+ -+ lockdep_off(); -+ err = kernel_read(file, kbuf, count, ppos); -+ lockdep_on(); -+ AuTraceErr(err); -+ if (err >= 0) -+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ -+ return err; -+} -+ -+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count, -+ loff_t *ppos) -+{ -+ ssize_t err; -+ -+ lockdep_off(); -+ err = vfs_write(file, ubuf, count, ppos); -+ lockdep_on(); -+ if (err >= 0) -+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ -+ return err; -+} -+ -+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos) -+{ -+ ssize_t err; -+ -+ lockdep_off(); -+ err = kernel_write(file, kbuf, count, ppos); -+ lockdep_on(); -+ if (err >= 0) -+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ -+ return err; -+} -+ -+int vfsub_flush(struct file *file, fl_owner_t id) -+{ -+ int err; -+ -+ err = 0; -+ if (file->f_op->flush) { -+ if (!au_test_nfs(file->f_path.dentry->d_sb)) -+ err = file->f_op->flush(file, id); -+ else { -+ lockdep_off(); -+ err = file->f_op->flush(file, id); -+ lockdep_on(); -+ } -+ if (!err) -+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); -+ /*ignore*/ -+ } -+ return err; -+} -+ -+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx) -+{ -+ int err; -+ -+ AuDbg("%pD, ctx{%ps, %llu}\n", file, ctx->actor, ctx->pos); -+ -+ lockdep_off(); -+ err = iterate_dir(file, ctx); -+ lockdep_on(); -+ if (err >= 0) -+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ -+ -+ return err; -+} -+ -+long vfsub_splice_read(struct file *in, loff_t *ppos, -+ struct pipe_inode_info *pipe, size_t len, -+ unsigned int flags) -+{ -+ long err; -+ -+ lockdep_off(); -+ err = vfs_splice_read(in, ppos, pipe, len, flags); -+ lockdep_on(); -+ file_accessed(in); -+ if (err >= 0) -+ vfsub_update_h_iattr(&in->f_path, /*did*/NULL); /*ignore*/ -+ return err; -+} -+ -+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out, -+ loff_t *ppos, size_t len, unsigned int flags) -+{ -+ long err; -+ -+ lockdep_off(); -+ err = do_splice_from(pipe, out, ppos, len, flags); -+ lockdep_on(); -+ if (err >= 0) -+ vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/ -+ return err; -+} -+ -+int vfsub_fsync(struct file *file, struct path *path, int datasync) -+{ -+ int err; -+ -+ /* file can be NULL */ -+ lockdep_off(); -+ err = vfs_fsync(file, datasync); -+ lockdep_on(); -+ if (!err) { -+ if (!path) { -+ AuDebugOn(!file); -+ path = &file->f_path; -+ } -+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/ -+ } -+ return err; -+} -+ -+/* cf. open.c:do_sys_truncate() and do_sys_ftruncate() */ -+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr, -+ struct file *h_file) -+{ -+ int err; -+ struct inode *h_inode; -+ struct super_block *h_sb; -+ struct mnt_idmap *h_idmap; -+ -+ if (!h_file) { -+ err = vfsub_truncate(h_path, length); -+ goto out; -+ } -+ -+ h_inode = d_inode(h_path->dentry); -+ h_sb = h_inode->i_sb; -+ lockdep_off(); -+ sb_start_write(h_sb); -+ lockdep_on(); -+ err = security_file_truncate(h_file); -+ if (!err) { -+ h_idmap = mnt_idmap(h_path->mnt); -+ lockdep_off(); -+ err = do_truncate(h_idmap, h_path->dentry, length, attr, -+ h_file); -+ lockdep_on(); -+ } -+ lockdep_off(); -+ sb_end_write(h_sb); -+ lockdep_on(); -+ -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_vfsub_mkdir_args { -+ int *errp; -+ struct inode *dir; -+ struct path *path; -+ int mode; -+}; -+ -+static void au_call_vfsub_mkdir(void *args) -+{ -+ struct au_vfsub_mkdir_args *a = args; -+ *a->errp = vfsub_mkdir(a->dir, a->path, a->mode); -+} -+ -+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode) -+{ -+ int err, do_sio, wkq_err; -+ struct mnt_idmap *idmap; -+ -+ idmap = mnt_idmap(path->mnt); -+ do_sio = au_test_h_perm_sio(idmap, dir, MAY_EXEC | MAY_WRITE); -+ if (!do_sio) { -+ lockdep_off(); -+ err = vfsub_mkdir(dir, path, mode); -+ lockdep_on(); -+ } else { -+ struct au_vfsub_mkdir_args args = { -+ .errp = &err, -+ .dir = dir, -+ .path = path, -+ .mode = mode -+ }; -+ wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } -+ -+ return err; -+} -+ -+struct au_vfsub_rmdir_args { -+ int *errp; -+ struct inode *dir; -+ struct path *path; -+}; -+ -+static void au_call_vfsub_rmdir(void *args) -+{ -+ struct au_vfsub_rmdir_args *a = args; -+ *a->errp = vfsub_rmdir(a->dir, a->path); -+} -+ -+int vfsub_sio_rmdir(struct inode *dir, struct path *path) -+{ -+ int err, do_sio, wkq_err; -+ struct mnt_idmap *idmap; -+ -+ idmap = mnt_idmap(path->mnt); -+ do_sio = au_test_h_perm_sio(idmap, dir, MAY_EXEC | MAY_WRITE); -+ if (!do_sio) { -+ lockdep_off(); -+ err = vfsub_rmdir(dir, path); -+ lockdep_on(); -+ } else { -+ struct au_vfsub_rmdir_args args = { -+ .errp = &err, -+ .dir = dir, -+ .path = path -+ }; -+ wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct notify_change_args { -+ int *errp; -+ struct path *path; -+ struct iattr *ia; -+ struct inode **delegated_inode; -+}; -+ -+static void call_notify_change(void *args) -+{ -+ struct notify_change_args *a = args; -+ struct inode *h_inode; -+ struct mnt_idmap *idmap; -+ -+ h_inode = d_inode(a->path->dentry); -+ IMustLock(h_inode); -+ -+ *a->errp = -EPERM; -+ if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) { -+ idmap = mnt_idmap(a->path->mnt); -+ lockdep_off(); -+ *a->errp = notify_change(idmap, a->path->dentry, a->ia, -+ a->delegated_inode); -+ lockdep_on(); -+ if (!*a->errp) -+ vfsub_update_h_iattr(a->path, /*did*/NULL); /*ignore*/ -+ } -+ AuTraceErr(*a->errp); -+} -+ -+int vfsub_notify_change(struct path *path, struct iattr *ia, -+ struct inode **delegated_inode) -+{ -+ int err; -+ struct notify_change_args args = { -+ .errp = &err, -+ .path = path, -+ .ia = ia, -+ .delegated_inode = delegated_inode -+ }; -+ -+ call_notify_change(&args); -+ -+ return err; -+} -+ -+int vfsub_sio_notify_change(struct path *path, struct iattr *ia, -+ struct inode **delegated_inode) -+{ -+ int err, wkq_err; -+ struct notify_change_args args = { -+ .errp = &err, -+ .path = path, -+ .ia = ia, -+ .delegated_inode = delegated_inode -+ }; -+ -+ wkq_err = au_wkq_wait(call_notify_change, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct unlink_args { -+ int *errp; -+ struct inode *dir; -+ struct path *path; -+ struct inode **delegated_inode; -+}; -+ -+static void call_unlink(void *args) -+{ -+ struct unlink_args *a = args; -+ struct dentry *d = a->path->dentry; -+ struct inode *h_inode; -+ struct mnt_idmap *idmap; -+ const int stop_sillyrename = (au_test_nfs(d->d_sb) -+ && au_dcount(d) == 1); -+ -+ IMustLock(a->dir); -+ -+ a->path->dentry = d->d_parent; -+ *a->errp = security_path_unlink(a->path, d); -+ a->path->dentry = d; -+ if (unlikely(*a->errp)) -+ return; -+ -+ if (!stop_sillyrename) -+ dget(d); -+ h_inode = NULL; -+ if (d_is_positive(d)) { -+ h_inode = d_inode(d); -+ ihold(h_inode); -+ } -+ -+ idmap = mnt_idmap(a->path->mnt); -+ lockdep_off(); -+ *a->errp = vfs_unlink(idmap, a->dir, d, a->delegated_inode); -+ lockdep_on(); -+ if (!*a->errp) { -+ struct path tmp = { -+ .dentry = d->d_parent, -+ .mnt = a->path->mnt -+ }; -+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/ -+ } -+ -+ if (!stop_sillyrename) -+ dput(d); -+ if (h_inode) -+ iput(h_inode); -+ -+ AuTraceErr(*a->errp); -+} -+ -+/* -+ * @dir: must be locked. -+ * @dentry: target dentry. -+ */ -+int vfsub_unlink(struct inode *dir, struct path *path, -+ struct inode **delegated_inode, int force) -+{ -+ int err; -+ struct unlink_args args = { -+ .errp = &err, -+ .dir = dir, -+ .path = path, -+ .delegated_inode = delegated_inode -+ }; -+ -+ if (!force) -+ call_unlink(&args); -+ else { -+ int wkq_err; -+ -+ wkq_err = au_wkq_wait(call_unlink, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } -+ -+ return err; -+} -diff -Naur null/fs/aufs/vfsub.h linux-6.6.63/fs/aufs/vfsub.h ---- /dev/null -+++ linux-6.6.63/fs/aufs/vfsub.h 2024-12-18 15:12:59.300519526 +0300 -@@ -0,0 +1,442 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * sub-routines for VFS -+ */ -+ -+#ifndef __AUFS_VFSUB_H__ -+#define __AUFS_VFSUB_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+#include -+#include -+#include "debug.h" -+#include "fstype.h" -+ -+/* copied from linux/fs/internal.h */ -+/* todo: BAD approach!! */ -+extern void __mnt_drop_write(struct vfsmount *); -+extern struct file *alloc_empty_file(int, const struct cred *); -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* lock subclass for lower inode */ -+/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */ -+/* reduce? gave up. */ -+enum { -+ AuLsc_I_Begin = I_MUTEX_PARENT2, /* 5 */ -+ AuLsc_I_PARENT, /* lower inode, parent first */ -+ AuLsc_I_PARENT2, /* copyup dirs */ -+ AuLsc_I_PARENT3, /* copyup wh */ -+ AuLsc_I_CHILD, -+ AuLsc_I_CHILD2, -+ AuLsc_I_End -+}; -+ -+/* to debug easier, do not make them inlined functions */ -+#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx)) -+#define IMustLock(i) AuDebugOn(!inode_is_locked(i)) -+ -+/* ---------------------------------------------------------------------- */ -+ -+unsigned int vfsub_inode_nlink_aufs(struct inode *inode); -+ -+enum au_inode_type { -+ AU_I_AUFS, -+ AU_I_BRANCH, -+ AU_I_UNKNOWN -+}; -+ -+static inline unsigned int vfsub_inode_nlink(struct inode *inode, -+ enum au_inode_type type) -+{ -+ unsigned int nlink; -+ -+ switch (type) { -+ case AU_I_AUFS: -+ nlink = vfsub_inode_nlink_aufs(inode); -+ break; -+ case AU_I_BRANCH: /* aufs cannot be a branch of another aufs mount */ -+ AuDebugOn(au_test_aufs(inode->i_sb)); -+ nlink = inode->i_nlink; -+ break; -+ case AU_I_UNKNOWN: -+ if (au_test_aufs(inode->i_sb)) -+ nlink = vfsub_inode_nlink_aufs(inode); -+ else -+ nlink = inode->i_nlink; -+ break; -+ }; -+ -+ return nlink; -+} -+ -+void vfsub_inc_nlink(struct inode *inode); -+void vfsub_drop_nlink(struct inode *inode); -+void vfsub_clear_nlink(struct inode *inode); -+void vfsub_set_nlink(struct inode *inode, unsigned int nlink); -+ -+static inline void vfsub_inode_nlink_init(struct inode *inode, -+ unsigned int nlink) -+{ -+ /* to ignore sb->s_remove_count, do not use set_nlink() */ -+ inode->__i_nlink = nlink; -+} -+ -+static inline void vfsub_dead_dir(struct inode *inode) -+{ -+ AuDebugOn(!S_ISDIR(inode->i_mode)); -+ inode->i_flags |= S_DEAD; -+ vfsub_clear_nlink(inode); -+} -+ -+static inline int vfsub_native_ro(struct inode *inode) -+{ -+ return sb_rdonly(inode->i_sb) -+ || IS_RDONLY(inode) -+ /* || IS_APPEND(inode) */ -+ || IS_IMMUTABLE(inode); -+} -+ -+#ifdef CONFIG_AUFS_BR_FUSE -+int vfsub_test_mntns(struct vfsmount *mnt, struct super_block *h_sb); -+#else -+AuStubInt0(vfsub_test_mntns, struct vfsmount *mnt, struct super_block *h_sb); -+#endif -+ -+int vfsub_sync_filesystem(struct super_block *h_sb); -+ -+/* ---------------------------------------------------------------------- */ -+ -+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 au_branch; -+struct vfsub_aopen_args { -+ struct file *file; -+ unsigned int open_flag; -+ umode_t create_mode; -+ struct au_branch *br; -+}; -+int vfsub_atomic_open(struct inode *dir, struct dentry *dentry, -+ struct vfsub_aopen_args *args); -+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path); -+ -+struct dentry *vfsub_lookup_one_len_unlocked(const char *name, -+ struct path *ppath, int len); -+struct dentry *vfsub_lookup_one_len(const char *name, struct path *ppath, -+ int len); -+ -+struct vfsub_lkup_one_args { -+ struct dentry **errp; -+ struct qstr *name; -+ struct path *ppath; -+}; -+ -+static inline struct dentry *vfsub_lkup_one(struct qstr *name, -+ struct path *ppath) -+{ -+ return vfsub_lookup_one_len(name->name, ppath, name->len); -+} -+ -+void vfsub_call_lkup_one(void *args); -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline int vfsub_mnt_want_write(struct vfsmount *mnt) -+{ -+ int err; -+ -+ lockdep_off(); -+ err = mnt_want_write(mnt); -+ lockdep_on(); -+ return err; -+} -+ -+static inline void vfsub_mnt_drop_write(struct vfsmount *mnt) -+{ -+ lockdep_off(); -+ mnt_drop_write(mnt); -+ 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 -+ -+static inline void vfsub_file_start_write(struct file *file) -+{ -+ lockdep_off(); -+ file_start_write(file); -+ lockdep_on(); -+} -+ -+static inline void vfsub_file_end_write(struct file *file) -+{ -+ lockdep_off(); -+ file_end_write(file); -+ lockdep_on(); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_hinode; -+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1, -+ struct dentry *d2, struct au_hinode *hdir2); -+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1, -+ struct dentry *d2, struct au_hinode *hdir2); -+ -+int vfsub_create(struct inode *dir, struct path *path, int mode, -+ bool want_excl); -+int vfsub_symlink(struct inode *dir, struct path *path, -+ const char *symname); -+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev); -+int vfsub_link(struct dentry *src_dentry, struct inode *dir, -+ struct path *path, struct inode **delegated_inode); -+int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry, -+ struct inode *hdir, struct path *path, -+ struct inode **delegated_inode, unsigned int flags); -+int vfsub_mkdir(struct inode *dir, struct path *path, int mode); -+int vfsub_rmdir(struct inode *dir, struct path *path); -+ -+/* ---------------------------------------------------------------------- */ -+ -+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count, -+ loff_t *ppos); -+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count, -+ loff_t *ppos); -+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count, -+ loff_t *ppos); -+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, -+ loff_t *ppos); -+int vfsub_flush(struct file *file, fl_owner_t id); -+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx); -+ -+static inline loff_t vfsub_f_size_read(struct file *file) -+{ -+ return i_size_read(file_inode(file)); -+} -+ -+static inline unsigned int vfsub_file_flags(struct file *file) -+{ -+ unsigned int flags; -+ -+ spin_lock(&file->f_lock); -+ flags = file->f_flags; -+ spin_unlock(&file->f_lock); -+ -+ return flags; -+} -+ -+static inline int vfsub_file_execed(struct file *file) -+{ -+ /* todo: direct access f_flags */ -+ return !!(vfsub_file_flags(file) & __FMODE_EXEC); -+} -+ -+#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 -+ -+#if 0 /* reserved */ -+static inline void vfsub_touch_atime(struct vfsmount *h_mnt, -+ struct dentry *h_dentry) -+{ -+ struct path h_path = { -+ .dentry = h_dentry, -+ .mnt = h_mnt -+ }; -+ touch_atime(&h_path); -+ vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/ -+} -+#endif -+ -+static inline int vfsub_update_time(struct inode *h_inode, int flags) -+{ -+ return inode_update_time(h_inode, flags); -+ /* no vfsub_update_h_iattr() since we don't have struct path */ -+} -+ -+#ifdef CONFIG_FS_POSIX_ACL -+static inline int vfsub_acl_chmod(struct mnt_idmap *h_idmap, -+ struct dentry *h_dentry, umode_t h_mode) -+{ -+ int err; -+ -+ err = posix_acl_chmod(h_idmap, h_dentry, h_mode); -+ if (err == -EOPNOTSUPP) -+ err = 0; -+ return err; -+} -+#else -+AuStubInt0(vfsub_acl_chmod, struct mnt_idmap *h_idmap, -+ struct dentry *h_dentry, umode_t h_mode); -+#endif -+ -+long vfsub_splice_read(struct file *in, loff_t *ppos, -+ struct pipe_inode_info *pipe, size_t len, -+ unsigned int flags); -+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out, -+ loff_t *ppos, size_t len, unsigned int flags); -+ -+static inline long vfsub_truncate(struct path *path, loff_t length) -+{ -+ long err; -+ -+ lockdep_off(); -+ err = vfs_truncate(path, length); -+ lockdep_on(); -+ return err; -+} -+ -+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr, -+ struct file *h_file); -+int vfsub_fsync(struct file *file, struct path *path, int datasync); -+ -+/* -+ * re-use branch fs's ioctl(FICLONE) while aufs itself doesn't support such -+ * ioctl. -+ */ -+static inline loff_t vfsub_clone_file_range(struct file *src, struct file *dst, -+ loff_t len) -+{ -+ loff_t err; -+ -+ lockdep_off(); -+ err = vfs_clone_file_range(src, 0, dst, 0, len, /*remap_flags*/0); -+ lockdep_on(); -+ -+ return err; -+} -+ -+/* copy_file_range(2) is a systemcall */ -+static inline ssize_t vfsub_copy_file_range(struct file *src, loff_t src_pos, -+ struct file *dst, loff_t dst_pos, -+ size_t len, unsigned int flags) -+{ -+ ssize_t ssz; -+ -+ lockdep_off(); -+ ssz = vfs_copy_file_range(src, src_pos, dst, dst_pos, len, flags); -+ lockdep_on(); -+ -+ return ssz; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin) -+{ -+ loff_t err; -+ -+ lockdep_off(); -+ err = vfs_llseek(file, offset, origin); -+ lockdep_on(); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+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, -+ struct inode **delegated_inode); -+int vfsub_notify_change(struct path *path, struct iattr *ia, -+ struct inode **delegated_inode); -+int vfsub_unlink(struct inode *dir, struct path *path, -+ struct inode **delegated_inode, int force); -+ -+static inline int vfsub_getattr(const struct path *path, struct kstat *st) -+{ -+ return vfs_getattr(path, st, STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline int vfsub_setxattr(struct mnt_idmap *idmap, -+ struct dentry *dentry, const char *name, -+ const void *value, size_t size, int flags) -+{ -+ int err; -+ -+ lockdep_off(); -+ err = vfs_setxattr(idmap, dentry, name, value, size, flags); -+ lockdep_on(); -+ -+ return err; -+} -+ -+static inline int vfsub_removexattr(struct mnt_idmap *idmap, -+ struct dentry *dentry, const char *name) -+{ -+ int err; -+ -+ lockdep_off(); -+ err = vfs_removexattr(idmap, dentry, name); -+ lockdep_on(); -+ -+ return err; -+} -+ -+#ifdef CONFIG_FS_POSIX_ACL -+static inline int vfsub_set_acl(struct mnt_idmap *idmap, -+ struct dentry *dentry, const char *name, -+ struct posix_acl *acl) -+{ -+ int err; -+ -+ lockdep_off(); -+ err = vfs_set_acl(idmap, dentry, name, acl); -+ lockdep_on(); -+ -+ return err; -+} -+ -+static inline int vfsub_remove_acl(struct mnt_idmap *idmap, -+ struct dentry *dentry, const char *name) -+{ -+ int err; -+ -+ lockdep_off(); -+ err = vfs_remove_acl(idmap, dentry, name); -+ lockdep_on(); -+ -+ return err; -+} -+#else -+AuStubInt0(vfsub_set_acl, struct mnt_idmap *idmap, struct dentry *dentry, -+ const char *name, struct posix_acl *acl); -+AuStubInt0(vfsub_remove_acl, struct mnt_idmap *idmap, -+ struct dentry *dentry, const char *name); -+#endif -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_VFSUB_H__ */ -diff -Naur null/fs/aufs/wbr_policy.c linux-6.6.63/fs/aufs/wbr_policy.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/wbr_policy.c 2024-12-18 15:12:59.300519526 +0300 -@@ -0,0 +1,830 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * policies for selecting one among multiple writable branches -+ */ -+ -+#include -+#include "aufs.h" -+ -+/* subset of cpup_attr() */ -+static noinline_for_stack -+int au_cpdown_attr(struct path *h_path, struct dentry *h_src) -+{ -+ int err, sbits; -+ struct iattr ia; -+ struct inode *h_isrc; -+ -+ 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(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); -+ -+ /* is this nfs only? */ -+ if (!err && sbits && au_test_nfs(h_path->dentry->d_sb)) { -+ ia.ia_valid = ATTR_FORCE | ATTR_MODE; -+ ia.ia_mode = h_isrc->i_mode; -+ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL); -+ } -+ -+ return err; -+} -+ -+#define AuCpdown_PARENT_OPQ 1 -+#define AuCpdown_WHED (1 << 1) -+#define AuCpdown_MADE_DIR (1 << 2) -+#define AuCpdown_DIROPQ (1 << 3) -+#define au_ftest_cpdown(flags, name) ((flags) & AuCpdown_##name) -+#define au_fset_cpdown(flags, name) \ -+ do { (flags) |= AuCpdown_##name; } while (0) -+#define au_fclr_cpdown(flags, name) \ -+ do { (flags) &= ~AuCpdown_##name; } while (0) -+ -+static int au_cpdown_dir_opq(struct dentry *dentry, aufs_bindex_t bdst, -+ unsigned int *flags) -+{ -+ int err; -+ struct dentry *opq_dentry; -+ -+ opq_dentry = au_diropq_create(dentry, bdst); -+ err = PTR_ERR(opq_dentry); -+ if (IS_ERR(opq_dentry)) -+ goto out; -+ dput(opq_dentry); -+ au_fset_cpdown(*flags, DIROPQ); -+ -+out: -+ return err; -+} -+ -+static int au_cpdown_dir_wh(struct dentry *dentry, struct dentry *h_parent, -+ struct inode *dir, aufs_bindex_t bdst) -+{ -+ int err; -+ struct path h_path; -+ struct au_branch *br; -+ -+ br = au_sbr(dentry->d_sb, bdst); -+ h_path.dentry = au_wh_lkup(h_parent, &dentry->d_name, br); -+ err = PTR_ERR(h_path.dentry); -+ if (IS_ERR(h_path.dentry)) -+ goto out; -+ -+ err = 0; -+ 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); -+ } -+ dput(h_path.dentry); -+ -+out: -+ return err; -+} -+ -+static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst, -+ struct au_pin *pin, -+ struct dentry *h_parent, void *arg) -+{ -+ int err, rerr; -+ aufs_bindex_t bopq, btop; -+ struct path h_path; -+ struct dentry *parent; -+ struct inode *h_dir, *h_inode, *inode, *dir; -+ unsigned int *flags = arg; -+ -+ btop = au_dbtop(dentry); -+ /* dentry is di-locked */ -+ parent = dget_parent(dentry); -+ dir = d_inode(parent); -+ h_dir = d_inode(h_parent); -+ AuDebugOn(h_dir != au_h_iptr(dir, bdst)); -+ IMustLock(h_dir); -+ -+ err = au_lkup_neg(dentry, bdst, /*wh*/0); -+ if (unlikely(err < 0)) -+ goto out; -+ h_path.dentry = au_h_dptr(dentry, bdst); -+ h_path.mnt = au_sbr_mnt(dentry->d_sb, bdst); -+ err = vfsub_sio_mkdir(au_h_iptr(dir, bdst), &h_path, 0755); -+ if (unlikely(err)) -+ goto out_put; -+ au_fset_cpdown(*flags, MADE_DIR); -+ -+ bopq = au_dbdiropq(dentry); -+ au_fclr_cpdown(*flags, WHED); -+ au_fclr_cpdown(*flags, DIROPQ); -+ if (au_dbwh(dentry) == bdst) -+ au_fset_cpdown(*flags, WHED); -+ if (!au_ftest_cpdown(*flags, PARENT_OPQ) && bopq <= bdst) -+ au_fset_cpdown(*flags, PARENT_OPQ); -+ h_inode = d_inode(h_path.dentry); -+ inode_lock_nested(h_inode, AuLsc_I_CHILD); -+ if (au_ftest_cpdown(*flags, WHED)) { -+ err = au_cpdown_dir_opq(dentry, bdst, flags); -+ if (unlikely(err)) { -+ inode_unlock(h_inode); -+ goto out_dir; -+ } -+ } -+ -+ err = au_cpdown_attr(&h_path, au_h_dptr(dentry, btop)); -+ inode_unlock(h_inode); -+ if (unlikely(err)) -+ goto out_opq; -+ -+ if (au_ftest_cpdown(*flags, WHED)) { -+ err = au_cpdown_dir_wh(dentry, h_parent, dir, bdst); -+ if (unlikely(err)) -+ goto out_opq; -+ } -+ -+ inode = d_inode(dentry); -+ if (au_ibbot(inode) < bdst) -+ au_set_ibbot(inode, bdst); -+ au_set_h_iptr(inode, bdst, au_igrab(h_inode), -+ au_hi_flags(inode, /*isdir*/1)); -+ au_fhsm_wrote(dentry->d_sb, bdst, /*force*/0); -+ goto out; /* success */ -+ -+ /* revert */ -+out_opq: -+ if (au_ftest_cpdown(*flags, DIROPQ)) { -+ inode_lock_nested(h_inode, AuLsc_I_CHILD); -+ rerr = au_diropq_remove(dentry, bdst); -+ inode_unlock(h_inode); -+ if (unlikely(rerr)) { -+ AuIOErr("failed removing diropq for %pd b%d (%d)\n", -+ dentry, bdst, rerr); -+ err = -EIO; -+ goto out; -+ } -+ } -+out_dir: -+ if (au_ftest_cpdown(*flags, MADE_DIR)) { -+ rerr = vfsub_sio_rmdir(au_h_iptr(dir, bdst), &h_path); -+ if (unlikely(rerr)) { -+ AuIOErr("failed removing %pd b%d (%d)\n", -+ dentry, bdst, rerr); -+ err = -EIO; -+ } -+ } -+out_put: -+ au_set_h_dptr(dentry, bdst, NULL); -+ if (au_dbbot(dentry) == bdst) -+ au_update_dbbot(dentry); -+out: -+ dput(parent); -+ return err; -+} -+ -+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst) -+{ -+ int err; -+ unsigned int flags; -+ -+ flags = 0; -+ err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &flags); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* policies for create */ -+ -+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex) -+{ -+ int err, i, j, ndentry; -+ aufs_bindex_t bopq; -+ struct au_dcsub_pages dpages; -+ struct au_dpage *dpage; -+ struct dentry **dentries, *parent, *d; -+ -+ err = au_dpages_init(&dpages, GFP_NOFS); -+ if (unlikely(err)) -+ goto out; -+ parent = dget_parent(dentry); -+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/0); -+ if (unlikely(err)) -+ goto out_free; -+ -+ err = bindex; -+ for (i = 0; i < dpages.ndpage; i++) { -+ dpage = dpages.dpages + i; -+ dentries = dpage->dentries; -+ ndentry = dpage->ndentry; -+ for (j = 0; j < ndentry; j++) { -+ d = dentries[j]; -+ di_read_lock_parent2(d, !AuLock_IR); -+ bopq = au_dbdiropq(d); -+ di_read_unlock(d, !AuLock_IR); -+ if (bopq >= 0 && bopq < err) -+ err = bopq; -+ } -+ } -+ -+out_free: -+ dput(parent); -+ au_dpages_free(&dpages); -+out: -+ return err; -+} -+ -+static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ for (; bindex >= 0; bindex--) -+ if (!au_br_rdonly(au_sbr(sb, bindex))) -+ return bindex; -+ return -EROFS; -+} -+ -+/* top down parent */ -+static int au_wbr_create_tdp(struct dentry *dentry, -+ unsigned int flags __maybe_unused) -+{ -+ int err; -+ aufs_bindex_t btop, bindex; -+ struct super_block *sb; -+ struct dentry *parent, *h_parent; -+ -+ sb = dentry->d_sb; -+ btop = au_dbtop(dentry); -+ err = btop; -+ if (!au_br_rdonly(au_sbr(sb, btop))) -+ goto out; -+ -+ err = -EROFS; -+ parent = dget_parent(dentry); -+ for (bindex = au_dbtop(parent); bindex < btop; bindex++) { -+ h_parent = au_h_dptr(parent, bindex); -+ if (!h_parent || d_is_negative(h_parent)) -+ continue; -+ -+ if (!au_br_rdonly(au_sbr(sb, bindex))) { -+ err = bindex; -+ break; -+ } -+ } -+ dput(parent); -+ -+ /* bottom up here */ -+ if (unlikely(err < 0)) { -+ err = au_wbr_bu(sb, btop - 1); -+ if (err >= 0) -+ err = au_wbr_nonopq(dentry, err); -+ } -+ -+out: -+ AuDbg("b%d\n", err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* an exception for the policy other than tdp */ -+static int au_wbr_create_exp(struct dentry *dentry) -+{ -+ int err; -+ aufs_bindex_t bwh, bdiropq; -+ struct dentry *parent; -+ -+ err = -1; -+ bwh = au_dbwh(dentry); -+ parent = dget_parent(dentry); -+ bdiropq = au_dbdiropq(parent); -+ if (bwh >= 0) { -+ if (bdiropq >= 0) -+ err = min(bdiropq, bwh); -+ else -+ err = bwh; -+ AuDbg("%d\n", err); -+ } else if (bdiropq >= 0) { -+ err = bdiropq; -+ AuDbg("%d\n", err); -+ } -+ dput(parent); -+ -+ if (err >= 0) -+ err = au_wbr_nonopq(dentry, err); -+ -+ if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err))) -+ err = -1; -+ -+ AuDbg("%d\n", err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* round robin */ -+static int au_wbr_create_init_rr(struct super_block *sb) -+{ -+ int err; -+ -+ err = au_wbr_bu(sb, au_sbbot(sb)); -+ atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */ -+ /* smp_mb(); */ -+ -+ AuDbg("b%d\n", err); -+ return err; -+} -+ -+static int au_wbr_create_rr(struct dentry *dentry, unsigned int flags) -+{ -+ int err, nbr; -+ unsigned int u; -+ aufs_bindex_t bindex, bbot; -+ struct super_block *sb; -+ atomic_t *next; -+ -+ err = au_wbr_create_exp(dentry); -+ if (err >= 0) -+ goto out; -+ -+ sb = dentry->d_sb; -+ next = &au_sbi(sb)->si_wbr_rr_next; -+ bbot = au_sbbot(sb); -+ nbr = bbot + 1; -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ if (!au_ftest_wbr(flags, DIR)) { -+ err = atomic_dec_return(next) + 1; -+ /* modulo for 0 is meaningless */ -+ if (unlikely(!err)) -+ err = atomic_dec_return(next) + 1; -+ } else -+ err = atomic_read(next); -+ AuDbg("%d\n", err); -+ u = err; -+ err = u % nbr; -+ AuDbg("%d\n", err); -+ if (!au_br_rdonly(au_sbr(sb, err))) -+ break; -+ err = -EROFS; -+ } -+ -+ if (err >= 0) -+ err = au_wbr_nonopq(dentry, err); -+ -+out: -+ AuDbg("%d\n", err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* most free space */ -+static void au_mfs(struct dentry *dentry, struct dentry *parent) -+{ -+ struct super_block *sb; -+ struct au_branch *br; -+ struct au_wbr_mfs *mfs; -+ struct dentry *h_parent; -+ aufs_bindex_t bindex, bbot; -+ int err; -+ unsigned long long b, bavail; -+ struct path h_path; -+ /* reduce the stack usage */ -+ struct kstatfs *st; -+ -+ st = kmalloc(sizeof(*st), GFP_NOFS); -+ if (unlikely(!st)) { -+ AuWarn1("failed updating mfs(%d), ignored\n", -ENOMEM); -+ return; -+ } -+ -+ bavail = 0; -+ sb = dentry->d_sb; -+ mfs = &au_sbi(sb)->si_wbr_mfs; -+ MtxMustLock(&mfs->mfs_lock); -+ mfs->mfs_bindex = -EROFS; -+ mfs->mfsrr_bytes = 0; -+ if (!parent) { -+ bindex = 0; -+ bbot = au_sbbot(sb); -+ } else { -+ bindex = au_dbtop(parent); -+ bbot = au_dbtaildir(parent); -+ } -+ -+ for (; bindex <= bbot; bindex++) { -+ if (parent) { -+ h_parent = au_h_dptr(parent, bindex); -+ if (!h_parent || d_is_negative(h_parent)) -+ continue; -+ } -+ br = au_sbr(sb, bindex); -+ if (au_br_rdonly(br)) -+ continue; -+ -+ /* sb->s_root for NFS is unreliable */ -+ h_path.mnt = au_br_mnt(br); -+ h_path.dentry = h_path.mnt->mnt_root; -+ err = vfs_statfs(&h_path, st); -+ if (unlikely(err)) { -+ AuWarn1("failed statfs, b%d, %d\n", bindex, err); -+ continue; -+ } -+ -+ /* when the available size is equal, select the lower one */ -+ BUILD_BUG_ON(sizeof(b) < sizeof(st->f_bavail) -+ || sizeof(b) < sizeof(st->f_bsize)); -+ b = st->f_bavail * st->f_bsize; -+ br->br_wbr->wbr_bytes = b; -+ if (b >= bavail) { -+ bavail = b; -+ mfs->mfs_bindex = bindex; -+ mfs->mfs_jiffy = jiffies; -+ } -+ } -+ -+ mfs->mfsrr_bytes = bavail; -+ AuDbg("b%d\n", mfs->mfs_bindex); -+ au_kfree_rcu(st); -+} -+ -+static int au_wbr_create_mfs(struct dentry *dentry, unsigned int flags) -+{ -+ int err; -+ struct dentry *parent; -+ struct super_block *sb; -+ struct au_wbr_mfs *mfs; -+ -+ err = au_wbr_create_exp(dentry); -+ if (err >= 0) -+ goto out; -+ -+ sb = dentry->d_sb; -+ parent = NULL; -+ if (au_ftest_wbr(flags, PARENT)) -+ parent = dget_parent(dentry); -+ mfs = &au_sbi(sb)->si_wbr_mfs; -+ mutex_lock(&mfs->mfs_lock); -+ if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire) -+ || mfs->mfs_bindex < 0 -+ || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex))) -+ au_mfs(dentry, parent); -+ mutex_unlock(&mfs->mfs_lock); -+ err = mfs->mfs_bindex; -+ dput(parent); -+ -+ if (err >= 0) -+ err = au_wbr_nonopq(dentry, err); -+ -+out: -+ AuDbg("b%d\n", err); -+ return err; -+} -+ -+static int au_wbr_create_init_mfs(struct super_block *sb) -+{ -+ struct au_wbr_mfs *mfs; -+ -+ mfs = &au_sbi(sb)->si_wbr_mfs; -+ mutex_init(&mfs->mfs_lock); -+ mfs->mfs_jiffy = 0; -+ mfs->mfs_bindex = -EROFS; -+ -+ return 0; -+} -+ -+static int au_wbr_create_fin_mfs(struct super_block *sb __maybe_unused) -+{ -+ mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock); -+ return 0; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* top down regardless parent, and then mfs */ -+static int au_wbr_create_tdmfs(struct dentry *dentry, -+ unsigned int flags __maybe_unused) -+{ -+ int err; -+ aufs_bindex_t bwh, btail, bindex, bfound, bmfs; -+ unsigned long long watermark; -+ struct super_block *sb; -+ struct au_wbr_mfs *mfs; -+ struct au_branch *br; -+ struct dentry *parent; -+ -+ sb = dentry->d_sb; -+ mfs = &au_sbi(sb)->si_wbr_mfs; -+ mutex_lock(&mfs->mfs_lock); -+ if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire) -+ || mfs->mfs_bindex < 0) -+ au_mfs(dentry, /*parent*/NULL); -+ watermark = mfs->mfsrr_watermark; -+ bmfs = mfs->mfs_bindex; -+ mutex_unlock(&mfs->mfs_lock); -+ -+ /* another style of au_wbr_create_exp() */ -+ bwh = au_dbwh(dentry); -+ parent = dget_parent(dentry); -+ btail = au_dbtaildir(parent); -+ if (bwh >= 0 && bwh < btail) -+ btail = bwh; -+ -+ err = au_wbr_nonopq(dentry, btail); -+ if (unlikely(err < 0)) -+ goto out; -+ btail = err; -+ bfound = -1; -+ for (bindex = 0; bindex <= btail; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (au_br_rdonly(br)) -+ continue; -+ if (br->br_wbr->wbr_bytes > watermark) { -+ bfound = bindex; -+ break; -+ } -+ } -+ err = bfound; -+ if (err < 0) -+ err = bmfs; -+ -+out: -+ dput(parent); -+ AuDbg("b%d\n", err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* most free space and then round robin */ -+static int au_wbr_create_mfsrr(struct dentry *dentry, unsigned int flags) -+{ -+ int err; -+ struct au_wbr_mfs *mfs; -+ -+ err = au_wbr_create_mfs(dentry, flags); -+ if (err >= 0) { -+ mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs; -+ mutex_lock(&mfs->mfs_lock); -+ if (mfs->mfsrr_bytes < mfs->mfsrr_watermark) -+ err = au_wbr_create_rr(dentry, flags); -+ mutex_unlock(&mfs->mfs_lock); -+ } -+ -+ AuDbg("b%d\n", err); -+ return err; -+} -+ -+static int au_wbr_create_init_mfsrr(struct super_block *sb) -+{ -+ int err; -+ -+ au_wbr_create_init_mfs(sb); /* ignore */ -+ err = au_wbr_create_init_rr(sb); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* top down parent and most free space */ -+static int au_wbr_create_pmfs(struct dentry *dentry, unsigned int flags) -+{ -+ int err, e2; -+ unsigned long long b; -+ aufs_bindex_t bindex, btop, bbot; -+ struct super_block *sb; -+ struct dentry *parent, *h_parent; -+ struct au_branch *br; -+ -+ err = au_wbr_create_tdp(dentry, flags); -+ if (unlikely(err < 0)) -+ goto out; -+ parent = dget_parent(dentry); -+ btop = au_dbtop(parent); -+ bbot = au_dbtaildir(parent); -+ if (btop == bbot) -+ goto out_parent; /* success */ -+ -+ e2 = au_wbr_create_mfs(dentry, flags); -+ if (e2 < 0) -+ goto out_parent; /* success */ -+ -+ /* when the available size is equal, select upper one */ -+ sb = dentry->d_sb; -+ br = au_sbr(sb, err); -+ b = br->br_wbr->wbr_bytes; -+ AuDbg("b%d, %llu\n", err, b); -+ -+ for (bindex = btop; bindex <= bbot; bindex++) { -+ h_parent = au_h_dptr(parent, bindex); -+ if (!h_parent || d_is_negative(h_parent)) -+ continue; -+ -+ br = au_sbr(sb, bindex); -+ if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) { -+ b = br->br_wbr->wbr_bytes; -+ err = bindex; -+ AuDbg("b%d, %llu\n", err, b); -+ } -+ } -+ -+ if (err >= 0) -+ err = au_wbr_nonopq(dentry, err); -+ -+out_parent: -+ dput(parent); -+out: -+ AuDbg("b%d\n", err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * - top down parent -+ * - most free space with parent -+ * - most free space round-robin regardless parent -+ */ -+static int au_wbr_create_pmfsrr(struct dentry *dentry, unsigned int flags) -+{ -+ int err; -+ unsigned long long watermark; -+ struct super_block *sb; -+ struct au_branch *br; -+ struct au_wbr_mfs *mfs; -+ -+ err = au_wbr_create_pmfs(dentry, flags | AuWbr_PARENT); -+ if (unlikely(err < 0)) -+ goto out; -+ -+ sb = dentry->d_sb; -+ br = au_sbr(sb, err); -+ mfs = &au_sbi(sb)->si_wbr_mfs; -+ mutex_lock(&mfs->mfs_lock); -+ watermark = mfs->mfsrr_watermark; -+ mutex_unlock(&mfs->mfs_lock); -+ if (br->br_wbr->wbr_bytes < watermark) -+ /* regardless the parent dir */ -+ err = au_wbr_create_mfsrr(dentry, flags); -+ -+out: -+ AuDbg("b%d\n", err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* policies for copyup */ -+ -+/* top down parent */ -+static int au_wbr_copyup_tdp(struct dentry *dentry) -+{ -+ return au_wbr_create_tdp(dentry, /*flags, anything is ok*/0); -+} -+ -+/* bottom up parent */ -+static int au_wbr_copyup_bup(struct dentry *dentry) -+{ -+ int err; -+ aufs_bindex_t bindex, btop; -+ struct dentry *parent, *h_parent; -+ struct super_block *sb; -+ -+ err = -EROFS; -+ sb = dentry->d_sb; -+ parent = dget_parent(dentry); -+ btop = au_dbtop(parent); -+ for (bindex = au_dbtop(dentry); bindex >= btop; bindex--) { -+ h_parent = au_h_dptr(parent, bindex); -+ if (!h_parent || d_is_negative(h_parent)) -+ continue; -+ -+ if (!au_br_rdonly(au_sbr(sb, bindex))) { -+ err = bindex; -+ break; -+ } -+ } -+ dput(parent); -+ -+ /* bottom up here */ -+ if (unlikely(err < 0)) -+ err = au_wbr_bu(sb, btop - 1); -+ -+ AuDbg("b%d\n", err); -+ return err; -+} -+ -+/* bottom up */ -+int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t btop) -+{ -+ int err; -+ -+ err = au_wbr_bu(dentry->d_sb, btop); -+ AuDbg("b%d\n", err); -+ if (err > btop) -+ err = au_wbr_nonopq(dentry, err); -+ -+ AuDbg("b%d\n", err); -+ return err; -+} -+ -+static int au_wbr_copyup_bu(struct dentry *dentry) -+{ -+ int err; -+ aufs_bindex_t btop; -+ -+ btop = au_dbtop(dentry); -+ err = au_wbr_do_copyup_bu(dentry, btop); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_wbr_copyup_operations au_wbr_copyup_ops[] = { -+ [AuWbrCopyup_TDP] = { -+ .copyup = au_wbr_copyup_tdp -+ }, -+ [AuWbrCopyup_BUP] = { -+ .copyup = au_wbr_copyup_bup -+ }, -+ [AuWbrCopyup_BU] = { -+ .copyup = au_wbr_copyup_bu -+ } -+}; -+ -+struct au_wbr_create_operations au_wbr_create_ops[] = { -+ [AuWbrCreate_TDP] = { -+ .create = au_wbr_create_tdp -+ }, -+ [AuWbrCreate_RR] = { -+ .create = au_wbr_create_rr, -+ .init = au_wbr_create_init_rr -+ }, -+ [AuWbrCreate_MFS] = { -+ .create = au_wbr_create_mfs, -+ .init = au_wbr_create_init_mfs, -+ .fin = au_wbr_create_fin_mfs -+ }, -+ [AuWbrCreate_MFSV] = { -+ .create = au_wbr_create_mfs, -+ .init = au_wbr_create_init_mfs, -+ .fin = au_wbr_create_fin_mfs -+ }, -+ [AuWbrCreate_MFSRR] = { -+ .create = au_wbr_create_mfsrr, -+ .init = au_wbr_create_init_mfsrr, -+ .fin = au_wbr_create_fin_mfs -+ }, -+ [AuWbrCreate_MFSRRV] = { -+ .create = au_wbr_create_mfsrr, -+ .init = au_wbr_create_init_mfsrr, -+ .fin = au_wbr_create_fin_mfs -+ }, -+ [AuWbrCreate_TDMFS] = { -+ .create = au_wbr_create_tdmfs, -+ .init = au_wbr_create_init_mfs, -+ .fin = au_wbr_create_fin_mfs -+ }, -+ [AuWbrCreate_TDMFSV] = { -+ .create = au_wbr_create_tdmfs, -+ .init = au_wbr_create_init_mfs, -+ .fin = au_wbr_create_fin_mfs -+ }, -+ [AuWbrCreate_PMFS] = { -+ .create = au_wbr_create_pmfs, -+ .init = au_wbr_create_init_mfs, -+ .fin = au_wbr_create_fin_mfs -+ }, -+ [AuWbrCreate_PMFSV] = { -+ .create = au_wbr_create_pmfs, -+ .init = au_wbr_create_init_mfs, -+ .fin = au_wbr_create_fin_mfs -+ }, -+ [AuWbrCreate_PMFSRR] = { -+ .create = au_wbr_create_pmfsrr, -+ .init = au_wbr_create_init_mfsrr, -+ .fin = au_wbr_create_fin_mfs -+ }, -+ [AuWbrCreate_PMFSRRV] = { -+ .create = au_wbr_create_pmfsrr, -+ .init = au_wbr_create_init_mfsrr, -+ .fin = au_wbr_create_fin_mfs -+ } -+}; -diff -Naur null/fs/aufs/whout.c linux-6.6.63/fs/aufs/whout.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/whout.c 2024-12-18 15:12:59.300519526 +0300 -@@ -0,0 +1,1072 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * whiteout for logical deletion and opaque directory -+ */ -+ -+#include "aufs.h" -+ -+#define WH_MASK 0444 -+ -+/* -+ * If a directory contains this file, then it is opaque. We start with the -+ * .wh. flag so that it is blocked by lookup. -+ */ -+static struct qstr diropq_name = QSTR_INIT(AUFS_WH_DIROPQ, -+ sizeof(AUFS_WH_DIROPQ) - 1); -+ -+/* -+ * generate whiteout name, which is NOT terminated by NULL. -+ * @name: original d_name.name -+ * @len: original d_name.len -+ * @wh: whiteout qstr -+ * returns zero when succeeds, otherwise error. -+ * succeeded value as wh->name should be freed by kfree(). -+ */ -+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name) -+{ -+ char *p; -+ -+ if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN)) -+ return -ENAMETOOLONG; -+ -+ wh->len = name->len + AUFS_WH_PFX_LEN; -+ p = kmalloc(wh->len, GFP_NOFS); -+ wh->name = p; -+ if (p) { -+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN); -+ memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len); -+ /* smp_mb(); */ -+ return 0; -+ } -+ return -ENOMEM; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * test if the @wh_name exists under @h_ppath. -+ * @try_sio specifies the necessary of super-io. -+ */ -+int au_wh_test(struct mnt_idmap *h_idmap, struct path *h_ppath, -+ struct qstr *wh_name, int try_sio) -+{ -+ int err; -+ struct dentry *wh_dentry; -+ -+ if (!try_sio) -+ wh_dentry = vfsub_lkup_one(wh_name, h_ppath); -+ else -+ wh_dentry = au_sio_lkup_one(h_idmap, wh_name, h_ppath); -+ err = PTR_ERR(wh_dentry); -+ if (IS_ERR(wh_dentry)) { -+ if (err == -ENAMETOOLONG) -+ err = 0; -+ goto out; -+ } -+ -+ err = 0; -+ if (d_is_negative(wh_dentry)) -+ goto out_wh; /* success */ -+ -+ err = 1; -+ if (d_is_reg(wh_dentry)) -+ goto out_wh; /* success */ -+ -+ err = -EIO; -+ AuIOErr("%pd Invalid whiteout entry type 0%o.\n", -+ wh_dentry, d_inode(wh_dentry)->i_mode); -+ -+out_wh: -+ dput(wh_dentry); -+out: -+ return err; -+} -+ -+/* -+ * test if the @h_path->dentry sets opaque or not. -+ */ -+int au_diropq_test(struct mnt_idmap *h_idmap, struct path *h_path) -+{ -+ int err; -+ struct inode *h_dir; -+ -+ h_dir = d_inode(h_path->dentry); -+ err = au_wh_test(h_idmap, h_path, &diropq_name, -+ au_test_h_perm_sio(h_idmap, h_dir, MAY_EXEC)); -+ return err; -+} -+ -+/* -+ * returns a negative dentry whose name is unique and temporary. -+ */ -+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br, -+ struct qstr *prefix) -+{ -+ struct dentry *dentry; -+ int i; -+ char defname[NAME_MAX - AUFS_MAX_NAMELEN + DNAME_INLINE_LEN + 1], -+ *name, *p; -+ /* strict atomic_t is unnecessary here */ -+ static unsigned short cnt; -+ struct qstr qs; -+ struct path h_ppath; -+ struct mnt_idmap *h_idmap; -+ -+ BUILD_BUG_ON(sizeof(cnt) * 2 > AUFS_WH_TMP_LEN); -+ -+ name = defname; -+ qs.len = sizeof(defname) - DNAME_INLINE_LEN + prefix->len - 1; -+ if (unlikely(prefix->len > DNAME_INLINE_LEN)) { -+ dentry = ERR_PTR(-ENAMETOOLONG); -+ if (unlikely(qs.len > NAME_MAX)) -+ goto out; -+ dentry = ERR_PTR(-ENOMEM); -+ name = kmalloc(qs.len + 1, GFP_NOFS); -+ if (unlikely(!name)) -+ goto out; -+ } -+ -+ /* doubly whiteout-ed */ -+ memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2); -+ p = name + AUFS_WH_PFX_LEN * 2; -+ memcpy(p, prefix->name, prefix->len); -+ p += prefix->len; -+ *p++ = '.'; -+ AuDebugOn(name + qs.len + 1 - p <= AUFS_WH_TMP_LEN); -+ -+ h_ppath.dentry = h_parent; -+ h_ppath.mnt = au_br_mnt(br); -+ h_idmap = au_br_idmap(br); -+ qs.name = name; -+ for (i = 0; i < 3; i++) { -+ sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++); -+ dentry = au_sio_lkup_one(h_idmap, &qs, &h_ppath); -+ if (IS_ERR(dentry) || d_is_negative(dentry)) -+ goto out_name; -+ dput(dentry); -+ } -+ /* pr_warn("could not get random name\n"); */ -+ dentry = ERR_PTR(-EEXIST); -+ AuDbg("%.*s\n", AuLNPair(&qs)); -+ BUG(); -+ -+out_name: -+ if (name != defname) -+ au_kfree_try_rcu(name); -+out: -+ AuTraceErrPtr(dentry); -+ return dentry; -+} -+ -+/* -+ * rename the @h_dentry on @br to the whiteouted temporary name. -+ */ -+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br) -+{ -+ int err; -+ struct path h_path = { -+ .mnt = au_br_mnt(br) -+ }; -+ struct inode *h_dir, *delegated; -+ struct dentry *h_parent; -+ -+ h_parent = h_dentry->d_parent; /* dir inode is locked */ -+ h_dir = d_inode(h_parent); -+ IMustLock(h_dir); -+ -+ h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name); -+ err = PTR_ERR(h_path.dentry); -+ if (IS_ERR(h_path.dentry)) -+ goto out; -+ -+ /* under the same dir, no need to lock_rename() */ -+ delegated = NULL; -+ err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path, &delegated, -+ /*flags*/0); -+ AuTraceErr(err); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal rename\n"); -+ iput(delegated); -+ } -+ dput(h_path.dentry); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+/* -+ * functions for removing a whiteout -+ */ -+ -+static int do_unlink_wh(struct inode *h_dir, struct path *h_path) -+{ -+ int err, force; -+ struct inode *delegated; -+ -+ /* -+ * forces superio when the dir has a sticky bit. -+ * this may be a violation of unix fs semantics. -+ */ -+ force = (h_dir->i_mode & S_ISVTX) -+ && !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)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal unlink\n"); -+ iput(delegated); -+ } -+ return err; -+} -+ -+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path, -+ struct dentry *dentry) -+{ -+ int err; -+ -+ err = do_unlink_wh(h_dir, h_path); -+ if (!err && dentry) -+ au_set_dbwh(dentry, -1); -+ -+ return err; -+} -+ -+static int unlink_wh_name(struct path *h_ppath, struct qstr *wh) -+{ -+ int err; -+ struct path h_path; -+ -+ err = 0; -+ h_path.dentry = vfsub_lkup_one(wh, h_ppath); -+ if (IS_ERR(h_path.dentry)) -+ err = PTR_ERR(h_path.dentry); -+ else { -+ if (d_is_reg(h_path.dentry)) { -+ h_path.mnt = h_ppath->mnt; -+ err = do_unlink_wh(d_inode(h_ppath->dentry), &h_path); -+ } -+ dput(h_path.dentry); -+ } -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+/* -+ * initialize/clean whiteout for a branch -+ */ -+ -+static void au_wh_clean(struct inode *h_dir, struct path *whpath, -+ const int isdir) -+{ -+ int err; -+ struct inode *delegated; -+ -+ if (d_is_negative(whpath->dentry)) -+ return; -+ -+ if (isdir) -+ err = vfsub_rmdir(h_dir, whpath); -+ else { -+ delegated = NULL; -+ err = vfsub_unlink(h_dir, whpath, &delegated, /*force*/0); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal unlink\n"); -+ iput(delegated); -+ } -+ } -+ if (unlikely(err)) -+ pr_warn("failed removing %pd (%d), ignored.\n", -+ whpath->dentry, err); -+} -+ -+static int test_linkable(struct dentry *h_root) -+{ -+ struct inode *h_dir = d_inode(h_root); -+ -+ if (h_dir->i_op->link) -+ return 0; -+ -+ pr_err("%pd (%s) doesn't support link(2), use noplink and rw+nolwh\n", -+ h_root, au_sbtype(h_root->d_sb)); -+ return -ENOSYS; /* the branch doesn't have its ->link() */ -+} -+ -+/* todo: should this mkdir be done in /sbin/mount.aufs helper? */ -+static int au_whdir(struct inode *h_dir, struct path *path) -+{ -+ int err; -+ -+ err = -EEXIST; -+ if (d_is_negative(path->dentry)) { -+ int mode = 0700; -+ -+ if (au_test_nfs(path->dentry->d_sb)) -+ mode |= 0111; -+ err = vfsub_mkdir(h_dir, path, mode); -+ } else if (d_is_dir(path->dentry)) -+ err = 0; -+ else -+ pr_err("unknown %pd exists\n", path->dentry); -+ -+ return err; -+} -+ -+struct au_wh_base { -+ const struct qstr *name; -+ struct dentry *dentry; -+}; -+ -+static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[], -+ struct path *h_path) -+{ -+ h_path->dentry = base[AuBrWh_BASE].dentry; -+ au_wh_clean(h_dir, h_path, /*isdir*/0); -+ h_path->dentry = base[AuBrWh_PLINK].dentry; -+ au_wh_clean(h_dir, h_path, /*isdir*/1); -+ h_path->dentry = base[AuBrWh_ORPH].dentry; -+ au_wh_clean(h_dir, h_path, /*isdir*/1); -+} -+ -+/* -+ * returns tri-state, -+ * minus: error, caller should print the message -+ * zero: success -+ * plus: error, caller should NOT print the message -+ */ -+static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr, -+ int do_plink, struct au_wh_base base[], -+ struct path *h_path) -+{ -+ int err; -+ struct inode *h_dir; -+ -+ 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; -+ if (do_plink) { -+ err = test_linkable(h_root); -+ if (unlikely(err)) { -+ err = 1; -+ goto out; -+ } -+ -+ err = au_whdir(h_dir, h_path); -+ if (unlikely(err)) -+ goto out; -+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry); -+ } else -+ au_wh_clean(h_dir, h_path, /*isdir*/1); -+ h_path->dentry = base[AuBrWh_ORPH].dentry; -+ err = au_whdir(h_dir, h_path); -+ if (unlikely(err)) -+ goto out; -+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry); -+ -+out: -+ return err; -+} -+ -+/* -+ * for the moment, aufs supports the branch filesystem which does not support -+ * link(2). testing on FAT which does not support i_op->setattr() fully either, -+ * copyup failed. finally, such filesystem will not be used as the writable -+ * branch. -+ * -+ * returns tri-state, see above. -+ */ -+static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr, -+ int do_plink, struct au_wh_base base[], -+ struct path *h_path) -+{ -+ int err; -+ struct inode *h_dir; -+ -+ WbrWhMustWriteLock(wbr); -+ -+ err = test_linkable(h_root); -+ if (unlikely(err)) { -+ err = 1; -+ goto out; -+ } -+ -+ /* -+ * todo: should this create be done in /sbin/mount.aufs helper? -+ */ -+ err = -EEXIST; -+ 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 (d_is_reg(base[AuBrWh_BASE].dentry)) -+ err = 0; -+ else -+ pr_err("unknown %pd2 exists\n", base[AuBrWh_BASE].dentry); -+ if (unlikely(err)) -+ goto out; -+ -+ h_path->dentry = base[AuBrWh_PLINK].dentry; -+ if (do_plink) { -+ err = au_whdir(h_dir, h_path); -+ if (unlikely(err)) -+ goto out; -+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry); -+ } else -+ au_wh_clean(h_dir, h_path, /*isdir*/1); -+ wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry); -+ -+ h_path->dentry = base[AuBrWh_ORPH].dentry; -+ err = au_whdir(h_dir, h_path); -+ if (unlikely(err)) -+ goto out; -+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry); -+ -+out: -+ return err; -+} -+ -+/* -+ * initialize the whiteout base file/dir for @br. -+ */ -+int au_wh_init(struct au_branch *br, struct super_block *sb) -+{ -+ int err, i; -+ const unsigned char do_plink -+ = !!au_opt_test(au_mntflags(sb), PLINK); -+ struct inode *h_dir; -+ struct path path = br->br_path; -+ struct dentry *h_root = path.dentry; -+ struct au_wbr *wbr = br->br_wbr; -+ static const struct qstr base_name[] = { -+ [AuBrWh_BASE] = QSTR_INIT(AUFS_BASE_NAME, -+ sizeof(AUFS_BASE_NAME) - 1), -+ [AuBrWh_PLINK] = QSTR_INIT(AUFS_PLINKDIR_NAME, -+ sizeof(AUFS_PLINKDIR_NAME) - 1), -+ [AuBrWh_ORPH] = QSTR_INIT(AUFS_ORPHDIR_NAME, -+ sizeof(AUFS_ORPHDIR_NAME) - 1) -+ }; -+ struct au_wh_base base[] = { -+ [AuBrWh_BASE] = { -+ .name = base_name + AuBrWh_BASE, -+ .dentry = NULL -+ }, -+ [AuBrWh_PLINK] = { -+ .name = base_name + AuBrWh_PLINK, -+ .dentry = NULL -+ }, -+ [AuBrWh_ORPH] = { -+ .name = base_name + AuBrWh_ORPH, -+ .dentry = NULL -+ } -+ }; -+ -+ if (wbr) -+ WbrWhMustWriteLock(wbr); -+ -+ for (i = 0; i < AuBrWh_Last; i++) { -+ /* doubly whiteouted */ -+ struct dentry *d; -+ -+ d = au_wh_lkup(h_root, (void *)base[i].name, br); -+ err = PTR_ERR(d); -+ if (IS_ERR(d)) -+ goto out; -+ -+ base[i].dentry = d; -+ AuDebugOn(wbr -+ && wbr->wbr_wh[i] -+ && wbr->wbr_wh[i] != base[i].dentry); -+ } -+ -+ if (wbr) -+ for (i = 0; i < AuBrWh_Last; i++) { -+ dput(wbr->wbr_wh[i]); -+ wbr->wbr_wh[i] = NULL; -+ } -+ -+ err = 0; -+ if (!au_br_writable(br->br_perm)) { -+ 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); -+ if (err > 0) -+ goto out; -+ else if (err) -+ goto out_err; -+ } else { -+ err = au_wh_init_rw(h_root, wbr, do_plink, base, &path); -+ if (err > 0) -+ goto out; -+ else if (err) -+ goto out_err; -+ } -+ goto out; /* success */ -+ -+out_err: -+ pr_err("an error(%d) on the writable branch %pd(%s)\n", -+ err, h_root, au_sbtype(h_root->d_sb)); -+out: -+ for (i = 0; i < AuBrWh_Last; i++) -+ dput(base[i].dentry); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+/* -+ * whiteouts are all hard-linked usually. -+ * when its link count reaches a ceiling, we create a new whiteout base -+ * asynchronously. -+ */ -+ -+struct reinit_br_wh { -+ struct super_block *sb; -+ struct au_branch *br; -+}; -+ -+static void reinit_br_wh(void *arg) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ struct path h_path; -+ struct reinit_br_wh *a = arg; -+ struct au_wbr *wbr; -+ struct inode *dir, *delegated; -+ struct dentry *h_root; -+ struct au_hinode *hdir; -+ -+ err = 0; -+ wbr = a->br->br_wbr; -+ /* big aufs lock */ -+ si_noflush_write_lock(a->sb); -+ if (!au_br_writable(a->br->br_perm)) -+ goto out; -+ bindex = au_br_index(a->sb, a->br->br_id); -+ if (unlikely(bindex < 0)) -+ goto out; -+ -+ di_read_lock_parent(a->sb->s_root, AuLock_IR); -+ 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)); -+ -+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT); -+ wbr_wh_write_lock(wbr); -+ err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode, -+ h_root, a->br); -+ if (!err) { -+ h_path.dentry = wbr->wbr_whbase; -+ h_path.mnt = au_br_mnt(a->br); -+ delegated = NULL; -+ err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated, -+ /*force*/0); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal unlink\n"); -+ iput(delegated); -+ } -+ } else { -+ pr_warn("%pd is moved, ignored\n", wbr->wbr_whbase); -+ err = 0; -+ } -+ dput(wbr->wbr_whbase); -+ wbr->wbr_whbase = NULL; -+ if (!err) -+ err = au_wh_init(a->br, a->sb); -+ wbr_wh_write_unlock(wbr); -+ au_hn_inode_unlock(hdir); -+ di_read_unlock(a->sb->s_root, AuLock_IR); -+ if (!err) -+ au_fhsm_wrote(a->sb, bindex, /*force*/0); -+ -+out: -+ if (wbr) -+ atomic_dec(&wbr->wbr_wh_running); -+ au_lcnt_dec(&a->br->br_count); -+ si_write_unlock(a->sb); -+ au_nwt_done(&au_sbi(a->sb)->si_nowait); -+ au_kfree_rcu(a); -+ if (unlikely(err)) -+ AuIOErr("err %d\n", err); -+} -+ -+static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br) -+{ -+ int do_dec, wkq_err; -+ struct reinit_br_wh *arg; -+ -+ do_dec = 1; -+ if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1) -+ goto out; -+ -+ /* ignore ENOMEM */ -+ arg = kmalloc(sizeof(*arg), GFP_NOFS); -+ if (arg) { -+ /* -+ * dec(wh_running), kfree(arg) and dec(br_count) -+ * in reinit function -+ */ -+ arg->sb = sb; -+ arg->br = br; -+ au_lcnt_inc(&br->br_count); -+ wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb, /*flags*/0); -+ if (unlikely(wkq_err)) { -+ atomic_dec(&br->br_wbr->wbr_wh_running); -+ au_lcnt_dec(&br->br_count); -+ au_kfree_rcu(arg); -+ } -+ do_dec = 0; -+ } -+ -+out: -+ if (do_dec) -+ atomic_dec(&br->br_wbr->wbr_wh_running); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * create the whiteout @wh. -+ */ -+static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex, -+ struct dentry *wh) -+{ -+ int err; -+ struct path h_path = { -+ .dentry = wh -+ }; -+ struct au_branch *br; -+ struct au_wbr *wbr; -+ struct dentry *h_parent; -+ struct inode *h_dir, *delegated; -+ -+ h_parent = wh->d_parent; /* dir inode is locked */ -+ h_dir = d_inode(h_parent); -+ IMustLock(h_dir); -+ -+ br = au_sbr(sb, bindex); -+ h_path.mnt = au_br_mnt(br); -+ wbr = br->br_wbr; -+ wbr_wh_read_lock(wbr); -+ if (wbr->wbr_whbase) { -+ delegated = NULL; -+ err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path, &delegated); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal link\n"); -+ iput(delegated); -+ } -+ if (!err || err != -EMLINK) -+ goto out; -+ -+ /* link count full. re-initialize br_whbase. */ -+ kick_reinit_br_wh(sb, br); -+ } -+ -+ /* return this error in this context */ -+ err = vfsub_create(h_dir, &h_path, WH_MASK, /*want_excl*/true); -+ if (!err) -+ au_fhsm_wrote(sb, bindex, /*force*/0); -+ -+out: -+ wbr_wh_read_unlock(wbr); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * create or remove the diropq. -+ */ -+static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex, -+ unsigned int flags) -+{ -+ struct dentry *opq_dentry; -+ struct super_block *sb; -+ struct au_branch *br; -+ struct path h_path; -+ int err; -+ -+ sb = dentry->d_sb; -+ br = au_sbr(sb, bindex); -+ h_path.dentry = au_h_dptr(dentry, bindex); -+ h_path.mnt = au_br_mnt(br); -+ opq_dentry = vfsub_lkup_one(&diropq_name, &h_path); -+ if (IS_ERR(opq_dentry)) -+ goto out; -+ -+ if (au_ftest_diropq(flags, CREATE)) { -+ err = link_or_create_wh(sb, bindex, opq_dentry); -+ if (!err) { -+ au_set_dbdiropq(dentry, bindex); -+ goto out; /* success */ -+ } -+ } else { -+ h_path.dentry = opq_dentry; -+ err = do_unlink_wh(au_h_iptr(d_inode(dentry), bindex), &h_path); -+ if (!err) -+ au_set_dbdiropq(dentry, -1); -+ } -+ dput(opq_dentry); -+ opq_dentry = ERR_PTR(err); -+ -+out: -+ return opq_dentry; -+} -+ -+struct do_diropq_args { -+ struct dentry **errp; -+ struct dentry *dentry; -+ aufs_bindex_t bindex; -+ unsigned int flags; -+}; -+ -+static void call_do_diropq(void *args) -+{ -+ struct do_diropq_args *a = args; -+ *a->errp = do_diropq(a->dentry, a->bindex, a->flags); -+} -+ -+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex, -+ unsigned int flags) -+{ -+ struct dentry *diropq, *h_dentry; -+ struct mnt_idmap *h_idmap; -+ -+ h_idmap = au_sbr_idmap(dentry->d_sb, bindex); -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (!au_test_h_perm_sio(h_idmap, d_inode(h_dentry), -+ MAY_EXEC | MAY_WRITE)) -+ diropq = do_diropq(dentry, bindex, flags); -+ else { -+ int wkq_err; -+ struct do_diropq_args args = { -+ .errp = &diropq, -+ .dentry = dentry, -+ .bindex = bindex, -+ .flags = flags -+ }; -+ -+ wkq_err = au_wkq_wait(call_do_diropq, &args); -+ if (unlikely(wkq_err)) -+ diropq = ERR_PTR(wkq_err); -+ } -+ -+ return diropq; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * lookup whiteout dentry. -+ * @h_parent: lower parent dentry which must exist and be locked -+ * @base_name: name of dentry which will be whiteouted -+ * returns dentry for whiteout. -+ */ -+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name, -+ struct au_branch *br) -+{ -+ int err; -+ struct qstr wh_name; -+ struct dentry *wh_dentry; -+ struct path h_path; -+ -+ err = au_wh_name_alloc(&wh_name, base_name); -+ wh_dentry = ERR_PTR(err); -+ if (!err) { -+ h_path.dentry = h_parent; -+ h_path.mnt = au_br_mnt(br); -+ wh_dentry = vfsub_lkup_one(&wh_name, &h_path); -+ au_kfree_try_rcu(wh_name.name); -+ } -+ return wh_dentry; -+} -+ -+/* -+ * link/create a whiteout for @dentry on @bindex. -+ */ -+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex, -+ struct dentry *h_parent) -+{ -+ struct dentry *wh_dentry; -+ struct super_block *sb; -+ int err; -+ -+ sb = dentry->d_sb; -+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex)); -+ 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); -+ au_fhsm_wrote(sb, bindex, /*force*/0); -+ } else { -+ dput(wh_dentry); -+ wh_dentry = ERR_PTR(err); -+ } -+ } -+ -+ return wh_dentry; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* Delete all whiteouts in this directory on branch bindex. */ -+static int del_wh_children(struct path *h_path, struct au_nhash *whlist, -+ aufs_bindex_t bindex) -+{ -+ int err; -+ unsigned long ul, n; -+ struct qstr wh_name; -+ char *p; -+ struct hlist_head *head; -+ struct au_vdir_wh *pos; -+ struct au_vdir_destr *str; -+ -+ err = -ENOMEM; -+ p = (void *)__get_free_page(GFP_NOFS); -+ wh_name.name = p; -+ if (unlikely(!wh_name.name)) -+ goto out; -+ -+ err = 0; -+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN); -+ p += AUFS_WH_PFX_LEN; -+ n = whlist->nh_num; -+ head = whlist->nh_head; -+ for (ul = 0; !err && ul < n; ul++, head++) { -+ hlist_for_each_entry(pos, head, wh_hash) { -+ if (pos->wh_bindex != bindex) -+ continue; -+ -+ str = &pos->wh_str; -+ if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) { -+ memcpy(p, str->name, str->len); -+ wh_name.len = AUFS_WH_PFX_LEN + str->len; -+ err = unlink_wh_name(h_path, &wh_name); -+ if (!err) -+ continue; -+ break; -+ } -+ AuIOErr("whiteout name too long %.*s\n", -+ str->len, str->name); -+ err = -EIO; -+ break; -+ } -+ } -+ free_page((unsigned long)wh_name.name); -+ -+out: -+ return err; -+} -+ -+struct del_wh_children_args { -+ int *errp; -+ struct path *h_path; -+ struct au_nhash *whlist; -+ aufs_bindex_t bindex; -+}; -+ -+static void call_del_wh_children(void *args) -+{ -+ struct del_wh_children_args *a = args; -+ *a->errp = del_wh_children(a->h_path, a->whlist, a->bindex); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp) -+{ -+ struct au_whtmp_rmdir *whtmp; -+ int err; -+ unsigned int rdhash; -+ -+ SiMustAnyLock(sb); -+ -+ whtmp = kzalloc(sizeof(*whtmp), gfp); -+ if (unlikely(!whtmp)) { -+ whtmp = ERR_PTR(-ENOMEM); -+ goto out; -+ } -+ -+ /* no estimation for dir size */ -+ rdhash = au_sbi(sb)->si_rdhash; -+ if (!rdhash) -+ rdhash = AUFS_RDHASH_DEF; -+ err = au_nhash_alloc(&whtmp->whlist, rdhash, gfp); -+ if (unlikely(err)) { -+ au_kfree_rcu(whtmp); -+ whtmp = ERR_PTR(err); -+ } -+ -+out: -+ return whtmp; -+} -+ -+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp) -+{ -+ if (whtmp->br) -+ au_lcnt_dec(&whtmp->br->br_count); -+ dput(whtmp->wh_dentry); -+ iput(whtmp->dir); -+ au_nhash_wh_free(&whtmp->whlist); -+ au_kfree_rcu(whtmp); -+} -+ -+/* -+ * rmdir the whiteouted temporary named dir @h_dentry. -+ * @whlist: whiteouted children. -+ */ -+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex, -+ struct dentry *wh_dentry, struct au_nhash *whlist) -+{ -+ int err; -+ unsigned int h_nlink; -+ struct path wh_path; -+ struct inode *wh_inode, *h_dir; -+ struct au_branch *br; -+ struct mnt_idmap *h_idmap; -+ -+ h_dir = d_inode(wh_dentry->d_parent); /* dir inode is locked */ -+ IMustLock(h_dir); -+ -+ br = au_sbr(dir->i_sb, bindex); -+ wh_path.dentry = wh_dentry; -+ wh_path.mnt = au_br_mnt(br); -+ h_idmap = au_br_idmap(br); -+ wh_inode = d_inode(wh_dentry); -+ inode_lock_nested(wh_inode, AuLsc_I_CHILD); -+ -+ /* -+ * someone else might change some whiteouts while we were sleeping. -+ * it means this whlist may have an obsoleted entry. -+ */ -+ if (!au_test_h_perm_sio(h_idmap, wh_inode, MAY_EXEC | MAY_WRITE)) -+ err = del_wh_children(&wh_path, whlist, bindex); -+ else { -+ int wkq_err; -+ struct del_wh_children_args args = { -+ .errp = &err, -+ .h_path = &wh_path, -+ .whlist = whlist, -+ .bindex = bindex -+ }; -+ -+ wkq_err = au_wkq_wait(call_del_wh_children, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } -+ inode_unlock(wh_inode); -+ -+ if (!err) { -+ h_nlink = vfsub_inode_nlink(h_dir, AU_I_BRANCH); -+ err = vfsub_rmdir(h_dir, &wh_path); -+ /* some fs doesn't change the parent nlink in some cases */ -+ h_nlink -= vfsub_inode_nlink(h_dir, AU_I_BRANCH); -+ } -+ -+ if (!err) { -+ if (au_ibtop(dir) == bindex) { -+ /* todo: dir->i_mutex is necessary */ -+ au_cpup_attr_timesizes(dir); -+ if (h_nlink) -+ vfsub_drop_nlink(dir); -+ } -+ return 0; /* success */ -+ } -+ -+ pr_warn("failed removing %pd(%d), ignored\n", wh_dentry, err); -+ return err; -+} -+ -+static void call_rmdir_whtmp(void *args) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ struct au_whtmp_rmdir *a = args; -+ struct super_block *sb; -+ struct dentry *h_parent; -+ struct inode *h_dir; -+ struct au_hinode *hdir; -+ -+ /* rmdir by nfsd may cause deadlock with this i_mutex */ -+ /* inode_lock(a->dir); */ -+ err = -EROFS; -+ sb = a->dir->i_sb; -+ si_read_lock(sb, !AuLock_FLUSH); -+ if (!au_br_writable(a->br->br_perm)) -+ goto out; -+ bindex = au_br_index(sb, a->br->br_id); -+ if (unlikely(bindex < 0)) -+ goto out; -+ -+ err = -EIO; -+ ii_write_lock_parent(a->dir); -+ h_parent = dget_parent(a->wh_dentry); -+ 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)) -+ goto out_mnt; -+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT); -+ err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent, -+ a->br); -+ if (!err) -+ err = au_whtmp_rmdir(a->dir, bindex, a->wh_dentry, &a->whlist); -+ au_hn_inode_unlock(hdir); -+ vfsub_mnt_drop_write(au_br_mnt(a->br)); -+ -+out_mnt: -+ dput(h_parent); -+ ii_write_unlock(a->dir); -+out: -+ /* inode_unlock(a->dir); */ -+ au_whtmp_rmdir_free(a); -+ si_read_unlock(sb); -+ au_nwt_done(&au_sbi(sb)->si_nowait); -+ if (unlikely(err)) -+ AuIOErr("err %d\n", err); -+} -+ -+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex, -+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args) -+{ -+ int wkq_err; -+ struct super_block *sb; -+ -+ IMustLock(dir); -+ -+ /* all post-process will be done in do_rmdir_whtmp(). */ -+ sb = dir->i_sb; -+ args->dir = au_igrab(dir); -+ args->br = au_sbr(sb, bindex); -+ au_lcnt_inc(&args->br->br_count); -+ args->wh_dentry = dget(wh_dentry); -+ wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, sb, /*flags*/0); -+ if (unlikely(wkq_err)) { -+ pr_warn("rmdir error %pd (%d), ignored\n", wh_dentry, wkq_err); -+ au_whtmp_rmdir_free(args); -+ } -+} -diff -Naur null/fs/aufs/whout.h linux-6.6.63/fs/aufs/whout.h ---- /dev/null -+++ linux-6.6.63/fs/aufs/whout.h 2024-12-18 15:12:59.300519526 +0300 -@@ -0,0 +1,87 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * whiteout for logical deletion and opaque directory -+ */ -+ -+#ifndef __AUFS_WHOUT_H__ -+#define __AUFS_WHOUT_H__ -+ -+#ifdef __KERNEL__ -+ -+#include "dir.h" -+ -+/* whout.c */ -+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name); -+int au_wh_test(struct mnt_idmap *h_idmap, struct path *h_ppath, -+ struct qstr *wh_name, int try_sio); -+int au_diropq_test(struct mnt_idmap *h_idmap, struct path *h_path); -+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); -+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path, -+ struct dentry *dentry); -+int au_wh_init(struct au_branch *br, struct super_block *sb); -+ -+/* diropq flags */ -+#define AuDiropq_CREATE 1 -+#define au_ftest_diropq(flags, name) ((flags) & AuDiropq_##name) -+#define au_fset_diropq(flags, name) \ -+ do { (flags) |= AuDiropq_##name; } while (0) -+#define au_fclr_diropq(flags, name) \ -+ do { (flags) &= ~AuDiropq_##name; } while (0) -+ -+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex, -+ unsigned int flags); -+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name, -+ struct au_branch *br); -+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex, -+ struct dentry *h_parent); -+ -+/* real rmdir for the whiteout-ed dir */ -+struct au_whtmp_rmdir { -+ struct inode *dir; -+ struct au_branch *br; -+ struct dentry *wh_dentry; -+ struct au_nhash whlist; -+}; -+ -+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp); -+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp); -+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex, -+ struct dentry *wh_dentry, struct au_nhash *whlist); -+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex, -+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args); -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline struct dentry *au_diropq_create(struct dentry *dentry, -+ aufs_bindex_t bindex) -+{ -+ return au_diropq_sio(dentry, bindex, AuDiropq_CREATE); -+} -+ -+static inline int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex) -+{ -+ return PTR_ERR(au_diropq_sio(dentry, bindex, !AuDiropq_CREATE)); -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_WHOUT_H__ */ -diff -Naur null/fs/aufs/wkq.c linux-6.6.63/fs/aufs/wkq.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/wkq.c 2024-12-18 15:12:59.300519526 +0300 -@@ -0,0 +1,370 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * workqueue for asynchronous/super-io operations -+ * todo: try new credential scheme -+ */ -+ -+#include -+#include "aufs.h" -+ -+/* internal workqueue named AUFS_WKQ_NAME */ -+ -+static struct workqueue_struct *au_wkq; -+ -+struct au_wkinfo { -+ struct work_struct wk; -+ struct kobject *kobj; -+ -+ unsigned int flags; /* see wkq.h */ -+ -+ au_wkq_func_t func; -+ void *args; -+ -+#ifdef CONFIG_LOCKDEP -+ int dont_check; -+ struct held_lock **hlock; -+#endif -+ -+ struct completion *comp; -+}; -+ -+/* ---------------------------------------------------------------------- */ -+/* -+ * Aufs passes some operations to the workqueue such as the internal copyup. -+ * This scheme looks rather unnatural for LOCKDEP debugging feature, since the -+ * job run by workqueue depends upon the locks acquired in the other task. -+ * Delegating a small operation to the workqueue, aufs passes its lockdep -+ * information too. And the job in the workqueue restores the info in order to -+ * pretend as if it acquired those locks. This is just to make LOCKDEP work -+ * correctly and expectedly. -+ */ -+ -+#ifndef CONFIG_LOCKDEP -+AuStubInt0(au_wkq_lockdep_alloc, struct au_wkinfo *wkinfo); -+AuStubVoid(au_wkq_lockdep_free, struct au_wkinfo *wkinfo); -+AuStubVoid(au_wkq_lockdep_pre, struct au_wkinfo *wkinfo); -+AuStubVoid(au_wkq_lockdep_post, struct au_wkinfo *wkinfo); -+AuStubVoid(au_wkq_lockdep_init, struct au_wkinfo *wkinfo); -+#else -+static void au_wkq_lockdep_init(struct au_wkinfo *wkinfo) -+{ -+ wkinfo->hlock = NULL; -+ wkinfo->dont_check = 0; -+} -+ -+/* -+ * 1: matched -+ * 0: unmatched -+ */ -+static int au_wkq_lockdep_test(struct lock_class_key *key, const char *name) -+{ -+ static DEFINE_SPINLOCK(spin); -+ static struct { -+ char *name; -+ struct lock_class_key *key; -+ } a[] = { -+ { .name = "&sbinfo->si_rwsem" }, -+ { .name = "&finfo->fi_rwsem" }, -+ { .name = "&dinfo->di_rwsem" }, -+ { .name = "&iinfo->ii_rwsem" } -+ }; -+ static int set; -+ int i; -+ -+ /* lockless read from 'set.' see below */ -+ if (set == ARRAY_SIZE(a)) { -+ for (i = 0; i < ARRAY_SIZE(a); i++) -+ if (a[i].key == key) -+ goto match; -+ goto unmatch; -+ } -+ -+ spin_lock(&spin); -+ if (set) -+ for (i = 0; i < ARRAY_SIZE(a); i++) -+ if (a[i].key == key) { -+ spin_unlock(&spin); -+ goto match; -+ } -+ for (i = 0; i < ARRAY_SIZE(a); i++) { -+ if (a[i].key) { -+ if (unlikely(a[i].key == key)) { /* rare but possible */ -+ spin_unlock(&spin); -+ goto match; -+ } else -+ continue; -+ } -+ if (strstr(a[i].name, name)) { -+ /* -+ * the order of these three lines is important for the -+ * lockless read above. -+ */ -+ a[i].key = key; -+ spin_unlock(&spin); -+ set++; -+ /* AuDbg("%d, %s\n", set, name); */ -+ goto match; -+ } -+ } -+ spin_unlock(&spin); -+ goto unmatch; -+ -+match: -+ return 1; -+unmatch: -+ return 0; -+} -+ -+static int au_wkq_lockdep_alloc(struct au_wkinfo *wkinfo) -+{ -+ int err, n; -+ struct task_struct *curr; -+ struct held_lock **hl, *held_locks, *p; -+ -+ err = 0; -+ curr = current; -+ wkinfo->dont_check = lockdep_recursing(curr); -+ if (wkinfo->dont_check) -+ goto out; -+ n = curr->lockdep_depth; -+ if (!n) -+ goto out; -+ -+ err = -ENOMEM; -+ wkinfo->hlock = kmalloc_array(n + 1, sizeof(*wkinfo->hlock), GFP_NOFS); -+ if (unlikely(!wkinfo->hlock)) -+ goto out; -+ -+ err = 0; -+#if 0 /* left for debugging */ -+ if (0 && au_debug_test()) -+ lockdep_print_held_locks(curr); -+#endif -+ held_locks = curr->held_locks; -+ hl = wkinfo->hlock; -+ while (n--) { -+ p = held_locks++; -+ if (au_wkq_lockdep_test(p->instance->key, p->instance->name)) -+ *hl++ = p; -+ } -+ *hl = NULL; -+ -+out: -+ return err; -+} -+ -+static void au_wkq_lockdep_free(struct au_wkinfo *wkinfo) -+{ -+ au_kfree_try_rcu(wkinfo->hlock); -+} -+ -+static void au_wkq_lockdep_pre(struct au_wkinfo *wkinfo) -+{ -+ struct held_lock *p, **hl = wkinfo->hlock; -+ int subclass; -+ -+ if (wkinfo->dont_check) -+ lockdep_off(); -+ if (!hl) -+ return; -+ while ((p = *hl++)) { /* assignment */ -+ subclass = lockdep_hlock_class(p)->subclass; -+ /* AuDbg("%s, %d\n", p->instance->name, subclass); */ -+ if (p->read) -+ rwsem_acquire_read(p->instance, subclass, 0, -+ /*p->acquire_ip*/_RET_IP_); -+ else -+ rwsem_acquire(p->instance, subclass, 0, -+ /*p->acquire_ip*/_RET_IP_); -+ } -+} -+ -+static void au_wkq_lockdep_post(struct au_wkinfo *wkinfo) -+{ -+ struct held_lock *p, **hl = wkinfo->hlock; -+ -+ if (wkinfo->dont_check) -+ lockdep_on(); -+ if (!hl) -+ return; -+ while ((p = *hl++)) /* assignment */ -+ rwsem_release(p->instance, /*p->acquire_ip*/_RET_IP_); -+} -+#endif -+ -+static void wkq_func(struct work_struct *wk) -+{ -+ struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk); -+ -+ AuDebugOn(!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)); -+ AuDebugOn(rlimit(RLIMIT_FSIZE) != RLIM_INFINITY); -+ -+ au_wkq_lockdep_pre(wkinfo); -+ wkinfo->func(wkinfo->args); -+ au_wkq_lockdep_post(wkinfo); -+ if (au_ftest_wkq(wkinfo->flags, WAIT)) -+ complete(wkinfo->comp); -+ else { -+ kobject_put(wkinfo->kobj); -+ module_put(THIS_MODULE); /* todo: ?? */ -+ au_kfree_rcu(wkinfo); -+ } -+} -+ -+/* -+ * Since struct completion is large, try allocating it dynamically. -+ */ -+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp) -+{ -+ *comp = kmalloc(sizeof(**comp), GFP_NOFS); -+ if (*comp) { -+ init_completion(*comp); -+ wkinfo->comp = *comp; -+ return 0; -+ } -+ return -ENOMEM; -+} -+ -+static void au_wkq_comp_free(struct completion *comp) -+{ -+ au_kfree_rcu(comp); -+} -+ -+static void au_wkq_run(struct au_wkinfo *wkinfo) -+{ -+ if (au_ftest_wkq(wkinfo->flags, NEST)) { -+ if (au_wkq_test()) { -+ AuWarn1("wkq from wkq, unless silly-rename on NFS," -+ " due to a dead dir by UDBA," -+ " or async xino write?\n"); -+ AuDebugOn(au_ftest_wkq(wkinfo->flags, WAIT)); -+ } -+ } else -+ au_dbg_verify_kthread(); -+ -+ if (au_ftest_wkq(wkinfo->flags, WAIT)) { -+ INIT_WORK_ONSTACK(&wkinfo->wk, wkq_func); -+ queue_work(au_wkq, &wkinfo->wk); -+ } else { -+ INIT_WORK(&wkinfo->wk, wkq_func); -+ schedule_work(&wkinfo->wk); -+ } -+} -+ -+/* -+ * Be careful. It is easy to make deadlock happen. -+ * processA: lock, wkq and wait -+ * processB: wkq and wait, lock in wkq -+ * --> deadlock -+ */ -+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args) -+{ -+ int err; -+ struct completion *comp = NULL; -+ struct au_wkinfo wkinfo = { -+ .flags = flags, -+ .func = func, -+ .args = args -+ }; -+ -+ err = au_wkq_comp_alloc(&wkinfo, &comp); -+ if (unlikely(err)) -+ goto out; -+ err = au_wkq_lockdep_alloc(&wkinfo); -+ if (unlikely(err)) -+ goto out_comp; -+ if (!err) { -+ au_wkq_run(&wkinfo); -+ /* no timeout, no interrupt */ -+ wait_for_completion(wkinfo.comp); -+ } -+ au_wkq_lockdep_free(&wkinfo); -+ -+out_comp: -+ au_wkq_comp_free(comp); -+out: -+ destroy_work_on_stack(&wkinfo.wk); -+ return err; -+} -+ -+/* -+ * Note: dget/dput() in func for aufs dentries are not supported. It will be a -+ * problem in a concurrent umounting. -+ */ -+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb, -+ unsigned int flags) -+{ -+ int err; -+ struct au_wkinfo *wkinfo; -+ -+ atomic_inc(&au_sbi(sb)->si_nowait.nw_len); -+ -+ /* -+ * wkq_func() must free this wkinfo. -+ * it highly depends upon the implementation of workqueue. -+ */ -+ err = 0; -+ wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS); -+ if (wkinfo) { -+ wkinfo->kobj = &au_sbi(sb)->si_kobj; -+ wkinfo->flags = flags & ~AuWkq_WAIT; -+ wkinfo->func = func; -+ wkinfo->args = args; -+ wkinfo->comp = NULL; -+ au_wkq_lockdep_init(wkinfo); -+ kobject_get(wkinfo->kobj); -+ __module_get(THIS_MODULE); /* todo: ?? */ -+ -+ au_wkq_run(wkinfo); -+ } else { -+ err = -ENOMEM; -+ au_nwt_done(&au_sbi(sb)->si_nowait); -+ } -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void au_nwt_init(struct au_nowait_tasks *nwt) -+{ -+ atomic_set(&nwt->nw_len, 0); -+ /* smp_mb(); */ /* atomic_set */ -+ init_waitqueue_head(&nwt->nw_wq); -+} -+ -+void au_wkq_fin(void) -+{ -+ destroy_workqueue(au_wkq); -+} -+ -+int __init au_wkq_init(void) -+{ -+ int err; -+ -+ err = 0; -+ au_wkq = alloc_workqueue(AUFS_WKQ_NAME, 0, WQ_DFL_ACTIVE); -+ if (IS_ERR(au_wkq)) -+ err = PTR_ERR(au_wkq); -+ else if (!au_wkq) -+ err = -ENOMEM; -+ -+ return err; -+} -diff -Naur null/fs/aufs/wkq.h linux-6.6.63/fs/aufs/wkq.h ---- /dev/null -+++ linux-6.6.63/fs/aufs/wkq.h 2024-12-18 15:12:59.300519526 +0300 -@@ -0,0 +1,89 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * workqueue for asynchronous/super-io operations -+ * todo: try new credentials management scheme -+ */ -+ -+#ifndef __AUFS_WKQ_H__ -+#define __AUFS_WKQ_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+ -+struct super_block; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * in the next operation, wait for the 'nowait' tasks in system-wide workqueue -+ */ -+struct au_nowait_tasks { -+ atomic_t nw_len; -+ wait_queue_head_t nw_wq; -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+typedef void (*au_wkq_func_t)(void *args); -+ -+/* wkq flags */ -+#define AuWkq_WAIT 1 -+#define AuWkq_NEST (1 << 1) -+#define au_ftest_wkq(flags, name) ((flags) & AuWkq_##name) -+#define au_fset_wkq(flags, name) \ -+ do { (flags) |= AuWkq_##name; } while (0) -+#define au_fclr_wkq(flags, name) \ -+ do { (flags) &= ~AuWkq_##name; } while (0) -+ -+/* wkq.c */ -+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args); -+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb, -+ unsigned int flags); -+void au_nwt_init(struct au_nowait_tasks *nwt); -+int __init au_wkq_init(void); -+void au_wkq_fin(void); -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline int au_wkq_test(void) -+{ -+ return current->flags & PF_WQ_WORKER; -+} -+ -+static inline int au_wkq_wait(au_wkq_func_t func, void *args) -+{ -+ return au_wkq_do_wait(AuWkq_WAIT, func, args); -+} -+ -+static inline void au_nwt_done(struct au_nowait_tasks *nwt) -+{ -+ if (atomic_dec_and_test(&nwt->nw_len)) -+ wake_up_all(&nwt->nw_wq); -+} -+ -+static inline int au_nwt_flush(struct au_nowait_tasks *nwt) -+{ -+ wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len)); -+ return 0; -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_WKQ_H__ */ -diff -Naur null/fs/aufs/xattr.c linux-6.6.63/fs/aufs/xattr.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/xattr.c 2024-12-18 15:12:59.301519513 +0300 -@@ -0,0 +1,360 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2014-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * handling xattr functions -+ */ -+ -+#include -+#include -+#include "aufs.h" -+ -+static int au_xattr_ignore(int err, char *name, unsigned int ignore_flags) -+{ -+ if (!ignore_flags) -+ goto out; -+ switch (err) { -+ case -ENOMEM: -+ case -EDQUOT: -+ goto out; -+ } -+ -+ if ((ignore_flags & AuBrAttr_ICEX) == AuBrAttr_ICEX) { -+ err = 0; -+ goto out; -+ } -+ -+#define cmp(brattr, prefix) do { \ -+ if (!strncmp(name, XATTR_##prefix##_PREFIX, \ -+ XATTR_##prefix##_PREFIX_LEN)) { \ -+ if (ignore_flags & AuBrAttr_ICEX_##brattr) \ -+ err = 0; \ -+ goto out; \ -+ } \ -+ } while (0) -+ -+ cmp(SEC, SECURITY); -+ cmp(SYS, SYSTEM); -+ cmp(TR, TRUSTED); -+ cmp(USR, USER); -+#undef cmp -+ -+ if (ignore_flags & AuBrAttr_ICEX_OTH) -+ err = 0; -+ -+out: -+ return err; -+} -+ -+static const int au_xattr_out_of_list = AuBrAttr_ICEX_OTH << 1; -+ -+static int au_do_cpup_xattr(struct path *h_dst, struct path *h_src, -+ char *name, char **buf, unsigned int ignore_flags, -+ unsigned int verbose) -+{ -+ int err, is_acl; -+ ssize_t ssz; -+ struct inode *h_idst; -+ struct dentry *h_dst_dentry, *h_src_dentry; -+ struct mnt_idmap *h_dst_idmap, *h_src_idmap; -+ struct posix_acl *acl; -+ -+ is_acl = !!is_posix_acl_xattr(name); -+ h_src_idmap = mnt_idmap(h_src->mnt); -+ h_src_dentry = h_src->dentry; -+ if (is_acl) { -+ acl = vfs_get_acl(h_src_idmap, h_src_dentry, name); -+ AuDebugOn(!acl); -+ if (IS_ERR(acl)) { -+ err = PTR_ERR(acl); -+ if (err == -ENODATA) -+ err = 0; -+ else if (err == -EOPNOTSUPP -+ && au_test_nfs_noacl(d_inode(h_src_dentry))) -+ err = 0; -+ else if (verbose || au_debug_test()) -+ pr_err("%s, err %d\n", name, err); -+ goto out; -+ } -+ } else { -+ ssz = vfs_getxattr_alloc(h_src_idmap, h_src_dentry, name, buf, -+ 0, GFP_NOFS); -+ if (unlikely(ssz <= 0)) { -+ err = ssz; -+ if (err == -ENODATA) -+ err = 0; -+ else if (err == -EOPNOTSUPP -+ && (ignore_flags & au_xattr_out_of_list)) -+ err = 0; -+ else if (err && (verbose || au_debug_test())) -+ pr_err("%s, err %d\n", name, err); -+ goto out; -+ } -+ } -+ -+ /* unlock it temporary */ -+ h_dst_idmap = mnt_idmap(h_dst->mnt); -+ h_dst_dentry = h_dst->dentry; -+ h_idst = d_inode(h_dst_dentry); -+ inode_unlock(h_idst); -+ if (is_acl) { -+ err = vfsub_set_acl(h_dst_idmap, h_dst_dentry, name, acl); -+ posix_acl_release(acl); -+ } else -+ err = vfsub_setxattr(h_dst_idmap, h_dst_dentry, name, *buf, -+ ssz, /*flags*/0); -+ inode_lock_nested(h_idst, AuLsc_I_CHILD2); -+ if (unlikely(err)) { -+ if (verbose || au_debug_test()) -+ pr_err("%s, err %d\n", name, err); -+ err = au_xattr_ignore(err, name, ignore_flags); -+ } -+ -+out: -+ return err; -+} -+ -+int au_cpup_xattr(struct path *h_dst, struct path *h_src, int ignore_flags, -+ unsigned int verbose) -+{ -+ int err, unlocked; -+ ssize_t ssz; -+ struct dentry *h_dst_dentry, *h_src_dentry; -+ struct inode *h_isrc, *h_idst; -+ char *value, *p, *o, *e; -+ -+ /* try stopping to update the source inode while we are referencing */ -+ /* there should not be the parent-child relationship between them */ -+ h_dst_dentry = h_dst->dentry; -+ h_idst = d_inode(h_dst_dentry); -+ h_src_dentry = h_src->dentry; -+ h_isrc = d_inode(h_src_dentry); -+ inode_unlock(h_idst); -+ inode_lock_shared_nested(h_isrc, AuLsc_I_CHILD); -+ inode_lock_nested(h_idst, AuLsc_I_CHILD2); -+ unlocked = 0; -+ -+ /* some filesystems don't list POSIX ACL, for example tmpfs */ -+ ssz = vfs_listxattr(h_src_dentry, NULL, 0); -+ err = ssz; -+ if (unlikely(err < 0)) { -+ AuTraceErr(err); -+ if (err == -ENODATA -+ || err == -EOPNOTSUPP) -+ err = 0; /* ignore */ -+ goto out; -+ } -+ -+ err = 0; -+ p = NULL; -+ o = NULL; -+ if (ssz) { -+ err = -ENOMEM; -+ p = kmalloc(ssz, GFP_NOFS); -+ o = p; -+ if (unlikely(!p)) -+ goto out; -+ err = vfs_listxattr(h_src_dentry, p, ssz); -+ } -+ inode_unlock_shared(h_isrc); -+ unlocked = 1; -+ AuDbg("err %d, ssz %zd\n", err, ssz); -+ if (unlikely(err < 0)) -+ goto out_free; -+ -+ err = 0; -+ e = p + ssz; -+ value = NULL; -+ ignore_flags |= au_xattr_out_of_list; -+ while (!err && p < e) { -+ err = au_do_cpup_xattr(h_dst, h_src, p, &value, ignore_flags, -+ verbose); -+ p += strlen(p) + 1; -+ } -+ au_kfree_try_rcu(value); -+ -+out_free: -+ au_kfree_try_rcu(o); -+out: -+ if (!unlocked) -+ inode_unlock_shared(h_isrc); -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_smack_reentering(struct super_block *sb) -+{ -+#if IS_ENABLED(CONFIG_SECURITY_SMACK) || IS_ENABLED(CONFIG_SECURITY_SELINUX) -+ /* -+ * as a part of lookup, smack_d_instantiate() is called, and it calls -+ * i_op->getxattr(). ouch. -+ */ -+ return si_pid_test(sb); -+#else -+ return 0; -+#endif -+} -+ -+enum { -+ AU_XATTR_LIST, -+ AU_XATTR_GET -+}; -+ -+struct au_lgxattr { -+ int type; -+ union { -+ struct { -+ char *list; -+ size_t size; -+ } list; -+ struct { -+ const char *name; -+ void *value; -+ size_t size; -+ } get; -+ } u; -+}; -+ -+static ssize_t au_lgxattr(struct dentry *dentry, struct inode *inode, -+ struct au_lgxattr *arg) -+{ -+ ssize_t err; -+ int reenter; -+ struct path h_path; -+ struct super_block *sb; -+ -+ sb = dentry->d_sb; -+ reenter = au_smack_reentering(sb); -+ if (!reenter) { -+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (unlikely(err)) -+ goto out; -+ } -+ err = au_h_path_getattr(dentry, inode, /*force*/1, &h_path, reenter); -+ if (unlikely(err)) -+ goto out_si; -+ if (unlikely(!h_path.dentry)) -+ /* illegally overlapped or something */ -+ goto out_di; /* pretending success */ -+ -+ /* always topmost entry only */ -+ switch (arg->type) { -+ case AU_XATTR_LIST: -+ err = vfs_listxattr(h_path.dentry, -+ arg->u.list.list, arg->u.list.size); -+ break; -+ case AU_XATTR_GET: -+ AuDebugOn(d_is_negative(h_path.dentry)); -+ err = vfs_getxattr(mnt_idmap(h_path.mnt), h_path.dentry, -+ arg->u.get.name, arg->u.get.value, -+ arg->u.get.size); -+ break; -+ } -+ -+out_di: -+ if (!reenter) -+ di_read_unlock(dentry, AuLock_IR); -+out_si: -+ if (!reenter) -+ si_read_unlock(sb); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size) -+{ -+ struct au_lgxattr arg = { -+ .type = AU_XATTR_LIST, -+ .u.list = { -+ .list = list, -+ .size = size -+ }, -+ }; -+ -+ return au_lgxattr(dentry, /*inode*/NULL, &arg); -+} -+ -+static ssize_t au_getxattr(struct dentry *dentry, struct inode *inode, -+ const char *name, void *value, size_t size) -+{ -+ struct au_lgxattr arg = { -+ .type = AU_XATTR_GET, -+ .u.get = { -+ .name = name, -+ .value = value, -+ .size = size -+ }, -+ }; -+ -+ return au_lgxattr(dentry, inode, &arg); -+} -+ -+static int au_setxattr(struct dentry *dentry, struct inode *inode, -+ const char *name, const void *value, size_t size, -+ int flags) -+{ -+ struct au_sxattr arg = { -+ .type = AU_XATTR_SET, -+ .u.set = { -+ .name = name, -+ .value = value, -+ .size = size, -+ .flags = flags -+ }, -+ }; -+ -+ return au_sxattr(dentry, inode, &arg); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_xattr_get(const struct xattr_handler *handler, -+ struct dentry *dentry, struct inode *inode, -+ const char *name, void *buffer, size_t size) -+{ -+ return au_getxattr(dentry, inode, name, buffer, size); -+} -+ -+static int au_xattr_set(const struct xattr_handler *handler, -+ struct mnt_idmap *idmap, -+ struct dentry *dentry, struct inode *inode, -+ const char *name, const void *value, size_t size, -+ int flags) -+{ -+ return au_setxattr(dentry, inode, name, value, size, flags); -+} -+ -+static const struct xattr_handler au_xattr_handler = { -+ .name = "", -+ .prefix = "", -+ .get = au_xattr_get, -+ .set = au_xattr_set -+}; -+ -+static const struct xattr_handler *au_xattr_handlers[] = { -+ &au_xattr_handler, /* must be last */ -+ NULL -+}; -+ -+void au_xattr_init(struct super_block *sb) -+{ -+ sb->s_xattr = au_xattr_handlers; -+} -diff -Naur null/fs/aufs/xino.c linux-6.6.63/fs/aufs/xino.c ---- /dev/null -+++ linux-6.6.63/fs/aufs/xino.c 2024-12-18 15:12:59.301519513 +0300 -@@ -0,0 +1,1926 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * external inode number translation table and bitmap -+ * -+ * things to consider -+ * - the lifetime -+ * + au_xino object -+ * + XINO files (xino, xib, xigen) -+ * + dynamic debugfs entries (xiN) -+ * + static debugfs entries (xib, xigen) -+ * + static sysfs entry (xi_path) -+ * - several entry points to handle them. -+ * + mount(2) without xino option (default) -+ * + mount(2) with xino option -+ * + mount(2) with noxino option -+ * + umount(2) -+ * + remount with add/del branches -+ * + remount with xino/noxino options -+ */ -+ -+#include -+#include -+#include "aufs.h" -+ -+static aufs_bindex_t sbr_find_shared(struct super_block *sb, aufs_bindex_t btop, -+ aufs_bindex_t bbot, -+ struct super_block *h_sb) -+{ -+ /* todo: try binary-search if the branches are many */ -+ for (; btop <= bbot; btop++) -+ if (h_sb == au_sbr_sb(sb, btop)) -+ return btop; -+ return -1; -+} -+ -+/* -+ * find another branch who is on the same filesystem of the specified -+ * branch{@btgt}. search until @bbot. -+ */ -+static aufs_bindex_t is_sb_shared(struct super_block *sb, aufs_bindex_t btgt, -+ aufs_bindex_t bbot) -+{ -+ aufs_bindex_t bindex; -+ struct super_block *tgt_sb; -+ -+ tgt_sb = au_sbr_sb(sb, btgt); -+ bindex = sbr_find_shared(sb, /*btop*/0, btgt - 1, tgt_sb); -+ if (bindex < 0) -+ bindex = sbr_find_shared(sb, btgt + 1, bbot, tgt_sb); -+ -+ return bindex; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * stop unnecessary notify events at creating xino files -+ */ -+ -+aufs_bindex_t au_xi_root(struct super_block *sb, struct dentry *dentry) -+{ -+ aufs_bindex_t bfound, bindex, bbot; -+ struct dentry *parent; -+ struct au_branch *br; -+ -+ bfound = -1; -+ parent = dentry->d_parent; /* safe d_parent access */ -+ bbot = au_sbbot(sb); -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (au_br_dentry(br) == parent) { -+ bfound = bindex; -+ break; -+ } -+ } -+ -+ AuDbg("bfound b%d\n", bfound); -+ return bfound; -+} -+ -+struct au_xino_lock_dir { -+ struct au_hinode *hdir; -+ struct dentry *parent; -+ struct inode *dir; -+}; -+ -+static struct dentry *au_dget_parent_lock(struct dentry *dentry, -+ unsigned int lsc) -+{ -+ struct dentry *parent; -+ struct inode *dir; -+ -+ parent = dget_parent(dentry); -+ dir = d_inode(parent); -+ inode_lock_nested(dir, lsc); -+#if 0 /* it should not happen */ -+ spin_lock(&dentry->d_lock); -+ if (unlikely(dentry->d_parent != parent)) { -+ spin_unlock(&dentry->d_lock); -+ inode_unlock(dir); -+ dput(parent); -+ parent = NULL; -+ goto out; -+ } -+ spin_unlock(&dentry->d_lock); -+ -+out: -+#endif -+ return parent; -+} -+ -+static void au_xino_lock_dir(struct super_block *sb, struct path *xipath, -+ struct au_xino_lock_dir *ldir) -+{ -+ aufs_bindex_t bindex; -+ -+ ldir->hdir = NULL; -+ bindex = au_xi_root(sb, xipath->dentry); -+ if (bindex >= 0) { -+ /* rw branch root */ -+ ldir->hdir = au_hi(d_inode(sb->s_root), bindex); -+ au_hn_inode_lock_nested(ldir->hdir, AuLsc_I_PARENT); -+ } else { -+ /* other */ -+ ldir->parent = au_dget_parent_lock(xipath->dentry, -+ AuLsc_I_PARENT); -+ ldir->dir = d_inode(ldir->parent); -+ } -+} -+ -+static void au_xino_unlock_dir(struct au_xino_lock_dir *ldir) -+{ -+ if (ldir->hdir) -+ au_hn_inode_unlock(ldir->hdir); -+ else { -+ inode_unlock(ldir->dir); -+ dput(ldir->parent); -+ } -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * create and set a new xino file -+ */ -+struct file *au_xino_create(struct super_block *sb, char *fpath, int silent, -+ int wbrtop) -+{ -+ struct file *file; -+ struct dentry *h_parent, *d; -+ struct inode *h_dir, *inode; -+ int err; -+ static DEFINE_MUTEX(mtx); -+ -+ /* -+ * at mount-time, and the xino file is the default path, -+ * hnotify is disabled so we have no notify events to ignore. -+ * when a user specified the xino, we cannot get au_hdir to be ignored. -+ */ -+ if (!wbrtop) -+ mutex_lock(&mtx); -+ file = vfsub_filp_open(fpath, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE -+ /* | __FMODE_NONOTIFY */, -+ 0666); -+ if (IS_ERR(file)) { -+ if (!wbrtop) -+ mutex_unlock(&mtx); -+ if (!silent) -+ pr_err("open %s(%ld)\n", fpath, PTR_ERR(file)); -+ return file; -+ } -+ -+ /* keep file count */ -+ err = 0; -+ d = file->f_path.dentry; -+ h_parent = au_dget_parent_lock(d, AuLsc_I_PARENT); -+ if (!wbrtop) -+ mutex_unlock(&mtx); -+ /* mnt_want_write() is unnecessary here */ -+ h_dir = d_inode(h_parent); -+ inode = file_inode(file); -+ /* no delegation since it is just created */ -+ if (vfsub_inode_nlink(inode, AU_I_BRANCH)) -+ err = vfsub_unlink(h_dir, &file->f_path, /*delegated*/NULL, -+ /*force*/0); -+ inode_unlock(h_dir); -+ dput(h_parent); -+ if (unlikely(err)) { -+ if (!silent) -+ pr_err("unlink %s(%d)\n", fpath, err); -+ goto out; -+ } -+ -+ err = -EINVAL; -+ if (unlikely(sb && sb == d->d_sb)) { -+ if (!silent) -+ pr_err("%s must be outside\n", fpath); -+ goto out; -+ } -+ if (unlikely(au_test_fs_bad_xino(d->d_sb))) { -+ if (!silent) -+ pr_err("xino doesn't support %s(%s)\n", -+ fpath, au_sbtype(d->d_sb)); -+ goto out; -+ } -+ return file; /* success */ -+ -+out: -+ fput(file); -+ file = ERR_PTR(err); -+ return file; -+} -+ -+/* -+ * create a new xinofile at the same place/path as @base. -+ */ -+struct file *au_xino_create2(struct super_block *sb, struct path *base, -+ struct file *copy_src) -+{ -+ struct file *file; -+ struct dentry *dentry; -+ struct inode *dir, *delegated; -+ struct qstr *name; -+ struct path ppath, path; -+ int err, do_unlock; -+ struct au_xino_lock_dir ldir; -+ -+ do_unlock = 1; -+ au_xino_lock_dir(sb, base, &ldir); -+ dentry = base->dentry; -+ ppath.dentry = dentry->d_parent; /* dir inode is locked */ -+ ppath.mnt = base->mnt; -+ dir = d_inode(ppath.dentry); -+ IMustLock(dir); -+ -+ name = &dentry->d_name; -+ path.dentry = vfsub_lookup_one_len(name->name, &ppath, name->len); -+ if (IS_ERR(path.dentry)) { -+ file = (void *)path.dentry; -+ pr_err("%pd lookup err %ld\n", dentry, PTR_ERR(path.dentry)); -+ goto out; -+ } -+ -+ /* no need to mnt_want_write() since we call dentry_open() later */ -+ err = vfs_create(mnt_idmap(base->mnt), dir, path.dentry, 0666, NULL); -+ if (unlikely(err)) { -+ file = ERR_PTR(err); -+ pr_err("%pd create err %d\n", dentry, err); -+ goto out_dput; -+ } -+ -+ path.mnt = base->mnt; -+ file = vfsub_dentry_open(&path, -+ O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE -+ /* | __FMODE_NONOTIFY */); -+ if (IS_ERR(file)) { -+ pr_err("%pd open err %ld\n", dentry, PTR_ERR(file)); -+ goto out_dput; -+ } -+ -+ delegated = NULL; -+ err = vfsub_unlink(dir, &file->f_path, &delegated, /*force*/0); -+ au_xino_unlock_dir(&ldir); -+ do_unlock = 0; -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal unlink\n"); -+ iput(delegated); -+ } -+ if (unlikely(err)) { -+ pr_err("%pd unlink err %d\n", dentry, err); -+ goto out_fput; -+ } -+ -+ if (copy_src) { -+ /* no one can touch copy_src xino */ -+ err = au_copy_file(file, copy_src, vfsub_f_size_read(copy_src)); -+ if (unlikely(err)) { -+ pr_err("%pd copy err %d\n", dentry, err); -+ goto out_fput; -+ } -+ } -+ goto out_dput; /* success */ -+ -+out_fput: -+ fput(file); -+ file = ERR_PTR(err); -+out_dput: -+ dput(path.dentry); -+out: -+ if (do_unlock) -+ au_xino_unlock_dir(&ldir); -+ return file; -+} -+ -+struct file *au_xino_file1(struct au_xino *xi) -+{ -+ struct file *file; -+ unsigned int u, nfile; -+ -+ file = NULL; -+ nfile = xi->xi_nfile; -+ for (u = 0; u < nfile; u++) { -+ file = xi->xi_file[u]; -+ if (file) -+ break; -+ } -+ -+ return file; -+} -+ -+static int au_xino_file_set(struct au_xino *xi, int idx, struct file *file) -+{ -+ int err; -+ struct file *f; -+ void *p; -+ -+ if (file) -+ get_file(file); -+ -+ err = 0; -+ f = NULL; -+ if (idx < xi->xi_nfile) { -+ f = xi->xi_file[idx]; -+ if (f) -+ fput(f); -+ } else { -+ p = au_kzrealloc(xi->xi_file, -+ sizeof(*xi->xi_file) * xi->xi_nfile, -+ sizeof(*xi->xi_file) * (idx + 1), -+ GFP_NOFS, /*may_shrink*/0); -+ if (p) { -+ MtxMustLock(&xi->xi_mtx); -+ xi->xi_file = p; -+ xi->xi_nfile = idx + 1; -+ } else { -+ err = -ENOMEM; -+ if (file) -+ fput(file); -+ goto out; -+ } -+ } -+ xi->xi_file[idx] = file; -+ -+out: -+ return err; -+} -+ -+/* -+ * if @xinew->xi is not set, then create new xigen file. -+ */ -+struct file *au_xi_new(struct super_block *sb, struct au_xi_new *xinew) -+{ -+ struct file *file; -+ int err; -+ -+ SiMustAnyLock(sb); -+ -+ file = au_xino_create2(sb, xinew->base, xinew->copy_src); -+ if (IS_ERR(file)) { -+ err = PTR_ERR(file); -+ pr_err("%s[%d], err %d\n", -+ xinew->xi ? "xino" : "xigen", -+ xinew->idx, err); -+ goto out; -+ } -+ -+ if (xinew->xi) -+ err = au_xino_file_set(xinew->xi, xinew->idx, file); -+ else { -+ BUG(); -+ /* todo: make xigen file an array */ -+ /* err = au_xigen_file_set(sb, xinew->idx, file); */ -+ } -+ fput(file); -+ if (unlikely(err)) -+ file = ERR_PTR(err); -+ -+out: -+ return file; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * truncate xino files -+ */ -+static int au_xino_do_trunc(struct super_block *sb, aufs_bindex_t bindex, -+ int idx, struct kstatfs *st) -+{ -+ int err; -+ blkcnt_t blocks; -+ struct file *file, *new_xino; -+ struct au_xi_new xinew = { -+ .idx = idx -+ }; -+ -+ err = 0; -+ xinew.xi = au_sbr(sb, bindex)->br_xino; -+ file = au_xino_file(xinew.xi, idx); -+ if (!file) -+ goto out; -+ -+ xinew.base = &file->f_path; -+ err = vfs_statfs(xinew.base, st); -+ if (unlikely(err)) { -+ AuErr1("statfs err %d, ignored\n", err); -+ err = 0; -+ goto out; -+ } -+ -+ blocks = file_inode(file)->i_blocks; -+ pr_info("begin truncating xino(b%d-%d), ib%llu, %llu/%llu free blks\n", -+ bindex, idx, (u64)blocks, st->f_bfree, st->f_blocks); -+ -+ xinew.copy_src = file; -+ new_xino = au_xi_new(sb, &xinew); -+ if (IS_ERR(new_xino)) { -+ err = PTR_ERR(new_xino); -+ pr_err("xino(b%d-%d), err %d, ignored\n", bindex, idx, err); -+ goto out; -+ } -+ -+ err = vfs_statfs(&new_xino->f_path, st); -+ if (!err) -+ pr_info("end truncating xino(b%d-%d), ib%llu, %llu/%llu free blks\n", -+ bindex, idx, (u64)file_inode(new_xino)->i_blocks, -+ st->f_bfree, st->f_blocks); -+ else { -+ AuErr1("statfs err %d, ignored\n", err); -+ err = 0; -+ } -+ -+out: -+ return err; -+} -+ -+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex, int idx_begin) -+{ -+ int err, i; -+ unsigned long jiffy; -+ aufs_bindex_t bbot; -+ struct kstatfs *st; -+ struct au_branch *br; -+ struct au_xino *xi; -+ -+ err = -ENOMEM; -+ st = kmalloc(sizeof(*st), GFP_NOFS); -+ if (unlikely(!st)) -+ goto out; -+ -+ err = -EINVAL; -+ bbot = au_sbbot(sb); -+ if (unlikely(bindex < 0 || bbot < bindex)) -+ goto out_st; -+ -+ err = 0; -+ jiffy = jiffies; -+ br = au_sbr(sb, bindex); -+ xi = br->br_xino; -+ for (i = idx_begin; !err && i < xi->xi_nfile; i++) -+ err = au_xino_do_trunc(sb, bindex, i, st); -+ if (!err) -+ au_sbi(sb)->si_xino_jiffy = jiffy; -+ -+out_st: -+ au_kfree_rcu(st); -+out: -+ return err; -+} -+ -+struct xino_do_trunc_args { -+ struct super_block *sb; -+ struct au_branch *br; -+ int idx; -+}; -+ -+static void xino_do_trunc(void *_args) -+{ -+ struct xino_do_trunc_args *args = _args; -+ struct super_block *sb; -+ struct au_branch *br; -+ struct inode *dir; -+ int err, idx; -+ aufs_bindex_t bindex; -+ -+ err = 0; -+ sb = args->sb; -+ dir = d_inode(sb->s_root); -+ br = args->br; -+ idx = args->idx; -+ -+ si_noflush_write_lock(sb); -+ ii_read_lock_parent(dir); -+ bindex = au_br_index(sb, br->br_id); -+ err = au_xino_trunc(sb, bindex, idx); -+ ii_read_unlock(dir); -+ if (unlikely(err)) -+ pr_warn("err b%d, (%d)\n", bindex, err); -+ atomic_dec(&br->br_xino->xi_truncating); -+ au_lcnt_dec(&br->br_count); -+ si_write_unlock(sb); -+ au_nwt_done(&au_sbi(sb)->si_nowait); -+ au_kfree_rcu(args); -+} -+ -+/* -+ * returns the index in the xi_file array whose corresponding file is necessary -+ * to truncate, or -1 which means no need to truncate. -+ */ -+static int xino_trunc_test(struct super_block *sb, struct au_branch *br) -+{ -+ int err; -+ unsigned int u; -+ struct kstatfs st; -+ struct au_sbinfo *sbinfo; -+ struct au_xino *xi; -+ struct file *file; -+ -+ /* todo: si_xino_expire and the ratio should be customizable */ -+ sbinfo = au_sbi(sb); -+ if (time_before(jiffies, -+ sbinfo->si_xino_jiffy + sbinfo->si_xino_expire)) -+ return -1; -+ -+ /* truncation border */ -+ xi = br->br_xino; -+ for (u = 0; u < xi->xi_nfile; u++) { -+ file = au_xino_file(xi, u); -+ if (!file) -+ continue; -+ -+ err = vfs_statfs(&file->f_path, &st); -+ if (unlikely(err)) { -+ AuErr1("statfs err %d, ignored\n", err); -+ return -1; -+ } -+ if (div64_u64(st.f_bfree * 100, st.f_blocks) -+ >= AUFS_XINO_DEF_TRUNC) -+ return u; -+ } -+ -+ return -1; -+} -+ -+static void xino_try_trunc(struct super_block *sb, struct au_branch *br) -+{ -+ int idx; -+ struct xino_do_trunc_args *args; -+ int wkq_err; -+ -+ idx = xino_trunc_test(sb, br); -+ if (idx < 0) -+ return; -+ -+ if (atomic_inc_return(&br->br_xino->xi_truncating) > 1) -+ goto out; -+ -+ /* lock and kfree() will be called in trunc_xino() */ -+ args = kmalloc(sizeof(*args), GFP_NOFS); -+ if (unlikely(!args)) { -+ AuErr1("no memory\n"); -+ goto out; -+ } -+ -+ au_lcnt_inc(&br->br_count); -+ args->sb = sb; -+ args->br = br; -+ args->idx = idx; -+ wkq_err = au_wkq_nowait(xino_do_trunc, args, sb, /*flags*/0); -+ if (!wkq_err) -+ return; /* success */ -+ -+ pr_err("wkq %d\n", wkq_err); -+ au_lcnt_dec(&br->br_count); -+ au_kfree_rcu(args); -+ -+out: -+ atomic_dec(&br->br_xino->xi_truncating); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_xi_calc { -+ int idx; -+ loff_t pos; -+}; -+ -+static void au_xi_calc(struct super_block *sb, ino_t h_ino, -+ struct au_xi_calc *calc) -+{ -+ loff_t maxent; -+ -+ maxent = au_xi_maxent(sb); -+ calc->idx = div64_u64_rem(h_ino, maxent, &calc->pos); -+ calc->pos *= sizeof(ino_t); -+} -+ -+static int au_xino_do_new_async(struct super_block *sb, struct au_branch *br, -+ struct au_xi_calc *calc) -+{ -+ int err; -+ struct file *file; -+ struct au_xino *xi = br->br_xino; -+ struct au_xi_new xinew = { -+ .xi = xi -+ }; -+ -+ SiMustAnyLock(sb); -+ -+ err = 0; -+ if (!xi) -+ goto out; -+ -+ mutex_lock(&xi->xi_mtx); -+ file = au_xino_file(xi, calc->idx); -+ if (file) -+ goto out_mtx; -+ -+ file = au_xino_file(xi, /*idx*/-1); -+ AuDebugOn(!file); -+ xinew.idx = calc->idx; -+ xinew.base = &file->f_path; -+ /* xinew.copy_src = NULL; */ -+ file = au_xi_new(sb, &xinew); -+ if (IS_ERR(file)) -+ err = PTR_ERR(file); -+ -+out_mtx: -+ mutex_unlock(&xi->xi_mtx); -+out: -+ return err; -+} -+ -+struct au_xino_do_new_async_args { -+ struct super_block *sb; -+ struct au_branch *br; -+ struct au_xi_calc calc; -+ ino_t ino; -+}; -+ -+struct au_xi_writing { -+ struct hlist_bl_node node; -+ ino_t h_ino, ino; -+}; -+ -+static int au_xino_do_write(struct file *file, struct au_xi_calc *calc, -+ ino_t ino); -+ -+static void au_xino_call_do_new_async(void *args) -+{ -+ struct au_xino_do_new_async_args *a = args; -+ struct au_branch *br; -+ struct super_block *sb; -+ struct au_sbinfo *sbi; -+ struct inode *root; -+ struct file *file; -+ struct au_xi_writing *del, *p; -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *pos; -+ int err; -+ -+ br = a->br; -+ sb = a->sb; -+ sbi = au_sbi(sb); -+ si_noflush_read_lock(sb); -+ root = d_inode(sb->s_root); -+ ii_read_lock_child(root); -+ err = au_xino_do_new_async(sb, br, &a->calc); -+ if (unlikely(err)) { -+ AuIOErr("err %d\n", err); -+ goto out; -+ } -+ -+ file = au_xino_file(br->br_xino, a->calc.idx); -+ AuDebugOn(!file); -+ err = au_xino_do_write(file, &a->calc, a->ino); -+ if (unlikely(err)) { -+ AuIOErr("err %d\n", err); -+ goto out; -+ } -+ -+ del = NULL; -+ hbl = &br->br_xino->xi_writing; -+ hlist_bl_lock(hbl); -+ au_hbl_for_each(pos, hbl) { -+ p = container_of(pos, struct au_xi_writing, node); -+ if (p->ino == a->ino) { -+ del = p; -+ hlist_bl_del(&p->node); -+ break; -+ } -+ } -+ hlist_bl_unlock(hbl); -+ au_kfree_rcu(del); -+ -+out: -+ au_lcnt_dec(&br->br_count); -+ ii_read_unlock(root); -+ si_read_unlock(sb); -+ au_nwt_done(&sbi->si_nowait); -+ au_kfree_rcu(a); -+} -+ -+/* -+ * create a new xino file asynchronously -+ */ -+static int au_xino_new_async(struct super_block *sb, struct au_branch *br, -+ struct au_xi_calc *calc, ino_t ino) -+{ -+ int err; -+ struct au_xino_do_new_async_args *arg; -+ -+ err = -ENOMEM; -+ arg = kmalloc(sizeof(*arg), GFP_NOFS); -+ if (unlikely(!arg)) -+ goto out; -+ -+ arg->sb = sb; -+ arg->br = br; -+ arg->calc = *calc; -+ arg->ino = ino; -+ au_lcnt_inc(&br->br_count); -+ err = au_wkq_nowait(au_xino_call_do_new_async, arg, sb, AuWkq_NEST); -+ if (unlikely(err)) { -+ pr_err("wkq %d\n", err); -+ au_lcnt_dec(&br->br_count); -+ au_kfree_rcu(arg); -+ } -+ -+out: -+ return err; -+} -+ -+/* -+ * read @ino from xinofile for the specified branch{@sb, @bindex} -+ * at the position of @h_ino. -+ */ -+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, -+ ino_t *ino) -+{ -+ int err; -+ ssize_t sz; -+ struct au_xi_calc calc; -+ struct au_sbinfo *sbinfo; -+ struct file *file; -+ struct au_xino *xi; -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *pos; -+ struct au_xi_writing *p; -+ -+ *ino = 0; -+ if (!au_opt_test(au_mntflags(sb), XINO)) -+ return 0; /* no xino */ -+ -+ err = 0; -+ au_xi_calc(sb, h_ino, &calc); -+ xi = au_sbr(sb, bindex)->br_xino; -+ file = au_xino_file(xi, calc.idx); -+ if (!file) { -+ hbl = &xi->xi_writing; -+ hlist_bl_lock(hbl); -+ au_hbl_for_each(pos, hbl) { -+ p = container_of(pos, struct au_xi_writing, node); -+ if (p->h_ino == h_ino) { -+ AuDbg("hi%llu, i%llu, found\n", -+ (u64)p->h_ino, (u64)p->ino); -+ *ino = p->ino; -+ break; -+ } -+ } -+ hlist_bl_unlock(hbl); -+ return 0; -+ } else if (vfsub_f_size_read(file) < calc.pos + sizeof(*ino)) -+ return 0; /* no xino */ -+ -+ sbinfo = au_sbi(sb); -+ sz = xino_fread(file, ino, sizeof(*ino), &calc.pos); -+ if (sz == sizeof(*ino)) -+ return 0; /* success */ -+ -+ err = sz; -+ if (unlikely(sz >= 0)) { -+ err = -EIO; -+ AuIOErr("xino read error (%zd)\n", sz); -+ } -+ return err; -+} -+ -+static int au_xino_do_write(struct file *file, struct au_xi_calc *calc, -+ ino_t ino) -+{ -+ ssize_t sz; -+ -+ sz = xino_fwrite(file, &ino, sizeof(ino), &calc->pos); -+ if (sz == sizeof(ino)) -+ return 0; /* success */ -+ -+ AuIOErr("write failed (%zd)\n", sz); -+ return -EIO; -+} -+ -+/* -+ * write @ino to the xinofile for the specified branch{@sb, @bindex} -+ * at the position of @h_ino. -+ * even if @ino is zero, it is written to the xinofile and means no entry. -+ * if the size of the xino file on a specific filesystem exceeds the watermark, -+ * try truncating it. -+ */ -+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, -+ ino_t ino) -+{ -+ int err; -+ unsigned int mnt_flags; -+ struct au_xi_calc calc; -+ struct file *file; -+ struct au_branch *br; -+ struct au_xino *xi; -+ struct au_xi_writing *p; -+ -+ SiMustAnyLock(sb); -+ -+ mnt_flags = au_mntflags(sb); -+ if (!au_opt_test(mnt_flags, XINO)) -+ return 0; -+ -+ au_xi_calc(sb, h_ino, &calc); -+ br = au_sbr(sb, bindex); -+ xi = br->br_xino; -+ file = au_xino_file(xi, calc.idx); -+ if (!file) { -+ /* store the inum pair into the list */ -+ p = kmalloc(sizeof(*p), GFP_NOFS | __GFP_NOFAIL); -+ p->h_ino = h_ino; -+ p->ino = ino; -+ au_hbl_add(&p->node, &xi->xi_writing); -+ -+ /* create and write a new xino file asynchronously */ -+ err = au_xino_new_async(sb, br, &calc, ino); -+ if (!err) -+ return 0; /* success */ -+ goto out; -+ } -+ -+ err = au_xino_do_write(file, &calc, ino); -+ if (!err) { -+ br = au_sbr(sb, bindex); -+ if (au_opt_test(mnt_flags, TRUNC_XINO) -+ && au_test_fs_trunc_xino(au_br_sb(br))) -+ xino_try_trunc(sb, br); -+ return 0; /* success */ -+ } -+ -+out: -+ AuIOErr("write failed (%d)\n", err); -+ return -EIO; -+} -+ -+static ssize_t xino_fread_wkq(struct file *file, void *buf, size_t size, -+ loff_t *pos); -+ -+/* todo: unnecessary to support mmap_sem since kernel-space? */ -+ssize_t xino_fread(struct file *file, void *kbuf, size_t size, loff_t *pos) -+{ -+ ssize_t err; -+ int i; -+ const int prevent_endless = 10; -+ -+ i = 0; -+ do { -+ err = vfsub_read_k(file, kbuf, size, pos); -+ if (err == -EINTR -+ && !au_wkq_test() -+ && fatal_signal_pending(current)) { -+ err = xino_fread_wkq(file, kbuf, size, pos); -+ BUG_ON(err == -EINTR); -+ } -+ } while (i++ < prevent_endless -+ && (err == -EAGAIN || err == -EINTR)); -+ -+#if 0 /* reserved for future use */ -+ if (err > 0) -+ fsnotify_access(file->f_path.dentry); -+#endif -+ -+ return err; -+} -+ -+struct xino_fread_args { -+ ssize_t *errp; -+ struct file *file; -+ void *buf; -+ size_t size; -+ loff_t *pos; -+}; -+ -+static void call_xino_fread(void *args) -+{ -+ struct xino_fread_args *a = args; -+ *a->errp = xino_fread(a->file, a->buf, a->size, a->pos); -+} -+ -+static ssize_t xino_fread_wkq(struct file *file, void *buf, size_t size, -+ loff_t *pos) -+{ -+ ssize_t err; -+ int wkq_err; -+ struct xino_fread_args args = { -+ .errp = &err, -+ .file = file, -+ .buf = buf, -+ .size = size, -+ .pos = pos -+ }; -+ -+ wkq_err = au_wkq_wait(call_xino_fread, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ -+ return err; -+} -+ -+static ssize_t xino_fwrite_wkq(struct file *file, void *buf, size_t size, -+ loff_t *pos); -+ -+static ssize_t do_xino_fwrite(struct file *file, void *kbuf, size_t size, -+ loff_t *pos) -+{ -+ ssize_t err; -+ int i; -+ const int prevent_endless = 10; -+ -+ i = 0; -+ do { -+ err = vfsub_write_k(file, kbuf, size, pos); -+ if (err == -EINTR -+ && !au_wkq_test() -+ && fatal_signal_pending(current)) { -+ err = xino_fwrite_wkq(file, kbuf, size, pos); -+ BUG_ON(err == -EINTR); -+ } -+ } while (i++ < prevent_endless -+ && (err == -EAGAIN || err == -EINTR)); -+ -+#if 0 /* reserved for future use */ -+ if (err > 0) -+ fsnotify_modify(file->f_path.dentry); -+#endif -+ -+ return err; -+} -+ -+struct do_xino_fwrite_args { -+ ssize_t *errp; -+ struct file *file; -+ void *buf; -+ size_t size; -+ loff_t *pos; -+}; -+ -+static void call_do_xino_fwrite(void *args) -+{ -+ struct do_xino_fwrite_args *a = args; -+ *a->errp = do_xino_fwrite(a->file, a->buf, a->size, a->pos); -+} -+ -+static ssize_t xino_fwrite_wkq(struct file *file, void *buf, size_t size, -+ loff_t *pos) -+{ -+ ssize_t err; -+ int wkq_err; -+ struct do_xino_fwrite_args args = { -+ .errp = &err, -+ .file = file, -+ .buf = buf, -+ .size = size, -+ .pos = pos -+ }; -+ -+ /* -+ * it breaks RLIMIT_FSIZE and normal user's limit, -+ * users should care about quota and real 'filesystem full.' -+ */ -+ wkq_err = au_wkq_wait(call_do_xino_fwrite, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ -+ return err; -+} -+ -+ssize_t xino_fwrite(struct file *file, void *buf, size_t size, loff_t *pos) -+{ -+ ssize_t err; -+ -+ if (rlimit(RLIMIT_FSIZE) == RLIM_INFINITY) { -+ lockdep_off(); -+ err = do_xino_fwrite(file, buf, size, pos); -+ lockdep_on(); -+ } else { -+ lockdep_off(); -+ err = xino_fwrite_wkq(file, buf, size, pos); -+ lockdep_on(); -+ } -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * inode number bitmap -+ */ -+static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE; -+static ino_t xib_calc_ino(unsigned long pindex, int bit) -+{ -+ ino_t ino; -+ -+ AuDebugOn(bit < 0 || page_bits <= bit); -+ ino = AUFS_FIRST_INO + pindex * page_bits + bit; -+ return ino; -+} -+ -+static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit) -+{ -+ AuDebugOn(ino < AUFS_FIRST_INO); -+ ino -= AUFS_FIRST_INO; -+ *pindex = ino / page_bits; -+ *bit = ino % page_bits; -+} -+ -+static int xib_pindex(struct super_block *sb, unsigned long pindex) -+{ -+ int err; -+ loff_t pos; -+ ssize_t sz; -+ struct au_sbinfo *sbinfo; -+ struct file *xib; -+ unsigned long *p; -+ -+ sbinfo = au_sbi(sb); -+ MtxMustLock(&sbinfo->si_xib_mtx); -+ AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE -+ || !au_opt_test(sbinfo->si_mntflags, XINO)); -+ -+ if (pindex == sbinfo->si_xib_last_pindex) -+ return 0; -+ -+ xib = sbinfo->si_xib; -+ p = sbinfo->si_xib_buf; -+ pos = sbinfo->si_xib_last_pindex; -+ pos *= PAGE_SIZE; -+ sz = xino_fwrite(xib, p, PAGE_SIZE, &pos); -+ if (unlikely(sz != PAGE_SIZE)) -+ goto out; -+ -+ pos = pindex; -+ pos *= PAGE_SIZE; -+ if (vfsub_f_size_read(xib) >= pos + PAGE_SIZE) -+ sz = xino_fread(xib, p, PAGE_SIZE, &pos); -+ else { -+ memset(p, 0, PAGE_SIZE); -+ sz = xino_fwrite(xib, p, PAGE_SIZE, &pos); -+ } -+ if (sz == PAGE_SIZE) { -+ sbinfo->si_xib_last_pindex = pindex; -+ return 0; /* success */ -+ } -+ -+out: -+ AuIOErr1("write failed (%zd)\n", sz); -+ err = sz; -+ if (sz >= 0) -+ err = -EIO; -+ return err; -+} -+ -+static void au_xib_clear_bit(struct inode *inode) -+{ -+ int err, bit; -+ unsigned long pindex; -+ struct super_block *sb; -+ struct au_sbinfo *sbinfo; -+ -+ AuDebugOn(vfsub_inode_nlink(inode, AU_I_AUFS)); -+ -+ sb = inode->i_sb; -+ xib_calc_bit(inode->i_ino, &pindex, &bit); -+ AuDebugOn(page_bits <= bit); -+ sbinfo = au_sbi(sb); -+ mutex_lock(&sbinfo->si_xib_mtx); -+ err = xib_pindex(sb, pindex); -+ if (!err) { -+ clear_bit(bit, sbinfo->si_xib_buf); -+ sbinfo->si_xib_next_bit = bit; -+ } -+ mutex_unlock(&sbinfo->si_xib_mtx); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * truncate a xino bitmap file -+ */ -+ -+/* todo: slow */ -+static int do_xib_restore(struct super_block *sb, struct file *file, void *page) -+{ -+ int err, bit; -+ ssize_t sz; -+ unsigned long pindex; -+ loff_t pos, pend; -+ struct au_sbinfo *sbinfo; -+ ino_t *ino; -+ unsigned long *p; -+ -+ err = 0; -+ sbinfo = au_sbi(sb); -+ MtxMustLock(&sbinfo->si_xib_mtx); -+ p = sbinfo->si_xib_buf; -+ pend = vfsub_f_size_read(file); -+ pos = 0; -+ while (pos < pend) { -+ sz = xino_fread(file, page, PAGE_SIZE, &pos); -+ err = sz; -+ if (unlikely(sz <= 0)) -+ goto out; -+ -+ err = 0; -+ for (ino = page; sz > 0; ino++, sz -= sizeof(ino)) { -+ if (unlikely(*ino < AUFS_FIRST_INO)) -+ continue; -+ -+ xib_calc_bit(*ino, &pindex, &bit); -+ AuDebugOn(page_bits <= bit); -+ err = xib_pindex(sb, pindex); -+ if (!err) -+ set_bit(bit, p); -+ else -+ goto out; -+ } -+ } -+ -+out: -+ return err; -+} -+ -+static int xib_restore(struct super_block *sb) -+{ -+ int err, i; -+ unsigned int nfile; -+ aufs_bindex_t bindex, bbot; -+ void *page; -+ struct au_branch *br; -+ struct au_xino *xi; -+ struct file *file; -+ -+ err = -ENOMEM; -+ page = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!page)) -+ goto out; -+ -+ err = 0; -+ bbot = au_sbbot(sb); -+ for (bindex = 0; !err && bindex <= bbot; bindex++) -+ if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0) { -+ br = au_sbr(sb, bindex); -+ xi = br->br_xino; -+ nfile = xi->xi_nfile; -+ for (i = 0; i < nfile; i++) { -+ file = au_xino_file(xi, i); -+ if (file) -+ err = do_xib_restore(sb, file, page); -+ } -+ } else -+ AuDbg("skip shared b%d\n", bindex); -+ free_page((unsigned long)page); -+ -+out: -+ return err; -+} -+ -+int au_xib_trunc(struct super_block *sb) -+{ -+ int err; -+ ssize_t sz; -+ loff_t pos; -+ struct au_sbinfo *sbinfo; -+ unsigned long *p; -+ struct file *file; -+ -+ SiMustWriteLock(sb); -+ -+ err = 0; -+ sbinfo = au_sbi(sb); -+ if (!au_opt_test(sbinfo->si_mntflags, XINO)) -+ goto out; -+ -+ file = sbinfo->si_xib; -+ if (vfsub_f_size_read(file) <= PAGE_SIZE) -+ goto out; -+ -+ file = au_xino_create2(sb, &sbinfo->si_xib->f_path, NULL); -+ err = PTR_ERR(file); -+ if (IS_ERR(file)) -+ goto out; -+ fput(sbinfo->si_xib); -+ sbinfo->si_xib = file; -+ -+ p = sbinfo->si_xib_buf; -+ memset(p, 0, PAGE_SIZE); -+ pos = 0; -+ sz = xino_fwrite(sbinfo->si_xib, p, PAGE_SIZE, &pos); -+ if (unlikely(sz != PAGE_SIZE)) { -+ err = sz; -+ AuIOErr("err %d\n", err); -+ if (sz >= 0) -+ err = -EIO; -+ goto out; -+ } -+ -+ mutex_lock(&sbinfo->si_xib_mtx); -+ /* mnt_want_write() is unnecessary here */ -+ err = xib_restore(sb); -+ mutex_unlock(&sbinfo->si_xib_mtx); -+ -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_xino *au_xino_alloc(unsigned int nfile) -+{ -+ struct au_xino *xi; -+ -+ xi = kzalloc(sizeof(*xi), GFP_NOFS); -+ if (unlikely(!xi)) -+ goto out; -+ xi->xi_nfile = nfile; -+ xi->xi_file = kcalloc(nfile, sizeof(*xi->xi_file), GFP_NOFS); -+ if (unlikely(!xi->xi_file)) -+ goto out_free; -+ -+ xi->xi_nondir.total = 8; /* initial size */ -+ xi->xi_nondir.array = kcalloc(xi->xi_nondir.total, sizeof(ino_t), -+ GFP_NOFS); -+ if (unlikely(!xi->xi_nondir.array)) -+ goto out_file; -+ -+ spin_lock_init(&xi->xi_nondir.spin); -+ init_waitqueue_head(&xi->xi_nondir.wqh); -+ mutex_init(&xi->xi_mtx); -+ INIT_HLIST_BL_HEAD(&xi->xi_writing); -+ atomic_set(&xi->xi_truncating, 0); -+ kref_init(&xi->xi_kref); -+ goto out; /* success */ -+ -+out_file: -+ au_kfree_try_rcu(xi->xi_file); -+out_free: -+ au_kfree_rcu(xi); -+ xi = NULL; -+out: -+ return xi; -+} -+ -+static int au_xino_init(struct au_branch *br, int idx, struct file *file) -+{ -+ int err; -+ struct au_xino *xi; -+ -+ err = 0; -+ xi = au_xino_alloc(idx + 1); -+ if (unlikely(!xi)) { -+ err = -ENOMEM; -+ goto out; -+ } -+ -+ if (file) -+ get_file(file); -+ xi->xi_file[idx] = file; -+ AuDebugOn(br->br_xino); -+ br->br_xino = xi; -+ -+out: -+ return err; -+} -+ -+static void au_xino_release(struct kref *kref) -+{ -+ struct au_xino *xi; -+ int i; -+ unsigned long ul; -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *pos, *n; -+ struct au_xi_writing *p; -+ -+ xi = container_of(kref, struct au_xino, xi_kref); -+ for (i = 0; i < xi->xi_nfile; i++) -+ if (xi->xi_file[i]) -+ fput(xi->xi_file[i]); -+ for (i = xi->xi_nondir.total - 1; i >= 0; i--) -+ AuDebugOn(xi->xi_nondir.array[i]); -+ mutex_destroy(&xi->xi_mtx); -+ hbl = &xi->xi_writing; -+ ul = au_hbl_count(hbl); -+ if (unlikely(ul)) { -+ pr_warn("xi_writing %lu\n", ul); -+ hlist_bl_lock(hbl); -+ hlist_bl_for_each_entry_safe(p, pos, n, hbl, node) { -+ hlist_bl_del(&p->node); -+ /* kmemleak reported au_kfree_rcu() doesn't free it */ -+ kfree(p); -+ } -+ hlist_bl_unlock(hbl); -+ } -+ au_kfree_try_rcu(xi->xi_file); -+ au_kfree_try_rcu(xi->xi_nondir.array); -+ au_kfree_rcu(xi); -+} -+ -+int au_xino_put(struct au_branch *br) -+{ -+ int ret; -+ struct au_xino *xi; -+ -+ ret = 0; -+ xi = br->br_xino; -+ if (xi) { -+ br->br_xino = NULL; -+ ret = kref_put(&xi->xi_kref, au_xino_release); -+ } -+ -+ return ret; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * xino mount option handlers -+ */ -+ -+/* xino bitmap */ -+static void xino_clear_xib(struct super_block *sb) -+{ -+ struct au_sbinfo *sbinfo; -+ -+ SiMustWriteLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ if (sbinfo->si_xib) -+ fput(sbinfo->si_xib); -+ sbinfo->si_xib = NULL; -+ if (sbinfo->si_xib_buf) -+ free_page((unsigned long)sbinfo->si_xib_buf); -+ sbinfo->si_xib_buf = NULL; -+} -+ -+static int au_xino_set_xib(struct super_block *sb, struct path *path) -+{ -+ int err; -+ loff_t pos; -+ struct au_sbinfo *sbinfo; -+ struct file *file; -+ struct super_block *xi_sb; -+ -+ SiMustWriteLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ file = au_xino_create2(sb, path, sbinfo->si_xib); -+ err = PTR_ERR(file); -+ if (IS_ERR(file)) -+ goto out; -+ if (sbinfo->si_xib) -+ fput(sbinfo->si_xib); -+ sbinfo->si_xib = file; -+ xi_sb = file_inode(file)->i_sb; -+ sbinfo->si_ximaxent = xi_sb->s_maxbytes; -+ if (unlikely(sbinfo->si_ximaxent < PAGE_SIZE)) { -+ err = -EIO; -+ pr_err("s_maxbytes(%llu) on %s is too small\n", -+ (u64)sbinfo->si_ximaxent, au_sbtype(xi_sb)); -+ goto out_unset; -+ } -+ sbinfo->si_ximaxent /= sizeof(ino_t); -+ -+ err = -ENOMEM; -+ if (!sbinfo->si_xib_buf) -+ sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS); -+ if (unlikely(!sbinfo->si_xib_buf)) -+ goto out_unset; -+ -+ sbinfo->si_xib_last_pindex = 0; -+ sbinfo->si_xib_next_bit = 0; -+ if (vfsub_f_size_read(file) < PAGE_SIZE) { -+ pos = 0; -+ err = xino_fwrite(file, sbinfo->si_xib_buf, PAGE_SIZE, &pos); -+ if (unlikely(err != PAGE_SIZE)) -+ goto out_free; -+ } -+ err = 0; -+ goto out; /* success */ -+ -+out_free: -+ if (sbinfo->si_xib_buf) -+ free_page((unsigned long)sbinfo->si_xib_buf); -+ sbinfo->si_xib_buf = NULL; -+ if (err >= 0) -+ err = -EIO; -+out_unset: -+ fput(sbinfo->si_xib); -+ sbinfo->si_xib = NULL; -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* xino for each branch */ -+static void xino_clear_br(struct super_block *sb) -+{ -+ aufs_bindex_t bindex, bbot; -+ struct au_branch *br; -+ -+ bbot = au_sbbot(sb); -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ AuDebugOn(!br); -+ au_xino_put(br); -+ } -+} -+ -+static void au_xino_set_br_shared(struct super_block *sb, struct au_branch *br, -+ aufs_bindex_t bshared) -+{ -+ struct au_branch *brshared; -+ -+ brshared = au_sbr(sb, bshared); -+ AuDebugOn(!brshared->br_xino); -+ AuDebugOn(!brshared->br_xino->xi_file); -+ if (br->br_xino != brshared->br_xino) { -+ au_xino_get(brshared); -+ au_xino_put(br); -+ br->br_xino = brshared->br_xino; -+ } -+} -+ -+struct au_xino_do_set_br { -+ struct au_branch *br; -+ ino_t h_ino; -+ aufs_bindex_t bshared; -+}; -+ -+static int au_xino_do_set_br(struct super_block *sb, struct path *path, -+ struct au_xino_do_set_br *args) -+{ -+ int err; -+ struct au_xi_calc calc; -+ struct file *file; -+ struct au_branch *br; -+ struct au_xi_new xinew = { -+ .base = path -+ }; -+ -+ br = args->br; -+ xinew.xi = br->br_xino; -+ au_xi_calc(sb, args->h_ino, &calc); -+ xinew.copy_src = au_xino_file(xinew.xi, calc.idx); -+ if (args->bshared >= 0) -+ /* shared xino */ -+ au_xino_set_br_shared(sb, br, args->bshared); -+ else if (!xinew.xi) { -+ /* new xino */ -+ err = au_xino_init(br, calc.idx, xinew.copy_src); -+ if (unlikely(err)) -+ goto out; -+ } -+ -+ /* force re-creating */ -+ xinew.xi = br->br_xino; -+ xinew.idx = calc.idx; -+ mutex_lock(&xinew.xi->xi_mtx); -+ file = au_xi_new(sb, &xinew); -+ mutex_unlock(&xinew.xi->xi_mtx); -+ err = PTR_ERR(file); -+ if (IS_ERR(file)) -+ goto out; -+ AuDebugOn(!file); -+ -+ err = au_xino_do_write(file, &calc, AUFS_ROOT_INO); -+ if (unlikely(err)) -+ au_xino_put(br); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_xino_set_br(struct super_block *sb, struct path *path) -+{ -+ int err; -+ aufs_bindex_t bindex, bbot; -+ struct au_xino_do_set_br args; -+ struct inode *inode; -+ -+ SiMustWriteLock(sb); -+ -+ bbot = au_sbbot(sb); -+ inode = d_inode(sb->s_root); -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ args.h_ino = au_h_iptr(inode, bindex)->i_ino; -+ args.br = au_sbr(sb, bindex); -+ args.bshared = is_sb_shared(sb, bindex, bindex - 1); -+ err = au_xino_do_set_br(sb, path, &args); -+ if (unlikely(err)) -+ break; -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+void au_xino_clr(struct super_block *sb) -+{ -+ struct au_sbinfo *sbinfo; -+ -+ au_xigen_clr(sb); -+ xino_clear_xib(sb); -+ xino_clear_br(sb); -+ dbgaufs_brs_del(sb, 0); -+ sbinfo = au_sbi(sb); -+ /* lvalue, do not call au_mntflags() */ -+ au_opt_clr(sbinfo->si_mntflags, XINO); -+} -+ -+int au_xino_set(struct super_block *sb, struct au_opt_xino *xiopt, int remount) -+{ -+ int err, skip; -+ struct dentry *dentry, *parent, *cur_dentry, *cur_parent; -+ struct qstr *dname, *cur_name; -+ struct file *cur_xino; -+ struct au_sbinfo *sbinfo; -+ struct path *path, *cur_path; -+ -+ SiMustWriteLock(sb); -+ -+ err = 0; -+ sbinfo = au_sbi(sb); -+ path = &xiopt->file->f_path; -+ dentry = path->dentry; -+ parent = dget_parent(dentry); -+ if (remount) { -+ skip = 0; -+ cur_xino = sbinfo->si_xib; -+ if (cur_xino) { -+ cur_path = &cur_xino->f_path; -+ cur_dentry = cur_path->dentry; -+ cur_parent = dget_parent(cur_dentry); -+ cur_name = &cur_dentry->d_name; -+ dname = &dentry->d_name; -+ skip = (cur_parent == parent -+ && au_qstreq(dname, cur_name)); -+ dput(cur_parent); -+ } -+ if (skip) -+ goto out; -+ } -+ -+ au_opt_set(sbinfo->si_mntflags, XINO); -+ err = au_xino_set_xib(sb, path); -+ /* si_x{read,write} are set */ -+ if (!err) -+ err = au_xigen_set(sb, path); -+ if (!err) -+ err = au_xino_set_br(sb, path); -+ if (!err) { -+ dbgaufs_brs_add(sb, 0, /*topdown*/1); -+ goto out; /* success */ -+ } -+ -+ /* reset all */ -+ AuIOErr("failed setting xino(%d).\n", err); -+ au_xino_clr(sb); -+ -+out: -+ dput(parent); -+ return err; -+} -+ -+/* -+ * create a xinofile at the default place/path. -+ */ -+struct file *au_xino_def(struct super_block *sb) -+{ -+ struct file *file; -+ char *page, *p; -+ struct au_branch *br; -+ struct super_block *h_sb; -+ struct path path; -+ aufs_bindex_t bbot, bindex, bwr; -+ -+ br = NULL; -+ bbot = au_sbbot(sb); -+ bwr = -1; -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (au_br_writable(br->br_perm) -+ && !au_test_fs_bad_xino(au_br_sb(br))) { -+ bwr = bindex; -+ break; -+ } -+ } -+ -+ if (bwr >= 0) { -+ file = ERR_PTR(-ENOMEM); -+ page = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!page)) -+ goto out; -+ path.mnt = au_br_mnt(br); -+ path.dentry = au_h_dptr(sb->s_root, bwr); -+ p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME)); -+ file = (void *)p; -+ if (!IS_ERR(p)) { -+ strcat(p, "/" AUFS_XINO_FNAME); -+ AuDbg("%s\n", p); -+ file = au_xino_create(sb, p, /*silent*/0, /*wbrtop*/1); -+ } -+ free_page((unsigned long)page); -+ } else { -+ file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0, -+ /*wbrtop*/0); -+ if (IS_ERR(file)) -+ goto out; -+ h_sb = file->f_path.dentry->d_sb; -+ if (unlikely(au_test_fs_bad_xino(h_sb))) { -+ pr_err("xino doesn't support %s(%s)\n", -+ AUFS_XINO_DEFPATH, au_sbtype(h_sb)); -+ fput(file); -+ file = ERR_PTR(-EINVAL); -+ } -+ } -+ -+out: -+ return file; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * initialize the xinofile for the specified branch @br -+ * at the place/path where @base_file indicates. -+ * test whether another branch is on the same filesystem or not, -+ * if found then share the xinofile with another branch. -+ */ -+int au_xino_init_br(struct super_block *sb, struct au_branch *br, ino_t h_ino, -+ struct path *base) -+{ -+ int err; -+ struct au_xino_do_set_br args = { -+ .h_ino = h_ino, -+ .br = br -+ }; -+ -+ args.bshared = sbr_find_shared(sb, /*btop*/0, au_sbbot(sb), -+ au_br_sb(br)); -+ err = au_xino_do_set_br(sb, base, &args); -+ if (unlikely(err)) -+ au_xino_put(br); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * get an unused inode number from bitmap -+ */ -+ino_t au_xino_new_ino(struct super_block *sb) -+{ -+ ino_t ino; -+ unsigned long *p, pindex, ul, pend; -+ struct au_sbinfo *sbinfo; -+ struct file *file; -+ int free_bit, err; -+ -+ if (!au_opt_test(au_mntflags(sb), XINO)) -+ return iunique(sb, AUFS_FIRST_INO); -+ -+ sbinfo = au_sbi(sb); -+ mutex_lock(&sbinfo->si_xib_mtx); -+ p = sbinfo->si_xib_buf; -+ free_bit = sbinfo->si_xib_next_bit; -+ if (free_bit < page_bits && !test_bit(free_bit, p)) -+ goto out; /* success */ -+ free_bit = find_first_zero_bit(p, page_bits); -+ if (free_bit < page_bits) -+ goto out; /* success */ -+ -+ pindex = sbinfo->si_xib_last_pindex; -+ for (ul = pindex - 1; ul < ULONG_MAX; ul--) { -+ err = xib_pindex(sb, ul); -+ if (unlikely(err)) -+ goto out_err; -+ free_bit = find_first_zero_bit(p, page_bits); -+ if (free_bit < page_bits) -+ goto out; /* success */ -+ } -+ -+ file = sbinfo->si_xib; -+ pend = vfsub_f_size_read(file) / PAGE_SIZE; -+ for (ul = pindex + 1; ul <= pend; ul++) { -+ err = xib_pindex(sb, ul); -+ if (unlikely(err)) -+ goto out_err; -+ free_bit = find_first_zero_bit(p, page_bits); -+ if (free_bit < page_bits) -+ goto out; /* success */ -+ } -+ BUG(); -+ -+out: -+ set_bit(free_bit, p); -+ sbinfo->si_xib_next_bit = free_bit + 1; -+ pindex = sbinfo->si_xib_last_pindex; -+ mutex_unlock(&sbinfo->si_xib_mtx); -+ ino = xib_calc_ino(pindex, free_bit); -+ AuDbg("i%lu\n", (unsigned long)ino); -+ return ino; -+out_err: -+ mutex_unlock(&sbinfo->si_xib_mtx); -+ AuDbg("i0\n"); -+ return 0; -+} -+ -+/* for s_op->delete_inode() */ -+void au_xino_delete_inode(struct inode *inode, const int unlinked) -+{ -+ int err; -+ unsigned int mnt_flags; -+ aufs_bindex_t bindex, bbot, bi; -+ unsigned char try_trunc; -+ struct au_iinfo *iinfo; -+ struct super_block *sb; -+ struct au_hinode *hi; -+ struct inode *h_inode; -+ struct au_branch *br; -+ struct au_xi_calc calc; -+ struct file *file; -+ -+ AuDebugOn(au_is_bad_inode(inode)); -+ -+ sb = inode->i_sb; -+ mnt_flags = au_mntflags(sb); -+ if (!au_opt_test(mnt_flags, XINO) -+ || inode->i_ino == AUFS_ROOT_INO) -+ return; -+ -+ if (unlinked) { -+ au_xigen_inc(inode); -+ au_xib_clear_bit(inode); -+ } -+ -+ iinfo = au_ii(inode); -+ bindex = iinfo->ii_btop; -+ if (bindex < 0) -+ return; -+ -+ try_trunc = !!au_opt_test(mnt_flags, TRUNC_XINO); -+ hi = au_hinode(iinfo, bindex); -+ bbot = iinfo->ii_bbot; -+ for (; bindex <= bbot; bindex++, hi++) { -+ h_inode = hi->hi_inode; -+ if (!h_inode -+ || (!unlinked && vfsub_inode_nlink(h_inode, AU_I_BRANCH))) -+ continue; -+ -+ /* inode may not be revalidated */ -+ bi = au_br_index(sb, hi->hi_id); -+ if (bi < 0) -+ continue; -+ -+ br = au_sbr(sb, bi); -+ au_xi_calc(sb, h_inode->i_ino, &calc); -+ file = au_xino_file(br->br_xino, calc.idx); -+ if (IS_ERR_OR_NULL(file)) -+ continue; -+ -+ err = au_xino_do_write(file, &calc, /*ino*/0); -+ if (!err && try_trunc -+ && au_test_fs_trunc_xino(au_br_sb(br))) -+ xino_try_trunc(sb, br); -+ } -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_xinondir_find(struct au_xino *xi, ino_t h_ino) -+{ -+ int found, total, i; -+ -+ found = -1; -+ total = xi->xi_nondir.total; -+ for (i = 0; i < total; i++) { -+ if (xi->xi_nondir.array[i] != h_ino) -+ continue; -+ found = i; -+ break; -+ } -+ -+ return found; -+} -+ -+static int au_xinondir_expand(struct au_xino *xi) -+{ -+ int err, sz; -+ ino_t *p; -+ -+ BUILD_BUG_ON(KMALLOC_MAX_SIZE > INT_MAX); -+ -+ err = -ENOMEM; -+ sz = xi->xi_nondir.total * sizeof(ino_t); -+ if (unlikely(sz > KMALLOC_MAX_SIZE / 2)) -+ goto out; -+ p = au_kzrealloc(xi->xi_nondir.array, sz, sz << 1, GFP_ATOMIC, -+ /*may_shrink*/0); -+ if (p) { -+ xi->xi_nondir.array = p; -+ xi->xi_nondir.total <<= 1; -+ AuDbg("xi_nondir.total %d\n", xi->xi_nondir.total); -+ err = 0; -+ } -+ -+out: -+ return err; -+} -+ -+void au_xinondir_leave(struct super_block *sb, aufs_bindex_t bindex, -+ ino_t h_ino, int idx) -+{ -+ struct au_xino *xi; -+ -+ AuDebugOn(!au_opt_test(au_mntflags(sb), XINO)); -+ xi = au_sbr(sb, bindex)->br_xino; -+ AuDebugOn(idx < 0 || xi->xi_nondir.total <= idx); -+ -+ spin_lock(&xi->xi_nondir.spin); -+ AuDebugOn(xi->xi_nondir.array[idx] != h_ino); -+ xi->xi_nondir.array[idx] = 0; -+ spin_unlock(&xi->xi_nondir.spin); -+ wake_up_all(&xi->xi_nondir.wqh); -+} -+ -+int au_xinondir_enter(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, -+ int *idx) -+{ -+ int err, found, empty; -+ struct au_xino *xi; -+ -+ err = 0; -+ *idx = -1; -+ if (!au_opt_test(au_mntflags(sb), XINO)) -+ goto out; /* no xino */ -+ -+ xi = au_sbr(sb, bindex)->br_xino; -+ -+again: -+ spin_lock(&xi->xi_nondir.spin); -+ found = au_xinondir_find(xi, h_ino); -+ if (found == -1) { -+ empty = au_xinondir_find(xi, /*h_ino*/0); -+ if (empty == -1) { -+ empty = xi->xi_nondir.total; -+ err = au_xinondir_expand(xi); -+ if (unlikely(err)) -+ goto out_unlock; -+ } -+ xi->xi_nondir.array[empty] = h_ino; -+ *idx = empty; -+ } else { -+ spin_unlock(&xi->xi_nondir.spin); -+ wait_event(xi->xi_nondir.wqh, -+ xi->xi_nondir.array[found] != h_ino); -+ goto again; -+ } -+ -+out_unlock: -+ spin_unlock(&xi->xi_nondir.spin); -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_xino_path(struct seq_file *seq, struct file *file) -+{ -+ int err; -+ -+ err = au_seq_path(seq, &file->f_path); -+ if (unlikely(err)) -+ goto out; -+ -+#define Deleted "\\040(deleted)" -+ seq->count -= sizeof(Deleted) - 1; -+ AuDebugOn(memcmp(seq->buf + seq->count, Deleted, -+ sizeof(Deleted) - 1)); -+#undef Deleted -+ -+out: -+ return err; -+} -diff -Naur null/include/uapi/linux/aufs_type.h linux-6.6.63/include/uapi/linux/aufs_type.h ---- /dev/null -+++ linux-6.6.63/include/uapi/linux/aufs_type.h 2024-12-18 15:12:59.301519513 +0300 -@@ -0,0 +1,452 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -+/* -+ * Copyright (C) 2005-2022 Junjiro R. Okajima -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#ifndef __AUFS_TYPE_H__ -+#define __AUFS_TYPE_H__ -+ -+#define AUFS_NAME "aufs" -+ -+#ifdef __KERNEL__ -+/* -+ * define it before including all other headers. -+ * sched.h may use pr_* macros before defining "current", so define the -+ * no-current version first, and re-define later. -+ */ -+#define pr_fmt(fmt) AUFS_NAME " %s:%d: " fmt, __func__, __LINE__ -+#include -+#undef pr_fmt -+#define pr_fmt(fmt) \ -+ AUFS_NAME " %s:%d:%.*s[%d]: " fmt, __func__, __LINE__, \ -+ (int)sizeof(current->comm), current->comm, current->pid -+#include -+#else -+#include -+#include -+#include -+#endif /* __KERNEL__ */ -+ -+#define AUFS_VERSION "6.6.63-20241202" -+ -+/* todo? move this to linux-2.6.19/include/magic.h */ -+#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's') -+ -+/* ---------------------------------------------------------------------- */ -+ -+#ifdef __KERNEL__ -+#ifdef CONFIG_AUFS_BRANCH_MAX_127 -+typedef int8_t aufs_bindex_t; -+#define AUFS_BRANCH_MAX 127 -+#else -+typedef int16_t aufs_bindex_t; -+#ifdef CONFIG_AUFS_BRANCH_MAX_511 -+#define AUFS_BRANCH_MAX 511 -+#elif defined(CONFIG_AUFS_BRANCH_MAX_1023) -+#define AUFS_BRANCH_MAX 1023 -+#elif defined(CONFIG_AUFS_BRANCH_MAX_32767) -+#define AUFS_BRANCH_MAX 32767 -+#endif -+#endif -+ -+#ifndef AUFS_BRANCH_MAX -+#error unknown CONFIG_AUFS_BRANCH_MAX value -+#endif -+#endif /* __KERNEL__ */ -+ -+/* ---------------------------------------------------------------------- */ -+ -+#define AUFS_FSTYPE AUFS_NAME -+ -+#define AUFS_ROOT_INO 2 -+#define AUFS_FIRST_INO 11 -+ -+#define AUFS_WH_PFX ".wh." -+#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1) -+#define AUFS_WH_TMP_LEN 4 -+/* a limit for rmdir/rename a dir and copyup */ -+#define AUFS_MAX_NAMELEN (NAME_MAX \ -+ - AUFS_WH_PFX_LEN * 2 /* doubly whiteouted */\ -+ - 1 /* dot */\ -+ - AUFS_WH_TMP_LEN) /* hex */ -+#define AUFS_XINO_FNAME "." AUFS_NAME ".xino" -+#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME -+#define AUFS_XINO_DEF_SEC 30 /* seconds */ -+#define AUFS_XINO_DEF_TRUNC 45 /* percentage */ -+#define AUFS_DIRWH_DEF 3 -+#define AUFS_RDCACHE_DEF 10 /* seconds */ -+#define AUFS_RDCACHE_MAX 3600 /* seconds */ -+#define AUFS_RDBLK_DEF 512 /* bytes */ -+#define AUFS_RDHASH_DEF 32 -+#define AUFS_WKQ_NAME AUFS_NAME "d" -+#define AUFS_MFS_DEF_SEC 30 /* seconds */ -+#define AUFS_MFS_MAX_SEC 3600 /* seconds */ -+#define AUFS_FHSM_CACHE_DEF_SEC 30 /* seconds */ -+#define AUFS_PLINK_WARN 50 /* number of plinks in a single bucket */ -+ -+/* pseudo-link maintenace under /proc */ -+#define AUFS_PLINK_MAINT_NAME "plink_maint" -+#define AUFS_PLINK_MAINT_DIR "fs/" AUFS_NAME -+#define AUFS_PLINK_MAINT_PATH AUFS_PLINK_MAINT_DIR "/" AUFS_PLINK_MAINT_NAME -+ -+/* dirren, renamed dir */ -+#define AUFS_DR_INFO_PFX AUFS_WH_PFX ".dr." -+#define AUFS_DR_BRHINO_NAME AUFS_WH_PFX "hino" -+/* whiteouted doubly */ -+#define AUFS_WH_DR_INFO_PFX AUFS_WH_PFX AUFS_DR_INFO_PFX -+#define AUFS_WH_DR_BRHINO AUFS_WH_PFX AUFS_DR_BRHINO_NAME -+ -+#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */ -+#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME -+ -+#define AUFS_BASE_NAME AUFS_WH_PFX AUFS_NAME -+#define AUFS_PLINKDIR_NAME AUFS_WH_PFX "plnk" -+#define AUFS_ORPHDIR_NAME AUFS_WH_PFX "orph" -+ -+/* doubly whiteouted */ -+#define AUFS_WH_BASE AUFS_WH_PFX AUFS_BASE_NAME -+#define AUFS_WH_PLINKDIR AUFS_WH_PFX AUFS_PLINKDIR_NAME -+#define AUFS_WH_ORPHDIR AUFS_WH_PFX AUFS_ORPHDIR_NAME -+ -+/* branch permissions and attributes */ -+#define AUFS_BRPERM_RW "rw" -+#define AUFS_BRPERM_RO "ro" -+#define AUFS_BRPERM_RR "rr" -+#define AUFS_BRATTR_COO_REG "coo_reg" -+#define AUFS_BRATTR_COO_ALL "coo_all" -+#define AUFS_BRATTR_FHSM "fhsm" -+#define AUFS_BRATTR_UNPIN "unpin" -+#define AUFS_BRATTR_ICEX "icex" -+#define AUFS_BRATTR_ICEX_SEC "icexsec" -+#define AUFS_BRATTR_ICEX_SYS "icexsys" -+#define AUFS_BRATTR_ICEX_TR "icextr" -+#define AUFS_BRATTR_ICEX_USR "icexusr" -+#define AUFS_BRATTR_ICEX_OTH "icexoth" -+#define AUFS_BRRATTR_WH "wh" -+#define AUFS_BRWATTR_NLWH "nolwh" -+#define AUFS_BRWATTR_MOO "moo" -+ -+#define AuBrPerm_RW 1 /* writable, hardlinkable wh */ -+#define AuBrPerm_RO (1 << 1) /* readonly */ -+#define AuBrPerm_RR (1 << 2) /* natively readonly */ -+#define AuBrPerm_Mask (AuBrPerm_RW | AuBrPerm_RO | AuBrPerm_RR) -+ -+#define AuBrAttr_COO_REG (1 << 3) /* copy-up on open */ -+#define AuBrAttr_COO_ALL (1 << 4) -+#define AuBrAttr_COO_Mask (AuBrAttr_COO_REG | AuBrAttr_COO_ALL) -+ -+#define AuBrAttr_FHSM (1 << 5) /* file-based hsm */ -+#define AuBrAttr_UNPIN (1 << 6) /* rename-able top dir of -+ branch. meaningless since -+ linux-3.18-rc1 */ -+ -+/* ignore error in copying XATTR */ -+#define AuBrAttr_ICEX_SEC (1 << 7) -+#define AuBrAttr_ICEX_SYS (1 << 8) -+#define AuBrAttr_ICEX_TR (1 << 9) -+#define AuBrAttr_ICEX_USR (1 << 10) -+#define AuBrAttr_ICEX_OTH (1 << 11) -+#define AuBrAttr_ICEX (AuBrAttr_ICEX_SEC \ -+ | AuBrAttr_ICEX_SYS \ -+ | AuBrAttr_ICEX_TR \ -+ | AuBrAttr_ICEX_USR \ -+ | AuBrAttr_ICEX_OTH) -+ -+#define AuBrRAttr_WH (1 << 12) /* whiteout-able */ -+#define AuBrRAttr_Mask AuBrRAttr_WH -+ -+#define AuBrWAttr_NoLinkWH (1 << 13) /* un-hardlinkable whiteouts */ -+#define AuBrWAttr_MOO (1 << 14) /* move-up on open */ -+#define AuBrWAttr_Mask (AuBrWAttr_NoLinkWH | AuBrWAttr_MOO) -+ -+#define AuBrAttr_CMOO_Mask (AuBrAttr_COO_Mask | AuBrWAttr_MOO) -+ -+/* #warning test userspace */ -+#ifdef __KERNEL__ -+#ifndef CONFIG_AUFS_FHSM -+#undef AuBrAttr_FHSM -+#define AuBrAttr_FHSM 0 -+#endif -+#ifndef CONFIG_AUFS_XATTR -+#undef AuBrAttr_ICEX -+#define AuBrAttr_ICEX 0 -+#undef AuBrAttr_ICEX_SEC -+#define AuBrAttr_ICEX_SEC 0 -+#undef AuBrAttr_ICEX_SYS -+#define AuBrAttr_ICEX_SYS 0 -+#undef AuBrAttr_ICEX_TR -+#define AuBrAttr_ICEX_TR 0 -+#undef AuBrAttr_ICEX_USR -+#define AuBrAttr_ICEX_USR 0 -+#undef AuBrAttr_ICEX_OTH -+#define AuBrAttr_ICEX_OTH 0 -+#endif -+#endif -+ -+/* the longest combination */ -+/* AUFS_BRATTR_ICEX and AUFS_BRATTR_ICEX_TR don't affect here */ -+#define AuBrPermStrSz sizeof(AUFS_BRPERM_RW \ -+ "+" 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_BRWATTR_NLWH) -+ -+typedef struct { -+ char a[AuBrPermStrSz]; -+} au_br_perm_str_t; -+ -+static inline int au_br_writable(int brperm) -+{ -+ return brperm & AuBrPerm_RW; -+} -+ -+static inline int au_br_whable(int brperm) -+{ -+ return brperm & (AuBrPerm_RW | AuBrRAttr_WH); -+} -+ -+static inline int au_br_wh_linkable(int brperm) -+{ -+ return !(brperm & AuBrWAttr_NoLinkWH); -+} -+ -+static inline int au_br_cmoo(int brperm) -+{ -+ return brperm & AuBrAttr_CMOO_Mask; -+} -+ -+static inline int au_br_fhsm(int brperm) -+{ -+ return brperm & AuBrAttr_FHSM; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* ioctl */ -+enum { -+ /* readdir in userspace */ -+ AuCtl_RDU, -+ AuCtl_RDU_INO, -+ -+ AuCtl_WBR_FD, /* pathconf wrapper */ -+ AuCtl_IBUSY, /* busy inode */ -+ AuCtl_MVDOWN, /* move-down */ -+ AuCtl_BR, /* info about branches */ -+ AuCtl_FHSM_FD /* connection for fhsm */ -+}; -+ -+/* borrowed from linux/include/linux/kernel.h */ -+#ifndef ALIGN -+#ifdef _GNU_SOURCE -+#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1) -+#else -+#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) -+#endif -+#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask)) -+#endif -+ -+/* borrowed from linux/include/linux/compiler-gcc3.h */ -+#ifndef __aligned -+#define __aligned(x) __attribute__((aligned(x))) -+#endif -+ -+#ifdef __KERNEL__ -+#ifndef __packed -+#define __packed __attribute__((packed)) -+#endif -+#endif -+ -+struct au_rdu_cookie { -+ uint64_t h_pos; -+ int16_t bindex; -+ uint8_t flags; -+ uint8_t pad; -+ uint32_t generation; -+} __aligned(8); -+ -+struct au_rdu_ent { -+ uint64_t ino; -+ int16_t bindex; -+ uint8_t type; -+ uint8_t nlen; -+ uint8_t wh; -+ char name[]; -+} __aligned(8); -+ -+static inline int au_rdu_len(int nlen) -+{ -+ /* include the terminating NULL */ -+ return ALIGN(sizeof(struct au_rdu_ent) + nlen + 1, -+ sizeof(uint64_t)); -+} -+ -+union au_rdu_ent_ul { -+ struct au_rdu_ent __user *e; -+ uint64_t ul; -+}; -+ -+enum { -+ AufsCtlRduV_SZ, -+ AufsCtlRduV_End -+}; -+ -+struct aufs_rdu { -+ /* input */ -+ union { -+ uint64_t sz; /* AuCtl_RDU */ -+ uint64_t nent; /* AuCtl_RDU_INO */ -+ }; -+ union au_rdu_ent_ul ent; -+ uint16_t verify[AufsCtlRduV_End]; -+ -+ /* input/output */ -+ uint32_t blk; -+ -+ /* output */ -+ union au_rdu_ent_ul tail; -+ /* number of entries which were added in a single call */ -+ uint64_t rent; -+ uint8_t full; -+ uint8_t shwh; -+ -+ struct au_rdu_cookie cookie; -+} __aligned(8); -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* dirren. the branch is identified by the filename who contains this */ -+struct au_drinfo { -+ uint64_t ino; -+ union { -+ uint8_t oldnamelen; -+ uint64_t _padding; -+ }; -+ uint8_t oldname[]; -+} __aligned(8); -+ -+struct au_drinfo_fdata { -+ uint32_t magic; -+ struct au_drinfo drinfo; -+} __aligned(8); -+ -+#define AUFS_DRINFO_MAGIC_V1 ('a' << 24 | 'd' << 16 | 'r' << 8 | 0x01) -+/* future */ -+#define AUFS_DRINFO_MAGIC_V2 ('a' << 24 | 'd' << 16 | 'r' << 8 | 0x02) -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct aufs_wbr_fd { -+ uint32_t oflags; -+ int16_t brid; -+} __aligned(8); -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct aufs_ibusy { -+ uint64_t ino, h_ino; -+ int16_t bindex; -+} __aligned(8); -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* error code for move-down */ -+/* the actual message strings are implemented in aufs-util.git */ -+enum { -+ EAU_MVDOWN_OPAQUE = 1, -+ EAU_MVDOWN_WHITEOUT, -+ EAU_MVDOWN_UPPER, -+ EAU_MVDOWN_BOTTOM, -+ EAU_MVDOWN_NOUPPER, -+ EAU_MVDOWN_NOLOWERBR, -+ EAU_Last -+}; -+ -+/* flags for move-down */ -+#define AUFS_MVDOWN_DMSG 1 -+#define AUFS_MVDOWN_OWLOWER (1 << 1) /* overwrite lower */ -+#define AUFS_MVDOWN_KUPPER (1 << 2) /* keep upper */ -+#define AUFS_MVDOWN_ROLOWER (1 << 3) /* do even if lower is RO */ -+#define AUFS_MVDOWN_ROLOWER_R (1 << 4) /* did on lower RO */ -+#define AUFS_MVDOWN_ROUPPER (1 << 5) /* do even if upper is RO */ -+#define AUFS_MVDOWN_ROUPPER_R (1 << 6) /* did on upper RO */ -+#define AUFS_MVDOWN_BRID_UPPER (1 << 7) /* upper brid */ -+#define AUFS_MVDOWN_BRID_LOWER (1 << 8) /* lower brid */ -+#define AUFS_MVDOWN_FHSM_LOWER (1 << 9) /* find fhsm attr for lower */ -+#define AUFS_MVDOWN_STFS (1 << 10) /* req. stfs */ -+#define AUFS_MVDOWN_STFS_FAILED (1 << 11) /* output: stfs is unusable */ -+#define AUFS_MVDOWN_BOTTOM (1 << 12) /* output: no more lowers */ -+ -+/* index for move-down */ -+enum { -+ AUFS_MVDOWN_UPPER, -+ AUFS_MVDOWN_LOWER, -+ AUFS_MVDOWN_NARRAY -+}; -+ -+/* -+ * additional info of move-down -+ * number of free blocks and inodes. -+ * subset of struct kstatfs, but smaller and always 64bit. -+ */ -+struct aufs_stfs { -+ uint64_t f_blocks; -+ uint64_t f_bavail; -+ uint64_t f_files; -+ uint64_t f_ffree; -+}; -+ -+struct aufs_stbr { -+ int16_t brid; /* optional input */ -+ int16_t bindex; /* output */ -+ struct aufs_stfs stfs; /* output when AUFS_MVDOWN_STFS set */ -+} __aligned(8); -+ -+struct aufs_mvdown { -+ uint32_t flags; /* input/output */ -+ struct aufs_stbr stbr[AUFS_MVDOWN_NARRAY]; /* input/output */ -+ int8_t au_errno; /* output */ -+} __aligned(8); -+ -+/* ---------------------------------------------------------------------- */ -+ -+union aufs_brinfo { -+ /* PATH_MAX may differ between kernel-space and user-space */ -+ char _spacer[4096]; -+ struct { -+ int16_t id; -+ int perm; -+ char path[]; -+ }; -+} __aligned(8); -+ -+/* ---------------------------------------------------------------------- */ -+ -+#define AuCtlType 'A' -+#define AUFS_CTL_RDU _IOWR(AuCtlType, AuCtl_RDU, struct aufs_rdu) -+#define AUFS_CTL_RDU_INO _IOWR(AuCtlType, AuCtl_RDU_INO, struct aufs_rdu) -+#define AUFS_CTL_WBR_FD _IOW(AuCtlType, AuCtl_WBR_FD, \ -+ struct aufs_wbr_fd) -+#define AUFS_CTL_IBUSY _IOWR(AuCtlType, AuCtl_IBUSY, struct aufs_ibusy) -+#define AUFS_CTL_MVDOWN _IOWR(AuCtlType, AuCtl_MVDOWN, \ -+ struct aufs_mvdown) -+#define AUFS_CTL_BRINFO _IOW(AuCtlType, AuCtl_BR, union aufs_brinfo) -+#define AUFS_CTL_FHSM_FD _IOW(AuCtlType, AuCtl_FHSM_FD, int) -+ -+#endif /* __AUFS_TYPE_H__ */ diff --git a/kernel/kernel/files/patches/aufs6/lockdep-debug.patch b/kernel/kernel/files/patches/aufs6/lockdep-debug.patch index 70d0e70c..81033ab7 100644 --- a/kernel/kernel/files/patches/aufs6/lockdep-debug.patch +++ b/kernel/kernel/files/patches/aufs6/lockdep-debug.patch @@ -1,8 +1,8 @@ SPDX-License-Identifier: GPL-2.0 -aufs6.6.84 lockdep patch +aufs6.12 lockdep patch diff --git a/include/linux/lockdep_types.h b/include/linux/lockdep_types.h -index 2ebc323d345ae..9d7009190515d 100644 +index 9f361d3ab9d95..57efd6ffe7a44 100644 --- a/include/linux/lockdep_types.h +++ b/include/linux/lockdep_types.h @@ -12,7 +12,7 @@ diff --git a/kernel/kernel/files/patches/aufs6/tmpfs-idr.patch b/kernel/kernel/files/patches/aufs6/tmpfs-idr.patch index 5a418b2b..40cf01c2 100644 --- a/kernel/kernel/files/patches/aufs6/tmpfs-idr.patch +++ b/kernel/kernel/files/patches/aufs6/tmpfs-idr.patch @@ -1,10 +1,10 @@ SPDX-License-Identifier: GPL-2.0 diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h -index 134c686c8676..632d447caf64 100644 +index 515a9a6a3c6f..9de809dac3be 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h -@@ -51,10 +51,13 @@ struct shmem_quota_limits { +@@ -55,10 +55,13 @@ struct shmem_quota_limits { }; struct shmem_sb_info { @@ -21,10 +21,10 @@ index 134c686c8676..632d447caf64 100644 umode_t mode; /* Mount mode for root directory */ unsigned char huge; /* Whether to try for hugepages */ diff --git a/mm/shmem.c b/mm/shmem.c -index 283fb62084d4..3ecdfcad9159 100644 +index 568bb290bdce..f8869230f782 100644 --- a/mm/shmem.c +++ b/mm/shmem.c -@@ -111,7 +111,7 @@ struct shmem_falloc { +@@ -112,7 +112,7 @@ struct shmem_falloc { struct shmem_options { unsigned long long blocks; @@ -33,7 +33,7 @@ index 283fb62084d4..3ecdfcad9159 100644 struct mempolicy *mpol; kuid_t uid; kgid_t gid; -@@ -136,12 +136,14 @@ static unsigned long shmem_default_max_blocks(void) +@@ -144,12 +144,14 @@ static unsigned long shmem_default_max_blocks(void) return totalram_pages() / 2; } @@ -51,7 +51,7 @@ index 283fb62084d4..3ecdfcad9159 100644 } #endif -@@ -1284,6 +1286,11 @@ static void shmem_evict_inode(struct inode *inode) +@@ -1291,6 +1293,11 @@ static void shmem_evict_inode(struct inode *inode) } simple_xattrs_free(&info->xattrs, sbinfo->max_inodes ? &freed : NULL); @@ -63,7 +63,7 @@ index 283fb62084d4..3ecdfcad9159 100644 shmem_free_inode(inode->i_sb, freed); WARN_ON(inode->i_blocks); clear_inode(inode); -@@ -2525,6 +2532,25 @@ static struct inode *__shmem_get_inode(struct mnt_idmap *idmap, +@@ -2854,6 +2861,25 @@ static struct inode *__shmem_get_inode(struct mnt_idmap *idmap, break; } @@ -89,7 +89,7 @@ index 283fb62084d4..3ecdfcad9159 100644 lockdep_annotate_inode_mutex_key(inode); return inode; } -@@ -3772,8 +3798,7 @@ static struct dentry *shmem_get_parent(struct dentry *child) +@@ -4098,8 +4124,7 @@ static struct dentry *shmem_get_parent(struct dentry *child) static int shmem_match(struct inode *ino, void *vfh) { __u32 *fh = vfh; @@ -99,7 +99,7 @@ index 283fb62084d4..3ecdfcad9159 100644 return ino->i_ino == inum && fh[0] == ino->i_generation; } -@@ -3793,14 +3818,11 @@ static struct dentry *shmem_fh_to_dentry(struct super_block *sb, +@@ -4118,14 +4143,11 @@ static struct dentry *shmem_fh_to_dentry(struct super_block *sb, struct dentry *dentry = NULL; u64 inum; @@ -117,7 +117,7 @@ index 283fb62084d4..3ecdfcad9159 100644 if (inode) { dentry = shmem_find_alias(inode); iput(inode); -@@ -3812,30 +3834,15 @@ static struct dentry *shmem_fh_to_dentry(struct super_block *sb, +@@ -4137,30 +4159,15 @@ static struct dentry *shmem_fh_to_dentry(struct super_block *sb, static int shmem_encode_fh(struct inode *inode, __u32 *fh, int *len, struct inode *parent) { @@ -151,7 +151,7 @@ index 283fb62084d4..3ecdfcad9159 100644 return 1; } -@@ -3934,7 +3941,7 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param) +@@ -4259,7 +4266,7 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param) break; case Opt_nr_inodes: ctx->inodes = memparse(param->string, &rest); @@ -160,7 +160,7 @@ index 283fb62084d4..3ecdfcad9159 100644 goto bad_value; ctx->seen |= SHMEM_SEEN_INODES; break; -@@ -4220,7 +4227,7 @@ static int shmem_show_options(struct seq_file *seq, struct dentry *root) +@@ -4541,7 +4548,7 @@ static int shmem_show_options(struct seq_file *seq, struct dentry *root) if (sbinfo->max_blocks != shmem_default_max_blocks()) seq_printf(seq, ",size=%luk", K(sbinfo->max_blocks)); if (sbinfo->max_inodes != shmem_default_max_inodes()) @@ -169,7 +169,7 @@ index 283fb62084d4..3ecdfcad9159 100644 if (sbinfo->mode != (0777 | S_ISVTX)) seq_printf(seq, ",mode=%03ho", sbinfo->mode); if (!uid_eq(sbinfo->uid, GLOBAL_ROOT_UID)) -@@ -4274,6 +4281,8 @@ static void shmem_put_super(struct super_block *sb) +@@ -4613,6 +4620,8 @@ static void shmem_put_super(struct super_block *sb) #ifdef CONFIG_TMPFS_QUOTA shmem_disable_quotas(sb); #endif @@ -178,7 +178,7 @@ index 283fb62084d4..3ecdfcad9159 100644 free_percpu(sbinfo->ino_batch); percpu_counter_destroy(&sbinfo->used_blocks); mpol_put(sbinfo->mpol); -@@ -4318,9 +4327,11 @@ static int shmem_fill_super(struct super_block *sb, struct fs_context *fc) +@@ -4657,9 +4666,11 @@ static int shmem_fill_super(struct super_block *sb, struct fs_context *fc) #else sb->s_flags |= SB_NOUSER; #endif @@ -191,7 +191,7 @@ index 283fb62084d4..3ecdfcad9159 100644 if (sb->s_flags & SB_KERNMOUNT) { sbinfo->ino_batch = alloc_percpu(ino_t); if (!sbinfo->ino_batch) -@@ -4463,6 +4474,15 @@ static int shmem_error_remove_page(struct address_space *mapping, +@@ -4804,6 +4815,15 @@ static int shmem_error_remove_folio(struct address_space *mapping, return 0; } @@ -204,10 +204,10 @@ index 283fb62084d4..3ecdfcad9159 100644 + idr_destroy(&sbinfo->idr); +} + - const struct address_space_operations shmem_aops = { + static const struct address_space_operations shmem_aops = { .writepage = shmem_writepage, .dirty_folio = noop_dirty_folio, -@@ -4636,6 +4656,7 @@ void __init shmem_init(void) +@@ -4968,6 +4988,7 @@ void __init shmem_init(void) pr_err("Could not kern_mount tmpfs\n"); goto out1; } diff --git a/kernel/kernel/files/patches/aufs6/vfs-ino.patch b/kernel/kernel/files/patches/aufs6/vfs-ino.patch index 552f1bf2..6ff72c1a 100644 --- a/kernel/kernel/files/patches/aufs6/vfs-ino.patch +++ b/kernel/kernel/files/patches/aufs6/vfs-ino.patch @@ -1,10 +1,10 @@ SPDX-License-Identifier: GPL-2.0 diff --git a/fs/inode.c b/fs/inode.c -index 030e07b169c2..44c331163dd5 100644 +index 8dabb224f941..4f03eaa25cc2 100644 --- a/fs/inode.c +++ b/fs/inode.c -@@ -1015,6 +1015,8 @@ unsigned int get_next_ino(void) +@@ -1070,6 +1070,8 @@ unsigned int get_next_ino(void) unsigned int *p = &get_cpu_var(last_ino); unsigned int res = *p; @@ -13,7 +13,7 @@ index 030e07b169c2..44c331163dd5 100644 #ifdef CONFIG_SMP if (unlikely((res & (LAST_INO_BATCH-1)) == 0)) { static atomic_t shared_last_ino; -@@ -1027,7 +1029,7 @@ unsigned int get_next_ino(void) +@@ -1082,7 +1084,7 @@ unsigned int get_next_ino(void) res++; /* get_next_ino should not provide a 0 inode number */ if (unlikely(!res)) diff --git a/kernel/kernel/files/patches/linux/patch-6.12.40.xz b/kernel/kernel/files/patches/linux/patch-6.12.40.xz new file mode 100644 index 00000000..41c50b45 Binary files /dev/null and b/kernel/kernel/files/patches/linux/patch-6.12.40.xz differ diff --git a/kernel/kernel/files/patches/linux/patch-6.6.72.xz b/kernel/kernel/files/patches/linux/patch-6.6.72.xz deleted file mode 100644 index 4b4c0c40..00000000 Binary files a/kernel/kernel/files/patches/linux/patch-6.6.72.xz and /dev/null differ diff --git a/kernel/kernel/files/patches/linux/patch-6.6.83.xz b/kernel/kernel/files/patches/linux/patch-6.6.83.xz deleted file mode 100644 index 0bcac155..00000000 Binary files a/kernel/kernel/files/patches/linux/patch-6.6.83.xz and /dev/null differ diff --git a/kernel/kernel/files/patches/linux/patch-6.6.87.xz b/kernel/kernel/files/patches/linux/patch-6.6.87.xz deleted file mode 100644 index 945ed7ea..00000000 Binary files a/kernel/kernel/files/patches/linux/patch-6.6.87.xz and /dev/null differ diff --git a/kernel/kernel/files/patches/linux/patch-6.6.92.xz b/kernel/kernel/files/patches/linux/patch-6.6.92.xz deleted file mode 100644 index eae10c50..00000000 Binary files a/kernel/kernel/files/patches/linux/patch-6.6.92.xz and /dev/null differ diff --git a/kernel/kernel/files/patches/mageia/0001-Pull-device-0x0821-from-list-of-device-supported-by-.patch b/kernel/kernel/files/patches/mageia/0001-Pull-device-0x0821-from-list-of-device-supported-by-.patch new file mode 100644 index 00000000..d519e9f8 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/0001-Pull-device-0x0821-from-list-of-device-supported-by-.patch @@ -0,0 +1,28 @@ +From cfa62868adc134623104a759902a95bc71790614 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Giuseppe=20Ghib=C3=B2?= +Date: Sat, 16 Dec 2023 19:50:53 +0100 +Subject: [PATCH] Pull device 0x0821 from list of device supported by rtl8812au + drivers + +The Realtek device with ID 0x0821 seems better supported by upstream rtl8821ae +kernel module (see bug https://bugs.mageia.org/show_bug.cgi?id=31965). + +--- + drivers/staging/rtl8812au/os_dep/linux/usb_intf.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/staging/rtl8812au/os_dep/linux/usb_intf.c b/drivers/staging/rtl8812au/os_dep/linux/usb_intf.c +index be0f654f0..c019fa82b 100644 +--- a/drivers/staging/rtl8812au/os_dep/linux/usb_intf.c ++++ b/drivers/staging/rtl8812au/os_dep/linux/usb_intf.c +@@ -185,7 +185,6 @@ static struct usb_device_id rtw_usb_id_tbl[] = { + #ifdef CONFIG_RTL8821A + /*=== Realtek demoboard ===*/ + {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x0811), .driver_info = RTL8821}, /* Default ID */ +- {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x0821), .driver_info = RTL8821}, /* Default ID */ + {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8822), .driver_info = RTL8821}, /* Default ID */ + {USB_DEVICE(USB_VENDER_ID_REALTEK, 0xA811) , .driver_info = RTL8821},/* Default ID */ + {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0x0820, 0xff, 0xff, 0xff), .driver_info = RTL8821}, /* 8821AU */ +-- +2.41.0 + diff --git a/kernel/kernel/files/patches/mageia/0001-rtl8812au-add-missed-prototypes.patch b/kernel/kernel/files/patches/mageia/0001-rtl8812au-add-missed-prototypes.patch new file mode 100644 index 00000000..40392f51 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/0001-rtl8812au-add-missed-prototypes.patch @@ -0,0 +1,6262 @@ +From 292797fe6f0fda6ab984e68d07eb97d85daa4837 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Giuseppe=20Ghib=C3=B2?= +Date: Wed, 20 Nov 2024 22:23:47 +0100 +Subject: [PATCH] rtl8812au: add missed prototypes + +--- + .../staging/rtl8812au/core/efuse/rtw_efuse.c | 12 ++ + drivers/staging/rtl8812au/core/rtw_ap.c | 4 + + drivers/staging/rtl8812au/core/rtw_br_ext.c | 4 + + drivers/staging/rtl8812au/core/rtw_chplan.c | 3 +- + drivers/staging/rtl8812au/core/rtw_cmd.c | 12 ++ + .../staging/rtl8812au/core/rtw_ieee80211.c | 4 + + drivers/staging/rtl8812au/core/rtw_mi.c | 2 + + drivers/staging/rtl8812au/core/rtw_mlme.c | 5 + + drivers/staging/rtl8812au/core/rtw_mlme_ext.c | 30 ++++- + drivers/staging/rtl8812au/core/rtw_mp.c | 4 + + drivers/staging/rtl8812au/core/rtw_odm.c | 3 + + drivers/staging/rtl8812au/core/rtw_p2p.c | 12 ++ + drivers/staging/rtl8812au/core/rtw_pwrctrl.c | 2 + + drivers/staging/rtl8812au/core/rtw_recv.c | 27 ++++ + drivers/staging/rtl8812au/core/rtw_rf.c | 2 + + drivers/staging/rtl8812au/core/rtw_sreset.c | 3 + + drivers/staging/rtl8812au/core/rtw_sta_mgt.c | 4 + + drivers/staging/rtl8812au/core/rtw_vht.c | 3 + + .../staging/rtl8812au/core/rtw_wlan_util.c | 7 ++ + drivers/staging/rtl8812au/core/rtw_xmit.c | 5 + + drivers/staging/rtl8812au/hal/hal_com.c | 14 +++ + .../staging/rtl8812au/hal/hal_com_phycfg.c | 83 +++++++++++++ + drivers/staging/rtl8812au/hal/hal_dm.c | 7 +- + drivers/staging/rtl8812au/hal/hal_intf.c | 2 + + drivers/staging/rtl8812au/hal/hal_mp.c | 15 +++ + .../staging/rtl8812au/hal/led/hal_usb_led.c | 109 +++++++++++++++++ + .../rtl8812au/hal/phydm/halrf/halphyrf_ce.c | 3 + + .../staging/rtl8812au/hal/phydm/halrf/halrf.c | 4 + + .../rtl8812au/hal/phydm/halrf/halrf_debug.c | 3 + + .../rtl8812au/hal/phydm/halrf/halrf_kfree.c | 26 ++++ + .../hal/phydm/halrf/halrf_powertracking_ce.c | 2 + + .../hal/phydm/halrf/rtl8812a/halrf_8812a_ce.c | 23 ++++ + .../hal/phydm/halrf/rtl8814a/halrf_8814a_ce.c | 9 ++ + .../phydm/halrf/rtl8814a/halrf_iqk_8814a.c | 67 +++++++++- + .../phydm/halrf/rtl8821a/halrf_iqk_8821a_ce.c | 69 +++++++++++ + drivers/staging/rtl8812au/hal/phydm/phydm.c | 15 +++ + .../rtl8812au/hal/phydm/phydm_adaptivity.c | 11 ++ + .../rtl8812au/hal/phydm/phydm_adc_sampling.c | 5 + + .../staging/rtl8812au/hal/phydm/phydm_api.c | 16 +++ + .../rtl8812au/hal/phydm/phydm_beamforming.c | 107 ++++++++++++++++ + .../rtl8812au/hal/phydm/phydm_cck_pd.c | 5 + + .../staging/rtl8812au/hal/phydm/phydm_ccx.c | 24 ++++ + .../rtl8812au/hal/phydm/phydm_cfotracking.c | 3 + + .../staging/rtl8812au/hal/phydm/phydm_debug.c | 41 +++++++ + .../staging/rtl8812au/hal/phydm/phydm_dig.c | 23 ++++ + .../rtl8812au/hal/phydm/phydm_interface.c | 1 + + .../rtl8812au/hal/phydm/phydm_noisemonitor.c | 5 + + .../rtl8812au/hal/phydm/phydm_phystatus.c | 29 +++++ + .../rtl8812au/hal/phydm/phydm_rainfo.c | 16 +++ + .../rtl8812au/hal/phydm/phydm_rssi_monitor.c | 2 + + .../hal/phydm/rtl8821a/phydm_rtl8821a.c | 8 ++ + .../rtl8812au/hal/phydm/txbf/halcomtxbf.c | 16 +++ + .../rtl8812au/hal/phydm/txbf/haltxbf8814a.c | 4 + + .../rtl8812au/hal/phydm/txbf/haltxbfjaguar.c | 8 ++ + .../rtl8812au/hal/rtl8812a/rtl8812a_cmd.c | 13 ++ + .../hal/rtl8812a/rtl8812a_hal_init.c | 89 ++++++++++++++ + .../rtl8812au/hal/rtl8812a/rtl8812a_phycfg.c | 74 +++++++++++ + .../rtl8812au/hal/rtl8812a/usb/usb_halinit.c | 65 +++++++++- + .../hal/rtl8812a/usb/usb_ops_linux.c | 1 + + .../rtl8812au/hal/rtl8814a/rtl8814a_cmd.c | 15 +++ + .../hal/rtl8814a/rtl8814a_hal_init.c | 115 ++++++++++++++++++ + .../rtl8812au/hal/rtl8814a/rtl8814a_phycfg.c | 67 +++++++++- + .../rtl8812au/hal/rtl8814a/usb/usb_halinit.c | 58 ++++++++- + .../hal/rtl8814a/usb/usb_ops_linux.c | 1 + + .../rtl8812au/os_dep/linux/ioctl_cfg80211.c | 12 ++ + .../rtl8812au/os_dep/linux/ioctl_linux.c | 2 + + .../staging/rtl8812au/os_dep/linux/os_intfs.c | 18 ++- + .../rtl8812au/os_dep/linux/rtw_android.c | 11 ++ + .../staging/rtl8812au/os_dep/linux/rtw_proc.c | 13 ++ + .../staging/rtl8812au/os_dep/linux/usb_intf.c | 1 + + .../rtl8812au/os_dep/linux/usb_ops_linux.c | 1 + + .../rtl8812au/os_dep/linux/xmit_linux.c | 1 + + .../staging/rtl8812au/os_dep/osdep_service.c | 1 + + .../staging/rtl8812au/platform/platform_ops.c | 2 + + 74 files changed, 1467 insertions(+), 16 deletions(-) + +diff --git a/drivers/staging/rtl8812au/core/efuse/rtw_efuse.c b/drivers/staging/rtl8812au/core/efuse/rtw_efuse.c +index cca02619e..6587eb7fe 100644 +--- a/drivers/staging/rtl8812au/core/efuse/rtw_efuse.c ++++ b/drivers/staging/rtl8812au/core/efuse/rtw_efuse.c +@@ -793,6 +793,9 @@ void rtw_efuse_analyze(PADAPTER padapter, u8 Type, u8 Fake) + rtw_mfree((u8 *)eFuseWord, EFUSE_MAX_SECTION_NUM * (EFUSE_MAX_WORD_UNIT * 2)); + } + ++VOID efuse_PreUpdateAction( ++ PADAPTER pAdapter, ++ pu4Byte BackupRegs); + VOID efuse_PreUpdateAction( + PADAPTER pAdapter, + pu4Byte BackupRegs) +@@ -822,6 +825,9 @@ VOID efuse_PreUpdateAction( + } + + ++VOID efuse_PostUpdateAction( ++ PADAPTER pAdapter, ++ pu4Byte BackupRegs); + VOID efuse_PostUpdateAction( + PADAPTER pAdapter, + pu4Byte BackupRegs) +@@ -2214,6 +2220,12 @@ Efuse_PgPacketWrite(IN PADAPTER pAdapter, + } + + ++int ++Efuse_PgPacketWrite_BT(IN PADAPTER pAdapter, ++ IN u8 offset, ++ IN u8 word_en, ++ IN u8 *data, ++ IN BOOLEAN bPseudoTest); + int + Efuse_PgPacketWrite_BT(IN PADAPTER pAdapter, + IN u8 offset, +diff --git a/drivers/staging/rtl8812au/core/rtw_ap.c b/drivers/staging/rtl8812au/core/rtw_ap.c +index 1912448ba..7c3cc03e8 100644 +--- a/drivers/staging/rtl8812au/core/rtw_ap.c ++++ b/drivers/staging/rtl8812au/core/rtw_ap.c +@@ -940,6 +940,7 @@ void rtw_update_bmc_sta_tx_rate(_adapter *adapter) + } + #endif + ++void rtw_init_bmc_sta_tx_rate(_adapter *padapter, struct sta_info *psta); + void rtw_init_bmc_sta_tx_rate(_adapter *padapter, struct sta_info *psta) + { + #ifdef CONFIG_BMC_TX_LOW_RATE +@@ -1027,6 +1028,7 @@ void update_bmc_sta(_adapter *padapter) + } + + #if defined(CONFIG_80211N_HT) && defined(CONFIG_BEAMFORMING) ++void update_sta_info_apmode_ht_bf_cap(_adapter *padapter, struct sta_info *psta); + void update_sta_info_apmode_ht_bf_cap(_adapter *padapter, struct sta_info *psta) + { + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); +@@ -2856,6 +2858,7 @@ int rtw_ap_set_wep_key(_adapter *padapter, u8 *key, u8 keylen, int keyid, u8 set + return rtw_ap_set_key(padapter, key, alg, keyid, set_tx); + } + ++u8 rtw_ap_bmc_frames_hdl(_adapter *padapter); + u8 rtw_ap_bmc_frames_hdl(_adapter *padapter) + { + #define HIQ_XMIT_COUNTS (6) +@@ -4182,6 +4185,7 @@ void start_ap_mode(_adapter *padapter) + + } + ++void rtw_ap_bcmc_sta_flush(_adapter *padapter); + void rtw_ap_bcmc_sta_flush(_adapter *padapter) + { + #ifdef CONFIG_CONCURRENT_MODE +diff --git a/drivers/staging/rtl8812au/core/rtw_br_ext.c b/drivers/staging/rtl8812au/core/rtw_br_ext.c +index c80474e8b..955a50912 100644 +--- a/drivers/staging/rtl8812au/core/rtw_br_ext.c ++++ b/drivers/staging/rtl8812au/core/rtw_br_ext.c +@@ -668,6 +668,7 @@ void nat25_db_cleanup(_adapter *priv) + } + + ++void nat25_db_expire(_adapter *priv); + void nat25_db_expire(_adapter *priv) + { + int i; +@@ -784,6 +785,7 @@ static int checkIPMcAndReplace(_adapter *priv, struct sk_buff *skb, unsigned int + } + #endif + ++int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method); + int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method) + { + unsigned short protocol; +@@ -1193,6 +1195,7 @@ int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method) + } + + ++int nat25_handle_frame(_adapter *priv, struct sk_buff *skb); + int nat25_handle_frame(_adapter *priv, struct sk_buff *skb) + { + #ifdef BR_EXT_DEBUG +@@ -1324,6 +1327,7 @@ struct dhcpMessage { + u_int8_t options[308]; /* 312 - cookie */ + }; + ++void dhcp_flag_bcast(_adapter *priv, struct sk_buff *skb); + void dhcp_flag_bcast(_adapter *priv, struct sk_buff *skb) + { + if (skb == NULL) +diff --git a/drivers/staging/rtl8812au/core/rtw_chplan.c b/drivers/staging/rtl8812au/core/rtw_chplan.c +index 34263a5fd..afefe957a 100644 +--- a/drivers/staging/rtl8812au/core/rtw_chplan.c ++++ b/drivers/staging/rtl8812au/core/rtw_chplan.c +@@ -404,7 +404,8 @@ bool rtw_chplan_is_empty(u8 id) + return _FALSE; + } + +-bool rtw_regsty_is_excl_chs(struct registry_priv *regsty, u8 ch) ++bool rtw_regsty_is_excl_chs(struct registry_priv *regsty, u8 ch); ++bool rtw_regsty_is_excl_chs(struct registry_priv *regsty, u8 ch) + { + int i; + +diff --git a/drivers/staging/rtl8812au/core/rtw_cmd.c b/drivers/staging/rtl8812au/core/rtw_cmd.c +index ca4e35b9b..62bd059c6 100644 +--- a/drivers/staging/rtl8812au/core/rtw_cmd.c ++++ b/drivers/staging/rtl8812au/core/rtw_cmd.c +@@ -2018,6 +2018,7 @@ u8 rtw_reset_securitypriv_cmd(_adapter *padapter) + + } + ++void free_assoc_resources_hdl(_adapter *padapter, u8 lock_scanned_queue); + void free_assoc_resources_hdl(_adapter *padapter, u8 lock_scanned_queue) + { + rtw_free_assoc_resources(padapter, lock_scanned_queue); +@@ -2177,6 +2178,7 @@ u8 rtw_set_chbw_cmd(_adapter *padapter, u8 ch, u8 bw, u8 ch_offset, u8 flags) + return res; + } + ++u8 _rtw_set_chplan_cmd(_adapter *adapter, int flags, u8 chplan, const struct country_chplan *country_ent, u8 swconfig); + u8 _rtw_set_chplan_cmd(_adapter *adapter, int flags, u8 chplan, const struct country_chplan *country_ent, u8 swconfig) + { + struct cmd_obj *cmdobj; +@@ -2444,6 +2446,7 @@ u8 rtw_periodic_tsf_update_end_cmd(_adapter *adapter) + exit: + return res; + } ++u8 rtw_ssmps_wk_hdl(_adapter *adapter, struct ssmps_cmd_parm *ssmp_param); + u8 rtw_ssmps_wk_hdl(_adapter *adapter, struct ssmps_cmd_parm *ssmp_param) + { + u8 res = _SUCCESS; +@@ -3232,6 +3235,7 @@ void rtw_iface_dynamic_chk_wk_hdl(_adapter *padapter) + #endif + + } ++void rtw_dynamic_chk_wk_hdl(_adapter *padapter); + void rtw_dynamic_chk_wk_hdl(_adapter *padapter) + { + rtw_mi_dynamic_chk_wk_hdl(padapter); +@@ -3609,6 +3613,7 @@ u8 rtw_antenna_select_cmd(_adapter *padapter, u8 antenna, u8 enqueue) + } + #endif + ++void rtw_dm_ra_mask_hdl(_adapter *padapter, struct sta_info *psta); + void rtw_dm_ra_mask_hdl(_adapter *padapter, struct sta_info *psta) + { + if (psta) +@@ -3651,12 +3656,14 @@ u8 rtw_dm_ra_mask_wk_cmd(_adapter *padapter, u8 *psta) + + } + ++void power_saving_wk_hdl(_adapter *padapter); + void power_saving_wk_hdl(_adapter *padapter) + { + rtw_ps_processor(padapter); + } + + /* add for CONFIG_IEEE80211W, none 11w can use it */ ++void reset_securitypriv_hdl(_adapter *padapter); + void reset_securitypriv_hdl(_adapter *padapter) + { + rtw_reset_securitypriv(padapter); +@@ -4903,6 +4910,7 @@ inline u8 rtw_customer_str_write_cmd(_adapter *adapter, const u8 *cstr) + } + #endif /* CONFIG_RTW_CUSTOMER_STR */ + ++u8 rtw_c2h_wk_cmd(PADAPTER padapter, u8 *pbuf, u16 length, u8 type); + u8 rtw_c2h_wk_cmd(PADAPTER padapter, u8 *pbuf, u16 length, u8 type) + { + struct cmd_obj *ph2c; +@@ -5021,6 +5029,7 @@ s32 c2h_evt_hdl(_adapter *adapter, u8 *c2h_evt, c2h_id_filter filter) + } + #endif /* CONFIG_FW_C2H_REG */ + ++u8 session_tracker_cmd(_adapter *adapter, u8 cmd, struct sta_info *sta, u8 *local_naddr, u8 *local_port, u8 *remote_naddr, u8 *remote_port); + u8 session_tracker_cmd(_adapter *adapter, u8 cmd, struct sta_info *sta, u8 *local_naddr, u8 *local_port, u8 *remote_naddr, u8 *remote_port) + { + struct cmd_priv *cmdpriv = &adapter->cmdpriv; +@@ -5087,6 +5096,7 @@ inline u8 session_tracker_del_cmd(_adapter *adapter, struct sta_info *sta, u8 *l + return session_tracker_cmd(adapter, ST_CMD_DEL, sta, local_naddr, local_port, remote_naddr, remote_port); + } + ++void session_tracker_chk_for_sta(_adapter *adapter, struct sta_info *sta); + void session_tracker_chk_for_sta(_adapter *adapter, struct sta_info *sta) + { + struct st_ctl_t *st_ctl = &sta->st_ctl; +@@ -5169,6 +5179,7 @@ void session_tracker_chk_for_sta(_adapter *adapter, struct sta_info *sta) + return; + } + ++void session_tracker_chk_for_adapter(_adapter *adapter); + void session_tracker_chk_for_adapter(_adapter *adapter) + { + struct sta_priv *stapriv = &adapter->stapriv; +@@ -5201,6 +5212,7 @@ void session_tracker_chk_for_adapter(_adapter *adapter) + #endif + } + ++void session_tracker_cmd_hdl(_adapter *adapter, struct st_cmd_parm *parm); + void session_tracker_cmd_hdl(_adapter *adapter, struct st_cmd_parm *parm) + { + u8 cmd = parm->cmd; +diff --git a/drivers/staging/rtl8812au/core/rtw_ieee80211.c b/drivers/staging/rtl8812au/core/rtw_ieee80211.c +index 01bf7ffb4..ddfe0b921 100644 +--- a/drivers/staging/rtl8812au/core/rtw_ieee80211.c ++++ b/drivers/staging/rtl8812au/core/rtw_ieee80211.c +@@ -672,6 +672,7 @@ int rtw_get_wpa2_cipher_suite(u8 *s) + return 0; + } + ++u32 rtw_get_akm_suite_bitmap(u8 *s); + u32 rtw_get_akm_suite_bitmap(u8 *s) + { + if (_rtw_memcmp(s, WLAN_AKM_8021X, RSN_SELECTOR_LEN) == _TRUE) +@@ -1666,6 +1667,7 @@ void dump_ht_cap_ie_content(void *sel, const u8 *buf, u32 buf_len) + , HT_SUP_MCS_SET_ARG(HT_CAP_ELE_SUP_MCS_SET(buf))); + } + ++void dump_ht_cap_ie(void *sel, const u8 *ie, u32 ie_len); + void dump_ht_cap_ie(void *sel, const u8 *ie, u32 ie_len) + { + const u8 *ht_cap_ie; +@@ -1685,6 +1687,7 @@ const char *const _ht_sc_offset_str[] = { + "SCB", + }; + ++void dump_ht_op_ie_content(void *sel, const u8 *buf, u32 buf_len); + void dump_ht_op_ie_content(void *sel, const u8 *buf, u32 buf_len) + { + if (buf_len != HT_OP_IE_LEN) { +@@ -1699,6 +1702,7 @@ void dump_ht_op_ie_content(void *sel, const u8 *buf, u32 buf_len) + ); + } + ++void dump_ht_op_ie(void *sel, const u8 *ie, u32 ie_len); + void dump_ht_op_ie(void *sel, const u8 *ie, u32 ie_len) + { + const u8 *ht_op_ie; +diff --git a/drivers/staging/rtl8812au/core/rtw_mi.c b/drivers/staging/rtl8812au/core/rtw_mi.c +index 2a9added7..409c9d2ca 100644 +--- a/drivers/staging/rtl8812au/core/rtw_mi.c ++++ b/drivers/staging/rtl8812au/core/rtw_mi.c +@@ -883,6 +883,7 @@ void rtw_mi_buddy_xmit_tasklet_schedule(_adapter *padapter) + } + #endif + ++u8 _rtw_mi_busy_traffic_check(_adapter *padapter, void *data); + u8 _rtw_mi_busy_traffic_check(_adapter *padapter, void *data) + { + u32 passtime; +@@ -1342,6 +1343,7 @@ _adapter *rtw_get_iface_by_hwport(_adapter *padapter, u8 hw_port) + /*#define CONFIG_SKB_ALLOCATED*/ + #define DBG_SKB_PROCESS + #ifdef DBG_SKB_PROCESS ++void rtw_dbg_skb_process(_adapter *padapter, union recv_frame *precvframe, union recv_frame *pcloneframe); + void rtw_dbg_skb_process(_adapter *padapter, union recv_frame *precvframe, union recv_frame *pcloneframe) + { + _pkt *pkt_copy, *pkt_org; +diff --git a/drivers/staging/rtl8812au/core/rtw_mlme.c b/drivers/staging/rtl8812au/core/rtw_mlme.c +index 573358826..daeb92407 100644 +--- a/drivers/staging/rtl8812au/core/rtw_mlme.c ++++ b/drivers/staging/rtl8812au/core/rtw_mlme.c +@@ -20,6 +20,7 @@ extern void indicate_wx_scan_complete_event(_adapter *padapter); + extern u8 rtw_do_join(_adapter *padapter); + + ++void rtw_init_mlme_timer(_adapter *padapter); + void rtw_init_mlme_timer(_adapter *padapter) + { + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; +@@ -37,6 +38,7 @@ void rtw_init_mlme_timer(_adapter *padapter) + #endif + } + ++sint _rtw_init_mlme_priv(_adapter *padapter); + sint _rtw_init_mlme_priv(_adapter *padapter) + { + sint i; +@@ -295,6 +297,7 @@ int rtw_mlme_update_wfd_ie_data(struct mlme_priv *mlme, u8 type, u8 *ie, u32 ie_ + } + #endif /* defined(CONFIG_WFD) && defined(CONFIG_IOCTL_CFG80211) */ + ++void _rtw_free_mlme_priv(struct mlme_priv *pmlmepriv); + void _rtw_free_mlme_priv(struct mlme_priv *pmlmepriv) + { + _adapter *adapter = mlme_to_adapter(pmlmepriv); +@@ -314,6 +317,7 @@ void _rtw_free_mlme_priv(struct mlme_priv *pmlmepriv) + return; + } + ++sint _rtw_enqueue_network(_queue *queue, struct wlan_network *pnetwork); + sint _rtw_enqueue_network(_queue *queue, struct wlan_network *pnetwork) + { + _irqL irqL; +@@ -1633,6 +1637,7 @@ static void free_scanqueue(struct mlme_priv *pmlmepriv) + + } + ++void rtw_reset_rx_info(_adapter *adapter); + void rtw_reset_rx_info(_adapter *adapter) + { + struct recv_priv *precvpriv = &adapter->recvpriv; +diff --git a/drivers/staging/rtl8812au/core/rtw_mlme_ext.c b/drivers/staging/rtl8812au/core/rtw_mlme_ext.c +index 527e06dd5..0d79cde59 100644 +--- a/drivers/staging/rtl8812au/core/rtw_mlme_ext.c ++++ b/drivers/staging/rtl8812au/core/rtw_mlme_ext.c +@@ -1106,6 +1106,7 @@ static void init_mlme_ext_priv_value(_adapter *padapter) + #endif /* ROKU_PRIVATE */ + } + ++void init_mlme_ext_timer(_adapter *padapter); + void init_mlme_ext_timer(_adapter *padapter) + { + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; +@@ -1380,6 +1381,7 @@ void mgt_dispatcher(_adapter *padapter, union recv_frame *precv_frame) + } + + #ifdef CONFIG_P2P ++u32 p2p_listen_state_process(_adapter *padapter, unsigned char *da); + u32 p2p_listen_state_process(_adapter *padapter, unsigned char *da) + { + bool response = _TRUE; +@@ -3081,7 +3083,8 @@ unsigned int OnAtim(_adapter *padapter, union recv_frame *precv_frame) + return _SUCCESS; + } + +-unsigned int on_action_spct_ch_switch(_adapter *padapter, struct sta_info *psta, u8 *ies, uint ies_len) ++unsigned int on_action_spct_ch_switch(_adapter *padapter, struct sta_info *psta, u8 *ies, uint ies_len); ++unsigned int on_action_spct_ch_switch(_adapter *padapter, struct sta_info *psta, u8 *ies, uint ies_len) + { + unsigned int ret = _FAIL; + struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv; +@@ -4134,6 +4137,7 @@ void issue_p2p_GO_request(_adapter *padapter, u8 *raddr) + } + + ++void issue_p2p_GO_response(_adapter *padapter, u8 *raddr, u8 *frame_body, uint len, u8 result); + void issue_p2p_GO_response(_adapter *padapter, u8 *raddr, u8 *frame_body, uint len, u8 result) + { + struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list); +@@ -4556,6 +4560,7 @@ void issue_p2p_GO_response(_adapter *padapter, u8 *raddr, u8 *frame_body, uint l + + } + ++void issue_p2p_GO_confirm(_adapter *padapter, u8 *raddr, u8 result); + void issue_p2p_GO_confirm(_adapter *padapter, u8 *raddr, u8 result) + { + +@@ -5434,6 +5439,7 @@ void issue_p2p_provision_request(_adapter *padapter, u8 *pssid, u8 ussidlen, u8 + } + + ++u8 is_matched_in_profilelist(u8 *peermacaddr, struct profile_info *profileinfo); + u8 is_matched_in_profilelist(u8 *peermacaddr, struct profile_info *profileinfo) + { + u8 i, match_result = 0; +@@ -5786,6 +5792,7 @@ void issue_probersp_p2p(_adapter *padapter, unsigned char *da) + + } + ++int _issue_probereq_p2p(_adapter *padapter, u8 *da, int wait_ack); + int _issue_probereq_p2p(_adapter *padapter, u8 *da, int wait_ack) + { + int ret = _FAIL; +@@ -6163,6 +6170,7 @@ int issue_probereq_p2p_ex(_adapter *adapter, u8 *da, int try_cnt, int wait_ms) + + #endif /* CONFIG_P2P */ + ++s32 rtw_action_public_decache(union recv_frame *rframe, u8 token_offset); + s32 rtw_action_public_decache(union recv_frame *rframe, u8 token_offset) + { + _adapter *adapter = rframe->u.hdr.adapter; +@@ -6188,7 +6196,8 @@ s32 rtw_action_public_decache(union recv_frame *rframe, u8 token_offset) + return _SUCCESS; + } + +-unsigned int on_action_public_p2p(union recv_frame *precv_frame) ++unsigned int on_action_public_p2p(union recv_frame *precv_frame); ++unsigned int on_action_public_p2p(union recv_frame *precv_frame) + { + _adapter *padapter = precv_frame->u.hdr.adapter; + u8 *pframe = precv_frame->u.hdr.rx_data; +@@ -6564,6 +6573,7 @@ unsigned int on_action_public_p2p(union recv_frame *precv_frame) + return _SUCCESS; + } + ++unsigned int on_action_public_vendor(union recv_frame *precv_frame); + unsigned int on_action_public_vendor(union recv_frame *precv_frame) + { + unsigned int ret = _FAIL; +@@ -6594,6 +6604,7 @@ unsigned int on_action_public_vendor(union recv_frame *precv_frame) + return ret; + } + ++unsigned int on_action_public_default(union recv_frame *precv_frame, u8 action); + unsigned int on_action_public_default(union recv_frame *precv_frame, u8 action) + { + unsigned int ret = _FAIL; +@@ -7462,6 +7473,7 @@ unsigned int DoReserved(_adapter *padapter, union recv_frame *precv_frame) + return _SUCCESS; + } + ++struct xmit_frame *_alloc_mgtxmitframe(struct xmit_priv *pxmitpriv, bool once); + struct xmit_frame *_alloc_mgtxmitframe(struct xmit_priv *pxmitpriv, bool once) + { + struct xmit_frame *pmgntframe; +@@ -7762,6 +7774,7 @@ s32 dump_mgntframe_and_wait_ack(_adapter *padapter, struct xmit_frame *pmgntfram + } + + ++int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode); + int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode) + { + u8 *ssid_ie; +@@ -8399,6 +8412,7 @@ void issue_probersp(_adapter *padapter, unsigned char *da, u8 is_valid_p2p_probe + + } + ++int _issue_probereq(_adapter *padapter, const NDIS_802_11_SSID *pssid, const u8 *da, u8 ch, bool append_wps, int wait_ack); + int _issue_probereq(_adapter *padapter, const NDIS_802_11_SSID *pssid, const u8 *da, u8 ch, bool append_wps, int wait_ack) + { + int ret = _FAIL; +@@ -10560,6 +10574,7 @@ void issue_action_BSSCoexistPacket(_adapter *padapter) + } + + /* Spatial Multiplexing Powersave (SMPS) action frame */ ++int _issue_action_SM_PS(_adapter *padapter , unsigned char *raddr , u8 NewMimoPsMode , u8 wait_ack); + int _issue_action_SM_PS(_adapter *padapter , unsigned char *raddr , u8 NewMimoPsMode , u8 wait_ack) + { + +@@ -12591,6 +12606,7 @@ When station does not receive any packet in MAX_CONTINUAL_NORXPACKET_COUNT*2 sec + recipient station will teardown the block ack by issuing DELBA frame. + + *********************************************************************/ ++void rtw_delba_check(_adapter *padapter, struct sta_info *psta, u8 from_timer); + void rtw_delba_check(_adapter *padapter, struct sta_info *psta, u8 from_timer) + { + int i = 0; +@@ -12629,6 +12645,7 @@ void rtw_delba_check(_adapter *padapter, struct sta_info *psta, u8 from_timer) + } + } + ++u8 chk_ap_is_alive(_adapter *padapter, struct sta_info *psta); + u8 chk_ap_is_alive(_adapter *padapter, struct sta_info *psta) + { + u8 ret = _FALSE; +@@ -12669,6 +12686,7 @@ u8 chk_ap_is_alive(_adapter *padapter, struct sta_info *psta) + return ret; + } + ++u8 chk_adhoc_peer_is_alive(struct sta_info *psta); + u8 chk_adhoc_peer_is_alive(struct sta_info *psta) + { + u8 ret = _TRUE; +@@ -13210,6 +13228,7 @@ void addba_timer_hdl(void *ctx) + } + + #ifdef CONFIG_IEEE80211W ++void report_sta_timeout_event(_adapter *padapter, u8 *MacAddr, unsigned short reason); + void report_sta_timeout_event(_adapter *padapter, u8 *MacAddr, unsigned short reason) + { + struct cmd_obj *pcmd_obj; +@@ -13267,6 +13286,7 @@ void report_sta_timeout_event(_adapter *padapter, u8 *MacAddr, unsigned short re + return; + } + ++void clnt_sa_query_timeout(_adapter *padapter); + void clnt_sa_query_timeout(_adapter *padapter) + { + struct mlme_ext_priv *mlmeext = &(padapter->mlmeextpriv); +@@ -14253,6 +14273,7 @@ static bool scan_abort_hdl(_adapter *adapter) + return ret; + } + ++u8 rtw_scan_sparse(_adapter *adapter, struct rtw_ieee80211_channel *ch, u8 ch_num); + u8 rtw_scan_sparse(_adapter *adapter, struct rtw_ieee80211_channel *ch, u8 ch_num) + { + /* interval larger than this is treated as backgroud scan */ +@@ -14357,6 +14378,7 @@ u8 rtw_scan_sparse(_adapter *adapter, struct rtw_ieee80211_channel *ch, u8 ch_nu + } + + #ifdef CONFIG_SCAN_BACKOP ++u8 rtw_scan_backop_decision(_adapter *adapter); + u8 rtw_scan_backop_decision(_adapter *adapter) + { + struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv; +@@ -14772,6 +14794,7 @@ void site_survey(_adapter *padapter, u8 survey_channel, RT_SCAN_TYPE ScanType) + return; + } + ++void survey_done_set_ch_bw(_adapter *padapter); + void survey_done_set_ch_bw(_adapter *padapter) + { + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; +@@ -14842,6 +14865,7 @@ void survey_done_set_ch_bw(_adapter *padapter) + * + * Returns: 0: no ps announcement is doing. 1: ps announcement is doing + */ ++u8 rtw_ps_annc(_adapter *adapter, bool ps); + u8 rtw_ps_annc(_adapter *adapter, bool ps) + { + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); +@@ -14931,6 +14955,7 @@ void rtw_back_opch(_adapter *adapter) + _exit_critical_mutex(&rfctl->offch_mutex, NULL); + } + ++void sitesurvey_set_igi(_adapter *adapter); + void sitesurvey_set_igi(_adapter *adapter) + { + struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv; +@@ -14991,6 +15016,7 @@ void sitesurvey_set_igi(_adapter *adapter) + break; + } + } ++void sitesurvey_set_msr(_adapter *adapter, bool enter); + void sitesurvey_set_msr(_adapter *adapter, bool enter) + { + u8 network_type; +diff --git a/drivers/staging/rtl8812au/core/rtw_mp.c b/drivers/staging/rtl8812au/core/rtw_mp.c +index bb7f78a4c..8d4966e32 100644 +--- a/drivers/staging/rtl8812au/core/rtw_mp.c ++++ b/drivers/staging/rtl8812au/core/rtw_mp.c +@@ -362,6 +362,7 @@ static VOID PHY_SetRFPathSwitch_default( + } + #endif + ++void mpt_InitHWConfig(PADAPTER Adapter); + void mpt_InitHWConfig(PADAPTER Adapter) + { + PHAL_DATA_TYPE hal; +@@ -1187,6 +1188,7 @@ int SetTxPower(PADAPTER pAdapter) + return _TRUE; + } + ++void SetTxAGCOffset(PADAPTER pAdapter, u32 ulTxAGCOffset); + void SetTxAGCOffset(PADAPTER pAdapter, u32 ulTxAGCOffset) + { + u32 TxAGCOffset_B, TxAGCOffset_C, TxAGCOffset_D, tmpAGC; +@@ -1483,6 +1485,7 @@ void fill_tx_desc_8188e(PADAPTER padapter) + #endif + + #if defined(CONFIG_RTL8814A) ++void fill_tx_desc_8814a(PADAPTER padapter); + void fill_tx_desc_8814a(PADAPTER padapter) + { + struct mp_priv *pmp_priv = &padapter->mppriv; +@@ -1541,6 +1544,7 @@ void fill_tx_desc_8814a(PADAPTER padapter) + #endif + + #if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) ++void fill_tx_desc_8812a(PADAPTER padapter); + void fill_tx_desc_8812a(PADAPTER padapter) + { + struct mp_priv *pmp_priv = &padapter->mppriv; +diff --git a/drivers/staging/rtl8812au/core/rtw_odm.c b/drivers/staging/rtl8812au/core/rtw_odm.c +index 4e1151d51..336dd9236 100644 +--- a/drivers/staging/rtl8812au/core/rtw_odm.c ++++ b/drivers/staging/rtl8812au/core/rtw_odm.c +@@ -64,6 +64,7 @@ void rtw_odm_init_ic_type(_adapter *adapter) + odm_cmn_info_init(odm, ODM_CMNINFO_IC_TYPE, ic_type); + } + ++void rtw_odm_adaptivity_ver_msg(void *sel, _adapter *adapter); + void rtw_odm_adaptivity_ver_msg(void *sel, _adapter *adapter) + { + RTW_PRINT_SEL(sel, "ADAPTIVITY_VERSION "ADAPTIVITY_VERSION"\n"); +@@ -72,6 +73,7 @@ void rtw_odm_adaptivity_ver_msg(void *sel, _adapter *adapter) + #define RTW_ADAPTIVITY_EN_DISABLE 0 + #define RTW_ADAPTIVITY_EN_ENABLE 1 + ++void rtw_odm_adaptivity_en_msg(void *sel, _adapter *adapter); + void rtw_odm_adaptivity_en_msg(void *sel, _adapter *adapter) + { + struct registry_priv *regsty = &adapter->registrypriv; +@@ -89,6 +91,7 @@ void rtw_odm_adaptivity_en_msg(void *sel, _adapter *adapter) + #define RTW_ADAPTIVITY_MODE_NORMAL 0 + #define RTW_ADAPTIVITY_MODE_CARRIER_SENSE 1 + ++void rtw_odm_adaptivity_mode_msg(void *sel, _adapter *adapter); + void rtw_odm_adaptivity_mode_msg(void *sel, _adapter *adapter) + { + struct registry_priv *regsty = &adapter->registrypriv; +diff --git a/drivers/staging/rtl8812au/core/rtw_p2p.c b/drivers/staging/rtl8812au/core/rtw_p2p.c +index f66fa7155..167dd067f 100644 +--- a/drivers/staging/rtl8812au/core/rtw_p2p.c ++++ b/drivers/staging/rtl8812au/core/rtw_p2p.c +@@ -18,6 +18,7 @@ + + #ifdef CONFIG_P2P + ++int rtw_p2p_is_channel_list_ok(u8 desired_ch, u8 *ch_list, u8 ch_cnt); + int rtw_p2p_is_channel_list_ok(u8 desired_ch, u8 *ch_list, u8 ch_cnt) + { + int found = 0, i = 0; +@@ -31,6 +32,7 @@ int rtw_p2p_is_channel_list_ok(u8 desired_ch, u8 *ch_list, u8 ch_cnt) + return found ; + } + ++int is_any_client_associated(_adapter *padapter); + int is_any_client_associated(_adapter *padapter) + { + return padapter->stapriv.asoc_list_cnt ? _TRUE : _FALSE; +@@ -2551,6 +2553,7 @@ u8 process_p2p_provdisc_resp(struct wifidirect_info *pwdinfo, u8 *pframe) + return _TRUE; + } + ++u8 rtw_p2p_get_peer_ch_list(struct wifidirect_info *pwdinfo, u8 *ch_content, u8 ch_cnt, u8 *peer_ch_list); + u8 rtw_p2p_get_peer_ch_list(struct wifidirect_info *pwdinfo, u8 *ch_content, u8 ch_cnt, u8 *peer_ch_list) + { + u8 i = 0, j = 0; +@@ -2573,6 +2576,7 @@ u8 rtw_p2p_get_peer_ch_list(struct wifidirect_info *pwdinfo, u8 *ch_content, u8 + return ch_no; + } + ++u8 rtw_p2p_ch_inclusion(_adapter *adapter, u8 *peer_ch_list, u8 peer_ch_num, u8 *ch_list_inclusioned); + u8 rtw_p2p_ch_inclusion(_adapter *adapter, u8 *peer_ch_list, u8 peer_ch_num, u8 *ch_list_inclusioned) + { + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); +@@ -3068,6 +3072,7 @@ u8 process_p2p_presence_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint le + return _TRUE; + } + ++void find_phase_handler(_adapter *padapter); + void find_phase_handler(_adapter *padapter) + { + struct wifidirect_info *pwdinfo = &padapter->wdinfo; +@@ -3093,6 +3098,7 @@ void find_phase_handler(_adapter *padapter) + + void p2p_concurrent_handler(_adapter *padapter); + ++void restore_p2p_state_handler(_adapter *padapter); + void restore_p2p_state_handler(_adapter *padapter) + { + struct wifidirect_info *pwdinfo = &padapter->wdinfo; +@@ -3126,6 +3132,7 @@ void restore_p2p_state_handler(_adapter *padapter) + } + } + ++void pre_tx_invitereq_handler(_adapter *padapter); + void pre_tx_invitereq_handler(_adapter *padapter) + { + struct wifidirect_info *pwdinfo = &padapter->wdinfo; +@@ -3138,6 +3145,7 @@ void pre_tx_invitereq_handler(_adapter *padapter) + + } + ++void pre_tx_provdisc_handler(_adapter *padapter); + void pre_tx_provdisc_handler(_adapter *padapter) + { + struct wifidirect_info *pwdinfo = &padapter->wdinfo; +@@ -3150,6 +3158,7 @@ void pre_tx_provdisc_handler(_adapter *padapter) + + } + ++void pre_tx_negoreq_handler(_adapter *padapter); + void pre_tx_negoreq_handler(_adapter *padapter) + { + struct wifidirect_info *pwdinfo = &padapter->wdinfo; +@@ -3737,6 +3746,7 @@ static void rtw_cfg80211_adjust_p2pie_channel(_adapter *padapter, const u8 *fram + #endif + + #ifdef CONFIG_WFD ++u32 rtw_xframe_build_wfd_ie(struct xmit_frame *xframe); + u32 rtw_xframe_build_wfd_ie(struct xmit_frame *xframe) + { + _adapter *adapter = xframe->padapter; +@@ -3815,6 +3825,7 @@ u32 rtw_xframe_build_wfd_ie(struct xmit_frame *xframe) + } + #endif /* CONFIG_WFD */ + ++bool rtw_xframe_del_wfd_ie(struct xmit_frame *xframe); + bool rtw_xframe_del_wfd_ie(struct xmit_frame *xframe) + { + #define DBG_XFRAME_DEL_WFD_IE 0 +@@ -3939,6 +3950,7 @@ u8 *dump_p2p_attr_ch_list(u8 *p2p_ie, uint p2p_ielen, u8 *buf, u32 buf_len) + /* + * return _TRUE if requester is GO, _FALSE if responder is GO + */ ++bool rtw_p2p_nego_intent_compare(u8 req, u8 resp); + bool rtw_p2p_nego_intent_compare(u8 req, u8 resp) + { + if (req >> 1 == resp >> 1) +diff --git a/drivers/staging/rtl8812au/core/rtw_pwrctrl.c b/drivers/staging/rtl8812au/core/rtw_pwrctrl.c +index 34e10dc0a..44d702868 100644 +--- a/drivers/staging/rtl8812au/core/rtw_pwrctrl.c ++++ b/drivers/staging/rtl8812au/core/rtw_pwrctrl.c +@@ -194,6 +194,7 @@ int ips_leave(_adapter *padapter) + int rtw_hw_resume(_adapter *padapter); + #endif + ++bool rtw_pwr_unassociated_idle(_adapter *adapter); + bool rtw_pwr_unassociated_idle(_adapter *adapter) + { + u8 i; +@@ -400,6 +401,7 @@ void rtw_ps_processor(_adapter *padapter) + return; + } + ++void pwr_state_check_handler(void *ctx); + void pwr_state_check_handler(void *ctx) + { + _adapter *padapter = (_adapter *)ctx; +diff --git a/drivers/staging/rtl8812au/core/rtw_recv.c b/drivers/staging/rtl8812au/core/rtw_recv.c +index 3c180740b..ed2bf605c 100644 +--- a/drivers/staging/rtl8812au/core/rtw_recv.c ++++ b/drivers/staging/rtl8812au/core/rtw_recv.c +@@ -851,6 +851,7 @@ sint recv_bcast_pn_decache(union recv_frame *precv_frame) + return _SUCCESS; + } + ++sint recv_decache(union recv_frame *precv_frame); + sint recv_decache(union recv_frame *precv_frame) + { + struct sta_info *psta = precv_frame->u.hdr.psta; +@@ -906,6 +907,7 @@ sint recv_decache(union recv_frame *precv_frame) + return _SUCCESS; + } + ++void process_pwrbit_data(_adapter *padapter, union recv_frame *precv_frame, struct sta_info *psta); + void process_pwrbit_data(_adapter *padapter, union recv_frame *precv_frame, struct sta_info *psta) + { + #ifdef CONFIG_AP_MODE +@@ -934,6 +936,7 @@ void process_pwrbit_data(_adapter *padapter, union recv_frame *precv_frame, stru + #endif + } + ++void process_wmmps_data(_adapter *padapter, union recv_frame *precv_frame, struct sta_info *psta); + void process_wmmps_data(_adapter *padapter, union recv_frame *precv_frame, struct sta_info *psta) + { + #ifdef CONFIG_AP_MODE +@@ -1167,6 +1170,11 @@ void count_rx_stats(_adapter *padapter, union recv_frame *prframe, struct sta_in + + } + ++sint sta2sta_data_frame( ++ _adapter *adapter, ++ union recv_frame *precv_frame, ++ struct sta_info **psta ++); + sint sta2sta_data_frame( + _adapter *adapter, + union recv_frame *precv_frame, +@@ -1346,6 +1354,10 @@ sint sta2sta_data_frame( + + } + ++sint ap2sta_data_frame( ++ _adapter *adapter, ++ union recv_frame *precv_frame, ++ struct sta_info **psta); + sint ap2sta_data_frame( + _adapter *adapter, + union recv_frame *precv_frame, +@@ -1486,6 +1498,10 @@ sint ap2sta_data_frame( + + } + ++sint sta2ap_data_frame( ++ _adapter *adapter, ++ union recv_frame *precv_frame, ++ struct sta_info **psta); + sint sta2ap_data_frame( + _adapter *adapter, + union recv_frame *precv_frame, +@@ -1960,6 +1976,7 @@ static sint validate_mgmt_protect(_adapter *adapter, union recv_frame *precv_fra + + union recv_frame *recvframe_chk_defrag(PADAPTER padapter, union recv_frame *precv_frame); + ++sint validate_recv_mgnt_frame(PADAPTER padapter, union recv_frame *precv_frame); + sint validate_recv_mgnt_frame(PADAPTER padapter, union recv_frame *precv_frame) + { + struct sta_info *psta = precv_frame->u.hdr.psta +@@ -2051,6 +2068,7 @@ sint validate_recv_mgnt_frame(PADAPTER padapter, union recv_frame *precv_frame) + + } + ++sint validate_recv_data_frame(_adapter *adapter, union recv_frame *precv_frame); + sint validate_recv_data_frame(_adapter *adapter, union recv_frame *precv_frame) + { + u8 bretry, a4_shift; +@@ -2408,6 +2426,7 @@ sint validate_recv_frame(_adapter *adapter, union recv_frame *precv_frame) + + /* remove the wlanhdr and add the eth_hdr */ + #if 1 ++sint wlanhdr_to_ethhdr(union recv_frame *precvframe); + sint wlanhdr_to_ethhdr(union recv_frame *precvframe) + { + sint rmv_len; +@@ -3013,6 +3032,7 @@ static void recv_fwd_pkt_hdl(_adapter *adapter, _pkt *pkt + } + #endif /* CONFIG_RTW_MESH */ + ++int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe); + int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe) + { + struct rx_pkt_attrib *rattrib = &prframe->u.hdr.attrib; +@@ -3649,6 +3669,7 @@ static void recv_set_iseq_after_mpdu_process(union recv_frame *rframe, u16 seq_n + } + + #ifdef CONFIG_MP_INCLUDED ++int validate_mp_recv_frame(_adapter *adapter, union recv_frame *precv_frame); + int validate_mp_recv_frame(_adapter *adapter, union recv_frame *precv_frame) + { + int ret = _SUCCESS; +@@ -3785,6 +3806,7 @@ static sint MPwlanhdr_to_ethhdr(union recv_frame *precvframe) + } + + ++int mp_recv_frame(_adapter *padapter, union recv_frame *rframe); + int mp_recv_frame(_adapter *padapter, union recv_frame *rframe) + { + int ret = _SUCCESS; +@@ -4290,6 +4312,7 @@ static sint fill_radiotap_hdr(_adapter *padapter, union recv_frame *precvframe, + + } + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)) ++int recv_frame_monitor(_adapter *padapter, union recv_frame *rframe); + int recv_frame_monitor(_adapter *padapter, union recv_frame *rframe) + { + int ret = _SUCCESS; +@@ -4336,6 +4359,7 @@ int recv_frame_monitor(_adapter *padapter, union recv_frame *rframe) + return ret; + } + #endif ++int recv_func_prehandle(_adapter *padapter, union recv_frame *rframe); + int recv_func_prehandle(_adapter *padapter, union recv_frame *rframe) + { + int ret = _SUCCESS; +@@ -4373,6 +4397,7 @@ int recv_func_prehandle(_adapter *padapter, union recv_frame *rframe) + } + + /*#define DBG_RX_BMC_FRAME*/ ++int recv_func_posthandle(_adapter *padapter, union recv_frame *prframe); + int recv_func_posthandle(_adapter *padapter, union recv_frame *prframe) + { + int ret = _SUCCESS; +@@ -4481,6 +4506,7 @@ int recv_func_posthandle(_adapter *padapter, union recv_frame *prframe) + return ret; + } + ++int recv_func(_adapter *padapter, union recv_frame *rframe); + int recv_func(_adapter *padapter, union recv_frame *rframe) + { + int ret; +@@ -4794,6 +4820,7 @@ static void rx_process_link_qual(_adapter *padapter, union recv_frame *prframe) + #endif /* CONFIG_NEW_SIGNAL_STAT_PROCESS */ + } + ++void rx_process_phy_info(_adapter *padapter, union recv_frame *rframe); + void rx_process_phy_info(_adapter *padapter, union recv_frame *rframe) + { + /* Check RSSI */ +diff --git a/drivers/staging/rtl8812au/core/rtw_rf.c b/drivers/staging/rtl8812au/core/rtw_rf.c +index 6d827c364..eb884c3ce 100644 +--- a/drivers/staging/rtl8812au/core/rtw_rf.c ++++ b/drivers/staging/rtl8812au/core/rtw_rf.c +@@ -588,6 +588,7 @@ const char *const _regd_str[] = { + }; + + #if CONFIG_TXPWR_LIMIT ++void _dump_regd_exc_list(void *sel, struct rf_ctl_t *rfctl); + void _dump_regd_exc_list(void *sel, struct rf_ctl_t *rfctl) + { + struct regd_exc_ent *ent; +@@ -1219,6 +1220,7 @@ int rtw_ch_to_bb_gain_sel(int ch) + return sel; + } + ++s8 rtw_rf_get_kfree_tx_gain_offset(_adapter *padapter, u8 path, u8 ch); + s8 rtw_rf_get_kfree_tx_gain_offset(_adapter *padapter, u8 path, u8 ch) + { + s8 kfree_offset = 0; +diff --git a/drivers/staging/rtl8812au/core/rtw_sreset.c b/drivers/staging/rtl8812au/core/rtw_sreset.c +index 03dba20f3..d3d4447b3 100644 +--- a/drivers/staging/rtl8812au/core/rtw_sreset.c ++++ b/drivers/staging/rtl8812au/core/rtw_sreset.c +@@ -101,6 +101,7 @@ bool sreset_inprogress(_adapter *padapter) + #endif + } + ++void sreset_restore_security_station(_adapter *padapter); + void sreset_restore_security_station(_adapter *padapter) + { + struct mlme_priv *mlmepriv = &padapter->mlmepriv; +@@ -137,6 +138,7 @@ void sreset_restore_security_station(_adapter *padapter) + } + } + ++void sreset_restore_network_station(_adapter *padapter); + void sreset_restore_network_station(_adapter *padapter) + { + struct mlme_priv *mlmepriv = &padapter->mlmepriv; +@@ -195,6 +197,7 @@ void sreset_restore_network_station(_adapter *padapter) + } + + ++void sreset_restore_network_status(_adapter *padapter); + void sreset_restore_network_status(_adapter *padapter) + { + struct mlme_priv *mlmepriv = &padapter->mlmepriv; +diff --git a/drivers/staging/rtl8812au/core/rtw_sta_mgt.c b/drivers/staging/rtl8812au/core/rtw_sta_mgt.c +index ddcd1f70b..b42102142 100644 +--- a/drivers/staging/rtl8812au/core/rtw_sta_mgt.c ++++ b/drivers/staging/rtl8812au/core/rtw_sta_mgt.c +@@ -16,6 +16,7 @@ + + #include + ++bool test_st_match_rule(_adapter *adapter, u8 *local_naddr, u8 *local_port, u8 *remote_naddr, u8 *remote_port); + bool test_st_match_rule(_adapter *adapter, u8 *local_naddr, u8 *local_port, u8 *remote_naddr, u8 *remote_port) + { + if (ntohs(*((u16 *)local_port)) == 5001 || ntohs(*((u16 *)remote_port)) == 5001) +@@ -365,6 +366,7 @@ static void _rtw_free_sta_recv_priv_lock(struct sta_recv_priv *psta_recvpriv) + + } + ++void rtw_mfree_stainfo(struct sta_info *psta); + void rtw_mfree_stainfo(struct sta_info *psta) + { + +@@ -376,6 +378,7 @@ void rtw_mfree_stainfo(struct sta_info *psta) + } + + /* this function is used to free the memory of lock || sema for all stainfos */ ++void rtw_mfree_all_stainfo(struct sta_priv *pstapriv); + void rtw_mfree_all_stainfo(struct sta_priv *pstapriv) + { + _irqL irqL; +@@ -1044,6 +1047,7 @@ const char *const _acl_mode_str[RTW_ACL_MODE_MAX] = { + "DENY_UNLESS_LISTED", + }; + ++u8 _rtw_access_ctrl(_adapter *adapter, u8 period, const u8 *mac_addr); + u8 _rtw_access_ctrl(_adapter *adapter, u8 period, const u8 *mac_addr) + { + u8 res = _TRUE; +diff --git a/drivers/staging/rtl8812au/core/rtw_vht.c b/drivers/staging/rtl8812au/core/rtw_vht.c +index 9a7608c8e..382813830 100644 +--- a/drivers/staging/rtl8812au/core/rtw_vht.c ++++ b/drivers/staging/rtl8812au/core/rtw_vht.c +@@ -39,6 +39,7 @@ const char *const _vht_sup_ch_width_set_str[] = { + "BW-RSVD", + }; + ++void dump_vht_cap_ie_content(void *sel, const u8 *buf, u32 buf_len); + void dump_vht_cap_ie_content(void *sel, const u8 *buf, u32 buf_len) + { + if (buf_len != VHT_CAP_IE_LEN) { +@@ -79,6 +80,7 @@ const char *const _vht_op_ch_width_str[] = { + "BW-RSVD", + }; + ++void dump_vht_op_ie_content(void *sel, const u8 *buf, u32 buf_len); + void dump_vht_op_ie_content(void *sel, const u8 *buf, u32 buf_len) + { + if (buf_len != VHT_OP_IE_LEN) { +@@ -359,6 +361,7 @@ u64 rtw_vht_mcs_map_to_bitmap(u8 *mcs_map, u8 nss) + } + + #ifdef CONFIG_BEAMFORMING ++void update_sta_vht_info_apmode_bf_cap(_adapter *padapter, struct sta_info *psta); + void update_sta_vht_info_apmode_bf_cap(_adapter *padapter, struct sta_info *psta) + { + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); +diff --git a/drivers/staging/rtl8812au/core/rtw_wlan_util.c b/drivers/staging/rtl8812au/core/rtw_wlan_util.c +index 817245957..a427c7c51 100644 +--- a/drivers/staging/rtl8812au/core/rtw_wlan_util.c ++++ b/drivers/staging/rtl8812au/core/rtw_wlan_util.c +@@ -1011,6 +1011,7 @@ inline bool rtw_sec_camid_is_drv_forbid(struct cam_ctl_t *cam_ctl, u8 id) + return 1; + } + ++bool _rtw_sec_camid_is_used(struct cam_ctl_t *cam_ctl, u8 id); + bool _rtw_sec_camid_is_used(struct cam_ctl_t *cam_ctl, u8 id) + { + bool ret = _FALSE; +@@ -1099,6 +1100,7 @@ inline bool rtw_camid_is_gk(_adapter *adapter, u8 cam_id) + return ret; + } + ++bool cam_cache_chk(_adapter *adapter, u8 id, u8 *addr, s16 kid, s8 gk); + bool cam_cache_chk(_adapter *adapter, u8 id, u8 *addr, s16 kid, s8 gk) + { + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); +@@ -1117,6 +1119,7 @@ bool cam_cache_chk(_adapter *adapter, u8 id, u8 *addr, s16 kid, s8 gk) + return ret; + } + ++s16 _rtw_camid_search(_adapter *adapter, u8 *addr, s16 kid, s8 gk); + s16 _rtw_camid_search(_adapter *adapter, u8 *addr, s16 kid, s8 gk) + { + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); +@@ -1157,6 +1160,7 @@ s16 rtw_camid_search(_adapter *adapter, u8 *addr, s16 kid, s8 gk) + return cam_id; + } + ++s16 rtw_get_camid(_adapter *adapter, u8 *addr, s16 kid, u8 gk); + s16 rtw_get_camid(_adapter *adapter, u8 *addr, s16 kid, u8 gk) + { + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); +@@ -1276,6 +1280,7 @@ s16 rtw_camid_alloc(_adapter *adapter, struct sta_info *sta, u8 kid, u8 gk, bool + return cam_id; + } + ++void rtw_camid_set(_adapter *adapter, u8 cam_id); + void rtw_camid_set(_adapter *adapter, u8 cam_id) + { + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); +@@ -1359,6 +1364,7 @@ inline void rtw_sec_cam_swap(_adapter *adapter, u8 cam_id_a, u8 cam_id_b) + } + } + ++s16 rtw_get_empty_cam_entry(_adapter *adapter, u8 start_camid); + s16 rtw_get_empty_cam_entry(_adapter *adapter, u8 start_camid) + { + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); +@@ -2232,6 +2238,7 @@ void update_ldpc_stbc_cap(struct sta_info *psta) + #endif /* CONFIG_80211N_HT */ + } + ++int check_ielen(u8 *start, uint len); + int check_ielen(u8 *start, uint len) + { + int left = len; +diff --git a/drivers/staging/rtl8812au/core/rtw_xmit.c b/drivers/staging/rtl8812au/core/rtw_xmit.c +index 8504dba09..0b97e5099 100644 +--- a/drivers/staging/rtl8812au/core/rtw_xmit.c ++++ b/drivers/staging/rtl8812au/core/rtw_xmit.c +@@ -56,6 +56,7 @@ void rtw_init_xmit_block(_adapter *padapter) + dvobj->xmit_block = XMIT_BLOCK_NONE; + + } ++void rtw_free_xmit_block(_adapter *padapter); + void rtw_free_xmit_block(_adapter *padapter) + { + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); +@@ -505,6 +506,7 @@ void rtw_get_adapter_tx_rate_bmp_by_bw(_adapter *adapter, u8 bw, u16 *r_bmp_cck_ + *r_bmp_vht = bmp_vht; + } + ++void rtw_get_shared_macid_tx_rate_bmp_by_bw(struct dvobj_priv *dvobj, u8 bw, u16 *r_bmp_cck_ofdm, u32 *r_bmp_ht, u32 *r_bmp_vht); + void rtw_get_shared_macid_tx_rate_bmp_by_bw(struct dvobj_priv *dvobj, u8 bw, u16 *r_bmp_cck_ofdm, u32 *r_bmp_ht, u32 *r_bmp_vht) + { + struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj); +@@ -3476,6 +3478,7 @@ s32 rtw_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf) + return _SUCCESS; + } + ++void rtw_init_xmitframe(struct xmit_frame *pxframe); + void rtw_init_xmitframe(struct xmit_frame *pxframe) + { + if (pxframe != NULL) { /* default value setting */ +@@ -4146,6 +4149,7 @@ void rtw_init_hwxmits(struct hw_xmit *phwxmit, sint entry) + } + + #ifdef CONFIG_BR_EXT ++int rtw_br_client_tx(_adapter *padapter, struct sk_buff **pskb); + int rtw_br_client_tx(_adapter *padapter, struct sk_buff **pskb) + { + struct sk_buff *skb = *pskb; +@@ -6040,6 +6044,7 @@ int rtw_sctx_wait(struct submit_ctx *sctx, const char *msg) + return ret; + } + ++bool rtw_sctx_chk_waring_status(int status); + bool rtw_sctx_chk_waring_status(int status) + { + switch (status) { +diff --git a/drivers/staging/rtl8812au/hal/hal_com.c b/drivers/staging/rtl8812au/hal/hal_com.c +index b3b1e16c8..a230ea6e5 100644 +--- a/drivers/staging/rtl8812au/hal/hal_com.c ++++ b/drivers/staging/rtl8812au/hal/hal_com.c +@@ -2021,6 +2021,7 @@ void rtw_hal_update_sta_wset(_adapter *adapter, struct sta_info *psta) + psta->cmn.support_wireless_set = w_set; + } + ++void rtw_hal_update_sta_mimo_type(_adapter *adapter, struct sta_info *psta); + void rtw_hal_update_sta_mimo_type(_adapter *adapter, struct sta_info *psta) + { + s8 tx_nss, rx_nss; +@@ -2054,6 +2055,7 @@ void rtw_hal_update_sta_mimo_type(_adapter *adapter, struct sta_info *psta) + psta->cmn.mac_id, tx_nss, rx_nss); + } + ++void rtw_hal_update_sta_smps_cap(_adapter *adapter, struct sta_info *psta); + void rtw_hal_update_sta_smps_cap(_adapter *adapter, struct sta_info *psta) + { + /*Spatial Multiplexing Power Save*/ +@@ -2092,6 +2094,7 @@ u8 rtw_get_mgntframe_raid(_adapter *adapter, unsigned char network_type) + return raid; + } + ++void rtw_hal_update_sta_rate_mask(PADAPTER padapter, struct sta_info *psta); + void rtw_hal_update_sta_rate_mask(PADAPTER padapter, struct sta_info *psta) + { + struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter); +@@ -4392,6 +4395,7 @@ inline s32 rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter *adapter, bool opmode + return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 1, macid_end); + } + ++void rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc); + void rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc) + { + struct hal_ops *pHalFunc = &padapter->hal_func; +@@ -4536,6 +4540,7 @@ void rtw_hal_set_input_gpio(_adapter *padapter, u8 index) + + #endif + ++void rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc); + void rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc) + { + struct hal_ops *pHalFunc = &padapter->hal_func; +@@ -7669,6 +7674,8 @@ void rtw_hal_construct_NullFunctionData( + *pLength = pktlen; + } + ++void rtw_hal_construct_ProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength, ++ BOOLEAN bHideSSID); + void rtw_hal_construct_ProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength, + BOOLEAN bHideSSID) + { +@@ -11502,6 +11509,7 @@ s32 rtw_hal_set_wifi_btc_port_id_cmd(_adapter *adapter) + #endif + + #define LPS_ACTIVE_TIMEOUT 50 /*number of times*/ ++void rtw_lps_state_chk(_adapter *adapter, u8 ps_mode); + void rtw_lps_state_chk(_adapter *adapter, u8 ps_mode) + { + if (ps_mode == PS_MODE_ACTIVE) { +@@ -11973,6 +11981,7 @@ SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value) + } + + #ifdef CONFIG_BEAMFORMING ++u8 rtw_hal_query_txbfer_rf_num(_adapter *adapter); + u8 rtw_hal_query_txbfer_rf_num(_adapter *adapter) + { + struct registry_priv *pregistrypriv = &adapter->registrypriv; +@@ -11998,6 +12007,7 @@ u8 rtw_hal_query_txbfer_rf_num(_adapter *adapter) + return 1; + + } ++u8 rtw_hal_query_txbfee_rf_num(_adapter *adapter); + u8 rtw_hal_query_txbfee_rf_num(_adapter *adapter) + { + struct registry_priv *pregistrypriv = &adapter->registrypriv; +@@ -13001,6 +13011,7 @@ bool kfree_data_is_bb_gain_empty(struct kfree_data_t *data) + } + + #ifdef CONFIG_USB_RX_AGGREGATION ++void rtw_set_usb_agg_by_mode_normal(_adapter *padapter, u8 cur_wireless_mode); + void rtw_set_usb_agg_by_mode_normal(_adapter *padapter, u8 cur_wireless_mode) + { + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); +@@ -13069,6 +13080,7 @@ void rtw_set_usb_agg_by_mode_normal(_adapter *padapter, u8 cur_wireless_mode) + } + } + ++void rtw_set_usb_agg_by_mode_customer(_adapter *padapter, u8 cur_wireless_mode, u8 UsbDmaSize, u8 Legacy_UsbDmaSize); + void rtw_set_usb_agg_by_mode_customer(_adapter *padapter, u8 cur_wireless_mode, u8 UsbDmaSize, u8 Legacy_UsbDmaSize) + { + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); +@@ -13096,6 +13108,7 @@ void rtw_set_usb_agg_by_mode_customer(_adapter *padapter, u8 cur_wireless_mode, + } + } + ++void rtw_set_usb_agg_by_mode(_adapter *padapter, u8 cur_wireless_mode); + void rtw_set_usb_agg_by_mode(_adapter *padapter, u8 cur_wireless_mode) + { + #ifdef CONFIG_PLATFORM_NOVATEK_NT72668 +@@ -14391,6 +14404,7 @@ void rtw_dump_phy_cap_by_phydmapi(void *sel, _adapter *adapter) + #endif + } + #else ++void rtw_dump_phy_cap_by_hal(void *sel, _adapter *adapter); + void rtw_dump_phy_cap_by_hal(void *sel, _adapter *adapter) + { + u8 phy_cap = _FALSE; +diff --git a/drivers/staging/rtl8812au/hal/hal_com_phycfg.c b/drivers/staging/rtl8812au/hal/hal_com_phycfg.c +index ada38b221..5ca3b824e 100644 +--- a/drivers/staging/rtl8812au/hal/hal_com_phycfg.c ++++ b/drivers/staging/rtl8812au/hal/hal_com_phycfg.c +@@ -610,6 +610,13 @@ static inline void hal_init_pg_txpwr_info_5g(_adapter *adapter, TxPowerInfo5G *p + #define LOAD_PG_TXPWR_WARN_COND(_txpwr_src) (_txpwr_src > PG_TXPWR_SRC_PG_DATA) + #endif + ++u16 hal_load_pg_txpwr_info_path_2g( ++ _adapter *adapter, ++ TxPowerInfo24G *pwr_info, ++ u32 path, ++ u8 txpwr_src, ++ const struct map_t *txpwr_map, ++ u16 pg_offset); + u16 hal_load_pg_txpwr_info_path_2g( + _adapter *adapter, + TxPowerInfo24G *pwr_info, +@@ -738,6 +745,13 @@ u16 hal_load_pg_txpwr_info_path_2g( + return offset; + } + ++u16 hal_load_pg_txpwr_info_path_5g( ++ _adapter *adapter, ++ TxPowerInfo5G *pwr_info, ++ u32 path, ++ u8 txpwr_src, ++ const struct map_t *txpwr_map, ++ u16 pg_offset); + u16 hal_load_pg_txpwr_info_path_5g( + _adapter *adapter, + TxPowerInfo5G *pwr_info, +@@ -897,6 +911,13 @@ u16 hal_load_pg_txpwr_info_path_5g( + return offset; + } + ++void hal_load_pg_txpwr_info( ++ _adapter *adapter, ++ TxPowerInfo24G *pwr_info_2g, ++ TxPowerInfo5G *pwr_info_5g, ++ u8 *pg_data, ++ BOOLEAN AutoLoadFail ++); + void hal_load_pg_txpwr_info( + _adapter *adapter, + TxPowerInfo24G *pwr_info_2g, +@@ -1317,6 +1338,12 @@ void dump_hal_txpwr_info_5g(void *sel, _adapter *adapter, u8 rfpath_num, u8 max_ + * + * Return dBm or -1 for undefined + */ ++s8 rtw_regsty_get_target_tx_power( ++ IN PADAPTER Adapter, ++ IN u8 Band, ++ IN u8 RfPath, ++ IN RATE_SECTION RateSection ++); + s8 rtw_regsty_get_target_tx_power( + IN PADAPTER Adapter, + IN u8 Band, +@@ -1361,6 +1388,7 @@ s8 rtw_regsty_get_target_tx_power( + return value; + } + ++bool rtw_regsty_chk_target_tx_power_valid(_adapter *adapter); + bool rtw_regsty_chk_target_tx_power_valid(_adapter *adapter) + { + struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); +@@ -1441,6 +1469,14 @@ PHY_GetTxPowerByRateBase( + return value; + } + ++VOID ++phy_SetTxPowerByRateBase( ++ IN PADAPTER Adapter, ++ IN u8 Band, ++ IN u8 RfPath, ++ IN RATE_SECTION RateSection, ++ IN u8 Value ++); + VOID + phy_SetTxPowerByRateBase( + IN PADAPTER Adapter, +@@ -1558,6 +1594,10 @@ static void phy_txpwr_by_rate_chk_for_path_dup(_adapter *adapter) + } + } + ++VOID ++phy_StoreTxPowerByRateBase( ++ IN PADAPTER pAdapter ++); + VOID + phy_StoreTxPowerByRateBase( + IN PADAPTER pAdapter +@@ -1964,6 +2004,15 @@ PHY_GetRateValuesOfTxPowerByRate( + }; + } + ++void ++PHY_StoreTxPowerByRateNew( ++ IN PADAPTER pAdapter, ++ IN u32 Band, ++ IN u32 RfPath, ++ IN u32 RegAddr, ++ IN u32 BitMask, ++ IN u32 Data ++); + void + PHY_StoreTxPowerByRateNew( + IN PADAPTER pAdapter, +@@ -2032,6 +2081,10 @@ phy_store_tx_power_by_rate( + + } + ++VOID ++phy_ConvertTxPowerByRateInDbmToRelativeValues( ++ IN PADAPTER pAdapter ++); + VOID + phy_ConvertTxPowerByRateInDbmToRelativeValues( + IN PADAPTER pAdapter +@@ -2162,6 +2215,11 @@ phy_set_tx_power_index_by_rate_section( + return; + } + ++BOOLEAN ++phy_GetChnlIndex( ++ IN u8 Channel, ++ OUT u8 *ChannelIdx ++); + BOOLEAN + phy_GetChnlIndex( + IN u8 Channel, +@@ -3524,6 +3582,11 @@ static void phy_txpwr_lmt_post_hdl(_adapter *adapter) + _exit_critical_mutex(&rfctl->txpwr_lmt_mutex, &irqL); + } + ++BOOLEAN ++GetS1ByteIntegerFromStringInDecimal( ++ IN char *str, ++ IN OUT s8 *val ++); + BOOLEAN + GetS1ByteIntegerFromStringInDecimal( + IN char *str, +@@ -4243,6 +4306,11 @@ phy_ConfigBBWithParaFile( + return rtStatus; + } + ++VOID ++phy_DecryptBBPgParaFile( ++ PADAPTER Adapter, ++ char *buffer ++); + VOID + phy_DecryptBBPgParaFile( + PADAPTER Adapter, +@@ -4285,6 +4353,11 @@ phy_DecryptBBPgParaFile( + #define DBG_TXPWR_BY_RATE_FILE_PARSE 0 + #endif + ++int ++phy_ParseBBPgParaFile( ++ PADAPTER Adapter, ++ char *buffer ++); + int + phy_ParseBBPgParaFile( + PADAPTER Adapter, +@@ -4714,6 +4787,16 @@ PHY_ConfigRFWithParaFile( + return rtStatus; + } + ++VOID ++initDeltaSwingIndexTables( ++ PADAPTER Adapter, ++ char *Band, ++ char *Path, ++ char *Sign, ++ char *Channel, ++ char *Rate, ++ char *Data ++); + VOID + initDeltaSwingIndexTables( + PADAPTER Adapter, +diff --git a/drivers/staging/rtl8812au/hal/hal_dm.c b/drivers/staging/rtl8812au/hal/hal_dm.c +index 0df8f64eb..1236b51ad 100644 +--- a/drivers/staging/rtl8812au/hal/hal_dm.c ++++ b/drivers/staging/rtl8812au/hal/hal_dm.c +@@ -17,7 +17,8 @@ + #include + + /* A mapping from HalData to ODM. */ +-enum odm_board_type boardType(u8 InterfaceSel) ++enum odm_board_type boardType(u8 InterfaceSel); ++enum odm_board_type boardType(u8 InterfaceSel) + { + enum odm_board_type board = ODM_BOARD_DEFAULT; + +@@ -94,6 +95,7 @@ void rtw_phydm_iqk_trigger(_adapter *adapter) + } + #endif + ++void rtw_phydm_iqk_trigger_dbg(_adapter *adapter, bool recovery, bool clear, bool segment); + void rtw_phydm_iqk_trigger_dbg(_adapter *adapter, bool recovery, bool clear, bool segment) + { + struct dm_struct *p_dm_odm = adapter_to_phydm(adapter); +@@ -104,6 +106,7 @@ void rtw_phydm_iqk_trigger_dbg(_adapter *adapter, bool recovery, bool clear, boo + halrf_iqk_trigger(p_dm_odm, recovery); + #endif + } ++void rtw_phydm_lck_trigger(_adapter *adapter); + void rtw_phydm_lck_trigger(_adapter *adapter) + { + struct dm_struct *p_dm_odm = adapter_to_phydm(adapter); +@@ -162,6 +165,7 @@ void rtw_hal_update_param_init_fw_offload_cap(_adapter *adapter) + } + #endif + ++void record_ra_info(void *p_dm_void, u8 macid, struct cmn_sta_info *p_sta, u64 ra_mask); + void record_ra_info(void *p_dm_void, u8 macid, struct cmn_sta_info *p_sta, u64 ra_mask) + { + struct dm_struct *p_dm = (struct dm_struct *)p_dm_void; +@@ -285,6 +289,7 @@ void rtw_phydm_tdmadig(_adapter *adapter, u8 state) + } + } + #endif/*CONFIG_TDMADIG*/ ++void rtw_phydm_ops_func_init(struct dm_struct *p_phydm); + void rtw_phydm_ops_func_init(struct dm_struct *p_phydm) + { + struct ra_table *p_ra_t = &p_phydm->dm_ra_table; +diff --git a/drivers/staging/rtl8812au/hal/hal_intf.c b/drivers/staging/rtl8812au/hal/hal_intf.c +index 66a2954c5..de72c9612 100644 +--- a/drivers/staging/rtl8812au/hal/hal_intf.c ++++ b/drivers/staging/rtl8812au/hal/hal_intf.c +@@ -260,6 +260,7 @@ void rtw_hal_power_off(_adapter *padapter) + } + + ++void rtw_hal_init_opmode(_adapter *padapter); + void rtw_hal_init_opmode(_adapter *padapter) + { + NDIS_802_11_NETWORK_INFRASTRUCTURE networkType = Ndis802_11InfrastructureMax; +@@ -639,6 +640,7 @@ void rtw_hal_free_recv_priv(_adapter *padapter) + padapter->hal_func.free_recv_priv(padapter); + } + ++void rtw_sta_ra_registed(_adapter *padapter, struct sta_info *psta); + void rtw_sta_ra_registed(_adapter *padapter, struct sta_info *psta) + { + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); +diff --git a/drivers/staging/rtl8812au/hal/hal_mp.c b/drivers/staging/rtl8812au/hal/hal_mp.c +index 7960556f2..2d2af16c8 100644 +--- a/drivers/staging/rtl8812au/hal/hal_mp.c ++++ b/drivers/staging/rtl8812au/hal/hal_mp.c +@@ -373,6 +373,7 @@ void hal_mpt_SetBandwidth(PADAPTER pAdapter) + + } + ++void mpt_SetTxPower_Old(PADAPTER pAdapter, MPT_TXPWR_DEF Rate, u8 *pTxPower); + void mpt_SetTxPower_Old(PADAPTER pAdapter, MPT_TXPWR_DEF Rate, u8 *pTxPower) + { + switch (Rate) { +@@ -431,6 +432,12 @@ void mpt_SetTxPower_Old(PADAPTER pAdapter, MPT_TXPWR_DEF Rate, u8 *pTxPower) + RTW_INFO("<===mpt_SetTxPower_Old()\n"); + } + ++void ++mpt_SetTxPower( ++ PADAPTER pAdapter, ++ MPT_TXPWR_DEF Rate, ++ pu1Byte pTxPower ++); + void + mpt_SetTxPower( + PADAPTER pAdapter, +@@ -603,6 +610,7 @@ void hal_mpt_SetDataRate(PADAPTER pAdapter) + #define RF_PATH_AB 22 + + #ifdef CONFIG_RTL8814A ++VOID mpt_ToggleIG_8814A(PADAPTER pAdapter); + VOID mpt_ToggleIG_8814A(PADAPTER pAdapter) + { + u1Byte Path = 0; +@@ -632,6 +640,7 @@ VOID mpt_ToggleIG_8814A(PADAPTER pAdapter) + + } + ++VOID mpt_SetRFPath_8814A(PADAPTER pAdapter); + VOID mpt_SetRFPath_8814A(PADAPTER pAdapter) + { + +@@ -866,6 +875,11 @@ VOID mpt_SetRFPath_8814A(PADAPTER pAdapter) + #endif /* CONFIG_RTL8814A */ + #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8812A) + VOID ++mpt_SetSingleTone_8814A( ++ IN PADAPTER pAdapter, ++ IN BOOLEAN bSingleTone, ++ IN BOOLEAN bEnPMacTx); ++VOID + mpt_SetSingleTone_8814A( + IN PADAPTER pAdapter, + IN BOOLEAN bSingleTone, +@@ -1167,6 +1181,7 @@ void mpt_SetRFPath_8723D(PADAPTER pAdapter) + } + #endif + ++VOID mpt_SetRFPath_819X(PADAPTER pAdapter); + VOID mpt_SetRFPath_819X(PADAPTER pAdapter) + { + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); +diff --git a/drivers/staging/rtl8812au/hal/led/hal_usb_led.c b/drivers/staging/rtl8812au/hal/led/hal_usb_led.c +index 80f7a393c..16fd74bad 100644 +--- a/drivers/staging/rtl8812au/hal/led/hal_usb_led.c ++++ b/drivers/staging/rtl8812au/hal/led/hal_usb_led.c +@@ -23,6 +23,10 @@ + * It toggle off LED and schedule corresponding timer if necessary. + * */ + void ++SwLedBlink( ++ PLED_USB pLed ++); ++void + SwLedBlink( + PLED_USB pLed + ) +@@ -112,6 +116,10 @@ SwLedBlink( + } + } + ++void ++SwLedBlink1( ++ PLED_USB pLed ++); + void + SwLedBlink1( + PLED_USB pLed +@@ -289,6 +297,10 @@ SwLedBlink1( + + } + ++void ++SwLedBlink2( ++ PLED_USB pLed ++); + void + SwLedBlink2( + PLED_USB pLed +@@ -375,6 +387,10 @@ SwLedBlink2( + + } + ++void ++SwLedBlink3( ++ PLED_USB pLed ++); + void + SwLedBlink3( + PLED_USB pLed +@@ -501,6 +517,10 @@ SwLedBlink3( + } + + ++void ++SwLedBlink4( ++ PLED_USB pLed ++); + void + SwLedBlink4( + PLED_USB pLed +@@ -689,6 +709,10 @@ SwLedBlink4( + + } + ++void ++SwLedBlink5( ++ PLED_USB pLed ++); + void + SwLedBlink5( + PLED_USB pLed +@@ -779,6 +803,10 @@ SwLedBlink5( + + } + ++void ++SwLedBlink6( ++ PLED_USB pLed ++); + void + SwLedBlink6( + PLED_USB pLed +@@ -797,6 +825,10 @@ SwLedBlink6( + + } + ++void ++SwLedBlink7( ++ PLED_USB pLed ++); + void + SwLedBlink7( + PLED_USB pLed +@@ -886,6 +918,10 @@ SwLedBlink7( + + } + ++void ++SwLedBlink8( ++ PLED_USB pLed ++); + void + SwLedBlink8( + PLED_USB pLed +@@ -905,6 +941,10 @@ SwLedBlink8( + + /* page added for Belkin AC950. 20120813 */ + void ++SwLedBlink9( ++ PLED_USB pLed ++); ++void + SwLedBlink9( + PLED_USB pLed + ) +@@ -1141,6 +1181,10 @@ SwLedBlink9( + + /* page added for Netgear A6200V2. 20120827 */ + void ++SwLedBlink10( ++ PLED_USB pLed ++); ++void + SwLedBlink10( + PLED_USB pLed + ) +@@ -1340,6 +1384,10 @@ SwLedBlink10( + + } + ++void ++SwLedBlink11( ++ PLED_USB pLed ++); + void + SwLedBlink11( + PLED_USB pLed +@@ -1411,6 +1459,10 @@ SwLedBlink11( + + } + ++void ++SwLedBlink12( ++ PLED_USB pLed ++); + void + SwLedBlink12( + PLED_USB pLed +@@ -1479,6 +1531,10 @@ SwLedBlink12( + + } + ++VOID ++SwLedBlink13( ++ IN PLED_USB pLed ++); + VOID + SwLedBlink13( + IN PLED_USB pLed +@@ -1540,6 +1596,10 @@ SwLedBlink13( + + } + ++VOID ++SwLedBlink14( ++ IN PLED_USB pLed ++); + VOID + SwLedBlink14( + IN PLED_USB pLed +@@ -1597,6 +1657,10 @@ SwLedBlink14( + + } + ++VOID ++SwLedBlink15( ++ IN PLED_USB pLed ++); + VOID + SwLedBlink15( + IN PLED_USB pLed +@@ -2909,6 +2973,11 @@ SwLedControlMode6( + + /* Netgear, added by sinda, 2011/11/11 */ + void ++SwLedControlMode7( ++ PADAPTER Adapter, ++ LED_CTL_MODE LedAction ++); ++void + SwLedControlMode7( + PADAPTER Adapter, + LED_CTL_MODE LedAction +@@ -3047,6 +3116,11 @@ SwLedControlMode7( + + } + ++void ++SwLedControlMode8( ++ PADAPTER Adapter, ++ LED_CTL_MODE LedAction ++); + void + SwLedControlMode8( + PADAPTER Adapter, +@@ -3085,6 +3159,11 @@ SwLedControlMode8( + + /* page added for Belkin AC950, 20120813 */ + void ++SwLedControlMode9( ++ IN PADAPTER Adapter, ++ IN LED_CTL_MODE LedAction ++); ++void + SwLedControlMode9( + IN PADAPTER Adapter, + IN LED_CTL_MODE LedAction +@@ -3387,6 +3466,11 @@ SwLedControlMode9( + + /* page added for Netgear A6200V2, 20120827 */ + void ++SwLedControlMode10( ++ PADAPTER Adapter, ++ LED_CTL_MODE LedAction ++); ++void + SwLedControlMode10( + PADAPTER Adapter, + LED_CTL_MODE LedAction +@@ -3585,6 +3669,11 @@ SwLedControlMode10( + + /* Edimax-ASUS, added by Page, 20121221 */ + void ++SwLedControlMode11( ++ PADAPTER Adapter, ++ LED_CTL_MODE LedAction ++); ++void + SwLedControlMode11( + PADAPTER Adapter, + LED_CTL_MODE LedAction +@@ -3683,6 +3772,11 @@ SwLedControlMode11( + + /* page added for NEC */ + ++VOID ++SwLedControlMode12( ++ PADAPTER Adapter, ++ LED_CTL_MODE LedAction ++); + VOID + SwLedControlMode12( + PADAPTER Adapter, +@@ -3764,6 +3858,11 @@ SwLedControlMode12( + + /* Maddest add for NETGEAR R6100 */ + ++VOID ++SwLedControlMode13( ++ IN PADAPTER Adapter, ++ IN LED_CTL_MODE LedAction ++); + VOID + SwLedControlMode13( + IN PADAPTER Adapter, +@@ -3910,6 +4009,11 @@ SwLedControlMode13( + + /* Maddest add for DNI Buffalo */ + ++VOID ++SwLedControlMode14( ++ IN PADAPTER Adapter, ++ IN LED_CTL_MODE LedAction ++); + VOID + SwLedControlMode14( + IN PADAPTER Adapter, +@@ -3969,6 +4073,11 @@ SwLedControlMode14( + + /* Maddest add for Dlink */ + ++VOID ++SwLedControlMode15( ++ IN PADAPTER Adapter, ++ IN LED_CTL_MODE LedAction ++); + VOID + SwLedControlMode15( + IN PADAPTER Adapter, +diff --git a/drivers/staging/rtl8812au/hal/phydm/halrf/halphyrf_ce.c b/drivers/staging/rtl8812au/hal/phydm/halrf/halphyrf_ce.c +index c8753e500..4443c7289 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/halrf/halphyrf_ce.c ++++ b/drivers/staging/rtl8812au/hal/phydm/halrf/halphyrf_ce.c +@@ -152,6 +152,7 @@ void odm_clear_txpowertracking_state(void *dm_void) + cali_info->modify_tx_agc_value_ofdm = 0; + } + ++void odm_get_tracking_table(void *dm_void, u8 thermal_value, u8 delta); + void odm_get_tracking_table(void *dm_void, u8 thermal_value, u8 delta) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -352,6 +353,7 @@ void odm_get_tracking_table(void *dm_void, u8 thermal_value, u8 delta) + } + } + ++void odm_pwrtrk_method(void *dm_void); + void odm_pwrtrk_method(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -858,6 +860,7 @@ u8 odm_get_right_chnl_place_for_iqk(u8 chnl) + } + #endif + ++void odm_iq_calibrate(struct dm_struct *dm); + void odm_iq_calibrate(struct dm_struct *dm) + { + void *adapter = dm->adapter; +diff --git a/drivers/staging/rtl8812au/hal/phydm/halrf/halrf.c b/drivers/staging/rtl8812au/hal/phydm/halrf/halrf.c +index 32fd1f3db..09ab5bae9 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/halrf/halrf.c ++++ b/drivers/staging/rtl8812au/hal/phydm/halrf/halrf.c +@@ -1135,6 +1135,7 @@ u64 halrf_cmn_info_get(void *dm_void, u32 cmn_info) + return return_value; + } + ++void halrf_supportability_init_mp(void *dm_void); + void halrf_supportability_init_mp(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -1353,6 +1354,7 @@ halrf_iqk_init( + } + #endif + ++void halrf_dack_trigger(void *dm_void); + void halrf_dack_trigger(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -1674,6 +1676,7 @@ void halrf_lck_trigger(void *dm_void) + } + } + ++void halrf_aac_check(struct dm_struct *dm); + void halrf_aac_check(struct dm_struct *dm) + { + switch (dm->support_ic_type) { +@@ -2052,6 +2055,7 @@ halrf_config_rfk_with_header_file(void *dm_void, u32 config_type) + return result; + } + ++void halrf_txgapk_trigger(void *dm_void); + void halrf_txgapk_trigger(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +diff --git a/drivers/staging/rtl8812au/hal/phydm/halrf/halrf_debug.c b/drivers/staging/rtl8812au/hal/phydm/halrf/halrf_debug.c +index 85a7cb22b..4d61870d8 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/halrf/halrf_debug.c ++++ b/drivers/staging/rtl8812au/hal/phydm/halrf/halrf_debug.c +@@ -31,6 +31,7 @@ + #include "mp_precomp.h" + #include "phydm_precomp.h" + ++void halrf_basic_profile(void *dm_void, u32 *_used, char *output, u32 *_out_len); + void halrf_basic_profile(void *dm_void, u32 *_used, char *output, u32 *_out_len) + { + #ifdef CONFIG_PHYDM_DEBUG_FUNCTION +@@ -65,6 +66,8 @@ void halrf_basic_profile(void *dm_void, u32 *_used, char *output, u32 *_out_len) + #endif + } + ++void halrf_debug_trace(void *dm_void, char input[][16], u32 *_used, ++ char *output, u32 *_out_len); + void halrf_debug_trace(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) + { +diff --git a/drivers/staging/rtl8812au/hal/phydm/halrf/halrf_kfree.c b/drivers/staging/rtl8812au/hal/phydm/halrf/halrf_kfree.c +index cee13be26..773364310 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/halrf/halrf_kfree.c ++++ b/drivers/staging/rtl8812au/hal/phydm/halrf/halrf_kfree.c +@@ -32,6 +32,7 @@ + /*@ Add for KFree Feature Requested by RF David.*/ + /*@This is a phydm API*/ + ++void phydm_set_kfree_to_rf_8814a(void *dm_void, u8 e_rf_path, u8 data); + void phydm_set_kfree_to_rf_8814a(void *dm_void, u8 e_rf_path, u8 data) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -124,6 +125,7 @@ void phydm_set_kfree_to_rf_8814a(void *dm_void, u8 e_rf_path, u8 data) + } + } + ++void phydm_get_thermal_trim_offset_8821c(void *dm_void); + void phydm_get_thermal_trim_offset_8821c(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -151,6 +153,7 @@ void phydm_get_thermal_trim_offset_8821c(void *dm_void) + power_trim_info->thermal); + } + ++void phydm_get_power_trim_offset_8821c(void *dm_void); + void phydm_get_power_trim_offset_8821c(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -188,6 +191,8 @@ void phydm_get_power_trim_offset_8821c(void *dm_void) + } + } + ++void phydm_set_kfree_to_rf_8821c(void *dm_void, u8 e_rf_path, boolean wlg_btg, ++ u8 data); + void phydm_set_kfree_to_rf_8821c(void *dm_void, u8 e_rf_path, boolean wlg_btg, + u8 data) + { +@@ -223,6 +228,7 @@ void phydm_set_kfree_to_rf_8821c(void *dm_void, u8 e_rf_path, boolean wlg_btg, + odm_get_rf_reg(dm, e_rf_path, RF_0x65, s_gain_bmask)); + } + ++void phydm_clear_kfree_to_rf_8821c(void *dm_void, u8 e_rf_path, u8 data); + void phydm_clear_kfree_to_rf_8821c(void *dm_void, u8 e_rf_path, u8 data) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -252,6 +258,7 @@ void phydm_clear_kfree_to_rf_8821c(void *dm_void, u8 e_rf_path, u8 data) + odm_get_rf_reg(dm, e_rf_path, RF_0x65, s_gain_bmask)); + } + ++void phydm_get_thermal_trim_offset_8822b(void *dm_void); + void phydm_get_thermal_trim_offset_8822b(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -279,6 +286,7 @@ void phydm_get_thermal_trim_offset_8822b(void *dm_void) + power_trim_info->thermal); + } + ++void phydm_get_power_trim_offset_8822b(void *dm_void); + void phydm_get_power_trim_offset_8822b(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -346,6 +354,7 @@ void phydm_get_power_trim_offset_8822b(void *dm_void) + } + } + ++void phydm_set_pa_bias_to_rf_8822b(void *dm_void, u8 e_rf_path, s8 tx_pa_bias); + void phydm_set_pa_bias_to_rf_8822b(void *dm_void, u8 e_rf_path, s8 tx_pa_bias) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -405,6 +414,7 @@ void phydm_set_pa_bias_to_rf_8822b(void *dm_void, u8 e_rf_path, s8 tx_pa_bias) + e_rf_path); + } + ++void phydm_get_pa_bias_offset_8822b(void *dm_void); + void phydm_get_pa_bias_offset_8822b(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -450,6 +460,7 @@ void phydm_get_pa_bias_offset_8822b(void *dm_void) + } + } + ++void phydm_set_kfree_to_rf_8822b(void *dm_void, u8 e_rf_path, u8 data); + void phydm_set_kfree_to_rf_8822b(void *dm_void, u8 e_rf_path, u8 data) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -470,6 +481,7 @@ void phydm_set_kfree_to_rf_8822b(void *dm_void, u8 e_rf_path, u8 data) + BIT(15) | BIT(14))), e_rf_path); + } + ++void phydm_clear_kfree_to_rf_8822b(void *dm_void, u8 e_rf_path, u8 data); + void phydm_clear_kfree_to_rf_8822b(void *dm_void, u8 e_rf_path, u8 data) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -497,6 +509,7 @@ void phydm_clear_kfree_to_rf_8822b(void *dm_void, u8 e_rf_path, u8 data) + BIT(15) | BIT(14))), e_rf_path); + } + ++void phydm_get_thermal_trim_offset_8710b(void *dm_void); + void phydm_get_thermal_trim_offset_8710b(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -524,6 +537,7 @@ void phydm_get_thermal_trim_offset_8710b(void *dm_void) + power_trim_info->thermal); + } + ++void phydm_get_power_trim_offset_8710b(void *dm_void); + void phydm_get_power_trim_offset_8710b(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -551,6 +565,7 @@ void phydm_get_power_trim_offset_8710b(void *dm_void) + power_trim_info->bb_gain[0][0]); + } + ++void phydm_set_kfree_to_rf_8710b(void *dm_void, u8 e_rf_path, u8 data); + void phydm_set_kfree_to_rf_8710b(void *dm_void, u8 e_rf_path, u8 data) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -565,6 +580,7 @@ void phydm_set_kfree_to_rf_8710b(void *dm_void, u8 e_rf_path, u8 data) + BIT(15) | BIT(14))), e_rf_path); + } + ++void phydm_clear_kfree_to_rf_8710b(void *dm_void, u8 e_rf_path, u8 data); + void phydm_clear_kfree_to_rf_8710b(void *dm_void, u8 e_rf_path, u8 data) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -581,6 +597,7 @@ void phydm_clear_kfree_to_rf_8710b(void *dm_void, u8 e_rf_path, u8 data) + BIT(15) | BIT(14))), e_rf_path); + } + ++void phydm_get_thermal_trim_offset_8192f(void *dm_void); + void phydm_get_thermal_trim_offset_8192f(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -608,6 +625,7 @@ void phydm_get_thermal_trim_offset_8192f(void *dm_void) + power_trim_info->thermal); + } + ++void phydm_get_power_trim_offset_8192f(void *dm_void); + void phydm_get_power_trim_offset_8192f(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -677,6 +695,8 @@ void phydm_get_power_trim_offset_8192f(void *dm_void) + } + } + ++void phydm_set_kfree_to_rf_8192f(void *dm_void, u8 e_rf_path, u8 channel_idx, ++ u8 data); + void phydm_set_kfree_to_rf_8192f(void *dm_void, u8 e_rf_path, u8 channel_idx, + u8 data) + { +@@ -765,6 +785,7 @@ void phydm_clear_kfree_to_rf_8192f(void *dm_void, u8 e_rf_path, u8 data) + */ + #endif + ++void phydm_get_thermal_trim_offset_8198f(void *dm_void); + void phydm_get_thermal_trim_offset_8198f(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -792,6 +813,7 @@ void phydm_get_thermal_trim_offset_8198f(void *dm_void) + power_trim_info->thermal); + } + ++void phydm_get_power_trim_offset_8198f(void *dm_void); + void phydm_get_power_trim_offset_8198f(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -843,6 +865,7 @@ void phydm_get_power_trim_offset_8198f(void *dm_void) + } + } + ++void phydm_set_kfree_to_rf_8198f(void *dm_void, u8 e_rf_path, u8 data); + void phydm_set_kfree_to_rf_8198f(void *dm_void, u8 e_rf_path, u8 data) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -885,6 +908,7 @@ void phydm_set_kfree_to_rf_8198f(void *dm_void, u8 e_rf_path, u8 data) + + } + ++void phydm_clear_kfree_to_rf_8198f(void *dm_void, u8 e_rf_path, u8 data); + void phydm_clear_kfree_to_rf_8198f(void *dm_void, u8 e_rf_path, u8 data) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -930,6 +954,7 @@ void phydm_clear_kfree_to_rf_8198f(void *dm_void, u8 e_rf_path, u8 data) + } + + ++void phydm_set_kfree_to_rf(void *dm_void, u8 e_rf_path, u8 data); + void phydm_set_kfree_to_rf(void *dm_void, u8 e_rf_path, u8 data) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -1048,6 +1073,7 @@ s8 phydm_get_thermal_offset(void *dm_void) + return 0; + } + ++void phydm_do_kfree(void *dm_void, u8 channel_to_sw); + void phydm_do_kfree(void *dm_void, u8 channel_to_sw) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +diff --git a/drivers/staging/rtl8812au/hal/phydm/halrf/halrf_powertracking_ce.c b/drivers/staging/rtl8812au/hal/phydm/halrf/halrf_powertracking_ce.c +index 55ec7bf16..32671c854 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/halrf/halrf_powertracking_ce.c ++++ b/drivers/staging/rtl8812au/hal/phydm/halrf/halrf_powertracking_ce.c +@@ -592,6 +592,7 @@ void odm_txpowertracking_init(void *dm_void) + odm_txpowertracking_thermal_meter_init(dm); + } + ++u8 get_swing_index(void *dm_void); + u8 get_swing_index(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -642,6 +643,7 @@ u8 get_swing_index(void *dm_void) + return i; + } + ++u8 get_cck_swing_index(void *dm_void); + u8 get_cck_swing_index(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +diff --git a/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8812a/halrf_8812a_ce.c b/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8812a/halrf_8812a_ce.c +index cebb7265d..a66721465 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8812a/halrf_8812a_ce.c ++++ b/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8812a/halrf_8812a_ce.c +@@ -428,6 +428,8 @@ void configure_txpower_track_8812a(struct txpwrtrack_cfg *config) + #define BW_40M 1 + #define BW_80M 2 + ++void _iqk_rx_fill_iqc_8812a(struct dm_struct *dm, enum rf_path path, ++ unsigned int RX_X, unsigned int RX_Y); + void _iqk_rx_fill_iqc_8812a(struct dm_struct *dm, enum rf_path path, + unsigned int RX_X, unsigned int RX_Y) + { +@@ -473,6 +475,8 @@ void _iqk_rx_fill_iqc_8812a(struct dm_struct *dm, enum rf_path path, + }; + } + ++void _iqk_tx_fill_iqc_8812a(struct dm_struct *dm, enum rf_path path, ++ unsigned int TX_X, unsigned int TX_Y); + void _iqk_tx_fill_iqc_8812a(struct dm_struct *dm, enum rf_path path, + unsigned int TX_X, unsigned int TX_Y) + { +@@ -518,6 +522,8 @@ void _iqk_tx_fill_iqc_8812a(struct dm_struct *dm, enum rf_path path, + }; + } + ++void _iqk_backup_mac_bb_8812a(struct dm_struct *dm, u32 *MACBB_backup, ++ u32 *backup_macbb_reg, u32 MACBB_NUM); + void _iqk_backup_mac_bb_8812a(struct dm_struct *dm, u32 *MACBB_backup, + u32 *backup_macbb_reg, u32 MACBB_NUM) + { +@@ -529,6 +535,8 @@ void _iqk_backup_mac_bb_8812a(struct dm_struct *dm, u32 *MACBB_backup, + + RF_DBG(dm, DBG_RF_IQK, "BackupMacBB Success!!!!\n"); + } ++void _iqk_backup_rf_8812a(struct dm_struct *dm, u32 *RFA_backup, ++ u32 *RFB_backup, u32 *backup_rf_reg, u32 RF_NUM); + void _iqk_backup_rf_8812a(struct dm_struct *dm, u32 *RFA_backup, + u32 *RFB_backup, u32 *backup_rf_reg, u32 RF_NUM) + { +@@ -541,6 +549,8 @@ void _iqk_backup_rf_8812a(struct dm_struct *dm, u32 *RFA_backup, + } + RF_DBG(dm, DBG_RF_IQK, "BackupRF Success!!!!\n"); + } ++void _iqk_backup_afe_8812a(struct dm_struct *dm, u32 *AFE_backup, ++ u32 *backup_afe_reg, u32 AFE_NUM); + void _iqk_backup_afe_8812a(struct dm_struct *dm, u32 *AFE_backup, + u32 *backup_afe_reg, u32 AFE_NUM) + { +@@ -551,6 +561,8 @@ void _iqk_backup_afe_8812a(struct dm_struct *dm, u32 *AFE_backup, + AFE_backup[i] = odm_read_4byte(dm, backup_afe_reg[i]); + RF_DBG(dm, DBG_RF_IQK, "BackupAFE Success!!!!\n"); + } ++void _iqk_restore_mac_bb_8812a(struct dm_struct *dm, u32 *MACBB_backup, ++ u32 *backup_macbb_reg, u32 MACBB_NUM); + void _iqk_restore_mac_bb_8812a(struct dm_struct *dm, u32 *MACBB_backup, + u32 *backup_macbb_reg, u32 MACBB_NUM) + { +@@ -561,6 +573,8 @@ void _iqk_restore_mac_bb_8812a(struct dm_struct *dm, u32 *MACBB_backup, + odm_write_4byte(dm, backup_macbb_reg[i], MACBB_backup[i]); + RF_DBG(dm, DBG_RF_IQK, "RestoreMacBB Success!!!!\n"); + } ++void _iqk_restore_rf_8812a(struct dm_struct *dm, enum rf_path path, ++ u32 *backup_rf_reg, u32 *RF_backup, u32 RF_REG_NUM); + void _iqk_restore_rf_8812a(struct dm_struct *dm, enum rf_path path, + u32 *backup_rf_reg, u32 *RF_backup, u32 RF_REG_NUM) + { +@@ -583,6 +597,8 @@ void _iqk_restore_rf_8812a(struct dm_struct *dm, enum rf_path path, + break; + } + } ++void _iqk_restore_afe_8812a(struct dm_struct *dm, u32 *AFE_backup, ++ u32 *backup_afe_reg, u32 AFE_NUM); + void _iqk_restore_afe_8812a(struct dm_struct *dm, u32 *AFE_backup, + u32 *backup_afe_reg, u32 AFE_NUM) + { +@@ -616,6 +632,7 @@ void _iqk_restore_afe_8812a(struct dm_struct *dm, u32 *AFE_backup, + RF_DBG(dm, DBG_RF_IQK, "RestoreAFE Success!!!!\n"); + } + ++void _iqk_configure_mac_8812a(struct dm_struct *dm); + void _iqk_configure_mac_8812a(struct dm_struct *dm) + { + /* ========MAC register setting======== */ +@@ -629,6 +646,7 @@ void _iqk_configure_mac_8812a(struct dm_struct *dm) + + #define cal_num 10 + ++void _iqk_tx_8812a(struct dm_struct *dm, u8 chnl_idx); + void _iqk_tx_8812a(struct dm_struct *dm, u8 chnl_idx) + { + u8 delay_count, cal = 0; +@@ -1122,6 +1140,7 @@ void _iqk_tx_8812a(struct dm_struct *dm, u8 chnl_idx) + #define RF_REG_NUM 3 + + /* Maintained by BB James. */ ++void _phy_iq_calibrate_8812a(struct dm_struct *dm, u8 channel); + void _phy_iq_calibrate_8812a(struct dm_struct *dm, u8 channel) + { + u32 MACBB_backup[MACBB_REG_NUM], AFE_backup[AFE_REG_NUM] = {0}, RFA_backup[RF_REG_NUM] = {0}, RFB_backup[RF_REG_NUM] = {0}; +@@ -1153,6 +1172,7 @@ void _phy_iq_calibrate_8812a(struct dm_struct *dm, u8 channel) + _iqk_restore_mac_bb_8812a(dm, MACBB_backup, backup_macbb_reg, MACBB_REG_NUM); + } + ++void _phy_lc_calibrate_8812a(struct dm_struct *dm, boolean is2T); + void _phy_lc_calibrate_8812a(struct dm_struct *dm, boolean is2T) + { + u32 /*rf_amode=0, rf_bmode=0,*/ lc_cal = 0, tmp = 0; +@@ -1218,6 +1238,7 @@ void _phy_lc_calibrate_8812a(struct dm_struct *dm, boolean is2T) + */ + } + ++void phy_reload_iqk_setting_8812a(struct dm_struct *dm, u8 channel); + void phy_reload_iqk_setting_8812a(struct dm_struct *dm, u8 channel) + { + struct dm_rf_calibration_struct *cali_info = &(dm->rf_calibrate_info); +@@ -1243,6 +1264,7 @@ void phy_reload_iqk_setting_8812a(struct dm_struct *dm, u8 channel) + odm_set_bb_reg(dm, R_0xe10, 0x03ff0000, (cali_info->iqk_matrix_reg_setting[chnl_idx].value[*dm->band_width][3] & 0x7ff) >> 1); + } + ++void phy_reset_iqk_result_8812a(struct dm_struct *dm); + void phy_reset_iqk_result_8812a(struct dm_struct *dm) + { + odm_set_bb_reg(dm, R_0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */ +@@ -1257,6 +1279,7 @@ void phy_reset_iqk_result_8812a(struct dm_struct *dm) + odm_set_bb_reg(dm, R_0xe10, 0x000003ff, 0x100); + } + ++void _phy_iq_calibrate_by_fw_8812a(struct dm_struct *dm); + void _phy_iq_calibrate_by_fw_8812a(struct dm_struct *dm) + { + u8 iqk_cmd[3] = {*dm->channel, 0x0, 0x0}; +diff --git a/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8814a/halrf_8814a_ce.c b/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8814a/halrf_8814a_ce.c +index 09c65ed3f..41ce0a6dd 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8814a/halrf_8814a_ce.c ++++ b/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8814a/halrf_8814a_ce.c +@@ -400,6 +400,11 @@ void configure_txpower_track_8814a( + pConfig->get_delta_swing_table8814only = GetDeltaSwingTable_8814A_PathCD; + } + ++VOID ++_phy_lc_calibrate_8814a( ++ IN struct dm_struct * pDM_Odm, ++ IN BOOLEAN is2T ++ ); + VOID + _phy_lc_calibrate_8814a( + IN struct dm_struct * pDM_Odm, +@@ -513,6 +518,10 @@ PHY_DPCalibrate_8814A( + } + + ++BOOLEAN ++phy_QueryRFPathSwitch_8814A( ++ IN PADAPTER pAdapter ++ ); + BOOLEAN + phy_QueryRFPathSwitch_8814A( + IN PADAPTER pAdapter +diff --git a/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8814a/halrf_iqk_8814a.c b/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8814a/halrf_iqk_8814a.c +index e019df35a..f8a7a020d 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8814a/halrf_iqk_8814a.c ++++ b/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8814a/halrf_iqk_8814a.c +@@ -63,6 +63,14 @@ void DoIQK_8814A( + #endif + //1 7. IQK + ++VOID ++_IQK_BackupMacBB_8814A( ++ IN struct dm_struct * pDM_Odm, ++ u32* MAC_backup, ++ u32* BB_backup, ++ u32* Backup_MAC_REG, ++ u32* Backup_BB_REG ++ ); + VOID + _IQK_BackupMacBB_8814A( + IN struct dm_struct * pDM_Odm, +@@ -90,7 +98,13 @@ _IQK_BackupRF_8814A( + IN struct dm_struct * pDM_Odm, + u32 RF_backup[][4], + u32* Backup_RF_REG +- ) ++ ); ++VOID ++_IQK_BackupRF_8814A( ++ IN struct dm_struct * pDM_Odm, ++ u32 RF_backup[][4], ++ u32* Backup_RF_REG ++ ) + { + u32 i; + //Save RF Parameters +@@ -105,6 +119,11 @@ _IQK_BackupRF_8814A( + } + + ++VOID ++_IQK_AFESetting_8814A( ++ IN struct dm_struct * pDM_Odm, ++ IN boolean Do_IQK ++ ); + VOID + _IQK_AFESetting_8814A( + IN struct dm_struct * pDM_Odm, +@@ -155,7 +174,15 @@ _IQK_RestoreMacBB_8814A( + u32* BB_backup, + u32* Backup_MAC_REG, + u32* Backup_BB_REG +- ) ++ ); ++VOID ++_IQK_RestoreMacBB_8814A( ++ IN struct dm_struct * pDM_Odm, ++ u32* MAC_backup, ++ u32* BB_backup, ++ u32* Backup_MAC_REG, ++ u32* Backup_BB_REG ++ ) + { + u32 i; + //Reload MacBB Parameters +@@ -168,6 +195,12 @@ _IQK_RestoreMacBB_8814A( + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("RestoreMacBB Success!!!!\n")); + } + ++VOID ++_IQK_RestoreRF_8814A( ++ IN struct dm_struct * pDM_Odm, ++ u32* Backup_RF_REG, ++ u32 RF_backup[][4] ++ ); + VOID + _IQK_RestoreRF_8814A( + IN struct dm_struct * pDM_Odm, +@@ -193,6 +226,10 @@ _IQK_RestoreRF_8814A( + + } + ++VOID ++PHY_ResetIQKResult_8814A( ++ IN struct dm_struct * pDM_Odm ++); + VOID + PHY_ResetIQKResult_8814A( + IN struct dm_struct * pDM_Odm +@@ -212,6 +249,10 @@ PHY_ResetIQKResult_8814A( + odm_write_4byte(pDM_Odm, 0x1a10, 0x100); + } + ++VOID ++_IQK_ResetNCTL_8814A( ++ IN struct dm_struct * pDM_Odm ++); + VOID + _IQK_ResetNCTL_8814A( + IN struct dm_struct * pDM_Odm +@@ -224,6 +265,10 @@ _IQK_ResetNCTL_8814A( + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("ResetNCTL Success!!!!\n")); + } + ++VOID ++_IQK_ConfigureMAC_8814A( ++ IN struct dm_struct * pDM_Odm ++ ); + VOID + _IQK_ConfigureMAC_8814A( + IN struct dm_struct * pDM_Odm +@@ -244,6 +289,10 @@ _IQK_ConfigureMAC_8814A( + odm_set_bb_reg(pDM_Odm, 0xcbc, 0xf, 0x0); + } + ++VOID ++_LOK_One_Shot( ++ IN void* pDM_VOID ++); + VOID + _LOK_One_Shot( + IN void* pDM_VOID +@@ -314,6 +363,10 @@ _LOK_One_Shot( + pIQK_info->lok_fail[0], pIQK_info->lok_fail[1], pIQK_info->lok_fail[2], pIQK_info->lok_fail[3])); + } + ++VOID ++_IQK_One_Shot( ++ IN void* pDM_VOID ++); + VOID + _IQK_One_Shot( + IN void* pDM_VOID +@@ -434,6 +487,11 @@ _IQK_One_Shot( + } + } + ++VOID ++_IQK_Tx_8814A( ++ IN struct dm_struct * pDM_Odm, ++ IN u8 chnlIdx ++ ); + VOID + _IQK_Tx_8814A( + IN struct dm_struct * pDM_Odm, +@@ -469,6 +527,11 @@ _IQK_Tx_8814A( + + } + ++VOID ++_phy_iq_calibrate_8814a( ++ IN struct dm_struct * pDM_Odm, ++ IN u8 Channel ++ ); + VOID + _phy_iq_calibrate_8814a( + IN struct dm_struct * pDM_Odm, +diff --git a/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8821a/halrf_iqk_8821a_ce.c b/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8821a/halrf_iqk_8821a_ce.c +index b6491baf7..cc46c94e1 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8821a/halrf_iqk_8821a_ce.c ++++ b/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8821a/halrf_iqk_8821a_ce.c +@@ -37,6 +37,12 @@ void do_iqk_8821a( + halrf_iqk_trigger(dm, false); + } + #endif ++void _iqk_rx_fill_iqc_8821a( ++ struct dm_struct *dm, ++ enum rf_path path, ++ unsigned int RX_X, ++ unsigned int RX_Y ++); + void _iqk_rx_fill_iqc_8821a( + struct dm_struct *dm, + enum rf_path path, +@@ -59,6 +65,12 @@ void _iqk_rx_fill_iqc_8821a( + }; + } + ++void _iqk_tx_fill_iqc_8821a( ++ struct dm_struct *dm, ++ enum rf_path path, ++ unsigned int TX_X, ++ unsigned int TX_Y ++); + void _iqk_tx_fill_iqc_8821a( + struct dm_struct *dm, + enum rf_path path, +@@ -84,6 +96,12 @@ void _iqk_tx_fill_iqc_8821a( + }; + } + ++void _iqk_backup_mac_bb_8821a( ++ struct dm_struct *dm, ++ u32 *MACBB_backup, ++ u32 *backup_macbb_reg, ++ u32 MACBB_NUM ++); + void _iqk_backup_mac_bb_8821a( + struct dm_struct *dm, + u32 *MACBB_backup, +@@ -100,6 +118,13 @@ void _iqk_backup_mac_bb_8821a( + PHYDM_DBG(dm, DBG_COMP_MCC, "BackupMacBB Success!!!!\n"); + } + ++void _iqk_backup_rf_8821a( ++ struct dm_struct *dm, ++ u32 *RFA_backup, ++ u32 *RFB_backup, ++ u32 *backup_rf_reg, ++ u32 RF_NUM ++); + void _iqk_backup_rf_8821a( + struct dm_struct *dm, + u32 *RFA_backup, +@@ -117,6 +142,12 @@ void _iqk_backup_rf_8821a( + PHYDM_DBG(dm, DBG_COMP_MCC, "BackupRF Success!!!!\n"); + } + ++void _iqk_backup_afe_8821a( ++ struct dm_struct *dm, ++ u32 *AFE_backup, ++ u32 *backup_afe_reg, ++ u32 AFE_NUM ++); + void _iqk_backup_afe_8821a( + struct dm_struct *dm, + u32 *AFE_backup, +@@ -132,6 +163,12 @@ void _iqk_backup_afe_8821a( + PHYDM_DBG(dm, DBG_COMP_MCC, "BackupAFE Success!!!!\n"); + } + ++void _iqk_restore_mac_bb_8821a( ++ struct dm_struct *dm, ++ u32 *MACBB_backup, ++ u32 *backup_macbb_reg, ++ u32 MACBB_NUM ++); + void _iqk_restore_mac_bb_8821a( + struct dm_struct *dm, + u32 *MACBB_backup, +@@ -147,6 +184,13 @@ void _iqk_restore_mac_bb_8821a( + PHYDM_DBG(dm, DBG_COMP_MCC, "RestoreMacBB Success!!!!\n"); + } + ++void _iqk_restore_rf_8821a( ++ struct dm_struct *dm, ++ enum rf_path path, ++ u32 *backup_rf_reg, ++ u32 *RF_backup, ++ u32 RF_REG_NUM ++); + void _iqk_restore_rf_8821a( + struct dm_struct *dm, + enum rf_path path, +@@ -172,6 +216,12 @@ void _iqk_restore_rf_8821a( + } + } + ++void _iqk_restore_afe_8821a( ++ struct dm_struct *dm, ++ u32 *AFE_backup, ++ u32 *backup_afe_reg, ++ u32 AFE_NUM ++); + void _iqk_restore_afe_8821a( + struct dm_struct *dm, + u32 *AFE_backup, +@@ -197,6 +247,9 @@ void _iqk_restore_afe_8821a( + PHYDM_DBG(dm, DBG_COMP_MCC, "RestoreAFE Success!!!!\n"); + } + ++void _iqk_configure_mac_8821a( ++ struct dm_struct *dm ++); + void _iqk_configure_mac_8821a( + struct dm_struct *dm + ) +@@ -210,6 +263,10 @@ void _iqk_configure_mac_8821a( + odm_write_1byte(dm, 0xa07, 0xf); /* CCK RX path off */ + } + ++void _iqk_tx_8821a( ++ struct dm_struct *dm, ++ enum rf_path path ++); + void _iqk_tx_8821a( + struct dm_struct *dm, + enum rf_path path +@@ -680,6 +737,10 @@ void _iqk_tx_8821a( + + #if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + void ++_phy_iq_calibrate_by_fw_8821a( ++ struct dm_struct *dm ++); ++void + _phy_iq_calibrate_by_fw_8821a( + struct dm_struct *dm + ) +@@ -714,6 +775,10 @@ _phy_iq_calibrate_by_fw_8821a( + } + #endif + ++void ++_phy_iq_calibrate_8821a( ++ struct dm_struct *dm ++); + void + _phy_iq_calibrate_8821a( + struct dm_struct *dm +@@ -736,6 +801,10 @@ _phy_iq_calibrate_8821a( + _iqk_restore_mac_bb_8821a(dm, MACBB_backup, backup_macbb_reg, MACBB_REG_NUM_8821A); + } + ++void ++phy_reset_iqk_result_8821a( ++ struct dm_struct *dm ++); + void + phy_reset_iqk_result_8821a( + struct dm_struct *dm +diff --git a/drivers/staging/rtl8812au/hal/phydm/phydm.c b/drivers/staging/rtl8812au/hal/phydm/phydm.c +index 1e980630e..867e8a073 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/phydm.c ++++ b/drivers/staging/rtl8812au/hal/phydm/phydm.c +@@ -38,6 +38,7 @@ const u16 phy_rate_table[] = { + 13, 26, 39, 52, 78, 104, 117, 130 /*@MCS8~15*/ + }; + ++void phydm_traffic_load_decision(void *dm_void); + void phydm_traffic_load_decision(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -109,6 +110,7 @@ void phydm_traffic_load_decision(void *dm_void) + #endif + } + ++void phydm_cck_new_agc_chk(struct dm_struct *dm); + void phydm_cck_new_agc_chk(struct dm_struct *dm) + { + dm->cck_new_agc = 0; +@@ -132,6 +134,7 @@ void phydm_cck_new_agc_chk(struct dm_struct *dm) + } + + /*select 3 or 4 bit LNA */ ++void phydm_cck_lna_bit_num_chk(struct dm_struct *dm); + void phydm_cck_lna_bit_num_chk(struct dm_struct *dm) + { + boolean report_type = 0; +@@ -177,6 +180,7 @@ void phydm_cck_lna_bit_num_chk(struct dm_struct *dm) + dm->cck_agc_report_type); + } + ++void phydm_init_cck_setting(struct dm_struct *dm); + void phydm_init_cck_setting(struct dm_struct *dm) + { + u32 reg_tmp = 0; +@@ -200,6 +204,7 @@ void phydm_init_cck_setting(struct dm_struct *dm) + phydm_get_cck_rssi_table_from_reg(dm); + } + ++void phydm_init_hw_info_by_rfe(struct dm_struct *dm); + void phydm_init_hw_info_by_rfe(struct dm_struct *dm) + { + #if (RTL8822B_SUPPORT == 1) +@@ -216,6 +221,7 @@ void phydm_init_hw_info_by_rfe(struct dm_struct *dm) + #endif + } + ++void phydm_common_info_self_init(struct dm_struct *dm); + void phydm_common_info_self_init(struct dm_struct *dm) + { + u32 reg_tmp = 0; +@@ -298,6 +304,7 @@ void phydm_common_info_self_init(struct dm_struct *dm) + dm->pause_lv_table.lv_dig = PHYDM_PAUSE_RELEASE; + } + ++void phydm_cmn_sta_info_update(void *dm_void, u8 macid); + void phydm_cmn_sta_info_update(void *dm_void, u8 macid) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -326,6 +333,7 @@ void phydm_cmn_sta_info_update(void *dm_void, u8 macid) + ra->is_noisy = dm->noisy_decision; + } + ++void phydm_common_info_self_update(struct dm_struct *dm); + void phydm_common_info_self_update(struct dm_struct *dm) + { + u8 sta_cnt = 0, num_active_client = 0; +@@ -431,6 +439,7 @@ void phydm_common_info_self_update(struct dm_struct *dm) + dm->phy_dbg_info.show_phy_sts_cnt = 0; + } + ++void phydm_common_info_self_reset(struct dm_struct *dm); + void phydm_common_info_self_reset(struct dm_struct *dm) + { + struct odm_phy_dbg_info *dbg_t = &dm->phy_dbg_info; +@@ -474,6 +483,7 @@ phydm_get_structure(struct dm_struct *dm, u8 structure_type) + return structure; + } + ++void phydm_phy_info_update(struct dm_struct *dm); + void phydm_phy_info_update(struct dm_struct *dm) + { + #if (RTL8822B_SUPPORT == 1) +@@ -482,6 +492,7 @@ void phydm_phy_info_update(struct dm_struct *dm) + #endif + } + ++void phydm_hw_setting(struct dm_struct *dm); + void phydm_hw_setting(struct dm_struct *dm) + { + #if (RTL8821A_SUPPORT == 1) +@@ -783,6 +794,7 @@ u64 phydm_supportability_init_win( + #endif + + #if (DM_ODM_SUPPORT_TYPE & (ODM_CE)) ++u64 phydm_supportability_init_ce(void *dm_void); + u64 phydm_supportability_init_ce(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -1401,6 +1413,7 @@ void phydm_fwoffload_ability_clear(struct dm_struct *dm, + dm->fw_offload_ability); + } + ++void phydm_supportability_init(void *dm_void); + void phydm_supportability_init(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -1440,6 +1453,7 @@ void phydm_supportability_init(void *dm_void) + dm->support_ic_type, *dm->mp_mode, dm->support_ability); + } + ++void phydm_rfe_init(void *dm_void); + void phydm_rfe_init(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -1970,6 +1984,7 @@ void phydm_pause_func_console(void *dm_void, char input[][16], u32 *_used, + *_out_len = out_len; + } + ++u8 phydm_stop_dm_watchdog_check(void *dm_void); + u8 phydm_stop_dm_watchdog_check(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +diff --git a/drivers/staging/rtl8812au/hal/phydm/phydm_adaptivity.c b/drivers/staging/rtl8812au/hal/phydm/phydm_adaptivity.c +index 086903624..e72e9d41d 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/phydm_adaptivity.c ++++ b/drivers/staging/rtl8812au/hal/phydm/phydm_adaptivity.c +@@ -111,6 +111,7 @@ phydm_soft_ap_special_set(void *dm_void) + } + #endif + ++void phydm_dig_up_bound_lmt_en(void *dm_void); + void phydm_dig_up_bound_lmt_en(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -140,6 +141,7 @@ void phydm_dig_up_bound_lmt_en(void *dm_void) + adapt->igi_up_bound_lmt_cnt); + } + ++void phydm_check_adaptivity(void *dm_void); + void phydm_check_adaptivity(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -174,6 +176,7 @@ void phydm_check_adaptivity(void *dm_void) + #endif + } + ++void phydm_set_edcca_threshold(void *dm_void, s8 H2L, s8 L2H); + void phydm_set_edcca_threshold(void *dm_void, s8 H2L, s8 L2H) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -190,6 +193,7 @@ void phydm_set_edcca_threshold(void *dm_void, s8 H2L, s8 L2H) + } + } + ++void phydm_mac_edcca_state(void *dm_void, enum phydm_mac_edcca_type state); + void phydm_mac_edcca_state(void *dm_void, enum phydm_mac_edcca_type state) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -208,6 +212,7 @@ void phydm_mac_edcca_state(void *dm_void, enum phydm_mac_edcca_type state) + PHYDM_DBG(dm, DBG_ADPTVTY, "EDCCA enable state = %d\n", state); + } + ++void phydm_search_pwdb_lower_bound(void *dm_void); + void phydm_search_pwdb_lower_bound(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -285,6 +290,8 @@ void phydm_search_pwdb_lower_bound(void *dm_void) + phydm_set_edcca_threshold(dm, 0x7f, 0x7f); /*resume to no link state*/ + } + ++boolean ++phydm_re_search_condition(void *dm_void); + boolean + phydm_re_search_condition(void *dm_void) + { +@@ -298,6 +305,7 @@ phydm_re_search_condition(void *dm_void) + return false; + } + ++void phydm_set_l2h_th_ini(void *dm_void); + void phydm_set_l2h_th_ini(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -317,6 +325,7 @@ void phydm_set_l2h_th_ini(void *dm_void) + } + } + ++void phydm_set_forgetting_factor(void *dm_void); + void phydm_set_forgetting_factor(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -327,6 +336,7 @@ void phydm_set_forgetting_factor(void *dm_void) + odm_set_bb_reg(dm, R_0x83c, BIT(31) | BIT(30) | BIT(29), 0x7); + } + ++void phydm_set_pwdb_mode(void *dm_void); + void phydm_set_pwdb_mode(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -445,6 +455,7 @@ void phydm_set_edcca_val(void *dm_void, u32 *val_buf, u8 val_len) + phydm_set_edcca_threshold(dm, (s8)val_buf[1], (s8)val_buf[0]); + } + ++boolean phydm_edcca_abort(void *dm_void); + boolean phydm_edcca_abort(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +diff --git a/drivers/staging/rtl8812au/hal/phydm/phydm_adc_sampling.c b/drivers/staging/rtl8812au/hal/phydm/phydm_adc_sampling.c +index d2278560e..903aa635b 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/phydm_adc_sampling.c ++++ b/drivers/staging/rtl8812au/hal/phydm/phydm_adc_sampling.c +@@ -43,6 +43,8 @@ + + #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE | ODM_AP)) + boolean ++phydm_la_buffer_allocate(void *dm_void); ++boolean + phydm_la_buffer_allocate(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -77,6 +79,7 @@ phydm_la_buffer_allocate(void *dm_void) + } + #endif + ++void phydm_la_get_tx_pkt_buf(void *dm_void); + void phydm_la_get_tx_pkt_buf(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -260,6 +263,7 @@ void phydm_la_get_tx_pkt_buf(void *dm_void) + #endif + } + ++void phydm_la_mode_set_mac_iq_dump(void *dm_void, boolean en_fake_trig); + void phydm_la_mode_set_mac_iq_dump(void *dm_void, boolean en_fake_trig) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -327,6 +331,7 @@ void phydm_la_mode_set_mac_iq_dump(void *dm_void, boolean en_fake_trig) + #endif + } + ++void phydm_adc_smp_start(void *dm_void); + void phydm_adc_smp_start(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +diff --git a/drivers/staging/rtl8812au/hal/phydm/phydm_api.c b/drivers/staging/rtl8812au/hal/phydm/phydm_api.c +index f84279c39..f16510291 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/phydm_api.c ++++ b/drivers/staging/rtl8812au/hal/phydm/phydm_api.c +@@ -105,6 +105,7 @@ void phydm_ant_weight_dbg(void *dm_void, char input[][16], u32 *_used, + } + #endif + ++void phydm_iq_gen_en(void *dm_void); + void phydm_iq_gen_en(void *dm_void) + { + #ifdef PHYDM_COMPILE_IC_2SS +@@ -160,6 +161,7 @@ void phydm_iq_gen_en(void *dm_void) + #endif + } + ++void phydm_dis_cdd(void *dm_void); + void phydm_dis_cdd(void *dm_void) + { + #ifdef PHYDM_COMPILE_IC_2SS +@@ -310,6 +312,7 @@ void phydm_trx_antenna_setting_init(void *dm_void, u8 num_rf_path) + __func__, dm->tx_ant_status, dm->rx_ant_status); + } + ++void phydm_config_ofdm_tx_path(void *dm_void, u32 path); + void phydm_config_ofdm_tx_path(void *dm_void, u32 path) + { + #if (RTL8192E_SUPPORT || RTL8812A_SUPPORT) +@@ -475,6 +478,7 @@ void phydm_config_cck_rx_path(void *dm_void, enum bb_path path) + #endif + } + ++void phydm_config_cck_tx_path(void *dm_void, enum bb_path path); + void phydm_config_cck_tx_path(void *dm_void, enum bb_path path) + { + #if (defined(PHYDM_COMPILE_ABOVE_2SS)) +@@ -489,6 +493,8 @@ void phydm_config_cck_tx_path(void *dm_void, enum bb_path path) + #endif + } + ++void phydm_config_trx_path_v2(void *dm_void, char input[][16], u32 *_used, ++ char *output, u32 *_out_len); + void phydm_config_trx_path_v2(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) + { +@@ -542,6 +548,8 @@ void phydm_config_trx_path_v2(void *dm_void, char input[][16], u32 *_used, + #endif + } + ++void phydm_config_trx_path_v1(void *dm_void, char input[][16], u32 *_used, ++ char *output, u32 *_out_len); + void phydm_config_trx_path_v1(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) + { +@@ -895,6 +903,7 @@ void phydm_set_ext_switch(void *dm_void, u32 ext_ant_switch) + #endif + } + ++void phydm_csi_mask_enable(void *dm_void, u32 enable); + void phydm_csi_mask_enable(void *dm_void, u32 enable) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -919,6 +928,7 @@ void phydm_csi_mask_enable(void *dm_void, u32 enable) + } + } + ++void phydm_clean_all_csi_mask(void *dm_void); + void phydm_clean_all_csi_mask(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -957,6 +967,7 @@ void phydm_clean_all_csi_mask(void *dm_void) + } + } + ++void phydm_set_csi_mask(void *dm_void, u32 tone_idx_tmp, u8 tone_direction); + void phydm_set_csi_mask(void *dm_void, u32 tone_idx_tmp, u8 tone_direction) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -1016,6 +1027,7 @@ void phydm_set_csi_mask(void *dm_void, u32 tone_idx_tmp, u8 tone_direction) + (tone_idx_tmp + tone_num_shift), target_reg, reg_tmp_value); + } + ++void phydm_set_nbi_reg(void *dm_void, u32 tone_idx_tmp, u32 bw); + void phydm_set_nbi_reg(void *dm_void, u32 tone_idx_tmp, u32 bw) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -1111,6 +1123,7 @@ void phydm_nbi_enable(void *dm_void, u32 enable) + } + } + ++u8 phydm_find_fc(void *dm_void, u32 channel, u32 bw, u32 second_ch, u32 *fc_in); + u8 phydm_find_fc(void *dm_void, u32 channel, u32 bw, u32 second_ch, u32 *fc_in) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -1186,6 +1199,8 @@ u8 phydm_find_fc(void *dm_void, u32 channel, u32 bw, u32 second_ch, u32 *fc_in) + return PHYDM_SET_SUCCESS; + } + ++u8 phydm_find_intf_distance(void *dm_void, u32 bw, u32 fc, u32 f_interference, ++ u32 *tone_idx_tmp_in); + u8 phydm_find_intf_distance(void *dm_void, u32 bw, u32 fc, u32 f_interference, + u32 *tone_idx_tmp_in) + { +@@ -2577,6 +2592,7 @@ phydm_api_trx_mode(void *dm_void, enum bb_path tx_path, enum bb_path rx_path, + return ret; + } + #else ++u8 config_phydm_read_txagc_n(void *dm_void, enum rf_path path, u8 hw_rate); + u8 config_phydm_read_txagc_n(void *dm_void, enum rf_path path, u8 hw_rate) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +diff --git a/drivers/staging/rtl8812au/hal/phydm/phydm_beamforming.c b/drivers/staging/rtl8812au/hal/phydm/phydm_beamforming.c +index bc4855c15..be4246612 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/phydm_beamforming.c ++++ b/drivers/staging/rtl8812au/hal/phydm/phydm_beamforming.c +@@ -92,6 +92,8 @@ void phydm_get_txbf_device_num( + } + + struct _RT_BEAMFORM_STAINFO * ++phydm_sta_info_init(struct dm_struct *dm, u16 sta_idx, u8 *my_mac_addr); ++struct _RT_BEAMFORM_STAINFO * + phydm_sta_info_init(struct dm_struct *dm, u16 sta_idx, u8 *my_mac_addr) + { + struct _RT_BEAMFORMING_INFO *beam_info = &dm->beamforming_info; +@@ -158,6 +160,10 @@ phydm_sta_info_init(struct dm_struct *dm, u16 sta_idx, u8 *my_mac_addr) + entry->cur_beamform, entry->cur_beamform_vht); + return entry; + } ++void phydm_sta_info_update( ++ struct dm_struct *dm, ++ u16 sta_idx, ++ struct _RT_BEAMFORMEE_ENTRY *beamform_entry); + void phydm_sta_info_update( + struct dm_struct *dm, + u16 sta_idx, +@@ -213,6 +219,11 @@ phydm_beamforming_get_bfer_entry_by_addr( + } + + struct _RT_BEAMFORMEE_ENTRY * ++phydm_beamforming_get_entry_by_mac_id( ++ void *dm_void, ++ u8 mac_id, ++ u8 *idx); ++struct _RT_BEAMFORMEE_ENTRY * + phydm_beamforming_get_entry_by_mac_id( + void *dm_void, + u8 mac_id, +@@ -253,6 +264,10 @@ phydm_beamforming_get_entry_beam_cap_by_mac_id( + } + + struct _RT_BEAMFORMEE_ENTRY * ++phydm_beamforming_get_free_bfee_entry( ++ void *dm_void, ++ u8 *idx); ++struct _RT_BEAMFORMEE_ENTRY * + phydm_beamforming_get_free_bfee_entry( + void *dm_void, + u8 *idx) +@@ -271,6 +286,10 @@ phydm_beamforming_get_free_bfee_entry( + } + + struct _RT_BEAMFORMER_ENTRY * ++phydm_beamforming_get_free_bfer_entry( ++ void *dm_void, ++ u8 *idx); ++struct _RT_BEAMFORMER_ENTRY * + phydm_beamforming_get_free_bfer_entry( + void *dm_void, + u8 *idx) +@@ -298,6 +317,8 @@ phydm_beamforming_get_free_bfer_entry( + * 2015.05.25. Created by tynli. + * + */ ++u8 phydm_beamforming_get_first_mu_bfee_entry_idx( ++ void *dm_void); + u8 phydm_beamforming_get_first_mu_bfee_entry_idx( + void *dm_void) + { +@@ -323,6 +344,14 @@ u8 phydm_beamforming_get_first_mu_bfee_entry_idx( + + /*@Add SU BFee and MU BFee*/ + struct _RT_BEAMFORMEE_ENTRY * ++beamforming_add_bfee_entry( ++ void *dm_void, ++ struct _RT_BEAMFORM_STAINFO *sta, ++ enum beamforming_cap beamform_cap, ++ u8 num_of_sounding_dim, ++ u8 comp_steering_num_of_bfer, ++ u8 *idx); ++struct _RT_BEAMFORMEE_ENTRY * + beamforming_add_bfee_entry( + void *dm_void, + struct _RT_BEAMFORM_STAINFO *sta, +@@ -400,6 +429,13 @@ beamforming_add_bfee_entry( + + /*@Add SU BFee and MU BFer*/ + struct _RT_BEAMFORMER_ENTRY * ++beamforming_add_bfer_entry( ++ void *dm_void, ++ struct _RT_BEAMFORM_STAINFO *sta, ++ enum beamforming_cap beamform_cap, ++ u8 num_of_sounding_dim, ++ u8 *idx); ++struct _RT_BEAMFORMER_ENTRY * + beamforming_add_bfer_entry( + void *dm_void, + struct _RT_BEAMFORM_STAINFO *sta, +@@ -496,6 +532,10 @@ beamforming_remove_entry( + #endif + + /* Used for beamforming_start_v1 */ ++void phydm_beamforming_ndpa_rate( ++ void *dm_void, ++ enum channel_width BW, ++ u8 rate); + void phydm_beamforming_ndpa_rate( + void *dm_void, + enum channel_width BW, +@@ -521,6 +561,8 @@ void phydm_beamforming_ndpa_rate( + } + + /* Used for beamforming_start_sw and beamforming_start_fw */ ++void phydm_beamforming_dym_ndpa_rate( ++ void *dm_void); + void phydm_beamforming_dym_ndpa_rate( + void *dm_void) + { +@@ -541,6 +583,9 @@ void phydm_beamforming_dym_ndpa_rate( + * HW Timer unit (1/32000) s 32k is clock. + * FW Sounding : FW Timer unit 10ms + */ ++void beamforming_dym_period( ++ void *dm_void, ++ u8 status); + void beamforming_dym_period( + void *dm_void, + u8 status) +@@ -655,6 +700,11 @@ beamforming_send_vht_ndpa_packet( + } + + enum beamforming_notify_state ++phydm_beamfomring_is_sounding( ++ void *dm_void, ++ struct _RT_BEAMFORMING_INFO *beam_info, ++ u8 *idx); ++enum beamforming_notify_state + phydm_beamfomring_is_sounding( + void *dm_void, + struct _RT_BEAMFORMING_INFO *beam_info, +@@ -707,6 +757,9 @@ phydm_beamfomring_is_sounding( + } + + /* This function is unused */ ++u8 phydm_beamforming_sounding_idx( ++ void *dm_void, ++ struct _RT_BEAMFORMING_INFO *beam_info); + u8 phydm_beamforming_sounding_idx( + void *dm_void, + struct _RT_BEAMFORMING_INFO *beam_info) +@@ -734,6 +787,11 @@ u8 phydm_beamforming_sounding_idx( + } + + enum sounding_mode ++phydm_beamforming_sounding_mode( ++ void *dm_void, ++ struct _RT_BEAMFORMING_INFO *beam_info, ++ u8 idx); ++enum sounding_mode + phydm_beamforming_sounding_mode( + void *dm_void, + struct _RT_BEAMFORMING_INFO *beam_info, +@@ -775,6 +833,11 @@ phydm_beamforming_sounding_mode( + return mode; + } + ++u16 phydm_beamforming_sounding_time( ++ void *dm_void, ++ struct _RT_BEAMFORMING_INFO *beam_info, ++ enum sounding_mode mode, ++ u8 idx); + u16 phydm_beamforming_sounding_time( + void *dm_void, + struct _RT_BEAMFORMING_INFO *beam_info, +@@ -800,6 +863,12 @@ u16 phydm_beamforming_sounding_time( + } + + enum channel_width ++phydm_beamforming_sounding_bw( ++ void *dm_void, ++ struct _RT_BEAMFORMING_INFO *beam_info, ++ enum sounding_mode mode, ++ u8 idx); ++enum channel_width + phydm_beamforming_sounding_bw( + void *dm_void, + struct _RT_BEAMFORMING_INFO *beam_info, +@@ -825,6 +894,10 @@ phydm_beamforming_sounding_bw( + return sounding_bw; + } + ++boolean ++phydm_beamforming_select_beam_entry( ++ void *dm_void, ++ struct _RT_BEAMFORMING_INFO *beam_info); + boolean + phydm_beamforming_select_beam_entry( + void *dm_void, +@@ -857,6 +930,9 @@ phydm_beamforming_select_beam_entry( + + /*SU BFee Entry Only*/ + boolean ++phydm_beamforming_start_period( ++ void *dm_void); ++boolean + phydm_beamforming_start_period( + void *dm_void) + { +@@ -901,6 +977,8 @@ phydm_beamforming_start_period( + + /* Used after beamforming_leave, and will clear the setting of the "already deleted" entry + *SU BFee Entry Only*/ ++void phydm_beamforming_end_period_sw( ++ void *dm_void); + void phydm_beamforming_end_period_sw( + void *dm_void) + { +@@ -922,6 +1000,8 @@ void phydm_beamforming_end_period_sw( + /*odm_write_1byte(dm, 0x15F, 0);*/ + } + ++void phydm_beamforming_end_period_fw( ++ void *dm_void); + void phydm_beamforming_end_period_fw( + void *dm_void) + { +@@ -933,6 +1013,10 @@ void phydm_beamforming_end_period_fw( + } + + /*SU BFee Entry Only*/ ++void phydm_beamforming_clear_entry_sw( ++ void *dm_void, ++ boolean is_delete, ++ u8 delete_idx); + void phydm_beamforming_clear_entry_sw( + void *dm_void, + boolean is_delete, +@@ -998,6 +1082,10 @@ void phydm_beamforming_clear_entry_sw( + } + } + ++void phydm_beamforming_clear_entry_fw( ++ void *dm_void, ++ boolean is_delete, ++ u8 delete_idx); + void phydm_beamforming_clear_entry_fw( + void *dm_void, + boolean is_delete, +@@ -1143,6 +1231,9 @@ void phydm_beamforming_notify( + } + } + ++boolean ++beamforming_init_entry(void *dm_void, u16 sta_idx, u8 *bfer_bfee_idx, ++ u8 *my_mac_addr); + boolean + beamforming_init_entry(void *dm_void, u16 sta_idx, u8 *bfer_bfee_idx, + u8 *my_mac_addr) +@@ -1293,6 +1384,9 @@ beamforming_init_entry(void *dm_void, u16 sta_idx, u8 *bfer_bfee_idx, + return true; + } + ++void beamforming_deinit_entry( ++ void *dm_void, ++ u8 *RA); + void beamforming_deinit_entry( + void *dm_void, + u8 *RA) +@@ -1336,6 +1430,13 @@ void beamforming_deinit_entry( + PHYDM_DBG(dm, DBG_TXBF, "%s End, idx = 0x%X\n", __func__, idx); + } + ++boolean ++beamforming_start_v1( ++ void *dm_void, ++ u8 *RA, ++ boolean mode, ++ enum channel_width BW, ++ u8 rate); + boolean + beamforming_start_v1( + void *dm_void, +@@ -1402,6 +1503,12 @@ beamforming_start_v1( + return true; + } + ++boolean ++beamforming_start_sw( ++ void *dm_void, ++ u8 idx, ++ u8 mode, ++ enum channel_width BW); + boolean + beamforming_start_sw( + void *dm_void, +diff --git a/drivers/staging/rtl8812au/hal/phydm/phydm_cck_pd.c b/drivers/staging/rtl8812au/hal/phydm/phydm_cck_pd.c +index 8f5229abf..0be5ae0fc 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/phydm_cck_pd.c ++++ b/drivers/staging/rtl8812au/hal/phydm/phydm_cck_pd.c +@@ -32,6 +32,7 @@ + + #ifdef PHYDM_SUPPORT_CCKPD + #ifdef PHYDM_COMPILE_CCKPD_TYPE1 ++void phydm_write_cck_pd_type1(void *dm_void, u8 cca_th); + void phydm_write_cck_pd_type1(void *dm_void, u8 cca_th) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -44,6 +45,7 @@ void phydm_write_cck_pd_type1(void *dm_void, u8 cca_th) + cckpd_t->cur_cck_cca_thres = cca_th; + } + ++void phydm_set_cckpd_lv_type1(void *dm_void, enum cckpd_lv lv); + void phydm_set_cckpd_lv_type1(void *dm_void, enum cckpd_lv lv) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -75,6 +77,7 @@ void phydm_set_cckpd_lv_type1(void *dm_void, enum cckpd_lv lv) + phydm_write_cck_pd_type1(dm, pd_th); + } + ++void phydm_cckpd_type1(void *dm_void); + void phydm_cckpd_type1(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -952,6 +955,8 @@ void phydm_set_cckpd_val(void *dm_void, u32 *val_buf, u8 val_len) + } + } + ++boolean ++phydm_stop_cck_pd_th(void *dm_void); + boolean + phydm_stop_cck_pd_th(void *dm_void) + { +diff --git a/drivers/staging/rtl8812au/hal/phydm/phydm_ccx.c b/drivers/staging/rtl8812au/hal/phydm/phydm_ccx.c +index f9ea9bb99..e0f42c0be 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/phydm_ccx.c ++++ b/drivers/staging/rtl8812au/hal/phydm/phydm_ccx.c +@@ -328,6 +328,7 @@ void phydm_fahm_dbg(void *dm_void, char input[][16], u32 *_used, char *output, + + #ifdef NHM_SUPPORT + ++void phydm_nhm_racing_release(void *dm_void); + void phydm_nhm_racing_release(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -348,6 +349,7 @@ void phydm_nhm_racing_release(void *dm_void) + ccx->nhm_app = NHM_BACKGROUND; + } + ++u8 phydm_nhm_racing_ctrl(void *dm_void, enum phydm_nhm_level nhm_lv); + u8 phydm_nhm_racing_ctrl(void *dm_void, enum phydm_nhm_level nhm_lv) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -397,6 +399,8 @@ void phydm_nhm_trigger(void *dm_void) + ccx->nhm_ongoing = true; + } + ++boolean ++phydm_nhm_check_rdy(void *dm_void); + boolean + phydm_nhm_check_rdy(void *dm_void) + { +@@ -487,6 +491,7 @@ phydm_nhm_check_rdy(void *dm_void) + return is_ready; + } + ++void phydm_nhm_get_utility(void *dm_void); + void phydm_nhm_get_utility(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -504,6 +509,8 @@ void phydm_nhm_get_utility(void *dm_void) + PHYDM_DBG(dm, DBG_ENV_MNTR, "nhm_ratio=%d\n", ccx->nhm_ratio); + } + ++boolean ++phydm_nhm_get_result(void *dm_void); + boolean + phydm_nhm_get_result(void *dm_void) + { +@@ -629,6 +636,7 @@ phydm_nhm_get_result(void *dm_void) + return true; + } + ++void phydm_nhm_set_th_reg(void *dm_void); + void phydm_nhm_set_th_reg(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -679,6 +687,9 @@ void phydm_nhm_set_th_reg(void *dm_void) + ccx->nhm_th[1], ccx->nhm_th[0]); + } + ++boolean ++phydm_nhm_th_update_chk(void *dm_void, enum nhm_application nhm_app, u8 *nhm_th, ++ u32 *igi_new); + boolean + phydm_nhm_th_update_chk(void *dm_void, enum nhm_application nhm_app, u8 *nhm_th, + u32 *igi_new) +@@ -763,6 +774,10 @@ phydm_nhm_th_update_chk(void *dm_void, enum nhm_application nhm_app, u8 *nhm_th, + return is_update; + } + ++void phydm_nhm_set(void *dm_void, enum nhm_option_txon_all include_tx, ++ enum nhm_option_cca_all include_cca, ++ enum nhm_divider_opt_all divi_opt, ++ enum nhm_application nhm_app, u16 period); + void phydm_nhm_set(void *dm_void, enum nhm_option_txon_all include_tx, + enum nhm_option_cca_all include_cca, + enum nhm_divider_opt_all divi_opt, +@@ -854,6 +869,7 @@ void phydm_nhm_set(void *dm_void, enum nhm_option_txon_all include_tx, + } + } + ++u8 phydm_nhm_mntr_set(void *dm_void, struct nhm_para_info *nhm_para); + u8 phydm_nhm_mntr_set(void *dm_void, struct nhm_para_info *nhm_para) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -885,6 +901,8 @@ u8 phydm_nhm_mntr_set(void *dm_void, struct nhm_para_info *nhm_para) + + /*@Environment Monitor*/ + boolean ++phydm_nhm_mntr_chk(void *dm_void, u16 monitor_time /*unit ms*/); ++boolean + phydm_nhm_mntr_chk(void *dm_void, u16 monitor_time /*unit ms*/) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -1067,6 +1085,7 @@ void phydm_nhm_dbg(void *dm_void, char input[][16], u32 *_used, char *output, + + #ifdef CLM_SUPPORT + ++void phydm_clm_racing_release(void *dm_void); + void phydm_clm_racing_release(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -1080,6 +1099,7 @@ void phydm_clm_racing_release(void *dm_void) + ccx->clm_app = CLM_BACKGROUND; + } + ++u8 phydm_clm_racing_ctrl(void *dm_void, enum phydm_nhm_level clm_lv); + u8 phydm_clm_racing_ctrl(void *dm_void, enum phydm_nhm_level clm_lv) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -1318,6 +1338,7 @@ phydm_clm_get_result(void *dm_void) + return true; + } + ++void phydm_clm_mntr_fw(void *dm_void, u16 monitor_time /*unit ms*/); + void phydm_clm_mntr_fw(void *dm_void, u16 monitor_time /*unit ms*/) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -1378,6 +1399,8 @@ u8 phydm_clm_mntr_set(void *dm_void, struct clm_para_info *clm_para) + return PHYDM_SET_SUCCESS; + } + ++boolean ++phydm_clm_mntr_chk(void *dm_void, u16 monitor_time /*unit ms*/); + boolean + phydm_clm_mntr_chk(void *dm_void, u16 monitor_time /*unit ms*/) + { +@@ -1441,6 +1464,7 @@ void phydm_set_clm_mntr_mode(void *dm_void, enum clm_monitor_mode mode) + } + } + ++void phydm_clm_init(void *dm_void); + void phydm_clm_init(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +diff --git a/drivers/staging/rtl8812au/hal/phydm/phydm_cfotracking.c b/drivers/staging/rtl8812au/hal/phydm/phydm_cfotracking.c +index 95d89e379..8aac6b094 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/phydm_cfotracking.c ++++ b/drivers/staging/rtl8812au/hal/phydm/phydm_cfotracking.c +@@ -25,6 +25,7 @@ + #include "mp_precomp.h" + #include "phydm_precomp.h" + ++s32 phydm_get_cfo_hz(void *dm_void, u32 val, u8 bit_num, u8 frac_num); + s32 phydm_get_cfo_hz(void *dm_void, u32 val, u8 bit_num, u8 frac_num) + { + s32 val_s = 0; +@@ -42,6 +43,7 @@ s32 phydm_get_cfo_hz(void *dm_void, u32 val, u8 bit_num, u8 frac_num) + } + + #if (ODM_IC_11AC_SERIES_SUPPORT) ++void phydm_get_cfo_info_ac(void *dm_void, struct phydm_cfo_rpt *cfo); + void phydm_get_cfo_info_ac(void *dm_void, struct phydm_cfo_rpt *cfo) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -310,6 +312,7 @@ phydm_set_crystal_cap_reg(void *dm_void, u8 crystal_cap) + return true; + } + ++void phydm_cfo_tracking_reset(void *dm_void); + void phydm_cfo_tracking_reset(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +diff --git a/drivers/staging/rtl8812au/hal/phydm/phydm_debug.c b/drivers/staging/rtl8812au/hal/phydm/phydm_debug.c +index 57d24e0e6..bab92632e 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/phydm_debug.c ++++ b/drivers/staging/rtl8812au/hal/phydm/phydm_debug.c +@@ -101,6 +101,7 @@ void phydm_bb_dbg_port_header_sel(void *dm_void, u32 header_idx) + } + } + ++void phydm_bb_dbg_port_clock_en(void *dm_void, u8 enable); + void phydm_bb_dbg_port_clock_en(void *dm_void, u8 enable) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -400,6 +401,8 @@ void phydm_bb_hw_dbg_info_8822b(void *dm_void, u32 *_used, char *output, + } + #endif + ++void phydm_bb_hw_dbg_info_ac(void *dm_void, u32 *_used, char *output, ++ u32 *_out_len); + void phydm_bb_hw_dbg_info_ac(void *dm_void, u32 *_used, char *output, + u32 *_out_len) + { +@@ -926,6 +929,8 @@ u8 phydm_get_l_sig_rate(void *dm_void, u8 rate_idx_l_sig) + return rate_idx; + } + ++void phydm_bb_hw_dbg_info(void *dm_void, char input[][16], u32 *_used, ++ char *output, u32 *_out_len); + void phydm_bb_hw_dbg_info(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) + { +@@ -1656,6 +1661,8 @@ void phydm_rx_rate_distribution(void *dm_void) + #endif + } + ++void phydm_print_hist_2_buf(void *dm_void, u16 *val, u16 len, char *buf, ++ u16 buf_size); + void phydm_print_hist_2_buf(void *dm_void, u16 *val, u16 len, char *buf, + u16 buf_size) + { +@@ -1676,6 +1683,7 @@ void phydm_print_hist_2_buf(void *dm_void, u16 *val, u16 len, char *buf, + } + } + ++void phydm_nss_hitogram(void *dm_void, enum PDM_RATE_TYPE rate_type); + void phydm_nss_hitogram(void *dm_void, enum PDM_RATE_TYPE rate_type) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -1935,6 +1943,7 @@ void phydm_get_phy_statistic(void *dm_void) + phydm_reset_phystatus_statistic(dm); + }; + ++void phydm_basic_dbg_msg_linked(void *dm_void); + void phydm_basic_dbg_msg_linked(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -2554,6 +2563,8 @@ void phydm_fw_trace_en_h2c(void *dm_void, boolean enable, + odm_fill_h2c_cmd(dm, PHYDM_H2C_FW_TRACE_EN, cmd_length, h2c_parameter); + } + ++void phydm_get_per_path_txagc(void *dm_void, u8 path, u32 *_used, char *output, ++ u32 *_out_len); + void phydm_get_per_path_txagc(void *dm_void, u8 path, u32 *_used, char *output, + u32 *_out_len) + { +@@ -2628,6 +2639,7 @@ void phydm_get_per_path_txagc(void *dm_void, u8 path, u32 *_used, char *output, + *_out_len = out_len; + } + ++void phydm_get_txagc(void *dm_void, u32 *_used, char *output, u32 *_out_len); + void phydm_get_txagc(void *dm_void, u32 *_used, char *output, u32 *_out_len) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -2658,6 +2670,8 @@ void phydm_get_txagc(void *dm_void, u32 *_used, char *output, u32 *_out_len) + *_out_len = out_len; + } + ++void phydm_set_txagc(void *dm_void, u32 *const val, u32 *_used, ++ char *output, u32 *_out_len); + void phydm_set_txagc(void *dm_void, u32 *const val, u32 *_used, + char *output, u32 *_out_len) + { +@@ -2738,6 +2752,8 @@ void phydm_set_txagc(void *dm_void, u32 *const val, u32 *_used, + *_out_len = out_len; + } + ++void phydm_shift_txagc(void *dm_void, u32 *const val, u32 *_used, char *output, ++ u32 *_out_len); + void phydm_shift_txagc(void *dm_void, u32 *const val, u32 *_used, char *output, + u32 *_out_len) + { +@@ -2850,6 +2866,8 @@ void phydm_shift_txagc(void *dm_void, u32 *const val, u32 *_used, char *output, + *_out_len = out_len; + } + ++void phydm_set_txagc_dbg(void *dm_void, char input[][16], u32 *_used, ++ char *output, u32 *_out_len); + void phydm_set_txagc_dbg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) + { +@@ -2891,6 +2909,8 @@ void phydm_set_txagc_dbg(void *dm_void, char input[][16], u32 *_used, + *_out_len = out_len; + } + ++void phydm_debug_trace(void *dm_void, char input[][16], u32 *_used, ++ char *output, u32 *_out_len); + void phydm_debug_trace(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) + { +@@ -3047,6 +3067,8 @@ void phydm_debug_trace(void *dm_void, char input[][16], u32 *_used, + *_out_len = out_len; + } + ++void phydm_fw_debug_trace(void *dm_void, char input[][16], u32 *_used, ++ char *output, u32 *_out_len); + void phydm_fw_debug_trace(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) + { +@@ -3126,6 +3148,8 @@ void phydm_dump_bb_reg_n(void *dm_void, u32 *_used, char *output, u32 *_out_len) + #endif + + #if (ODM_IC_11AC_SERIES_SUPPORT) ++void phydm_dump_bb_reg_ac(void *dm_void, u32 *_used, char *output, ++ u32 *_out_len); + void phydm_dump_bb_reg_ac(void *dm_void, u32 *_used, char *output, + u32 *_out_len) + { +@@ -3247,6 +3271,7 @@ void phydm_dump_bb_reg2_jgr3(void *dm_void, u32 *_used, char *output, + } + #endif + ++void phydm_dump_bb_reg(void *dm_void, u32 *_used, char *output, u32 *_out_len); + void phydm_dump_bb_reg(void *dm_void, u32 *_used, char *output, u32 *_out_len) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -3277,6 +3302,7 @@ void phydm_dump_bb_reg(void *dm_void, u32 *_used, char *output, u32 *_out_len) + *_out_len = out_len; + } + ++void phydm_dump_rf_reg(void *dm_void, u32 *_used, char *output, u32 *_out_len); + void phydm_dump_rf_reg(void *dm_void, u32 *_used, char *output, u32 *_out_len) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -3341,6 +3367,7 @@ void phydm_dump_rf_reg(void *dm_void, u32 *_used, char *output, u32 *_out_len) + *_out_len = out_len; + } + ++void phydm_dump_mac_reg(void *dm_void, u32 *_used, char *output, u32 *_out_len); + void phydm_dump_mac_reg(void *dm_void, u32 *_used, char *output, u32 *_out_len) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -3366,6 +3393,8 @@ void phydm_dump_mac_reg(void *dm_void, u32 *_used, char *output, u32 *_out_len) + *_out_len = out_len; + } + ++void phydm_dump_reg(void *dm_void, char input[][16], u32 *_used, char *output, ++ u32 *_out_len); + void phydm_dump_reg(void *dm_void, char input[][16], u32 *_used, char *output, + u32 *_out_len) + { +@@ -3416,6 +3445,8 @@ void phydm_dump_reg(void *dm_void, char input[][16], u32 *_used, char *output, + *_out_len = out_len; + } + ++void phydm_enable_big_jump(void *dm_void, char input[][16], u32 *_used, ++ char *output, u32 *_out_len); + void phydm_enable_big_jump(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) + { +@@ -3453,6 +3484,8 @@ void phydm_enable_big_jump(void *dm_void, char input[][16], u32 *_used, + #endif + } + ++void phydm_show_rx_rate(void *dm_void, char input[][16], u32 *_used, ++ char *output, u32 *_out_len); + void phydm_show_rx_rate(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) + { +@@ -3541,6 +3574,8 @@ void phydm_show_rx_rate(void *dm_void, char input[][16], u32 *_used, + #endif + } + ++void phydm_per_tone_evm(void *dm_void, char input[][16], u32 *_used, ++ char *output, u32 *_out_len); + void phydm_per_tone_evm(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) + { +@@ -3754,6 +3789,8 @@ void phydm_per_tone_evm(void *dm_void, char input[][16], u32 *_used, + *_out_len = out_len; + } + ++void phydm_bw_ch_adjust(void *dm_void, char input[][16], ++ u32 *_used, char *output, u32 *_out_len); + void phydm_bw_ch_adjust(void *dm_void, char input[][16], + u32 *_used, char *output, u32 *_out_len) + { +@@ -3806,6 +3843,8 @@ void phydm_bw_ch_adjust(void *dm_void, char input[][16], + *_out_len = out_len; + } + ++void phydm_ext_rf_element_ctrl(void *dm_void, char input[][16], u32 *_used, ++ char *output, u32 *_out_len); + void phydm_ext_rf_element_ctrl(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) + { +@@ -3828,6 +3867,8 @@ void phydm_ext_rf_element_ctrl(void *dm_void, char input[][16], u32 *_used, + } + } + ++void phydm_print_dbgport(void *dm_void, char input[][16], u32 *_used, ++ char *output, u32 *_out_len); + void phydm_print_dbgport(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) + { +diff --git a/drivers/staging/rtl8812au/hal/phydm/phydm_dig.c b/drivers/staging/rtl8812au/hal/phydm/phydm_dig.c +index eea6dcee4..b26e85515 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/phydm_dig.c ++++ b/drivers/staging/rtl8812au/hal/phydm/phydm_dig.c +@@ -31,6 +31,7 @@ + #include "phydm_precomp.h" + + #ifdef CFG_DIG_DAMPING_CHK ++void phydm_dig_recorder_reset(void *dm_void); + void phydm_dig_recorder_reset(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -43,6 +44,8 @@ void phydm_dig_recorder_reset(void *dm_void) + sizeof(struct phydm_dig_recorder_strcut)); + } + ++void phydm_dig_recorder(void *dm_void, boolean first_connect, u8 igi_curr, ++ u32 fa_cnt); + void phydm_dig_recorder(void *dm_void, boolean first_connect, u8 igi_curr, + u32 fa_cnt) + { +@@ -95,6 +98,7 @@ void phydm_dig_recorder(void *dm_void, boolean first_connect, u8 igi_curr, + dig_rc->igi_bitmap); + } + ++void phydm_dig_damping_chk(void *dm_void); + void phydm_dig_damping_chk(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -195,6 +199,8 @@ void phydm_dig_damping_chk(void *dm_void) + } + #endif + ++boolean ++phydm_dig_go_up_check(void *dm_void); + boolean + phydm_dig_go_up_check(void *dm_void) + { +@@ -271,6 +277,7 @@ phydm_dig_go_up_check(void *dm_void) + return ret; + } + ++void phydm_fa_threshold_check(void *dm_void, boolean is_dfs_band); + void phydm_fa_threshold_check(void *dm_void, boolean is_dfs_band) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -310,6 +317,7 @@ void phydm_fa_threshold_check(void *dm_void, boolean is_dfs_band) + dig_t->fa_th[1], dig_t->fa_th[2]); + } + ++void phydm_set_big_jump_step(void *dm_void, u8 curr_igi); + void phydm_set_big_jump_step(void *dm_void, u8 curr_igi) + { + #if (RTL8822B_SUPPORT || RTL8197F_SUPPORT || RTL8192F_SUPPORT) +@@ -498,6 +506,7 @@ void phydm_fa_cnt_statistics_jgr3(void *dm_void) + + #endif + ++void phydm_write_dig_reg_c50(void *dm_void, u8 igi); + void phydm_write_dig_reg_c50(void *dm_void, u8 igi) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -598,6 +607,7 @@ void odm_write_dig(void *dm_void, u8 new_igi) + PHYDM_DBG(dm, DBG_DIG, "New_igi=((0x%x))\n\n", new_igi); + } + ++u8 phydm_get_igi_reg_val(void *dm_void, enum bb_path path); + u8 phydm_get_igi_reg_val(void *dm_void, enum bb_path path) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -689,6 +699,8 @@ void odm_pause_dig(void *dm_void, enum phydm_pause_type type, + PHYDM_DBG(dm, DBG_DIG, "pause_result=%d\n", rpt); + } + ++boolean ++phydm_dig_abort(void *dm_void); + boolean + phydm_dig_abort(void *dm_void) + { +@@ -787,6 +799,7 @@ void phydm_dig_init(void *dm_void) + #endif + } + ++void phydm_dig_abs_boundary_decision(struct dm_struct *dm, boolean is_dfs_band); + void phydm_dig_abs_boundary_decision(struct dm_struct *dm, boolean is_dfs_band) + { + struct phydm_dig_struct *dig_t = &dm->dm_dig_table; +@@ -839,6 +852,7 @@ void phydm_dig_abs_boundary_decision(struct dm_struct *dm, boolean is_dfs_band) + dig_t->dm_dig_max, dig_t->dm_dig_min, dig_t->dig_max_of_min); + } + ++void phydm_dig_dym_boundary_decision(struct dm_struct *dm); + void phydm_dig_dym_boundary_decision(struct dm_struct *dm) + { + struct phydm_dig_struct *dig_t = &dm->dm_dig_table; +@@ -918,6 +932,7 @@ void phydm_dig_dym_boundary_decision(struct dm_struct *dm) + dig_t->rx_gain_range_max, dig_t->rx_gain_range_min); + } + ++void phydm_dig_abnormal_case(struct dm_struct *dm); + void phydm_dig_abnormal_case(struct dm_struct *dm) + { + struct phydm_dig_struct *dig_t = &dm->dm_dig_table; +@@ -930,6 +945,7 @@ void phydm_dig_abnormal_case(struct dm_struct *dm) + dig_t->rx_gain_range_max, dig_t->rx_gain_range_min); + } + ++u8 phydm_new_igi_by_fa(struct dm_struct *dm, u8 igi, u32 fa_cnt, u8 *step_size); + u8 phydm_new_igi_by_fa(struct dm_struct *dm, u8 igi, u32 fa_cnt, u8 *step_size) + { + boolean dig_go_up_check = true; +@@ -949,6 +965,8 @@ u8 phydm_new_igi_by_fa(struct dm_struct *dm, u8 igi, u32 fa_cnt, u8 *step_size) + return igi; + } + ++u8 phydm_get_new_igi(struct dm_struct *dm, u8 igi, u32 fa_cnt, ++ boolean is_dfs_band); + u8 phydm_get_new_igi(struct dm_struct *dm, u8 igi, u32 fa_cnt, + boolean is_dfs_band) + { +@@ -1045,6 +1063,7 @@ u8 phydm_get_new_igi(struct dm_struct *dm, u8 igi, u32 fa_cnt, + return igi; + } + ++boolean phydm_dig_dfs_mode_en(void *dm_void); + boolean phydm_dig_dfs_mode_en(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -1203,6 +1222,7 @@ void phydm_dig_by_rssi_lps(void *dm_void) + * 3 FASLE ALARM CHECK + * 3============================================================ + */ ++void phydm_false_alarm_counter_reg_reset(void *dm_void); + void phydm_false_alarm_counter_reg_reset(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -1299,6 +1319,7 @@ void phydm_false_alarm_counter_reg_reset(void *dm_void) + #endif /* @#if (ODM_IC_11AC_SERIES_SUPPORT) */ + } + ++void phydm_false_alarm_counter_reg_hold(void *dm_void); + void phydm_false_alarm_counter_reg_hold(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -1418,6 +1439,7 @@ void phydm_fa_cnt_statistics_n(void *dm_void) + #endif + + #if (ODM_IC_11AC_SERIES_SUPPORT) ++void phydm_fa_cnt_statistics_ac(void *dm_void); + void phydm_fa_cnt_statistics_ac(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -1510,6 +1532,7 @@ void phydm_fa_cnt_statistics_ac(void *dm_void) + } + #endif + ++void phydm_get_dbg_port_info(void *dm_void); + void phydm_get_dbg_port_info(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +diff --git a/drivers/staging/rtl8812au/hal/phydm/phydm_interface.c b/drivers/staging/rtl8812au/hal/phydm/phydm_interface.c +index fe0f5c220..ef2cac6d0 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/phydm_interface.c ++++ b/drivers/staging/rtl8812au/hal/phydm/phydm_interface.c +@@ -749,6 +749,7 @@ void odm_release_timer(struct dm_struct *dm, struct phydm_timer_list *timer) + #endif + } + ++u8 phydm_trans_h2c_id(struct dm_struct *dm, u8 phydm_h2c_id); + u8 phydm_trans_h2c_id(struct dm_struct *dm, u8 phydm_h2c_id) + { + u8 platform_h2c_id = phydm_h2c_id; +diff --git a/drivers/staging/rtl8812au/hal/phydm/phydm_noisemonitor.c b/drivers/staging/rtl8812au/hal/phydm/phydm_noisemonitor.c +index 77fe94e3f..6e76266d9 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/phydm_noisemonitor.c ++++ b/drivers/staging/rtl8812au/hal/phydm/phydm_noisemonitor.c +@@ -39,6 +39,7 @@ + * + *************************************************/ + ++void phydm_set_noise_data_sum(struct noise_level *noise_data, u8 max_rf_path); + void phydm_set_noise_data_sum(struct noise_level *noise_data, u8 max_rf_path) + { + u8 i = 0; +@@ -152,6 +153,8 @@ s16 odm_inband_noise_monitor_n(struct dm_struct *dm, u8 is_pause_dig, u8 igi, + #endif + + #if (ODM_IC_11AC_SERIES_SUPPORT) ++s16 phydm_idle_noise_measure_ac(struct dm_struct *dm, u8 pause_dig, ++ u8 igi, u32 max_time); + s16 phydm_idle_noise_measure_ac(struct dm_struct *dm, u8 pause_dig, + u8 igi, u32 max_time) + { +@@ -251,6 +254,8 @@ s16 phydm_idle_noise_measure_ac(struct dm_struct *dm, u8 pause_dig, + return dm->noise_level.noise_all; + } + ++s16 odm_inband_noise_monitor_ac(struct dm_struct *dm, u8 pause_dig, u8 igi, ++ u32 max_time); + s16 odm_inband_noise_monitor_ac(struct dm_struct *dm, u8 pause_dig, u8 igi, + u32 max_time) + { +diff --git a/drivers/staging/rtl8812au/hal/phydm/phydm_phystatus.c b/drivers/staging/rtl8812au/hal/phydm/phydm_phystatus.c +index 060390b3c..627eb5074 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/phydm_phystatus.c ++++ b/drivers/staging/rtl8812au/hal/phydm/phydm_phystatus.c +@@ -68,6 +68,10 @@ u8 phydm_get_gid(struct dm_struct *dm, u8 *phy_status_inf) + } + #endif + ++void phydm_rx_statistic_cal(struct dm_struct *dm, ++ struct phydm_phyinfo_struct *phy_info, ++ u8 *phy_status_inf, ++ struct phydm_perpkt_info_struct *pktinfo); + void phydm_rx_statistic_cal(struct dm_struct *dm, + struct phydm_phyinfo_struct *phy_info, + u8 *phy_status_inf, +@@ -186,6 +190,9 @@ void phydm_reset_phystatus_statistic(struct dm_struct *dm) + sizeof(struct phydm_phystatus_statistic)); + } + ++void phydm_avg_phystatus_index(void *dm_void, ++ struct phydm_phyinfo_struct *phy_info, ++ struct phydm_perpkt_info_struct *pktinfo); + void phydm_avg_phystatus_index(void *dm_void, + struct phydm_phyinfo_struct *phy_info, + struct phydm_perpkt_info_struct *pktinfo) +@@ -326,6 +333,7 @@ void phydm_avg_phystatus_index(void *dm_void, + } + } + ++void phydm_avg_phystatus_init(void *dm_void); + void phydm_avg_phystatus_init(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -340,6 +348,9 @@ void phydm_avg_phystatus_init(void *dm_void) + odm_move_memory(dm, dbg_i->evm_hist_th, evm_hist_th, size); + } + ++u8 phydm_get_signal_quality(struct phydm_phyinfo_struct *phy_info, ++ struct dm_struct *dm, ++ struct phy_status_rpt_8192cd *phy_sts); + u8 phydm_get_signal_quality(struct phydm_phyinfo_struct *phy_info, + struct dm_struct *dm, + struct phy_status_rpt_8192cd *phy_sts) +@@ -363,6 +374,7 @@ u8 phydm_get_signal_quality(struct phydm_phyinfo_struct *phy_info, + return result; + } + ++u8 phydm_pwr_2_percent(s8 ant_power); + u8 phydm_pwr_2_percent(s8 ant_power) + { + if ((ant_power <= -100) || ant_power >= 20) +@@ -750,6 +762,7 @@ phydm_cfo(s8 value) + return ret_val; + } + ++s8 phydm_cck_rssi_convert(struct dm_struct *dm, u16 lna_idx, u8 vga_idx); + s8 phydm_cck_rssi_convert(struct dm_struct *dm, u16 lna_idx, u8 vga_idx) + { + /*@phydm_get_cck_rssi_table_from_reg*/ +@@ -791,6 +804,7 @@ void phydm_get_cck_rssi_table_from_reg(struct dm_struct *dm) + dm->cck_lna_gain_table[6], dm->cck_lna_gain_table[7]); + } + ++s8 phydm_get_cck_rssi(void *dm_void, u8 lna_idx, u8 vga_idx); + s8 phydm_get_cck_rssi(void *dm_void, u8 lna_idx, u8 vga_idx) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -1071,6 +1085,11 @@ void phydm_phy_sts_n_parsing(struct dm_struct *dm, + #endif + + #if ODM_IC_11AC_SERIES_SUPPORT ++void phydm_rx_physts_bw_parsing(struct phydm_phyinfo_struct *phy_info, ++ struct phydm_perpkt_info_struct * ++ pktinfo, ++ struct phy_status_rpt_8812 * ++ phy_sts); + void phydm_rx_physts_bw_parsing(struct phydm_phyinfo_struct *phy_info, + struct phydm_perpkt_info_struct * + pktinfo, +@@ -1104,6 +1123,8 @@ void phydm_rx_physts_bw_parsing(struct phydm_phyinfo_struct *phy_info, + } + } + ++void phydm_get_sq(struct dm_struct *dm, struct phydm_phyinfo_struct *phy_info, ++ u8 is_cck_rate); + void phydm_get_sq(struct dm_struct *dm, struct phydm_phyinfo_struct *phy_info, + u8 is_cck_rate) + { +@@ -1144,6 +1165,10 @@ void phydm_get_sq(struct dm_struct *dm, struct phydm_phyinfo_struct *phy_info, + phy_info->signal_quality = sq; + } + ++void phydm_rx_physts_1st_type(struct dm_struct *dm, ++ struct phydm_phyinfo_struct *phy_info, ++ u8 *phy_status_inf, ++ struct phydm_perpkt_info_struct *pktinfo); + void phydm_rx_physts_1st_type(struct dm_struct *dm, + struct phydm_phyinfo_struct *phy_info, + u8 *phy_status_inf, +@@ -1312,6 +1337,7 @@ void phydm_reset_rssi_for_dm(struct dm_struct *dm, u8 station_id) + + #if (ODM_IC_11N_SERIES_SUPPORT || ODM_IC_11AC_SERIES_SUPPORT) + ++s32 phydm_get_rssi_8814_ofdm(struct dm_struct *dm, u8 *rssi_in); + s32 phydm_get_rssi_8814_ofdm(struct dm_struct *dm, u8 *rssi_in) + { + s32 rssi_avg; +@@ -1358,6 +1384,9 @@ s32 phydm_get_rssi_8814_ofdm(struct dm_struct *dm, u8 *rssi_in) + return rssi_avg; + } + ++void phydm_process_rssi_for_dm(struct dm_struct *dm, ++ struct phydm_phyinfo_struct *phy_info, ++ struct phydm_perpkt_info_struct *pktinfo); + void phydm_process_rssi_for_dm(struct dm_struct *dm, + struct phydm_phyinfo_struct *phy_info, + struct phydm_perpkt_info_struct *pktinfo) +diff --git a/drivers/staging/rtl8812au/hal/phydm/phydm_rainfo.c b/drivers/staging/rtl8812au/hal/phydm/phydm_rainfo.c +index 077585dfc..2c24b9be9 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/phydm_rainfo.c ++++ b/drivers/staging/rtl8812au/hal/phydm/phydm_rainfo.c +@@ -51,6 +51,7 @@ boolean phydm_is_cck_rate(void *dm_void, u8 rate) + return ((rate & 0x7f) <= ODM_RATE11M) ? true : false; + } + ++u8 phydm_rate_2_rate_digit(void *dm_void, u8 rate); + u8 phydm_rate_2_rate_digit(void *dm_void, u8 rate) + { + u8 legacy_table[12] = {1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54}; +@@ -151,6 +152,7 @@ void phydm_h2C_debug(void *dm_void, char input[][16], u32 *_used, + *_out_len = out_len; + } + ++void phydm_fw_fix_rate(void *dm_void, u8 en, u8 macid, u8 bw, u8 rate); + void phydm_fw_fix_rate(void *dm_void, u8 en, u8 macid, u8 bw, u8 rate) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -661,6 +663,7 @@ void phydm_update_hal_ra_mask( + + #endif + ++void phydm_rate_adaptive_mask_init(void *dm_void); + void phydm_rate_adaptive_mask_init(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -812,6 +815,7 @@ void phydm_show_sta_info(void *dm_void, char input[][16], u32 *_used, + *_out_len = out_len; + } + ++u8 phydm_get_tx_stream_num(void *dm_void, enum rf_type type); + u8 phydm_get_tx_stream_num(void *dm_void, enum rf_type type) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -831,6 +835,7 @@ u8 phydm_get_tx_stream_num(void *dm_void, enum rf_type type) + return tx_num; + } + ++u64 phydm_get_bb_mod_ra_mask(void *dm_void, u8 sta_idx); + u64 phydm_get_bb_mod_ra_mask(void *dm_void, u8 sta_idx) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -1005,6 +1010,7 @@ u8 phydm_get_rate_from_rssi_lv(void *dm_void, u8 sta_idx) + return rate_idx; + } + ++u8 phydm_get_rate_id(void *dm_void, u8 sta_idx); + u8 phydm_get_rate_id(void *dm_void, u8 sta_idx) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -1109,6 +1115,8 @@ u8 phydm_get_rate_id(void *dm_void, u8 sta_idx) + return rate_id_idx; + } + ++void phydm_ra_h2c(void *dm_void, u8 sta_idx, u8 dis_ra, u8 dis_pt, ++ u8 no_update_bw, u8 init_ra_lv, u64 ra_mask); + void phydm_ra_h2c(void *dm_void, u8 sta_idx, u8 dis_ra, u8 dis_pt, + u8 no_update_bw, u8 init_ra_lv, u64 ra_mask) + { +@@ -1379,6 +1387,7 @@ u8 phydm_vht_en_mapping(void *dm_void, u32 wireless_mode) + return vht_en_out; + } + ++u8 phydm_rftype2rateid_2g_n20(void *dm_void, u8 rf_type); + u8 phydm_rftype2rateid_2g_n20(void *dm_void, u8 rf_type) + { + u8 rate_id_idx = 0; +@@ -1394,6 +1403,7 @@ u8 phydm_rftype2rateid_2g_n20(void *dm_void, u8 rf_type) + return rate_id_idx; + } + ++u8 phydm_rftype2rateid_2g_n40(void *dm_void, u8 rf_type); + u8 phydm_rftype2rateid_2g_n40(void *dm_void, u8 rf_type) + { + u8 rate_id_idx = 0; +@@ -1409,6 +1419,7 @@ u8 phydm_rftype2rateid_2g_n40(void *dm_void, u8 rf_type) + return rate_id_idx; + } + ++u8 phydm_rftype2rateid_5g_n(void *dm_void, u8 rf_type); + u8 phydm_rftype2rateid_5g_n(void *dm_void, u8 rf_type) + { + u8 rate_id_idx = 0; +@@ -1424,6 +1435,7 @@ u8 phydm_rftype2rateid_5g_n(void *dm_void, u8 rf_type) + return rate_id_idx; + } + ++u8 phydm_rftype2rateid_ac80(void *dm_void, u8 rf_type); + u8 phydm_rftype2rateid_ac80(void *dm_void, u8 rf_type) + { + u8 rate_id_idx = 0; +@@ -1439,6 +1451,7 @@ u8 phydm_rftype2rateid_ac80(void *dm_void, u8 rf_type) + return rate_id_idx; + } + ++u8 phydm_rftype2rateid_ac40(void *dm_void, u8 rf_type); + u8 phydm_rftype2rateid_ac40(void *dm_void, u8 rf_type) + { + u8 rate_id_idx = 0; +@@ -1566,6 +1579,7 @@ u8 phydm_rate_order_compute(void *dm_void, u8 rate_idx) + } + + #if (DM_ODM_SUPPORT_TYPE == ODM_CE) ++u8 phydm_rate2ss(void *dm_void, u8 rate_idx); + u8 phydm_rate2ss(void *dm_void, u8 rate_idx) + { + u8 ret = 0xff; +@@ -1591,6 +1605,7 @@ u8 phydm_rate2ss(void *dm_void, u8 rate_idx) + return ret; + } + ++u8 phydm_rate2plcp(void *dm_void, u8 rate_idx); + u8 phydm_rate2plcp(void *dm_void, u8 rate_idx) + { + u8 rate2ss = 0; +@@ -1635,6 +1650,7 @@ u8 phydm_get_plcp(void *dm_void, u16 macid) + } + #endif + ++void phydm_ra_common_info_update(void *dm_void); + void phydm_ra_common_info_update(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +diff --git a/drivers/staging/rtl8812au/hal/phydm/phydm_rssi_monitor.c b/drivers/staging/rtl8812au/hal/phydm/phydm_rssi_monitor.c +index 0d5e41766..8936cc31e 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/phydm_rssi_monitor.c ++++ b/drivers/staging/rtl8812au/hal/phydm/phydm_rssi_monitor.c +@@ -32,6 +32,7 @@ + + #ifdef PHYDM_SUPPORT_RSSI_MONITOR + ++void phydm_rssi_monitor_h2c(void *dm_void, u8 macid); + void phydm_rssi_monitor_h2c(void *dm_void, u8 macid) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -95,6 +96,7 @@ void phydm_rssi_monitor_h2c(void *dm_void, u8 macid) + } + } + ++void phydm_calculate_rssi_min_max(void *dm_void); + void phydm_calculate_rssi_min_max(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +diff --git a/drivers/staging/rtl8812au/hal/phydm/rtl8821a/phydm_rtl8821a.c b/drivers/staging/rtl8812au/hal/phydm/rtl8821a/phydm_rtl8821a.c +index 5de0754da..ba3432e60 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/rtl8821a/phydm_rtl8821a.c ++++ b/drivers/staging/rtl8812au/hal/phydm/rtl8821a/phydm_rtl8821a.c +@@ -86,6 +86,10 @@ phydm_set_ext_band_switch_8821A( + } + + ++void ++odm_dynamic_try_state_agg_8821a( ++ struct dm_struct *dm ++); + void + odm_dynamic_try_state_agg_8821a( + struct dm_struct *dm +@@ -99,6 +103,10 @@ odm_dynamic_try_state_agg_8821a( + } + } + ++void ++odm_dynamic_packet_detection_th_8821a( ++ struct dm_struct *dm ++); + void + odm_dynamic_packet_detection_th_8821a( + struct dm_struct *dm +diff --git a/drivers/staging/rtl8812au/hal/phydm/txbf/halcomtxbf.c b/drivers/staging/rtl8812au/hal/phydm/txbf/halcomtxbf.c +index ae45a5b1a..4329dcaee 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/txbf/halcomtxbf.c ++++ b/drivers/staging/rtl8812au/hal/phydm/txbf/halcomtxbf.c +@@ -47,6 +47,8 @@ void hal_com_txbf_config_gtab( + hal_txbf_8822b_config_gtab(dm); + } + ++void phydm_beamform_set_sounding_enter( ++ void *dm_void); + void phydm_beamform_set_sounding_enter( + void *dm_void) + { +@@ -61,6 +63,8 @@ void phydm_beamform_set_sounding_enter( + #endif + } + ++void phydm_beamform_set_sounding_leave( ++ void *dm_void); + void phydm_beamform_set_sounding_leave( + void *dm_void) + { +@@ -75,6 +79,8 @@ void phydm_beamform_set_sounding_leave( + #endif + } + ++void phydm_beamform_set_sounding_rate( ++ void *dm_void); + void phydm_beamform_set_sounding_rate( + void *dm_void) + { +@@ -89,6 +95,8 @@ void phydm_beamform_set_sounding_rate( + #endif + } + ++void phydm_beamform_set_sounding_status( ++ void *dm_void); + void phydm_beamform_set_sounding_status( + void *dm_void) + { +@@ -103,6 +111,8 @@ void phydm_beamform_set_sounding_status( + #endif + } + ++void phydm_beamform_set_sounding_fw_ndpa( ++ void *dm_void); + void phydm_beamform_set_sounding_fw_ndpa( + void *dm_void) + { +@@ -119,6 +129,8 @@ void phydm_beamform_set_sounding_fw_ndpa( + #endif + } + ++void phydm_beamform_set_sounding_clk( ++ void *dm_void); + void phydm_beamform_set_sounding_clk( + void *dm_void) + { +@@ -135,6 +147,8 @@ void phydm_beamform_set_sounding_clk( + #endif + } + ++void phydm_beamform_set_reset_tx_path( ++ void *dm_void); + void phydm_beamform_set_reset_tx_path( + void *dm_void) + { +@@ -150,6 +164,8 @@ void phydm_beamform_set_reset_tx_path( + #endif + } + ++void phydm_beamform_set_get_tx_rate( ++ void *dm_void); + void phydm_beamform_set_get_tx_rate( + void *dm_void) + { +diff --git a/drivers/staging/rtl8812au/hal/phydm/txbf/haltxbf8814a.c b/drivers/staging/rtl8812au/hal/phydm/txbf/haltxbf8814a.c +index 7ad6ca909..328a4b5d2 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/txbf/haltxbf8814a.c ++++ b/drivers/staging/rtl8812au/hal/phydm/txbf/haltxbf8814a.c +@@ -233,6 +233,7 @@ u8 hal_txbf_8814a_get_ntx(void *dm_void) + return ntx; + } + ++u8 hal_txbf_8814a_get_nrx(void *dm_void); + u8 hal_txbf_8814a_get_nrx(void *dm_void) + { + struct dm_struct *dm = (struct dm_struct *)dm_void; +@@ -259,6 +260,9 @@ u8 hal_txbf_8814a_get_nrx(void *dm_void) + return nrx; + } + ++void hal_txbf_8814a_rf_mode(void *dm_void, ++ struct _RT_BEAMFORMING_INFO *beamforming_info, ++ u8 idx); + void hal_txbf_8814a_rf_mode(void *dm_void, + struct _RT_BEAMFORMING_INFO *beamforming_info, + u8 idx) +diff --git a/drivers/staging/rtl8812au/hal/phydm/txbf/haltxbfjaguar.c b/drivers/staging/rtl8812au/hal/phydm/txbf/haltxbfjaguar.c +index 18a47d4a9..c42fa53a6 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/txbf/haltxbfjaguar.c ++++ b/drivers/staging/rtl8812au/hal/phydm/txbf/haltxbfjaguar.c +@@ -33,6 +33,9 @@ void hal_txbf_8812a_set_ndpa_rate( + odm_write_1byte(dm, REG_NDPA_OPT_CTRL_8812A, (rate << 2 | BW)); + } + ++void hal_txbf_jaguar_rf_mode( ++ void *dm_void, ++ struct _RT_BEAMFORMING_INFO *beam_info); + void hal_txbf_jaguar_rf_mode( + void *dm_void, + struct _RT_BEAMFORMING_INFO *beam_info) +@@ -76,6 +79,9 @@ void hal_txbf_jaguar_rf_mode( + odm_set_bb_reg(dm, R_0x80c, MASKBYTE1, 0x11); + } + ++void hal_txbf_jaguar_download_ndpa( ++ void *dm_void, ++ u8 idx); + void hal_txbf_jaguar_download_ndpa( + void *dm_void, + u8 idx) +@@ -165,6 +171,8 @@ void hal_txbf_jaguar_download_ndpa( + #endif + } + ++void hal_txbf_jaguar_fw_txbf_cmd( ++ void *dm_void); + void hal_txbf_jaguar_fw_txbf_cmd( + void *dm_void) + { +diff --git a/drivers/staging/rtl8812au/hal/rtl8812a/rtl8812a_cmd.c b/drivers/staging/rtl8812au/hal/rtl8812a/rtl8812a_cmd.c +index ecbb397d5..75a0594ef 100644 +--- a/drivers/staging/rtl8812au/hal/rtl8812a/rtl8812a_cmd.c ++++ b/drivers/staging/rtl8812au/hal/rtl8812a/rtl8812a_cmd.c +@@ -158,6 +158,11 @@ u8 rtl8812_set_rssi_cmd(_adapter *padapter, u8 *param) + return res; + } + ++u8 Get_VHT_ENI( ++ u32 IOTAction, ++ u32 WirelessMode, ++ u32 ratr_bitmap ++); + u8 Get_VHT_ENI( + u32 IOTAction, + u32 WirelessMode, +@@ -178,6 +183,13 @@ u8 Get_VHT_ENI( + return Ret << 4; + } + ++BOOLEAN ++Get_RA_ShortGI_8812( ++ PADAPTER Adapter, ++ struct sta_info *psta, ++ u8 shortGIrate, ++ u32 ratr_bitmap ++); + BOOLEAN + Get_RA_ShortGI_8812( + PADAPTER Adapter, +@@ -449,6 +461,7 @@ void rtl8812_set_p2p_ps_offload_cmd(_adapter *padapter, u8 p2p_ps_state) + } + #endif /* CONFIG_P2P */ + ++void rtl8812_download_rsvd_page(PADAPTER padapter, u8 mstatus); + void rtl8812_download_rsvd_page(PADAPTER padapter, u8 mstatus) + { + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); +diff --git a/drivers/staging/rtl8812au/hal/rtl8812a/rtl8812a_hal_init.c b/drivers/staging/rtl8812au/hal/rtl8812a/rtl8812a_hal_init.c +index 4a21818b7..5e26efadb 100644 +--- a/drivers/staging/rtl8812au/hal/rtl8812a/rtl8812a_hal_init.c ++++ b/drivers/staging/rtl8812au/hal/rtl8812a/rtl8812a_hal_init.c +@@ -685,6 +685,11 @@ void InitializeFirmwareVars8812(PADAPTER padapter) + * Porting from 8723B. 2013.04.01 + * */ + VOID ++SetFwBTFwPatchCmd_8821( ++ IN PADAPTER Adapter, ++ IN u2Byte FwSize ++); ++VOID + SetFwBTFwPatchCmd_8821( + IN PADAPTER Adapter, + IN u2Byte FwSize +@@ -705,6 +710,7 @@ SetFwBTFwPatchCmd_8821( + } + + #ifdef CONFIG_MP_INCLUDED ++int ReservedPage_Compare(PADAPTER Adapter, PRT_MP_FIRMWARE pFirmware, u32 BTPatchSize); + int ReservedPage_Compare(PADAPTER Adapter, PRT_MP_FIRMWARE pFirmware, u32 BTPatchSize) + { + u8 temp, ret, lastBTsz; +@@ -1119,6 +1125,12 @@ Hal_ReadAntennaDiversity8812A( + #endif + } + ++VOID ++hal_ReadPAType_8812A( ++ IN PADAPTER Adapter, ++ IN u8 *PROMContent, ++ IN BOOLEAN AutoloadFail ++); + VOID + hal_ReadPAType_8812A( + IN PADAPTER Adapter, +@@ -1976,6 +1988,13 @@ rtl8812_ReadEFuse( + + /* Do not support BT */ + VOID ++Hal_EFUSEGetEfuseDefinition8812A( ++ IN PADAPTER pAdapter, ++ IN u1Byte efuseType, ++ IN u1Byte type, ++ OUT PVOID pOut ++); ++VOID + Hal_EFUSEGetEfuseDefinition8812A( + IN PADAPTER pAdapter, + IN u1Byte efuseType, +@@ -2057,6 +2076,13 @@ Hal_EFUSEGetEfuseDefinition8812A( + } + } + VOID ++Hal_EFUSEGetEfuseDefinition_Pseudo8812A( ++ IN PADAPTER pAdapter, ++ IN u8 efuseType, ++ IN u8 type, ++ OUT PVOID pOut ++); ++VOID + Hal_EFUSEGetEfuseDefinition_Pseudo8812A( + IN PADAPTER pAdapter, + IN u8 efuseType, +@@ -2486,6 +2512,14 @@ rtl8812_Efuse_PgPacketRead(IN PADAPTER pAdapter, + } + + ++BOOLEAN ++hal_EfuseFixHeaderProcess( ++ IN PADAPTER pAdapter, ++ IN u8 efuseType, ++ IN PPGPKT_STRUCT pFixPkt, ++ IN u16 *pAddr, ++ IN BOOLEAN bPseudoTest ++); + BOOLEAN + hal_EfuseFixHeaderProcess( + IN PADAPTER pAdapter, +@@ -2687,6 +2721,11 @@ hal_EfusePgPacketWriteData( + return _TRUE; + } + ++BOOLEAN efuse_PgPacketCheck( ++ PADAPTER pAdapter, ++ u8 efuseType, ++ BOOLEAN bPseudoTest ++); + BOOLEAN efuse_PgPacketCheck( + PADAPTER pAdapter, + u8 efuseType, +@@ -2704,6 +2743,13 @@ BOOLEAN efuse_PgPacketCheck( + } + + ++VOID ++efuse_PgPacketConstruct( ++ IN u8 offset, ++ IN u8 word_en, ++ IN u8 *pData, ++ IN OUT PPGPKT_STRUCT pTargetPkt ++); + VOID + efuse_PgPacketConstruct( + IN u8 offset, +@@ -2721,6 +2767,11 @@ efuse_PgPacketConstruct( + RTW_INFO("efuse_PgPacketConstruct(), targetPkt, offset=%d, word_en=0x%x, word_cnts=%d\n", pTargetPkt->offset, pTargetPkt->word_en, pTargetPkt->word_cnts); + } + ++u2Byte ++Hal_EfusePgPacketExceptionHandle_8812A( ++ PADAPTER pAdapter, ++ u2Byte ErrOffset ++ ); + u2Byte + Hal_EfusePgPacketExceptionHandle_8812A( + PADAPTER pAdapter, +@@ -2794,6 +2845,12 @@ Hal_EfusePgPacketExceptionHandle_8812A( + } + + ++BOOLEAN hal_EfuseCheckIfDatafollowed( ++ IN PADAPTER pAdapter, ++ IN u8 word_cnts, ++ IN u16 startAddr, ++ IN BOOLEAN bPseudoTest ++); + BOOLEAN hal_EfuseCheckIfDatafollowed( + IN PADAPTER pAdapter, + IN u8 word_cnts, +@@ -2813,6 +2870,12 @@ BOOLEAN hal_EfuseCheckIfDatafollowed( + } + + ++BOOLEAN ++hal_EfuseWordEnMatched( ++ IN PPGPKT_STRUCT pTargetPkt, ++ IN PPGPKT_STRUCT pCurPkt, ++ IN u8 *pWden ++); + BOOLEAN + hal_EfuseWordEnMatched( + IN PPGPKT_STRUCT pTargetPkt, +@@ -2849,6 +2912,14 @@ hal_EfuseWordEnMatched( + } + + ++BOOLEAN ++efuse_PgPacketPartialWrite( ++ IN PADAPTER pAdapter, ++ IN u8 efuseType, ++ IN OUT u16 *pAddr, ++ IN PPGPKT_STRUCT pTargetPkt, ++ IN BOOLEAN bPseudoTest ++); + BOOLEAN + efuse_PgPacketPartialWrite( + IN PADAPTER pAdapter, +@@ -3004,6 +3075,12 @@ efuse_PgPacketPartialWrite( + return bRet; + } + ++BOOLEAN efuse_PgPacketWriteHeader( ++ PADAPTER pAdapter, ++ u8 efuseType, ++ u16 *pAddr, ++ PPGPKT_STRUCT pTargetPkt, ++ BOOLEAN bPseudoTest); + BOOLEAN efuse_PgPacketWriteHeader( + PADAPTER pAdapter, + u8 efuseType, +@@ -3021,6 +3098,12 @@ BOOLEAN efuse_PgPacketWriteHeader( + return bRet; + } + ++int ++hal_EfusePgPacketWrite_8812A(IN PADAPTER pAdapter, ++ u8 offset, ++ u8 word_en, ++ u8 *pData, ++ BOOLEAN bPseudoTest); + int + hal_EfusePgPacketWrite_8812A(IN PADAPTER pAdapter, + u8 offset, +@@ -3288,6 +3371,7 @@ void rtl8812_stop_thread(PADAPTER padapter) + { + } + ++void hal_notch_filter_8812(_adapter *adapter, bool enable); + void hal_notch_filter_8812(_adapter *adapter, bool enable) + { + if (enable) { +@@ -5194,6 +5278,7 @@ struct bcn_qinfo_8812a { + u16 pkt_num:8; + }; + ++void dump_qinfo_8812a(void *sel, struct qinfo_8812a *info, const char *tag); + void dump_qinfo_8812a(void *sel, struct qinfo_8812a *info, const char *tag) + { + /* if (info->pkt_num) */ +@@ -5202,6 +5287,7 @@ void dump_qinfo_8812a(void *sel, struct qinfo_8812a *info, const char *tag) + ); + } + ++void dump_bcn_qinfo_8812a(void *sel, struct bcn_qinfo_8812a *info, const char *tag); + void dump_bcn_qinfo_8812a(void *sel, struct bcn_qinfo_8812a *info, const char *tag) + { + /* if (info->pkt_num) */ +@@ -5210,6 +5296,7 @@ void dump_bcn_qinfo_8812a(void *sel, struct bcn_qinfo_8812a *info, const char *t + ); + } + ++void dump_mac_qinfo_8812a(void *sel, _adapter *adapter); + void dump_mac_qinfo_8812a(void *sel, _adapter *adapter) + { + u32 q0_info; +@@ -5277,6 +5364,7 @@ static void dump_mac_txfifo_8812a(void *sel, _adapter *adapter) + } + } + ++void rtl8812a_read_wmmedca_reg(PADAPTER adapter, u16 *vo_params, u16 *vi_params, u16 *be_params, u16 *bk_params); + void rtl8812a_read_wmmedca_reg(PADAPTER adapter, u16 *vo_params, u16 *vi_params, u16 *be_params, u16 *bk_params) + { + u8 vo_reg_params[4]; +@@ -5447,6 +5535,7 @@ u8 SetHalDefVar8812A(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval) + return bResult; + } + ++void hal_ra_info_dump(_adapter *padapter , void *sel); + void hal_ra_info_dump(_adapter *padapter , void *sel) + { + int i; +diff --git a/drivers/staging/rtl8812au/hal/rtl8812a/rtl8812a_phycfg.c b/drivers/staging/rtl8812au/hal/rtl8812a/rtl8812a_phycfg.c +index 464168823..f44fb3c3e 100644 +--- a/drivers/staging/rtl8812au/hal/rtl8812a/rtl8812a_phycfg.c ++++ b/drivers/staging/rtl8812au/hal/rtl8812a/rtl8812a_phycfg.c +@@ -446,6 +446,13 @@ PHY_RFConfig8812( + return rtStatus; + } + ++VOID ++PHY_TxPowerTrainingByPath_8812( ++ IN PADAPTER Adapter, ++ IN enum channel_width BandWidth, ++ IN u8 Channel, ++ IN u8 RfPath ++); + VOID + PHY_TxPowerTrainingByPath_8812( + IN PADAPTER Adapter, +@@ -1097,6 +1104,11 @@ u32 phy_get_tx_bb_swing_8812a( + return out; + } + ++VOID ++phy_SetRFEReg8812( ++ IN PADAPTER Adapter, ++ IN u8 Band ++); + VOID + phy_SetRFEReg8812( + IN PADAPTER Adapter, +@@ -1218,6 +1230,11 @@ phy_SetRFEReg8812( + } + } + ++void phy_SetBBSwingByBand_8812A( ++ IN PADAPTER Adapter, ++ IN u8 Band, ++ IN u1Byte PreviousBand ++); + void phy_SetBBSwingByBand_8812A( + IN PADAPTER Adapter, + IN u8 Band, +@@ -1260,6 +1277,11 @@ void phy_SetBBSwingByBand_8812A( + } + + ++VOID ++phy_SetRFEReg8821( ++ IN PADAPTER Adapter, ++ IN u1Byte Band ++); + VOID + phy_SetRFEReg8821( + IN PADAPTER Adapter, +@@ -1459,6 +1481,11 @@ PHY_SwitchWirelessBand8812( + return _SUCCESS; + } + ++BOOLEAN ++phy_SwBand8812( ++ IN PADAPTER pAdapter, ++ IN u8 channelToSW ++); + BOOLEAN + phy_SwBand8812( + IN PADAPTER pAdapter, +@@ -1489,6 +1516,10 @@ phy_SwBand8812( + + #pragma clang optimize off + u8 ++phy_GetSecondaryChnl_8812( ++ IN PADAPTER Adapter ++); ++u8 + phy_GetSecondaryChnl_8812( + IN PADAPTER Adapter + ) +@@ -1531,6 +1562,11 @@ phy_GetSecondaryChnl_8812( + } + #pragma clang optimize on + ++VOID ++phy_SetRegBW_8812( ++ IN PADAPTER Adapter, ++ enum channel_width CurrentBW ++); + VOID + phy_SetRegBW_8812( + IN PADAPTER Adapter, +@@ -1562,6 +1598,12 @@ phy_SetRegBW_8812( + + } + ++void ++phy_FixSpur_8812A( ++ IN PADAPTER pAdapter, ++ IN enum channel_width Bandwidth, ++ IN u1Byte Channel ++); + void + phy_FixSpur_8812A( + IN PADAPTER pAdapter, +@@ -1605,6 +1647,10 @@ phy_FixSpur_8812A( + + } + ++VOID ++phy_PostSetBwMode8812( ++ IN PADAPTER Adapter ++); + VOID + phy_PostSetBwMode8812( + IN PADAPTER Adapter +@@ -1699,6 +1745,9 @@ phy_PostSetBwMode8812( + } + + /* <20130207, Kordan> The variales initialized here are used in odm_LNAPowerControl(). */ ++VOID phy_InitRssiTRSW( ++ IN PADAPTER pAdapter ++); + VOID phy_InitRssiTRSW( + IN PADAPTER pAdapter + ) +@@ -1723,6 +1772,12 @@ VOID phy_InitRssiTRSW( + + /*Referenced from "WB-20130801-YN-RL6286 Settings for Spur Issues R02.xls"*/ + VOID ++phy_SpurCalibration_8812A( ++ IN PADAPTER pAdapter, ++ IN u8 Channel, ++ IN u8 Bandwidth ++); ++VOID + phy_SpurCalibration_8812A( + IN PADAPTER pAdapter, + IN u8 Channel, +@@ -1769,6 +1824,10 @@ phy_SpurCalibration_8812A( + + } + ++VOID ++phy_SwChnl8812( ++ IN PADAPTER pAdapter ++); + VOID + phy_SwChnl8812( + IN PADAPTER pAdapter +@@ -1861,6 +1920,10 @@ phy_SwChnl8812( + phy_SpurCalibration_8812A(pAdapter, channelToSW, bandwidthToSw); + } + ++VOID ++phy_SwChnlAndSetBwMode8812( ++ IN PADAPTER Adapter ++); + VOID + phy_SwChnlAndSetBwMode8812( + IN PADAPTER Adapter +@@ -1918,6 +1981,17 @@ phy_SwChnlAndSetBwMode8812( + } + } + ++VOID ++PHY_HandleSwChnlAndSetBW8812( ++ IN PADAPTER Adapter, ++ IN BOOLEAN bSwitchChannel, ++ IN BOOLEAN bSetBandWidth, ++ IN u8 ChannelNum, ++ IN enum channel_width ChnlWidth, ++ IN u8 ChnlOffsetOf40MHz, ++ IN u8 ChnlOffsetOf80MHz, ++ IN u8 CenterFrequencyIndex1 ++); + VOID + PHY_HandleSwChnlAndSetBW8812( + IN PADAPTER Adapter, +diff --git a/drivers/staging/rtl8812au/hal/rtl8812a/usb/usb_halinit.c b/drivers/staging/rtl8812au/hal/rtl8812a/usb/usb_halinit.c +index 37d6cec0a..d2b2b2c99 100644 +--- a/drivers/staging/rtl8812au/hal/rtl8812a/usb/usb_halinit.c ++++ b/drivers/staging/rtl8812au/hal/rtl8812a/usb/usb_halinit.c +@@ -145,6 +145,7 @@ static BOOLEAN HalUsbSetQueuePipeMapping8812AUsb( + + } + ++void rtl8812au_interface_configure(_adapter *padapter); + void rtl8812au_interface_configure(_adapter *padapter) + { + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); +@@ -1116,6 +1117,10 @@ init_UsbAggregationSetting_8812A( + * + *---------------------------------------------------------------------------*/ + VOID ++USB_AggModeSwitch( ++ IN PADAPTER Adapter ++); ++VOID + USB_AggModeSwitch( + IN PADAPTER Adapter + ) +@@ -1278,6 +1283,7 @@ HalDetectSelectiveSuspendMode( + #endif + } /* HalDetectSelectiveSuspendMode */ + ++rt_rf_power_state RfOnOffDetect(IN PADAPTER pAdapter); + rt_rf_power_state RfOnOffDetect(IN PADAPTER pAdapter) + { + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); +@@ -1298,12 +1304,14 @@ rt_rf_power_state RfOnOffDetect(IN PADAPTER pAdapter) + return rfpowerstate; + } /* HalDetectPwrDownMode */ + ++void _ps_open_RF(_adapter *padapter); + void _ps_open_RF(_adapter *padapter) + { + /* here call with bRegSSPwrLvl 1, bRegSSPwrLvl 2 needs to be verified */ + /* phy_SsPwrSwitch92CU(padapter, rf_on, 1); */ + } + ++void _ps_close_RF(_adapter *padapter); + void _ps_close_RF(_adapter *padapter) + { + /* here call with bRegSSPwrLvl 1, bRegSSPwrLvl 2 needs to be verified */ +@@ -1353,6 +1361,7 @@ static void rtl8812au_hw_reset(_adapter *Adapter) + } + } + ++u32 rtl8812au_hal_init(PADAPTER Adapter); + u32 rtl8812au_hal_init(PADAPTER Adapter) + { + u8 value8 = 0, u1bRegCR; +@@ -1804,6 +1813,10 @@ u32 rtl8812au_hal_init(PADAPTER Adapter) + return status; + } + ++VOID ++hal_poweroff_8812au( ++ IN PADAPTER Adapter ++); + VOID + hal_poweroff_8812au( + IN PADAPTER Adapter +@@ -1872,6 +1885,7 @@ static void rtl8812au_hw_power_down(_adapter *padapter) + rtw_write16(padapter, REG_APS_FSMCO, 0x8812); + } + ++u32 rtl8812au_hal_deinit(PADAPTER Adapter); + u32 rtl8812au_hal_deinit(PADAPTER Adapter) + { + struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(Adapter); +@@ -1922,7 +1936,8 @@ u32 rtl8812au_hal_deinit(PADAPTER Adapter) + } + + +-unsigned int rtl8812au_inirp_init(PADAPTER Adapter) ++unsigned int rtl8812au_inirp_init(PADAPTER Adapter); ++unsigned int rtl8812au_inirp_init(PADAPTER Adapter) + { + u8 i; + struct recv_buf *precvbuf; +@@ -1976,7 +1991,8 @@ unsigned int rtl8812au_inirp_init(PADAPTER Adapter) + + } + +-unsigned int rtl8812au_inirp_deinit(PADAPTER Adapter) ++unsigned int rtl8812au_inirp_deinit(PADAPTER Adapter); ++unsigned int rtl8812au_inirp_deinit(PADAPTER Adapter) + { + + rtw_read_port_cancel(Adapter); +@@ -1991,6 +2007,12 @@ unsigned int rtl8812au_inirp_deinit(PADAPTER Adapter) + * + * ------------------------------------------------------------------- */ + VOID ++hal_ReadIDs_8812AU( ++ IN PADAPTER Adapter, ++ IN pu1Byte PROMContent, ++ IN BOOLEAN AutoloadFail ++); ++VOID + hal_ReadIDs_8812AU( + IN PADAPTER Adapter, + IN pu1Byte PROMContent, +@@ -2049,6 +2071,11 @@ hal_ReadIDs_8812AU( + RTW_INFO("Customer ID: 0x%02X, SubCustomer ID: 0x%02X\n", pHalData->EEPROMCustomerID, pHalData->EEPROMSubCustomerID); + } + ++VOID ++hal_InitPGData_8812A( ++ IN PADAPTER padapter, ++ IN OUT u8 *PROMContent ++); + VOID + hal_InitPGData_8812A( + IN PADAPTER padapter, +@@ -2127,6 +2154,10 @@ hal_InitPGData_8812A( + + } + ++VOID ++hal_CustomizedBehavior_8812AU( ++ IN PADAPTER Adapter ++); + VOID + hal_CustomizedBehavior_8812AU( + IN PADAPTER Adapter +@@ -2266,6 +2297,12 @@ hal_CustomizeByCustomerID_8812AU( + hal_CustomizedBehavior_8812AU(pAdapter); + } + ++VOID ++hal_ReadUsbModeSwitch_8812AU( ++ IN PADAPTER Adapter, ++ IN u8 *PROMContent, ++ IN BOOLEAN AutoloadFail ++); + VOID + hal_ReadUsbModeSwitch_8812AU( + IN PADAPTER Adapter, +@@ -2302,6 +2339,10 @@ ReadLEDSetting_8812AU( + #endif + } + ++VOID ++InitAdapterVariablesByPROM_8812AU( ++ IN PADAPTER Adapter ++); + VOID + InitAdapterVariablesByPROM_8812AU( + IN PADAPTER Adapter +@@ -2372,6 +2413,10 @@ static void Hal_ReadPROMContent_8812A( + InitAdapterVariablesByPROM_8812AU(Adapter); + } + ++u8 ++ReadAdapterInfo8812AU( ++ IN PADAPTER Adapter ++); + u8 + ReadAdapterInfo8812AU( + IN PADAPTER Adapter +@@ -2386,6 +2431,7 @@ ReadAdapterInfo8812AU( + return _SUCCESS; + } + ++void UpdateInterruptMask8812AU(PADAPTER padapter, u8 bHIMR0 , u32 AddMSR, u32 RemoveMSR); + void UpdateInterruptMask8812AU(PADAPTER padapter, u8 bHIMR0 , u32 AddMSR, u32 RemoveMSR) + { + HAL_DATA_TYPE *pHalData; +@@ -2411,6 +2457,7 @@ void UpdateInterruptMask8812AU(PADAPTER padapter, u8 bHIMR0 , u32 AddMSR, u32 Re + + } + ++u8 SetHwReg8812AU(PADAPTER Adapter, u8 variable, u8 *val); + u8 SetHwReg8812AU(PADAPTER Adapter, u8 variable, u8 *val) + { + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); +@@ -2500,6 +2547,7 @@ u8 SetHwReg8812AU(PADAPTER Adapter, u8 variable, u8 *val) + return ret; + } + ++void GetHwReg8812AU(PADAPTER Adapter, u8 variable, u8 *val); + void GetHwReg8812AU(PADAPTER Adapter, u8 variable, u8 *val) + { + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); +@@ -2531,6 +2579,12 @@ void GetHwReg8812AU(PADAPTER Adapter, u8 variable, u8 *val) + * Change default setting of specified variable. + * */ + u8 ++SetHalDefVar8812AUsb( ++ IN PADAPTER Adapter, ++ IN HAL_DEF_VARIABLE eVariable, ++ IN PVOID pValue ++); ++u8 + SetHalDefVar8812AUsb( + IN PADAPTER Adapter, + IN HAL_DEF_VARIABLE eVariable, +@@ -2554,6 +2608,12 @@ SetHalDefVar8812AUsb( + * Query setting of specified variable. + * */ + u8 ++GetHalDefVar8812AUsb( ++ IN PADAPTER Adapter, ++ IN HAL_DEF_VARIABLE eVariable, ++ IN PVOID pValue ++); ++u8 + GetHalDefVar8812AUsb( + IN PADAPTER Adapter, + IN HAL_DEF_VARIABLE eVariable, +@@ -2572,6 +2632,7 @@ GetHalDefVar8812AUsb( + return bResult; + } + ++void _update_response_rate(_adapter *padapter, unsigned int mask); + void _update_response_rate(_adapter *padapter, unsigned int mask) + { + u8 RateIndex = 0; +diff --git a/drivers/staging/rtl8812au/hal/rtl8812a/usb/usb_ops_linux.c b/drivers/staging/rtl8812au/hal/rtl8812a/usb/usb_ops_linux.c +index 22f8c42cf..db7f3b2c5 100644 +--- a/drivers/staging/rtl8812au/hal/rtl8812a/usb/usb_ops_linux.c ++++ b/drivers/staging/rtl8812au/hal/rtl8812a/usb/usb_ops_linux.c +@@ -101,6 +101,7 @@ void interrupt_handler_8812au(_adapter *padapter, u16 pkt_len, u8 *pbuf) + } + #endif + ++int recvbuf2recvframe(PADAPTER padapter, void *ptr); + int recvbuf2recvframe(PADAPTER padapter, void *ptr) + { + u8 *pbuf; +diff --git a/drivers/staging/rtl8812au/hal/rtl8814a/rtl8814a_cmd.c b/drivers/staging/rtl8812au/hal/rtl8814a/rtl8814a_cmd.c +index 6aa1fda17..76ed34e50 100644 +--- a/drivers/staging/rtl8812au/hal/rtl8814a/rtl8814a_cmd.c ++++ b/drivers/staging/rtl8812au/hal/rtl8814a/rtl8814a_cmd.c +@@ -151,6 +151,7 @@ s32 FillH2CCmd_8814(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer) + return ret; + } + ++u8 rtl8814_set_rssi_cmd(_adapter*padapter, u8 *param); + u8 rtl8814_set_rssi_cmd(_adapter*padapter, u8 *param) + { + u8 res=_SUCCESS; +@@ -206,6 +207,13 @@ static u8 Get_VHT_ENI( + return (Ret << 4); + } + ++BOOLEAN ++Get_RA_ShortGI_8814( ++ PADAPTER Adapter, ++ struct sta_info *psta, ++ u8 shortGIrate, ++ u32 ratr_bitmap ++); + BOOLEAN + Get_RA_ShortGI_8814( + PADAPTER Adapter, +@@ -267,6 +275,10 @@ Set_RA_LDPC_8814( + } + + ++u8 ++Get_RA_LDPC_8814( ++ struct sta_info *psta ++); + u8 + Get_RA_LDPC_8814( + struct sta_info *psta +@@ -597,6 +609,7 @@ static void ConstructNullFunctionData( + *pLength = pktlen; + } + ++void ConstructProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength, u8 *StaAddr, BOOLEAN bHideSSID); + void ConstructProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength, u8 *StaAddr, BOOLEAN bHideSSID) + { + struct rtw_ieee80211_hdr *pwlanhdr; +@@ -1152,6 +1165,7 @@ static void rtl8814_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvd + #endif + + ++int rtl8814_iqk_wait(_adapter* padapter, u32 timeout_ms); + int rtl8814_iqk_wait(_adapter* padapter, u32 timeout_ms) + { + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); +@@ -1164,6 +1178,7 @@ int rtl8814_iqk_wait(_adapter* padapter, u32 timeout_ms) + return rtw_sctx_wait(iqk_sctx, __func__); + } + ++void rtl8814_iqk_done(_adapter* padapter); + void rtl8814_iqk_done(_adapter* padapter) + { + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); +diff --git a/drivers/staging/rtl8812au/hal/rtl8814a/rtl8814a_hal_init.c b/drivers/staging/rtl8812au/hal/rtl8814a/rtl8814a_hal_init.c +index f1a903d68..d203753b6 100644 +--- a/drivers/staging/rtl8812au/hal/rtl8814a/rtl8814a_hal_init.c ++++ b/drivers/staging/rtl8812au/hal/rtl8814a/rtl8814a_hal_init.c +@@ -119,6 +119,11 @@ void hal_DetectWoWMode(PADAPTER pAdapter) + #endif + + ++VOID ++_FWDownloadEnable_8814A( ++ IN PADAPTER Adapter, ++ IN BOOLEAN enable ++ ); + VOID + _FWDownloadEnable_8814A( + IN PADAPTER Adapter, +@@ -152,6 +157,12 @@ _FWDownloadEnable_8814A( + + #define MAX_REG_BOLCK_SIZE 196 + ++VOID ++_BlockWrite_8814A( ++ IN PADAPTER Adapter, ++ IN PVOID buffer, ++ IN u32 buffSize ++ ); + VOID + _BlockWrite_8814A( + IN PADAPTER Adapter, +@@ -212,6 +223,13 @@ _BlockWrite_8814A( + } + } + ++VOID ++_PageWrite_8814A( ++ IN PADAPTER Adapter, ++ IN u32 page, ++ IN PVOID buffer, ++ IN u32 size ++ ); + VOID + _PageWrite_8814A( + IN PADAPTER Adapter, +@@ -229,6 +247,11 @@ _PageWrite_8814A( + _BlockWrite_8814A(Adapter,buffer,size); + } + ++VOID ++_FillDummy_8814A( ++ u8* pFwBuf, ++ pu4Byte pFwLen ++ ); + VOID + _FillDummy_8814A( + u8* pFwBuf, +@@ -249,6 +272,12 @@ _FillDummy_8814A( + *pFwLen = FwLen; + } + ++VOID ++_WriteFW_8814A( ++ IN PADAPTER Adapter, ++ IN PVOID buffer, ++ IN u32 size ++ ); + VOID + _WriteFW_8814A( + IN PADAPTER Adapter, +@@ -284,6 +313,10 @@ _WriteFW_8814A( + } + } + ++VOID ++_3081Disable8814A( ++ IN PADAPTER Adapter ++ ); + VOID + _3081Disable8814A( + IN PADAPTER Adapter +@@ -296,6 +329,10 @@ _3081Disable8814A( + + } + ++VOID ++_3081Enable8814A( ++ IN PADAPTER Adapter ++ ); + VOID + _3081Enable8814A( + IN PADAPTER Adapter +@@ -453,6 +490,12 @@ WaitDownLoadRSVDPageOK_3081( + } + + ++VOID ++SetDownLoadFwRsvdPagePkt_8814A( ++ IN PADAPTER Adapter, ++ IN PVOID buffer, ++ IN u32 len ++ ); + VOID + SetDownLoadFwRsvdPagePkt_8814A( + IN PADAPTER Adapter, +@@ -535,6 +578,12 @@ static void SetBcnCtrlReg( + rtw_write8(padapter, REG_BCN_CTRL, RegBcnCtrlVal); + } + ++VOID ++HalROMDownloadFWRSVDPage8814A( ++ IN PADAPTER Adapter, ++ IN PVOID buffer, ++ IN u32 Len ++); + VOID + HalROMDownloadFWRSVDPage8814A( + IN PADAPTER Adapter, +@@ -726,6 +775,10 @@ HalROMDownloadFWRSVDPage8814A( + } + } + ++s32 ++_FWFreeToGo8814A( ++ IN PADAPTER Adapter ++ ); + s32 + _FWFreeToGo8814A( + IN PADAPTER Adapter +@@ -1444,6 +1497,11 @@ SetFwRelatedForWoWLAN8812( + // Efuse related code + //=========================================================== + BOOLEAN ++hal_GetChnlGroup8814A( ++ IN u8 Channel, ++ OUT u8* pGroup ++ ); ++BOOLEAN + hal_GetChnlGroup8814A( + IN u8 Channel, + OUT u8* pGroup +@@ -1774,6 +1832,10 @@ hal_ReadPowerValueFromPROM8814A( + } + #endif + ++VOID ++HALBT_InitHalVars( ++ IN PADAPTER Adapter ++ ); + VOID + HALBT_InitHalVars( + IN PADAPTER Adapter +@@ -1792,6 +1854,10 @@ HALBT_InitHalVars( + } + + ++VOID ++BT_InitHalVars( ++ IN PADAPTER Adapter ++ ); + VOID + BT_InitHalVars( + IN PADAPTER Adapter +@@ -2789,6 +2855,13 @@ rtl8814_ReadEFuse( + + //Do not support BT + VOID ++hal_EFUSEGetEfuseDefinition8814A( ++ IN PADAPTER pAdapter, ++ IN u8 efuseType, ++ IN u8 type, ++ OUT PVOID pOut ++ ); ++VOID + hal_EFUSEGetEfuseDefinition8814A( + IN PADAPTER pAdapter, + IN u8 efuseType, +@@ -3231,6 +3304,11 @@ efuse_PgPacketConstruct( + } + + ++u16 ++efuse_PgPacketExceptionHandle( ++ IN PADAPTER pAdapter, ++ IN u16 ErrOffset ++ ); + u16 + efuse_PgPacketExceptionHandle( + IN PADAPTER pAdapter, +@@ -3528,6 +3606,13 @@ hal_EfuseFixHeaderProcess( + } + + ++BOOLEAN ++efuse_PgPacketWrite2ByteHeader( ++ IN PADAPTER pAdapter, ++ IN u8 efuseType, ++ IN OUT u16* pAddr, ++ IN PPGPKT_STRUCT pTargetPkt, ++ IN BOOLEAN bPseudoTest); + BOOLEAN + efuse_PgPacketWrite2ByteHeader( + IN PADAPTER pAdapter, +@@ -3631,6 +3716,13 @@ efuse_PgPacketWrite2ByteHeader( + } + + ++BOOLEAN ++efuse_PgPacketWrite1ByteHeader( ++ IN PADAPTER pAdapter, ++ IN u8 efuseType, ++ IN OUT u16* pAddr, ++ IN PPGPKT_STRUCT pTargetPkt, ++ IN BOOLEAN bPseudoTest); + BOOLEAN + efuse_PgPacketWrite1ByteHeader( + IN PADAPTER pAdapter, +@@ -3724,6 +3816,13 @@ efuse_PgPacketWriteHeader( + return bRet; + } + ++BOOLEAN ++efuse_PgPacketWriteData( ++ IN PADAPTER pAdapter, ++ IN u8 efuseType, ++ IN u16* pAddr, ++ IN PPGPKT_STRUCT pTargetPkt, ++ IN BOOLEAN bPseudoTest); + BOOLEAN + efuse_PgPacketWriteData( + IN PADAPTER pAdapter, +@@ -3760,6 +3859,12 @@ efuse_PgPacketWriteData( + } + + ++int ++hal_EfusePgPacketWrite_8814A(IN PADAPTER pAdapter, ++ IN u8 offset, ++ IN u8 word_en, ++ IN u8 *pData, ++ IN BOOLEAN bPseudoTest); + int + hal_EfusePgPacketWrite_8814A(IN PADAPTER pAdapter, + IN u8 offset, +@@ -3871,6 +3976,7 @@ void rtl8814_stop_thread(PADAPTER padapter) + { + } + ++void hal_notch_filter_8814(_adapter *adapter, bool enable); + void hal_notch_filter_8814(_adapter *adapter, bool enable) + { + if (enable) { +@@ -3918,6 +4024,7 @@ void CheckAutoloadState8812A(PADAPTER padapter) + } + */ + ++void InitPGData8814A(PADAPTER padapter); + void InitPGData8814A(PADAPTER padapter) + { + u32 i; +@@ -3997,6 +4104,11 @@ static void read_chip_version_8814a(PADAPTER Adapter) + + } + ++VOID ++hal_PatchwithJaguar_8814( ++ IN PADAPTER Adapter, ++ IN RT_MEDIA_STATUS MediaStatus ++ ); + VOID + hal_PatchwithJaguar_8814( + IN PADAPTER Adapter, +@@ -6300,6 +6412,7 @@ struct bcn_qinfo_8814a { + u16 pkt_num:8; + }; + ++void dump_qinfo_8814a(void *sel, struct qinfo_8814a *info, const char *tag); + void dump_qinfo_8814a(void *sel, struct qinfo_8814a *info, const char *tag) + { + //if (info->pkt_num) +@@ -6308,6 +6421,7 @@ void dump_qinfo_8814a(void *sel, struct qinfo_8814a *info, const char *tag) + ); + } + ++void dump_bcn_qinfo_8814a(void *sel, struct bcn_qinfo_8814a *info, const char *tag); + void dump_bcn_qinfo_8814a(void *sel, struct bcn_qinfo_8814a *info, const char *tag) + { + //if (info->pkt_num) +@@ -6316,6 +6430,7 @@ void dump_bcn_qinfo_8814a(void *sel, struct bcn_qinfo_8814a *info, const char *t + ); + } + ++void dump_mac_qinfo_8814a(void *sel, _adapter *adapter); + void dump_mac_qinfo_8814a(void *sel, _adapter *adapter) + { + u32 q0_info; +diff --git a/drivers/staging/rtl8812au/hal/rtl8814a/rtl8814a_phycfg.c b/drivers/staging/rtl8812au/hal/rtl8814a/rtl8814a_phycfg.c +index 1c212540c..675a0591b 100644 +--- a/drivers/staging/rtl8812au/hal/rtl8814a/rtl8814a_phycfg.c ++++ b/drivers/staging/rtl8812au/hal/rtl8814a/rtl8814a_phycfg.c +@@ -1102,6 +1102,10 @@ PHY_SetRFPowerState8814A( + todo */ + //1 5. Tx Power setting API + ++VOID ++phy_TxPwrAdjInPercentage( ++ IN PADAPTER Adapter, ++ OUT u8* pTxPwrIdx); + VOID + phy_TxPwrAdjInPercentage( + IN PADAPTER Adapter, +@@ -1455,7 +1459,13 @@ phy_SetBwRegAdc_8814A( + IN PADAPTER Adapter, + IN u8 Band, + IN enum channel_width CurrentBW +-) ++); ++VOID ++phy_SetBwRegAdc_8814A( ++ IN PADAPTER Adapter, ++ IN u8 Band, ++ IN enum channel_width CurrentBW ++) + { + switch(CurrentBW) + { +@@ -1497,7 +1507,13 @@ phy_SetBwRegAgc_8814A( + IN PADAPTER Adapter, + IN u8 Band, + IN enum channel_width CurrentBW +-) ++); ++VOID ++phy_SetBwRegAgc_8814A( ++ IN PADAPTER Adapter, ++ IN u8 Band, ++ IN enum channel_width CurrentBW ++) + { + u32 AgcValue = 7; + switch(CurrentBW) +@@ -1529,6 +1545,10 @@ phy_SetBwRegAgc_8814A( + } + + ++BOOLEAN ++phy_SwBand8814A( ++ IN PADAPTER pAdapter, ++ IN u8 channelToSW); + BOOLEAN + phy_SwBand8814A( + IN PADAPTER pAdapter, +@@ -1648,6 +1668,12 @@ PHY_SetRFEReg8814A( + } + } + ++VOID ++phy_SetBBSwingByBand_8814A( ++ IN PADAPTER Adapter, ++ IN u8 Band, ++ IN u8 PreviousBand ++ ); + VOID + phy_SetBBSwingByBand_8814A( + IN PADAPTER Adapter, +@@ -1766,6 +1792,10 @@ PHY_SwitchWirelessBand8814A( + } + + ++u8 ++phy_GetSecondaryChnl_8814A( ++ IN PADAPTER Adapter ++); + u8 + phy_GetSecondaryChnl_8814A( + IN PADAPTER Adapter +@@ -1823,7 +1853,12 @@ VOID + phy_SetBwRegMac_8814A( + IN PADAPTER Adapter, + enum channel_width CurrentBW +-) ++); ++VOID ++phy_SetBwRegMac_8814A( ++ IN PADAPTER Adapter, ++ enum channel_width CurrentBW ++) + { + u16 RegRfMod_BW, u2tmp = 0; + RegRfMod_BW = PlatformEFIORead2Byte(Adapter, REG_TRXPTCL_CTL_8814A); +@@ -1974,7 +2009,8 @@ void PHY_Set_SecCCATH_by_RXANT_8814A(PADAPTER pAdapter,u4Byte ulAntennaRx) + } + + +-VOID PHY_SetRXSC_by_TXSC_8814A(PADAPTER Adapter, u1Byte SubChnlNum) ++VOID PHY_SetRXSC_by_TXSC_8814A(PADAPTER Adapter, u1Byte SubChnlNum); ++VOID PHY_SetRXSC_by_TXSC_8814A(PADAPTER Adapter, u1Byte SubChnlNum) + { + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + +@@ -2004,6 +2040,7 @@ VOID PHY_SetRXSC_by_TXSC_8814A(PADAPTER Adapter, u1Byte SubChnlNum) + + + /* <20141230, James> A workaround to eliminate the 5280MHz & 5600MHz & 5760MHzspur of 8814A. (Asked by BBSD Neil.)*/ ++VOID phy_SpurCalibration_8814A(PADAPTER Adapter); + VOID phy_SpurCalibration_8814A(PADAPTER Adapter) + { + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); +@@ -2125,6 +2162,8 @@ VOID phy_SpurCalibration_8814A(PADAPTER Adapter) + } + + ++void phy_ModifyInitialGain_8814A( ++ PADAPTER Adapter); + void phy_ModifyInitialGain_8814A( + PADAPTER Adapter) + { +@@ -2179,6 +2218,7 @@ void phy_ModifyInitialGain_8814A( + } + + ++VOID phy_SetBwMode8814A(PADAPTER Adapter); + VOID phy_SetBwMode8814A(PADAPTER Adapter) + { + u8 SubChnlNum = 0; +@@ -2445,6 +2485,10 @@ phy_ConfigKFree8814A( + } + #endif + VOID ++phy_SwChnl8814A( ++ IN PADAPTER pAdapter ++ ); ++VOID + phy_SwChnl8814A( + IN PADAPTER pAdapter + ) +@@ -2658,6 +2702,10 @@ HAL_HandleSwChnl8814A( // Call after initialization + } + */ + ++VOID ++phy_SwChnlAndSetBwMode8814A( ++ IN PADAPTER Adapter ++); + VOID + phy_SwChnlAndSetBwMode8814A( + IN PADAPTER Adapter +@@ -2980,6 +3028,12 @@ SetAntennaConfig8814A( + return TRUE; + } + ++VOID ++PHY_SetBWMode8814( ++ IN PADAPTER Adapter, ++ IN enum channel_width Bandwidth, // 20M or 40M ++ IN u8 Offset // Upper, Lower, or Don't care ++); + VOID + PHY_SetBWMode8814( + IN PADAPTER Adapter, +@@ -2996,6 +3050,11 @@ PHY_SetBWMode8814( + //RTW_INFO("<==%s()\n",__FUNCTION__); + } + ++VOID ++PHY_SwChnl8814( ++ IN PADAPTER Adapter, ++ IN u8 channel ++ ); + VOID + PHY_SwChnl8814( + IN PADAPTER Adapter, +diff --git a/drivers/staging/rtl8812au/hal/rtl8814a/usb/usb_halinit.c b/drivers/staging/rtl8812au/hal/rtl8814a/usb/usb_halinit.c +index 5c0bf0d03..f08839b93 100644 +--- a/drivers/staging/rtl8812au/hal/rtl8814a/usb/usb_halinit.c ++++ b/drivers/staging/rtl8812au/hal/rtl8814a/usb/usb_halinit.c +@@ -102,6 +102,7 @@ static BOOLEAN HalUsbSetQueuePipeMapping8814AUsb( + + } + ++void rtl8814au_interface_configure(_adapter *padapter); + void rtl8814au_interface_configure(_adapter *padapter) + { + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); +@@ -229,6 +230,10 @@ _InitBurstPktLen(IN PADAPTER Adapter) + } + + ++VOID ++_InitQueueReservedPage_8814AUsb( ++ IN PADAPTER Adapter ++ ); + VOID + _InitQueueReservedPage_8814AUsb( + IN PADAPTER Adapter +@@ -1216,6 +1221,7 @@ static void rtl8814au_hw_reset(_adapter *Adapter) + #endif //0 + } + ++u32 rtl8814au_hal_init(PADAPTER Adapter); + u32 rtl8814au_hal_init(PADAPTER Adapter) + { + u8 value8 = 0, u1bRegCR; +@@ -1697,6 +1703,10 @@ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_END); + return status; + } + ++VOID ++hal_carddisable_8814( ++ IN PADAPTER Adapter ++); + VOID + hal_carddisable_8814( + IN PADAPTER Adapter +@@ -1726,8 +1736,9 @@ static void rtl8814au_hw_power_down(_adapter *padapter) + rtw_write16(padapter, REG_APS_FSMCO, 0x8812); + } + ++u32 rtl8814au_hal_deinit(PADAPTER Adapter); + u32 rtl8814au_hal_deinit(PADAPTER Adapter) +- { ++{ + struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(Adapter); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + RTW_INFO("==> %s \n",__FUNCTION__); +@@ -1781,7 +1792,8 @@ u32 rtl8814au_hal_deinit(PADAPTER Adapter) + } + + +-unsigned int rtl8814au_inirp_init(PADAPTER Adapter) ++unsigned int rtl8814au_inirp_init(PADAPTER Adapter); ++unsigned int rtl8814au_inirp_init(PADAPTER Adapter) + { + u8 i; + struct recv_buf *precvbuf; +@@ -1840,7 +1852,8 @@ unsigned int rtl8814au_inirp_init(PADAPTER Adapter) + + } + +-unsigned int rtl8814au_inirp_deinit(PADAPTER Adapter) ++unsigned int rtl8814au_inirp_deinit(PADAPTER Adapter); ++unsigned int rtl8814au_inirp_deinit(PADAPTER Adapter) + { + RTW_INFO("\n ===> usb_rx_deinit \n"); + +@@ -1857,6 +1870,12 @@ unsigned int rtl8814au_inirp_deinit(PADAPTER Adapter) + // + //------------------------------------------------------------------- + VOID ++hal_ReadIDs_8814AU( ++ IN PADAPTER Adapter, ++ IN pu1Byte PROMContent, ++ IN BOOLEAN AutoloadFail ++ ); ++VOID + hal_ReadIDs_8814AU( + IN PADAPTER Adapter, + IN pu1Byte PROMContent, +@@ -1923,6 +1942,10 @@ hal_InitPGData_8814A( + #endif + } + ++VOID ++hal_CustomizedBehavior_8814AU( ++ IN PADAPTER Adapter ++ ); + VOID + hal_CustomizedBehavior_8814AU( + IN PADAPTER Adapter +@@ -1999,6 +2022,12 @@ hal_CustomizeByCustomerID_8814AU( + hal_CustomizedBehavior_8814AU(pAdapter); + } + ++VOID ++hal_ReadUsbModeSwitch_8814AU( ++ IN PADAPTER Adapter, ++ IN u8* PROMContent, ++ IN BOOLEAN AutoloadFail ++ ); + VOID + hal_ReadUsbModeSwitch_8814AU( + IN PADAPTER Adapter, +@@ -2032,6 +2061,10 @@ ReadLEDSetting_8814AU( + #endif //CONFIG_RTW_LED + } + ++VOID ++InitAdapterVariablesByPROM_8814AU( ++ IN PADAPTER Adapter ++ ); + VOID + InitAdapterVariablesByPROM_8814AU( + IN PADAPTER Adapter +@@ -2091,6 +2124,10 @@ static void hal_ReadPROMContent_8814A( + InitAdapterVariablesByPROM_8814AU(Adapter); + } + ++u8 ++ReadAdapterInfo8814AU( ++ IN PADAPTER Adapter ++ ); + u8 + ReadAdapterInfo8814AU( + IN PADAPTER Adapter +@@ -2107,6 +2144,7 @@ ReadAdapterInfo8814AU( + return _SUCCESS; + } + ++void UpdateInterruptMask8814AU(PADAPTER padapter,u8 bHIMR0 ,u32 AddMSR, u32 RemoveMSR); + void UpdateInterruptMask8814AU(PADAPTER padapter,u8 bHIMR0 ,u32 AddMSR, u32 RemoveMSR) + { + HAL_DATA_TYPE *pHalData; +@@ -2132,6 +2170,7 @@ void UpdateInterruptMask8814AU(PADAPTER padapter,u8 bHIMR0 ,u32 AddMSR, u32 Remo + + } + ++u8 SetHwReg8814AU(PADAPTER Adapter, u8 variable, u8* val); + u8 SetHwReg8814AU(PADAPTER Adapter, u8 variable, u8* val) + { + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); +@@ -2221,6 +2260,7 @@ u8 SetHwReg8814AU(PADAPTER Adapter, u8 variable, u8* val) + return ret; + } + ++void GetHwReg8814AU(PADAPTER Adapter, u8 variable, u8* val); + void GetHwReg8814AU(PADAPTER Adapter, u8 variable, u8* val) + { + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); +@@ -2239,6 +2279,12 @@ void GetHwReg8814AU(PADAPTER Adapter, u8 variable, u8* val) + // Change default setting of specified variable. + // + u8 ++SetHalDefVar8814AUsb( ++ IN PADAPTER Adapter, ++ IN HAL_DEF_VARIABLE eVariable, ++ IN PVOID pValue ++ ); ++u8 + SetHalDefVar8814AUsb( + IN PADAPTER Adapter, + IN HAL_DEF_VARIABLE eVariable, +@@ -2263,6 +2309,12 @@ SetHalDefVar8814AUsb( + // Query setting of specified variable. + // + u8 ++GetHalDefVar8814AUsb( ++ IN PADAPTER Adapter, ++ IN HAL_DEF_VARIABLE eVariable, ++ IN PVOID pValue ++ ); ++u8 + GetHalDefVar8814AUsb( + IN PADAPTER Adapter, + IN HAL_DEF_VARIABLE eVariable, +diff --git a/drivers/staging/rtl8812au/hal/rtl8814a/usb/usb_ops_linux.c b/drivers/staging/rtl8812au/hal/rtl8814a/usb/usb_ops_linux.c +index 320024cae..1f0ca9682 100644 +--- a/drivers/staging/rtl8812au/hal/rtl8814a/usb/usb_ops_linux.c ++++ b/drivers/staging/rtl8812au/hal/rtl8814a/usb/usb_ops_linux.c +@@ -273,6 +273,7 @@ void rtl8814au_xmit_tasklet(void *priv) + + } + ++void rtl8814au_set_intf_ops(struct _io_ops *pops); + void rtl8814au_set_intf_ops(struct _io_ops *pops) + { + _rtw_memset((u8 *)pops, 0, sizeof(struct _io_ops)); +diff --git a/drivers/staging/rtl8812au/os_dep/linux/ioctl_cfg80211.c b/drivers/staging/rtl8812au/os_dep/linux/ioctl_cfg80211.c +index 6f5d97a11..ae4202ad4 100644 +--- a/drivers/staging/rtl8812au/os_dep/linux/ioctl_cfg80211.c ++++ b/drivers/staging/rtl8812au/os_dep/linux/ioctl_cfg80211.c +@@ -428,6 +428,7 @@ static void rtw_get_chbw_from_cfg80211_chan_def(struct cfg80211_chan_def *chdef, + #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) */ + + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)) ++bool rtw_cfg80211_allow_ch_switch_notify(_adapter *adapter); + bool rtw_cfg80211_allow_ch_switch_notify(_adapter *adapter) + { + #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)) +@@ -505,16 +506,19 @@ u8 rtw_cfg80211_ch_switch_notify(_adapter *adapter, u8 ch, u8 bw, u8 offset, + } + #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)) */ + ++void rtw_2g_channels_init(struct ieee80211_channel *channels); + void rtw_2g_channels_init(struct ieee80211_channel *channels) + { + _rtw_memcpy((void *)channels, (void *)rtw_2ghz_channels, sizeof(rtw_2ghz_channels)); + } + ++void rtw_5g_channels_init(struct ieee80211_channel *channels); + void rtw_5g_channels_init(struct ieee80211_channel *channels) + { + _rtw_memcpy((void *)channels, (void *)rtw_5ghz_a_channels, sizeof(rtw_5ghz_a_channels)); + } + ++void rtw_2g_rates_init(struct ieee80211_rate *rates); + void rtw_2g_rates_init(struct ieee80211_rate *rates) + { + _rtw_memcpy(rates, rtw_g_rates, +@@ -522,6 +526,7 @@ void rtw_2g_rates_init(struct ieee80211_rate *rates) + ); + } + ++void rtw_5g_rates_init(struct ieee80211_rate *rates); + void rtw_5g_rates_init(struct ieee80211_rate *rates) + { + _rtw_memcpy(rates, rtw_a_rates, +@@ -572,6 +577,7 @@ struct ieee80211_supported_band *rtw_spt_band_alloc(BAND_TYPE band) + return spt_band; + } + ++void rtw_spt_band_free(struct ieee80211_supported_band *spt_band); + void rtw_spt_band_free(struct ieee80211_supported_band *spt_band) + { + u32 size = 0; +@@ -660,6 +666,7 @@ static const struct ieee80211_txrx_stypes + }; + #endif + ++NDIS_802_11_NETWORK_INFRASTRUCTURE nl80211_iftype_to_rtw_network_type(enum nl80211_iftype type); + NDIS_802_11_NETWORK_INFRASTRUCTURE nl80211_iftype_to_rtw_network_type(enum nl80211_iftype type) + { + switch (type) { +@@ -693,6 +700,7 @@ NDIS_802_11_NETWORK_INFRASTRUCTURE nl80211_iftype_to_rtw_network_type(enum nl802 + } + } + ++u32 nl80211_iftype_to_rtw_mlme_state(enum nl80211_iftype type); + u32 nl80211_iftype_to_rtw_mlme_state(enum nl80211_iftype type) + { + switch (type) { +@@ -2711,6 +2719,7 @@ void rtw_cfg80211_unlink_bss(_adapter *padapter, struct wlan_network *pnetwork) + } + + /* if target wps scan ongoing, target_ssid is filled */ ++int rtw_cfg80211_is_target_wps_scan(struct cfg80211_scan_request *scan_req, struct cfg80211_ssid *target_ssid); + int rtw_cfg80211_is_target_wps_scan(struct cfg80211_scan_request *scan_req, struct cfg80211_ssid *target_ssid) + { + int ret = 0; +@@ -5420,6 +5429,7 @@ const char *_nl80211_mesh_power_mode_str[] = { + #define nl80211_mesh_power_mode_str(_p) ((_p <= NL80211_MESH_POWER_MAX) ? _nl80211_mesh_power_mode_str[_p] : _nl80211_mesh_power_mode_str[0]) + #endif + ++void dump_station_parameters(void *sel, struct wiphy *wiphy, const struct station_parameters *params); + void dump_station_parameters(void *sel, struct wiphy *wiphy, const struct station_parameters *params) + { + #if DBG_RTW_CFG80211_STA_PARAM +@@ -10093,6 +10103,8 @@ int rtw_hostapd_acs_dump_survey(struct wiphy *wiphy, struct net_device *netdev, + #endif /* defined(CONFIG_RTW_HOSTAPD_ACS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) */ + + #if (KERNEL_VERSION(4, 17, 0) <= LINUX_VERSION_CODE) ++int cfg80211_rtw_external_auth(struct wiphy *wiphy, struct net_device *dev, ++ struct cfg80211_external_auth_params *params); + int cfg80211_rtw_external_auth(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_external_auth_params *params) + { +diff --git a/drivers/staging/rtl8812au/os_dep/linux/ioctl_linux.c b/drivers/staging/rtl8812au/os_dep/linux/ioctl_linux.c +index c5776117f..27eb11239 100644 +--- a/drivers/staging/rtl8812au/os_dep/linux/ioctl_linux.c ++++ b/drivers/staging/rtl8812au/os_dep/linux/ioctl_linux.c +@@ -188,6 +188,7 @@ void indicate_wx_scan_complete_event(_adapter *padapter) + #endif + } + ++void rtw_indicate_wx_assoc_event(_adapter *padapter); + void rtw_indicate_wx_assoc_event(_adapter *padapter) + { + union iwreq_data wrqu; +@@ -211,6 +212,7 @@ void rtw_indicate_wx_assoc_event(_adapter *padapter) + #endif + } + ++void rtw_indicate_wx_disassoc_event(_adapter *padapter); + void rtw_indicate_wx_disassoc_event(_adapter *padapter) + { + union iwreq_data wrqu; +diff --git a/drivers/staging/rtl8812au/os_dep/linux/os_intfs.c b/drivers/staging/rtl8812au/os_dep/linux/os_intfs.c +index f4f2ef90e..0b95a14e5 100644 +--- a/drivers/staging/rtl8812au/os_dep/linux/os_intfs.c ++++ b/drivers/staging/rtl8812au/os_dep/linux/os_intfs.c +@@ -836,6 +836,7 @@ uint rtw_suspend_type = RTW_SUSPEND_TYPE; + module_param(rtw_suspend_type, uint, 0644); + #endif + ++void rtw_regsty_load_target_tx_power(struct registry_priv *regsty); + void rtw_regsty_load_target_tx_power(struct registry_priv *regsty) + { + int path, rs; +@@ -1351,7 +1352,8 @@ static struct net_device_stats *rtw_net_get_stats(struct net_device *pnetdev) + static const u16 rtw_1d_to_queue[8] = { 2, 3, 3, 2, 1, 1, 0, 0 }; + + /* Given a data frame determine the 802.1p/1d tag to use. */ +-unsigned int rtw_classify8021d(struct sk_buff *skb) ++unsigned int rtw_classify8021d(struct sk_buff *skb); ++unsigned int rtw_classify8021d(struct sk_buff *skb) + { + unsigned int dscp; + +@@ -1499,6 +1501,7 @@ void rtw_ndev_notifier_unregister(void) + unregister_netdevice_notifier(&rtw_ndev_notifier); + } + ++int rtw_ndev_init(struct net_device *dev); + int rtw_ndev_init(struct net_device *dev) + { + _adapter *adapter = rtw_netdev_priv(dev); +@@ -1512,6 +1515,7 @@ int rtw_ndev_init(struct net_device *dev) + return 0; + } + ++void rtw_ndev_uninit(struct net_device *dev); + void rtw_ndev_uninit(struct net_device *dev) + { + _adapter *adapter = rtw_netdev_priv(dev); +@@ -1584,6 +1588,7 @@ int rtw_init_netdev_name(struct net_device *pnetdev, const char *ifname) + return 0; + } + ++void rtw_hook_if_ops(struct net_device *ndev); + void rtw_hook_if_ops(struct net_device *ndev) + { + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)) +@@ -1676,6 +1681,7 @@ struct net_device *rtw_init_netdev(_adapter *old_padapter) + return pnetdev; + } + ++int rtw_os_ndev_alloc(_adapter *adapter); + int rtw_os_ndev_alloc(_adapter *adapter) + { + int ret = _FAIL; +@@ -1730,6 +1736,7 @@ void rtw_os_ndev_free(_adapter *adapter) + } + } + ++int rtw_os_ndev_register(_adapter *adapter, const char *name); + int rtw_os_ndev_register(_adapter *adapter, const char *name) + { + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); +@@ -1872,6 +1879,7 @@ void rtw_os_ndev_deinit(_adapter *adapter) + rtw_os_ndev_free(adapter); + } + ++int rtw_os_ndevs_alloc(struct dvobj_priv *dvobj); + int rtw_os_ndevs_alloc(struct dvobj_priv *dvobj) + { + int i, status = _SUCCESS; +@@ -1925,6 +1933,7 @@ int rtw_os_ndevs_alloc(struct dvobj_priv *dvobj) + return status; + } + ++void rtw_os_ndevs_free(struct dvobj_priv *dvobj); + void rtw_os_ndevs_free(struct dvobj_priv *dvobj) + { + int i; +@@ -2056,6 +2065,7 @@ void rtw_stop_drv_threads(_adapter *padapter) + rtw_hal_stop_thread(padapter); + } + ++u8 rtw_init_default_value(_adapter *padapter); + u8 rtw_init_default_value(_adapter *padapter) + { + u8 ret = _SUCCESS; +@@ -3141,6 +3151,7 @@ void rtw_inetaddr_notifier_unregister(void) + #endif + } + ++int rtw_os_ndevs_register(struct dvobj_priv *dvobj); + int rtw_os_ndevs_register(struct dvobj_priv *dvobj) + { + int i, status = _SUCCESS; +@@ -3260,6 +3271,7 @@ void rtw_os_ndevs_deinit(struct dvobj_priv *dvobj) + } + + #ifdef CONFIG_BR_EXT ++void netdev_br_init(struct net_device *netdev); + void netdev_br_init(struct net_device *netdev) + { + _adapter *adapter = (_adapter *)rtw_netdev_priv(netdev); +@@ -3899,6 +3911,7 @@ static int netdev_close(struct net_device *pnetdev) + + } + ++int pm_netdev_close(struct net_device *pnetdev, u8 bnormal); + int pm_netdev_close(struct net_device *pnetdev, u8 bnormal) + { + int status = 0; +@@ -4585,6 +4598,7 @@ int rtw_suspend_ap_wow(_adapter *padapter) + } + #endif /* #ifdef CONFIG_AP_WOWLAN */ + ++int rtw_suspend_normal(_adapter *padapter); + int rtw_suspend_normal(_adapter *padapter) + { + int ret = _SUCCESS; +@@ -4991,6 +5005,7 @@ int rtw_resume_process_ap_wow(_adapter *padapter) + } + #endif /* #ifdef CONFIG_APWOWLAN */ + ++void rtw_mi_resume_process_normal(_adapter *padapter); + void rtw_mi_resume_process_normal(_adapter *padapter) + { + int i; +@@ -5020,6 +5035,7 @@ void rtw_mi_resume_process_normal(_adapter *padapter) + } + } + ++int rtw_resume_process_normal(_adapter *padapter); + int rtw_resume_process_normal(_adapter *padapter) + { + struct net_device *pnetdev; +diff --git a/drivers/staging/rtl8812au/os_dep/linux/rtw_android.c b/drivers/staging/rtl8812au/os_dep/linux/rtw_android.c +index 480ea83f9..bd599ecd3 100644 +--- a/drivers/staging/rtl8812au/os_dep/linux/rtw_android.c ++++ b/drivers/staging/rtl8812au/os_dep/linux/rtw_android.c +@@ -364,6 +364,7 @@ int rtw_android_cmdstr_to_num(char *cmdstr) + return cmd_num; + } + ++int rtw_android_get_rssi(struct net_device *net, char *command, int total_len); + int rtw_android_get_rssi(struct net_device *net, char *command, int total_len) + { + _adapter *padapter = (_adapter *)rtw_netdev_priv(net); +@@ -379,6 +380,7 @@ int rtw_android_get_rssi(struct net_device *net, char *command, int total_len) + return bytes_written; + } + ++int rtw_android_get_link_speed(struct net_device *net, char *command, int total_len); + int rtw_android_get_link_speed(struct net_device *net, char *command, int total_len) + { + _adapter *padapter = (_adapter *)rtw_netdev_priv(net); +@@ -391,6 +393,7 @@ int rtw_android_get_link_speed(struct net_device *net, char *command, int total_ + return bytes_written; + } + ++int rtw_android_get_macaddr(struct net_device *net, char *command, int total_len); + int rtw_android_get_macaddr(struct net_device *net, char *command, int total_len) + { + int bytes_written = 0; +@@ -399,6 +402,7 @@ int rtw_android_get_macaddr(struct net_device *net, char *command, int total_len + return bytes_written; + } + ++int rtw_android_set_country(struct net_device *net, char *command, int total_len); + int rtw_android_set_country(struct net_device *net, char *command, int total_len) + { + _adapter *adapter = (_adapter *)rtw_netdev_priv(net); +@@ -410,6 +414,7 @@ int rtw_android_set_country(struct net_device *net, char *command, int total_len + return (ret == _SUCCESS) ? 0 : -1; + } + ++int rtw_android_get_p2p_dev_addr(struct net_device *net, char *command, int total_len); + int rtw_android_get_p2p_dev_addr(struct net_device *net, char *command, int total_len) + { + int bytes_written = 0; +@@ -421,6 +426,7 @@ int rtw_android_get_p2p_dev_addr(struct net_device *net, char *command, int tota + return bytes_written; + } + ++int rtw_android_set_block_scan(struct net_device *net, char *command, int total_len); + int rtw_android_set_block_scan(struct net_device *net, char *command, int total_len) + { + _adapter *adapter = (_adapter *)rtw_netdev_priv(net); +@@ -433,6 +439,7 @@ int rtw_android_set_block_scan(struct net_device *net, char *command, int total_ + return 0; + } + ++int rtw_android_set_block(struct net_device *net, char *command, int total_len); + int rtw_android_set_block(struct net_device *net, char *command, int total_len) + { + _adapter *adapter = (_adapter *)rtw_netdev_priv(net); +@@ -445,6 +452,7 @@ int rtw_android_set_block(struct net_device *net, char *command, int total_len) + return 0; + } + ++int rtw_android_setband(struct net_device *net, char *command, int total_len); + int rtw_android_setband(struct net_device *net, char *command, int total_len) + { + _adapter *adapter = (_adapter *)rtw_netdev_priv(net); +@@ -458,6 +466,7 @@ int rtw_android_setband(struct net_device *net, char *command, int total_len) + return (ret == _SUCCESS) ? 0 : -1; + } + ++int rtw_android_getband(struct net_device *net, char *command, int total_len); + int rtw_android_getband(struct net_device *net, char *command, int total_len) + { + _adapter *adapter = (_adapter *)rtw_netdev_priv(net); +@@ -469,6 +478,7 @@ int rtw_android_getband(struct net_device *net, char *command, int total_len) + } + + #ifdef CONFIG_WFD ++int rtw_android_set_miracast_mode(struct net_device *net, char *command, int total_len); + int rtw_android_set_miracast_mode(struct net_device *net, char *command, int total_len) + { + _adapter *adapter = (_adapter *)rtw_netdev_priv(net); +@@ -505,6 +515,7 @@ int rtw_android_set_miracast_mode(struct net_device *net, char *command, int tot + } + #endif /* CONFIG_WFD */ + ++int get_int_from_command(char *pcmd); + int get_int_from_command(char *pcmd) + { + int i = 0; +diff --git a/drivers/staging/rtl8812au/os_dep/linux/rtw_proc.c b/drivers/staging/rtl8812au/os_dep/linux/rtw_proc.c +index 840a675cc..db1177c3a 100644 +--- a/drivers/staging/rtl8812au/os_dep/linux/rtw_proc.c ++++ b/drivers/staging/rtl8812au/os_dep/linux/rtw_proc.c +@@ -483,6 +483,7 @@ static int proc_get_rf_reg_dump(struct seq_file *m, void *v) + } + + #ifdef CONFIG_RTW_LED ++int proc_get_led_config(struct seq_file *m, void *v); + int proc_get_led_config(struct seq_file *m, void *v) + { + struct net_device *dev = m->private; +@@ -493,6 +494,7 @@ int proc_get_led_config(struct seq_file *m, void *v) + return 0; + } + ++ssize_t proc_set_led_config(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); + ssize_t proc_set_led_config(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) + { + struct net_device *dev = data; +@@ -525,6 +527,7 @@ ssize_t proc_set_led_config(struct file *file, const char __user *buffer, size_t + #endif /* CONFIG_RTW_LED */ + + #ifdef CONFIG_AP_MODE ++int proc_get_aid_status(struct seq_file *m, void *v); + int proc_get_aid_status(struct seq_file *m, void *v) + { + struct net_device *dev = m->private; +@@ -535,6 +538,7 @@ int proc_get_aid_status(struct seq_file *m, void *v) + return 0; + } + ++ssize_t proc_set_aid_status(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); + ssize_t proc_set_aid_status(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) + { + struct net_device *dev = data; +@@ -1287,6 +1291,7 @@ static int proc_get_macaddr_acl(struct seq_file *m, void *v) + return 0; + } + ++ssize_t proc_set_macaddr_acl(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); + ssize_t proc_set_macaddr_acl(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) + { + struct net_device *dev = data; +@@ -1745,6 +1750,7 @@ static ssize_t proc_set_dfs_slave_with_rd(struct file *file, const char __user * + #endif /* CONFIG_DFS_MASTER */ + + #ifdef CONFIG_80211N_HT ++int proc_get_rx_ampdu_size_limit(struct seq_file *m, void *v); + int proc_get_rx_ampdu_size_limit(struct seq_file *m, void *v) + { + struct net_device *dev = m->private; +@@ -1755,6 +1761,7 @@ int proc_get_rx_ampdu_size_limit(struct seq_file *m, void *v) + return 0; + } + ++ssize_t proc_set_rx_ampdu_size_limit(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); + ssize_t proc_set_rx_ampdu_size_limit(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) + { + struct net_device *dev = data; +@@ -2765,6 +2772,7 @@ int proc_get_mbid_cam_cache(struct seq_file *m, void *v) + } + #endif /* CONFIG_MBSSID_CAM */ + ++int proc_get_mac_addr(struct seq_file *m, void *v); + int proc_get_mac_addr(struct seq_file *m, void *v) + { + struct net_device *dev = m->private; +@@ -3146,6 +3154,7 @@ static ssize_t proc_set_napi_th(struct file *file, const char __user *buffer, si + #endif /* CONFIG_RTW_NAPI_DYNAMIC */ + + ++ssize_t proc_set_dynamic_agg_enable(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); + ssize_t proc_set_dynamic_agg_enable(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) + { + struct net_device *dev = data; +@@ -3775,6 +3784,7 @@ static ssize_t proc_set_tpt_mode(struct file *file, const char __user *buffer, + } + #endif /* CONFIG_RTW_TPT_MODE */ + ++int proc_get_cur_beacon_keys(struct seq_file *m, void *v); + int proc_get_cur_beacon_keys(struct seq_file *m, void *v) + { + struct net_device *dev = m->private; +@@ -4281,6 +4291,7 @@ ssize_t proc_set_odm_adaptivity(struct file *file, const char __user *buffer, si + static char *phydm_msg = NULL; + #define PHYDM_MSG_LEN 80*24 + ++int proc_get_phydm_cmd(struct seq_file *m, void *v); + int proc_get_phydm_cmd(struct seq_file *m, void *v) + { + struct net_device *netdev; +@@ -4308,6 +4319,7 @@ int proc_get_phydm_cmd(struct seq_file *m, void *v) + return 0; + } + ++ssize_t proc_set_phydm_cmd(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); + ssize_t proc_set_phydm_cmd(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) + { + struct net_device *netdev; +@@ -4477,6 +4489,7 @@ struct proc_dir_entry *rtw_odm_proc_init(struct net_device *dev) + return dir_odm; + } + ++void rtw_odm_proc_deinit(_adapter *adapter); + void rtw_odm_proc_deinit(_adapter *adapter) + { + struct proc_dir_entry *dir_odm = NULL; +diff --git a/drivers/staging/rtl8812au/os_dep/linux/usb_intf.c b/drivers/staging/rtl8812au/os_dep/linux/usb_intf.c +index a285c011c..915ef6476 100644 +--- a/drivers/staging/rtl8812au/os_dep/linux/usb_intf.c ++++ b/drivers/staging/rtl8812au/os_dep/linux/usb_intf.c +@@ -951,6 +951,7 @@ static int rtw_suspend(struct usb_interface *pusb_intf, pm_message_t message) + return ret; + } + ++int rtw_resume_process(_adapter *padapter); + int rtw_resume_process(_adapter *padapter) + { + int ret; +diff --git a/drivers/staging/rtl8812au/os_dep/linux/usb_ops_linux.c b/drivers/staging/rtl8812au/os_dep/linux/usb_ops_linux.c +index fd03f8696..c7eb7ea40 100644 +--- a/drivers/staging/rtl8812au/os_dep/linux/usb_ops_linux.c ++++ b/drivers/staging/rtl8812au/os_dep/linux/usb_ops_linux.c +@@ -705,6 +705,7 @@ void usb_write_port_cancel(struct intf_hdl *pintfhdl) + } + } + ++void usb_init_recvbuf(_adapter *padapter, struct recv_buf *precvbuf); + void usb_init_recvbuf(_adapter *padapter, struct recv_buf *precvbuf) + { + +diff --git a/drivers/staging/rtl8812au/os_dep/linux/xmit_linux.c b/drivers/staging/rtl8812au/os_dep/linux/xmit_linux.c +index f08dd8e8c..c931a8014 100644 +--- a/drivers/staging/rtl8812au/os_dep/linux/xmit_linux.c ++++ b/drivers/staging/rtl8812au/os_dep/linux/xmit_linux.c +@@ -366,6 +366,7 @@ void rtw_os_wake_queue_at_free_stainfo(_adapter *padapter, int *qcnt_freed) + } + + #ifdef CONFIG_TX_MCAST2UNI ++int rtw_mlcst2unicst(_adapter *padapter, struct sk_buff *skb); + int rtw_mlcst2unicst(_adapter *padapter, struct sk_buff *skb) + { + struct sta_priv *pstapriv = &padapter->stapriv; +diff --git a/drivers/staging/rtl8812au/os_dep/osdep_service.c b/drivers/staging/rtl8812au/os_dep/osdep_service.c +index d24b3e1f0..5b2aa5d00 100644 +--- a/drivers/staging/rtl8812au/os_dep/osdep_service.c ++++ b/drivers/staging/rtl8812au/os_dep/osdep_service.c +@@ -2258,6 +2258,7 @@ void rtw_free_netdev(struct net_device *netdev) + return; + } + ++int rtw_change_ifname(_adapter *padapter, const char *ifname); + int rtw_change_ifname(_adapter *padapter, const char *ifname) + { + struct dvobj_priv *dvobj; +diff --git a/drivers/staging/rtl8812au/platform/platform_ops.c b/drivers/staging/rtl8812au/platform/platform_ops.c +index 10766aad8..eac273047 100644 +--- a/drivers/staging/rtl8812au/platform/platform_ops.c ++++ b/drivers/staging/rtl8812au/platform/platform_ops.c +@@ -18,6 +18,7 @@ + * 0: power on successfully + * others: power on failed + */ ++int platform_wifi_power_on(void); + int platform_wifi_power_on(void) + { + int ret = 0; +@@ -26,6 +27,7 @@ int platform_wifi_power_on(void) + return ret; + } + ++void platform_wifi_power_off(void); + void platform_wifi_power_off(void) + { + } +-- +2.41.1 + diff --git a/kernel/kernel/files/patches/mageia/0002-rtl8812au-fix-warnings.patch b/kernel/kernel/files/patches/mageia/0002-rtl8812au-fix-warnings.patch new file mode 100644 index 00000000..25f5aacc --- /dev/null +++ b/kernel/kernel/files/patches/mageia/0002-rtl8812au-fix-warnings.patch @@ -0,0 +1,22 @@ +diff -up linux-6.12/drivers/staging/rtl8812au/core/rtw_mlme_ext.c.fixwarning linux-6.12/drivers/staging/rtl8812au/core/rtw_mlme_ext.c +--- linux-6.12/drivers/staging/rtl8812au/core/rtw_mlme_ext.c.fixwarning 2024-11-20 22:55:13.263847617 +0100 ++++ linux-6.12/drivers/staging/rtl8812au/core/rtw_mlme_ext.c 2024-11-20 22:56:20.104794574 +0100 +@@ -2152,13 +2152,15 @@ unsigned int OnAuth(_adapter *padapter, + if (rtw_is_list_empty(&pstat->asoc_list) == _FALSE) { + rtw_list_delete(&pstat->asoc_list); + pstapriv->asoc_list_cnt--; +- if (pstat->expire_to > 0) +- ;/* TODO: STA re_auth within expire_to */ ++ if (pstat->expire_to > 0) { ++ ; /* TODO: STA re_auth within expire_to */ ++ } + } + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + +- if (seq == 1) ++ if (seq == 1) { + ; /* TODO: STA re_auth and auth timeout */ ++ } + + } + } diff --git a/kernel/kernel/files/patches/mageia/0005-rtl8812au-add-missed-prototypes.patch b/kernel/kernel/files/patches/mageia/0005-rtl8812au-add-missed-prototypes.patch new file mode 100644 index 00000000..c8b42379 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/0005-rtl8812au-add-missed-prototypes.patch @@ -0,0 +1,188 @@ +From 61116d468dd551124c1ae2c01fff5da99d787fad Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Giuseppe=20Ghib=C3=B2?= +Date: Thu, 21 Nov 2024 15:47:58 +0100 +Subject: [PATCH] rtl8812au: add missed prototypes + +--- + drivers/staging/rtl8812au/core/rtw_br_ext.c | 2 ++ + drivers/staging/rtl8812au/core/rtw_p2p.c | 1 + + drivers/staging/rtl8812au/core/rtw_xmit.c | 1 + + .../hal/phydm/halrf/rtl8812a/halrf_8812a_ce.c | 7 +++++++ + .../hal/phydm/halrf/rtl8814a/halrf_8814a_ce.c | 21 ++++++++++++++++++- + .../staging/rtl8812au/hal/phydm/phydm_ccx.c | 1 + + .../rtl8812au/os_dep/linux/ioctl_cfg80211.c | 12 +++++++++++ + .../staging/rtl8812au/os_dep/linux/rtw_proc.c | 1 + + .../staging/rtl8812au/os_dep/linux/usb_intf.c | 2 ++ + 9 files changed, 47 insertions(+), 1 deletion(-) + +diff --git a/drivers/staging/rtl8812au/core/rtw_br_ext.c b/drivers/staging/rtl8812au/core/rtw_br_ext.c +index 955a50912..283676d36 100644 +--- a/drivers/staging/rtl8812au/core/rtw_br_ext.c ++++ b/drivers/staging/rtl8812au/core/rtw_br_ext.c +@@ -1369,6 +1369,8 @@ void dhcp_flag_bcast(_adapter *priv, struct sk_buff *skb) + } + + ++void *scdb_findEntry(_adapter *priv, unsigned char *macAddr, ++ unsigned char *ipAddr); + void *scdb_findEntry(_adapter *priv, unsigned char *macAddr, + unsigned char *ipAddr) + { +diff --git a/drivers/staging/rtl8812au/core/rtw_p2p.c b/drivers/staging/rtl8812au/core/rtw_p2p.c +index 167dd067f..c560d1712 100644 +--- a/drivers/staging/rtl8812au/core/rtw_p2p.c ++++ b/drivers/staging/rtl8812au/core/rtw_p2p.c +@@ -3898,6 +3898,7 @@ void rtw_xframe_chk_wfd_ie(struct xmit_frame *xframe) + #endif + } + ++u8 *dump_p2p_attr_ch_list(u8 *p2p_ie, uint p2p_ielen, u8 *buf, u32 buf_len); + u8 *dump_p2p_attr_ch_list(u8 *p2p_ie, uint p2p_ielen, u8 *buf, u32 buf_len) + { + uint attr_contentlen = 0; +diff --git a/drivers/staging/rtl8812au/core/rtw_xmit.c b/drivers/staging/rtl8812au/core/rtw_xmit.c +index 0b97e5099..e40c0aecc 100644 +--- a/drivers/staging/rtl8812au/core/rtw_xmit.c ++++ b/drivers/staging/rtl8812au/core/rtw_xmit.c +@@ -3766,6 +3766,7 @@ static struct xmit_frame *get_one_xmitframe(struct xmit_priv *pxmitpriv, struct + return pxmitframe; + } + ++struct xmit_frame *rtw_get_xframe(struct xmit_priv *pxmitpriv, int *num_frame); + struct xmit_frame *rtw_get_xframe(struct xmit_priv *pxmitpriv, int *num_frame) + { + _irqL irqL0; +diff --git a/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8812a/halrf_8812a_ce.c b/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8812a/halrf_8812a_ce.c +index a66721465..e2113e37a 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8812a/halrf_8812a_ce.c ++++ b/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8812a/halrf_8812a_ce.c +@@ -1334,6 +1334,13 @@ void phy_lc_calibrate_8812a(void *dm_void) + _phy_lc_calibrate_8812a(dm, true); + } + ++void _phy_set_rf_path_switch_8812a( ++#if ((DM_ODM_SUPPORT_TYPE & ODM_AP) || (DM_ODM_SUPPORT_TYPE == ODM_CE)) ++ struct dm_struct *dm, ++#else ++ void *adapter, ++#endif ++ boolean is_main, boolean is2T); + void _phy_set_rf_path_switch_8812a( + #if ((DM_ODM_SUPPORT_TYPE & ODM_AP) || (DM_ODM_SUPPORT_TYPE == ODM_CE)) + struct dm_struct *dm, +diff --git a/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8814a/halrf_8814a_ce.c b/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8814a/halrf_8814a_ce.c +index 41ce0a6dd..ae060a648 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8814a/halrf_8814a_ce.c ++++ b/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8814a/halrf_8814a_ce.c +@@ -450,7 +450,17 @@ _phy_lc_calibrate_8814a( + + + VOID +-phy_APCalibrate_8814A( ++ phy_APCalibrate_8814A( ++#if (DM_ODM_SUPPORT_TYPE & ODM_AP) ++ IN struct dm_struct * pDM_Odm, ++#else ++ IN PADAPTER pAdapter, ++#endif ++ IN s1Byte delta, ++ IN BOOLEAN is2T ++ ); ++VOID ++ phy_APCalibrate_8814A( + #if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN struct dm_struct * pDM_Odm, + #else +@@ -545,6 +555,15 @@ BOOLEAN PHY_QueryRFPathSwitch_8814A( + } + + ++VOID _phy_SetRFPathSwitch_8814A( ++#if (DM_ODM_SUPPORT_TYPE & ODM_AP) ++ IN struct dm_struct * pDM_Odm, ++#else ++ IN PADAPTER pAdapter, ++#endif ++ IN BOOLEAN bMain, ++ IN BOOLEAN is2T ++ ); + VOID _phy_SetRFPathSwitch_8814A( + #if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN struct dm_struct * pDM_Odm, +diff --git a/drivers/staging/rtl8812au/hal/phydm/phydm_ccx.c b/drivers/staging/rtl8812au/hal/phydm/phydm_ccx.c +index e0f42c0be..fe69c19b2 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/phydm_ccx.c ++++ b/drivers/staging/rtl8812au/hal/phydm/phydm_ccx.c +@@ -26,6 +26,7 @@ + #include "mp_precomp.h" + #include "phydm_precomp.h" + ++void phydm_ccx_hw_restart(void *dm_void); + void phydm_ccx_hw_restart(void *dm_void) + /*@Will Restart NHM/CLM/FAHM simultaneously*/ + { +diff --git a/drivers/staging/rtl8812au/os_dep/linux/ioctl_cfg80211.c b/drivers/staging/rtl8812au/os_dep/linux/ioctl_cfg80211.c +index ae4202ad4..c0f563430 100644 +--- a/drivers/staging/rtl8812au/os_dep/linux/ioctl_cfg80211.c ++++ b/drivers/staging/rtl8812au/os_dep/linux/ioctl_cfg80211.c +@@ -534,6 +534,7 @@ void rtw_5g_rates_init(struct ieee80211_rate *rates) + ); + } + ++struct ieee80211_supported_band *rtw_spt_band_alloc(BAND_TYPE band); + struct ieee80211_supported_band *rtw_spt_band_alloc(BAND_TYPE band) + { + struct ieee80211_supported_band *spt_band = NULL; +@@ -2083,6 +2084,16 @@ static int cfg80211_rtw_del_key(struct wiphy *wiphy, struct net_device *ndev, + return 0; + } + ++static int cfg80211_rtw_set_default_key(struct wiphy *wiphy, ++ struct net_device *ndev, ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)) ++ int link_id, ++#endif ++ u8 key_index ++ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE) ++ , bool unicast, bool multicast ++ #endif ++); + static int cfg80211_rtw_set_default_key(struct wiphy *wiphy, + struct net_device *ndev, + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)) +@@ -5956,6 +5967,7 @@ static int cfg80211_rtw_change_station(struct wiphy *wiphy, struct net_device *n + return ret; + } + ++struct sta_info *rtw_sta_info_get_by_idx(struct sta_priv *pstapriv, const int idx, u8 *asoc_list_num); + struct sta_info *rtw_sta_info_get_by_idx(struct sta_priv *pstapriv, const int idx, u8 *asoc_list_num) + { + _list *phead, *plist; +diff --git a/drivers/staging/rtl8812au/os_dep/linux/rtw_proc.c b/drivers/staging/rtl8812au/os_dep/linux/rtw_proc.c +index db1177c3a..3b9246bc9 100644 +--- a/drivers/staging/rtl8812au/os_dep/linux/rtw_proc.c ++++ b/drivers/staging/rtl8812au/os_dep/linux/rtw_proc.c +@@ -4446,6 +4446,7 @@ static const struct file_operations rtw_odm_proc_sseq_ops = { + }; + #endif + ++struct proc_dir_entry *rtw_odm_proc_init(struct net_device *dev); + struct proc_dir_entry *rtw_odm_proc_init(struct net_device *dev) + { + struct proc_dir_entry *dir_odm = NULL; +diff --git a/drivers/staging/rtl8812au/os_dep/linux/usb_intf.c b/drivers/staging/rtl8812au/os_dep/linux/usb_intf.c +index 915ef6476..ae2a5a0b9 100644 +--- a/drivers/staging/rtl8812au/os_dep/linux/usb_intf.c ++++ b/drivers/staging/rtl8812au/os_dep/linux/usb_intf.c +@@ -1206,6 +1206,8 @@ extern void rtd2885_wlan_netlink_sendMsg(char *action_string, char *name); + + _adapter *rtw_sw_export = NULL; + ++_adapter *rtw_usb_primary_adapter_init(struct dvobj_priv *dvobj, ++ struct usb_interface *pusb_intf); + _adapter *rtw_usb_primary_adapter_init(struct dvobj_priv *dvobj, + struct usb_interface *pusb_intf) + { +-- +2.41.1 + diff --git a/kernel/kernel/files/patches/mageia/0006-rtl8812au-add-suggested-braces-around-empty-body-in-.patch b/kernel/kernel/files/patches/mageia/0006-rtl8812au-add-suggested-braces-around-empty-body-in-.patch new file mode 100644 index 00000000..af28127e --- /dev/null +++ b/kernel/kernel/files/patches/mageia/0006-rtl8812au-add-suggested-braces-around-empty-body-in-.patch @@ -0,0 +1,33 @@ +From a9d9038b7a15077395013f1954665656959c81b8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Giuseppe=20Ghib=C3=B2?= +From: Your Name +Date: Thu, 21 Nov 2024 15:53:01 +0100 +Subject: [PATCH 6/8] rtl8812au: add suggested braces around empty body in an + else statement + +--- + drivers/staging/rtl8812au/os_dep/linux/recv_linux.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/staging/rtl8812au/os_dep/linux/recv_linux.c b/drivers/staging/rtl8812au/os_dep/linux/recv_linux.c +index 5637e9970..051abba70 100644 +--- a/drivers/staging/rtl8812au/os_dep/linux/recv_linux.c ++++ b/drivers/staging/rtl8812au/os_dep/linux/recv_linux.c +@@ -531,10 +531,12 @@ void rtw_os_recv_indicate_pkt(_adapter *padapter, _pkt *pkt, union recv_frame *r + #endif /* CONFIG_RTW_NAPI */ + + ret = rtw_netif_rx(padapter->pnetdev, pkt); +- if (ret == NET_RX_SUCCESS) ++ if (ret == NET_RX_SUCCESS) { + DBG_COUNTER(padapter->rx_logs.os_netif_ok); +- else ++ } ++ else { + DBG_COUNTER(padapter->rx_logs.os_netif_err); ++ } + } + } + +-- +2.41.1 + diff --git a/kernel/kernel/files/patches/mageia/0007-rtl8812au-add-suggested-braces-around-empty-body-in-.patch b/kernel/kernel/files/patches/mageia/0007-rtl8812au-add-suggested-braces-around-empty-body-in-.patch new file mode 100644 index 00000000..685574b5 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/0007-rtl8812au-add-suggested-braces-around-empty-body-in-.patch @@ -0,0 +1,45 @@ +From e7f5d03d8bde8f104ed06ad0946e2e40eaf51094 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Giuseppe=20Ghib=C3=B2?= +Date: Thu, 21 Nov 2024 16:06:25 +0100 +Subject: [PATCH 7/8] rtl8812au: add suggested braces around empty body in an + else statement + +--- + drivers/staging/rtl8812au/hal/phydm/phydm_debug.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/staging/rtl8812au/hal/phydm/phydm_debug.c b/drivers/staging/rtl8812au/hal/phydm/phydm_debug.c +index bab92632e..a3e8bc48e 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/phydm_debug.c ++++ b/drivers/staging/rtl8812au/hal/phydm/phydm_debug.c +@@ -2222,10 +2222,12 @@ void phydm_basic_dbg_message(void *dm_void) + PHYDM_DBG(dm, DBG_CMN, "[%s] System up time: ((%d sec))---->\n", + __func__, dm->phydm_sys_up_time); + +- if (dm->is_linked) ++ if (dm->is_linked) { + phydm_basic_dbg_msg_linked(dm); +- else ++ } ++ else { + PHYDM_DBG(dm, DBG_CMN, "No Link !!!\n"); ++ } + + PHYDM_DBG(dm, DBG_CMN, "[CCA Cnt] {CCK, OFDM, Total} = {%d, %d, %d}\n", + fa_t->cnt_cck_cca, fa_t->cnt_ofdm_cca, fa_t->cnt_cca_all); +@@ -4491,10 +4493,11 @@ void phydm_fw_trace_handler_code(void *dm_void, u8 *buffer, u8 cmd_len) + u16 content_3 = (((u16)buffer[9]) << 8) | ((u16)buffer[8]); + u16 content_4 = (((u16)buffer[11]) << 8) | ((u16)buffer[10]); + +- if (cmd_len > 12) ++ if (cmd_len > 12) { + PHYDM_DBG(dm, DBG_FW_TRACE, + "[FW Msg] Invalid cmd length (( %d )) >12\n", + cmd_len); ++ } + /*@--------------------------------------------*/ + #ifdef CONFIG_RA_FW_DBG_CODE + if (function == RATE_DECISION) { +-- +2.41.1 + diff --git a/kernel/kernel/files/patches/mageia/0008-rtl8812au-add-suggested-braces-around-empty-body-in-.patch b/kernel/kernel/files/patches/mageia/0008-rtl8812au-add-suggested-braces-around-empty-body-in-.patch new file mode 100644 index 00000000..a99c5627 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/0008-rtl8812au-add-suggested-braces-around-empty-body-in-.patch @@ -0,0 +1,311 @@ +From 22b4d5685d828b85d9fc80bfa3d8c5e97b289224 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Giuseppe=20Ghib=C3=B2?= +Date: Thu, 21 Nov 2024 16:27:10 +0100 +Subject: [PATCH 8/8] rtl8812au: add suggested braces around empty body in an + else statement + +--- + .../rtl8812au/hal/phydm/halrf/halphyrf_ce.c | 3 ++- + .../staging/rtl8812au/hal/phydm/halrf/halrf.c | 3 ++- + .../rtl8812au/hal/phydm/halrf/halrf_kfree.c | 18 ++++++++++++------ + .../hal/phydm/halrf/rtl8812a/halrf_8812a_ce.c | 3 ++- + .../rtl8812au/hal/phydm/phydm_beamforming.c | 6 ++++-- + .../rtl8812au/hal/phydm/phydm_cfotracking.c | 6 ++++-- + .../staging/rtl8812au/hal/phydm/phydm_psd.c | 3 ++- + .../staging/rtl8812au/hal/phydm/phydm_rainfo.c | 6 ++++-- + .../rtl8812au/hal/phydm/txbf/halcomtxbf.c | 15 ++++++++++----- + .../rtl8812au/hal/phydm/txbf/haltxbfjaguar.c | 3 ++- + 10 files changed, 44 insertions(+), 22 deletions(-) + +diff --git a/drivers/staging/rtl8812au/hal/phydm/halrf/halphyrf_ce.c b/drivers/staging/rtl8812au/hal/phydm/halrf/halphyrf_ce.c +index 4443c7289..3b05d87c8 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/halrf/halphyrf_ce.c ++++ b/drivers/staging/rtl8812au/hal/phydm/halrf/halphyrf_ce.c +@@ -478,9 +478,10 @@ void odm_txpowertracking_callback_thermal_meter(void *adapter) + + /*@4 3. Initialize ThermalValues of rf_calibrate_info*/ + +- if (cali_info->is_reloadtxpowerindex) ++ if (cali_info->is_reloadtxpowerindex) { + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, + "reload ofdm index for band switch\n"); ++ } + + /*@4 4. Calculate average thermal meter*/ + +diff --git a/drivers/staging/rtl8812au/hal/phydm/halrf/halrf.c b/drivers/staging/rtl8812au/hal/phydm/halrf/halrf.c +index 09ab5bae9..609333db8 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/halrf/halrf.c ++++ b/drivers/staging/rtl8812au/hal/phydm/halrf/halrf.c +@@ -2270,8 +2270,9 @@ boolean halrf_compare(void *dm_void, u32 value) + else if (value < 0x200 && value > 0x64) + fail = true; + +- if (fail) ++ if (fail) { + RF_DBG(dm, DBG_RF_DACK, "[DACK]overflow!!!!!!!!!!!!!!!"); ++ } + return fail; + } + +diff --git a/drivers/staging/rtl8812au/hal/phydm/halrf/halrf_kfree.c b/drivers/staging/rtl8812au/hal/phydm/halrf/halrf_kfree.c +index 773364310..a4e3504a3 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/halrf/halrf_kfree.c ++++ b/drivers/staging/rtl8812au/hal/phydm/halrf/halrf_kfree.c +@@ -148,9 +148,10 @@ void phydm_get_thermal_trim_offset_8821c(void *dm_void) + RF_DBG(dm, DBG_RF_MP, "[kfree] 8821c thermal trim flag:0x%02x\n", + power_trim_info->flag); + +- if (power_trim_info->flag & KFREE_FLAG_THERMAL_K_ON) ++ if (power_trim_info->flag & KFREE_FLAG_THERMAL_K_ON) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8821c thermal:%d\n", + power_trim_info->thermal); ++ } + } + + void phydm_get_power_trim_offset_8821c(void *dm_void); +@@ -281,9 +282,10 @@ void phydm_get_thermal_trim_offset_8822b(void *dm_void) + RF_DBG(dm, DBG_RF_MP, "[kfree] 8822b thermal trim flag:0x%02x\n", + power_trim_info->flag); + +- if (power_trim_info->flag & KFREE_FLAG_THERMAL_K_ON) ++ if (power_trim_info->flag & KFREE_FLAG_THERMAL_K_ON) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8822b thermal:%d\n", + power_trim_info->thermal); ++ } + } + + void phydm_get_power_trim_offset_8822b(void *dm_void); +@@ -532,9 +534,10 @@ void phydm_get_thermal_trim_offset_8710b(void *dm_void) + RF_DBG(dm, DBG_RF_MP, "[kfree] 8710b thermal trim flag:0x%02x\n", + power_trim_info->flag); + +- if (power_trim_info->flag & KFREE_FLAG_THERMAL_K_ON) ++ if (power_trim_info->flag & KFREE_FLAG_THERMAL_K_ON) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8710b thermal:%d\n", + power_trim_info->thermal); ++ } + } + + void phydm_get_power_trim_offset_8710b(void *dm_void); +@@ -559,10 +562,11 @@ void phydm_get_power_trim_offset_8710b(void *dm_void) + RF_DBG(dm, DBG_RF_MP, "[kfree] 8710b power trim flag:0x%02x\n", + power_trim_info->flag); + +- if (power_trim_info->flag & KFREE_FLAG_ON) ++ if (power_trim_info->flag & KFREE_FLAG_ON) { + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8710b power_trim_data->bb_gain[0][0]=0x%X\n", + power_trim_info->bb_gain[0][0]); ++ } + } + + void phydm_set_kfree_to_rf_8710b(void *dm_void, u8 e_rf_path, u8 data); +@@ -620,9 +624,10 @@ void phydm_get_thermal_trim_offset_8192f(void *dm_void) + RF_DBG(dm, DBG_RF_MP, "[kfree] 8192f thermal trim flag:0x%02x\n", + power_trim_info->flag); + +- if (power_trim_info->flag & KFREE_FLAG_THERMAL_K_ON) ++ if (power_trim_info->flag & KFREE_FLAG_THERMAL_K_ON) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8192f thermal:%d\n", + power_trim_info->thermal); ++ } + } + + void phydm_get_power_trim_offset_8192f(void *dm_void); +@@ -799,8 +804,9 @@ void phydm_get_thermal_trim_offset_8198f(void *dm_void) + pg_therm = pg_therm & 0x1f; + if ((pg_therm & BIT(0)) == 0) + power_trim_info->thermal = (-1 * (pg_therm >> 1)); +- else ++ else { + power_trim_info->thermal = (pg_therm >> 1); ++ } + + power_trim_info->flag |= KFREE_FLAG_THERMAL_K_ON; + } +diff --git a/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8812a/halrf_8812a_ce.c b/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8812a/halrf_8812a_ce.c +index e2113e37a..a006d7e74 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8812a/halrf_8812a_ce.c ++++ b/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8812a/halrf_8812a_ce.c +@@ -1323,8 +1323,9 @@ void phy_iq_calibrate_8812a(void *dm_void, boolean is_recovery) + if (dm->rf_calibrate_info.is_iqk_in_progress) + RF_DBG(dm, DBG_RF_IQK, + "== FW IQK TIMEOUT (Still in progress after 500ms) ==\n"); +- } else ++ } else { + _phy_iq_calibrate_8812a(dm, *dm->channel); ++ } + } + + void phy_lc_calibrate_8812a(void *dm_void) +diff --git a/drivers/staging/rtl8812au/hal/phydm/phydm_beamforming.c b/drivers/staging/rtl8812au/hal/phydm/phydm_beamforming.c +index 4a770aa72..952b5600b 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/phydm_beamforming.c ++++ b/drivers/staging/rtl8812au/hal/phydm/phydm_beamforming.c +@@ -1337,10 +1337,11 @@ beamforming_init_entry(void *dm_void, u16 sta_idx, u8 *bfer_bfee_idx, + + if (beamformer_entry == NULL) { + beamformer_entry = beamforming_add_bfer_entry(dm, sta, beamform_cap, num_of_sounding_dim, &bfer_idx); +- if (beamformer_entry == NULL) ++ if (beamformer_entry == NULL) { + PHYDM_DBG(dm, DBG_TXBF, + "[%s]Not enough BFer entry!!!!!\n", + __func__); ++ } + } + } + +@@ -1781,10 +1782,11 @@ void beamforming_timer_callback( + #endif + if (ret) + ret = beamforming_start_sw(dm, sound_info->sound_idx, sound_info->sound_mode, sound_info->sound_bw); +- else ++ else { + PHYDM_DBG(dm, DBG_TXBF, + "%s, Error value return from BeamformingStart_V2\n", + __func__); ++ } + + if (beam_info->beamformee_su_cnt != 0 || beam_info->beamformee_mu_cnt > 1) { + if (sound_info->sound_mode == SOUNDING_SW_VHT_TIMER || sound_info->sound_mode == SOUNDING_SW_HT_TIMER) +diff --git a/drivers/staging/rtl8812au/hal/phydm/phydm_cfotracking.c b/drivers/staging/rtl8812au/hal/phydm/phydm_cfotracking.c +index 8aac6b094..d88d7a6c0 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/phydm_cfotracking.c ++++ b/drivers/staging/rtl8812au/hal/phydm/phydm_cfotracking.c +@@ -213,11 +213,13 @@ void phydm_set_crystal_cap(void *dm_void, u8 crystal_cap) + if (cfo_track->crystal_cap == crystal_cap) + return; + +- if (phydm_set_crystal_cap_reg(dm, crystal_cap)) ++ if (phydm_set_crystal_cap_reg(dm, crystal_cap)) { + PHYDM_DBG(dm, DBG_CFO_TRK, "Set crystal_cap = 0x%x\n", + cfo_track->crystal_cap); +- else ++ } ++ else { + PHYDM_DBG(dm, DBG_CFO_TRK, "Set fail\n"); ++ } + } + + boolean +diff --git a/drivers/staging/rtl8812au/hal/phydm/phydm_psd.c b/drivers/staging/rtl8812au/hal/phydm/phydm_psd.c +index 458677b59..33f715bcc 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/phydm_psd.c ++++ b/drivers/staging/rtl8812au/hal/phydm/phydm_psd.c +@@ -199,9 +199,10 @@ u8 phydm_psd(void *dm_void, u32 igi, u16 start_point, u16 stop_point) + if (dm->support_ic_type & ODM_IC_JGR3_SERIES) + PHYDM_DBG(dm, ODM_COMP_API, "0x1d70=((0x%x))\n", + odm_get_bb_reg(dm, R_0x1d70, MASKDWORD)); +- else ++ else { + PHYDM_DBG(dm, ODM_COMP_API, "0xc50=((0x%x))\n", + odm_get_bb_reg(dm, R_0xc50, MASKDWORD)); ++ } + + PHYDM_DBG(dm, ODM_COMP_API, "RF0x18=((0x%x))\n", + odm_get_rf_reg(dm, RF_PATH_A, RF_0x18, RFREG_MASK)); +diff --git a/drivers/staging/rtl8812au/hal/phydm/phydm_rainfo.c b/drivers/staging/rtl8812au/hal/phydm/phydm_rainfo.c +index 2c24b9be9..ca341c827 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/phydm_rainfo.c ++++ b/drivers/staging/rtl8812au/hal/phydm/phydm_rainfo.c +@@ -443,8 +443,9 @@ void phydm_c2h_ra_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len) + PHYDM_DBG(dm, DBG_RA, "Rate Back\n"); + else if (cmd_buf[3] == 4) + PHYDM_DBG(dm, DBG_RA, "Start rate by RSSI\n"); +- else if (cmd_buf[3] == 5) ++ else if (cmd_buf[3] == 5) { + PHYDM_DBG(dm, DBG_RA, "Try rate\n"); ++ } + } + phydm_print_rate_2_buff(dm, rate, dbg_buf, PHYDM_SNPRINT_SIZE); + PHYDM_DBG(dm, DBG_RA, "Tx Rate=%s (%d)", dbg_buf, rate); +@@ -829,8 +830,9 @@ u8 phydm_get_tx_stream_num(void *dm_void, enum rf_type type) + tx_num = 3; + else if (type == RF_4T4R) + tx_num = 4; +- else ++ else { + PHYDM_DBG(dm, DBG_RA, "[Warrning] no mimo_type is found\n"); ++ } + + return tx_num; + } +diff --git a/drivers/staging/rtl8812au/hal/phydm/txbf/halcomtxbf.c b/drivers/staging/rtl8812au/hal/phydm/txbf/halcomtxbf.c +index 4329dcaee..286105ec0 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/txbf/halcomtxbf.c ++++ b/drivers/staging/rtl8812au/hal/phydm/txbf/halcomtxbf.c +@@ -43,8 +43,9 @@ void hal_com_txbf_config_gtab( + { + struct dm_struct *dm = (struct dm_struct *)dm_void; + +- if (dm->support_ic_type & ODM_RTL8822B) ++ if (dm->support_ic_type & ODM_RTL8822B) { + hal_txbf_8822b_config_gtab(dm); ++ } + } + + void phydm_beamform_set_sounding_enter( +@@ -206,8 +207,9 @@ void hal_com_txbf_enter_work_item_callback( + hal_txbf_8192e_enter(dm, idx); + else if (dm->support_ic_type & ODM_RTL8814A) + hal_txbf_8814a_enter(dm, idx); +- else if (dm->support_ic_type & ODM_RTL8822B) ++ else if (dm->support_ic_type & ODM_RTL8822B) { + hal_txbf_8822b_enter(dm, idx); ++ } + } + + void hal_com_txbf_leave_work_item_callback( +@@ -236,8 +238,9 @@ void hal_com_txbf_leave_work_item_callback( + hal_txbf_8192e_leave(dm, idx); + else if (dm->support_ic_type & ODM_RTL8814A) + hal_txbf_8814a_leave(dm, idx); +- else if (dm->support_ic_type & ODM_RTL8822B) ++ else if (dm->support_ic_type & ODM_RTL8822B) { + hal_txbf_8822b_leave(dm, idx); ++ } + } + + void hal_com_txbf_fw_ndpa_work_item_callback( +@@ -265,8 +268,9 @@ void hal_com_txbf_fw_ndpa_work_item_callback( + hal_txbf_8192e_fw_tx_bf(dm, idx); + else if (dm->support_ic_type & ODM_RTL8814A) + hal_txbf_8814a_fw_txbf(dm, idx); +- else if (dm->support_ic_type & ODM_RTL8822B) ++ else if (dm->support_ic_type & ODM_RTL8822B) { + hal_txbf_8822b_fw_txbf(dm, idx); ++ } + } + + void hal_com_txbf_clk_work_item_callback( +@@ -363,8 +367,9 @@ void hal_com_txbf_status_work_item_callback( + hal_txbf_8192e_status(dm, idx); + else if (dm->support_ic_type & ODM_RTL8814A) + hal_txbf_8814a_status(dm, idx); +- else if (dm->support_ic_type & ODM_RTL8822B) ++ else if (dm->support_ic_type & ODM_RTL8822B) { + hal_txbf_8822b_status(dm, idx); ++ } + } + + void hal_com_txbf_reset_tx_path_work_item_callback( +diff --git a/drivers/staging/rtl8812au/hal/phydm/txbf/haltxbfjaguar.c b/drivers/staging/rtl8812au/hal/phydm/txbf/haltxbfjaguar.c +index c42fa53a6..78bb399d9 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/txbf/haltxbfjaguar.c ++++ b/drivers/staging/rtl8812au/hal/phydm/txbf/haltxbfjaguar.c +@@ -145,9 +145,10 @@ void hal_txbf_jaguar_download_ndpa( + dl_bcn_count++; + } while (!(bcn_valid_reg & BIT(0)) && dl_bcn_count < 5); + +- if (!(bcn_valid_reg & BIT(0))) ++ if (!(bcn_valid_reg & BIT(0))) { + PHYDM_DBG(dm, DBG_TXBF, "%s Download RSVD page failed!\n", + __func__); ++ } + + /*TDECTRL[15:8] 0x209[7:0] = 0xF6 Beacon Head for TXDMA*/ + odm_write_1byte(dm, REG_TDECTRL_8812A + 1, tx_page_bndy); +-- +2.41.1 + diff --git a/kernel/kernel/files/patches/mageia/0009-rtl8812au-add-suggested-braces-around-empty-body-in-.patch b/kernel/kernel/files/patches/mageia/0009-rtl8812au-add-suggested-braces-around-empty-body-in-.patch new file mode 100644 index 00000000..3571454e --- /dev/null +++ b/kernel/kernel/files/patches/mageia/0009-rtl8812au-add-suggested-braces-around-empty-body-in-.patch @@ -0,0 +1,96 @@ +From f9a18119d2a8f5bd4c35197c89c60305d58d3abd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Giuseppe=20Ghib=C3=B2?= +Date: Thu, 21 Nov 2024 17:03:25 +0100 +Subject: [PATCH 09/10] rtl8812au: add suggested braces around empty body in an + else statement + +--- + drivers/staging/rtl8812au/core/rtw_recv.c | 3 ++- + drivers/staging/rtl8812au/core/rtw_xmit.c | 3 ++- + drivers/staging/rtl8812au/hal/phydm/halrf/halrf_kfree.c | 3 ++- + .../rtl8812au/hal/phydm/halrf/rtl8812a/halrf_8812a_ce.c | 3 ++- + drivers/staging/rtl8812au/hal/phydm/phydm_beamforming.c | 3 ++- + 5 files changed, 10 insertions(+), 5 deletions(-) + +diff --git a/drivers/staging/rtl8812au/core/rtw_recv.c b/drivers/staging/rtl8812au/core/rtw_recv.c +index ed2bf605c..bdbc146ca 100644 +--- a/drivers/staging/rtl8812au/core/rtw_recv.c ++++ b/drivers/staging/rtl8812au/core/rtw_recv.c +@@ -2404,8 +2404,9 @@ sint validate_recv_frame(_adapter *adapter, union recv_frame *precv_frame) + dump_rx_packet(ptr); + } + #endif +- } else ++ } else { + DBG_COUNTER(adapter->rx_logs.core_rx_pre_data_handled); ++ } + break; + default: + DBG_COUNTER(adapter->rx_logs.core_rx_pre_unknown); +diff --git a/drivers/staging/rtl8812au/core/rtw_xmit.c b/drivers/staging/rtl8812au/core/rtw_xmit.c +index e40c0aecc..12a2d5d79 100644 +--- a/drivers/staging/rtl8812au/core/rtw_xmit.c ++++ b/drivers/staging/rtl8812au/core/rtw_xmit.c +@@ -1374,8 +1374,9 @@ static s32 update_attrib(_adapter *padapter, _pkt *pkt, struct pkt_attrib *pattr + _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); + _rtw_memcpy(pattrib->ta, get_bssid(pmlmepriv), ETH_ALEN); + DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_ap); +- } else ++ } else { + DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_unknown); ++ } + + get_sta_info: + bmcast = IS_MCAST(pattrib->ra); +diff --git a/drivers/staging/rtl8812au/hal/phydm/halrf/halrf_kfree.c b/drivers/staging/rtl8812au/hal/phydm/halrf/halrf_kfree.c +index a4e3504a3..c31566d70 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/halrf/halrf_kfree.c ++++ b/drivers/staging/rtl8812au/hal/phydm/halrf/halrf_kfree.c +@@ -814,9 +814,10 @@ void phydm_get_thermal_trim_offset_8198f(void *dm_void) + RF_DBG(dm, DBG_RF_MP, "[kfree] 8198f thermal trim flag:0x%02x\n", + power_trim_info->flag); + +- if (power_trim_info->flag & KFREE_FLAG_THERMAL_K_ON) ++ if (power_trim_info->flag & KFREE_FLAG_THERMAL_K_ON) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8198f thermal:%d\n", + power_trim_info->thermal); ++ } + } + + void phydm_get_power_trim_offset_8198f(void *dm_void); +diff --git a/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8812a/halrf_8812a_ce.c b/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8812a/halrf_8812a_ce.c +index a006d7e74..4f11b8223 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8812a/halrf_8812a_ce.c ++++ b/drivers/staging/rtl8812au/hal/phydm/halrf/rtl8812a/halrf_8812a_ce.c +@@ -1320,9 +1320,10 @@ void phy_iq_calibrate_8812a(void *dm_void, boolean is_recovery) + if (dm->fw_offload_ability & PHYDM_RF_IQK_OFFLOAD) { + _phy_iq_calibrate_by_fw_8812a(dm); + phydm_iqk_wait(dm, 500); +- if (dm->rf_calibrate_info.is_iqk_in_progress) ++ if (dm->rf_calibrate_info.is_iqk_in_progress) { + RF_DBG(dm, DBG_RF_IQK, + "== FW IQK TIMEOUT (Still in progress after 500ms) ==\n"); ++ } + } else { + _phy_iq_calibrate_8812a(dm, *dm->channel); + } +diff --git a/drivers/staging/rtl8812au/hal/phydm/phydm_beamforming.c b/drivers/staging/rtl8812au/hal/phydm/phydm_beamforming.c +index 952b5600b..28ab2dd54 100644 +--- a/drivers/staging/rtl8812au/hal/phydm/phydm_beamforming.c ++++ b/drivers/staging/rtl8812au/hal/phydm/phydm_beamforming.c +@@ -1196,10 +1196,11 @@ void phydm_beamforming_notify( + /*@if (sound_info->sound_mode == SOUNDING_SW_VHT_TIMER || sound_info->sound_mode == SOUNDING_SW_HT_TIMER) + odm_set_timer(dm, &beam_info->beamforming_timer, sound_info->sound_period);*/ + odm_set_timer(dm, &beam_info->beamforming_timer, 1000); /*@Do MU sounding every 1sec*/ +- } else ++ } else { + PHYDM_DBG(dm, DBG_TXBF, + "%s: Less or larger than 2 MU STAs, not to set timer\n", + __func__); ++ } + break; + + case BEAMFORMEE_NOTIFY_DELETE_MU: +-- +2.41.1 + diff --git a/kernel/kernel/files/patches/mageia/0010-rtl8812au-add-missed-prototypes.patch b/kernel/kernel/files/patches/mageia/0010-rtl8812au-add-missed-prototypes.patch new file mode 100644 index 00000000..c6f47d7f --- /dev/null +++ b/kernel/kernel/files/patches/mageia/0010-rtl8812au-add-missed-prototypes.patch @@ -0,0 +1,42 @@ +From 18bb3090b6c0876842813ac10d1822412f51e97e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Giuseppe=20Ghib=C3=B2?= +Date: Thu, 21 Nov 2024 17:07:41 +0100 +Subject: [PATCH 10/10] rtl8812au: add missed prototypes + +--- + drivers/staging/rtl8812au/os_dep/linux/ioctl_cfg80211.c | 7 +++++++ + drivers/staging/rtl8812au/os_dep/linux/usb_ops_linux.c | 1 + + 2 files changed, 8 insertions(+) + +diff --git a/drivers/staging/rtl8812au/os_dep/linux/ioctl_cfg80211.c b/drivers/staging/rtl8812au/os_dep/linux/ioctl_cfg80211.c +index c0f563430..72538365a 100644 +--- a/drivers/staging/rtl8812au/os_dep/linux/ioctl_cfg80211.c ++++ b/drivers/staging/rtl8812au/os_dep/linux/ioctl_cfg80211.c +@@ -2151,6 +2151,12 @@ + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)) + int link_id, + #endif ++ u8 key_index); ++int cfg80211_rtw_set_default_mgmt_key(struct wiphy *wiphy, ++ struct net_device *ndev, ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)) ++ int link_id, ++#endif + u8 key_index) + { + #define SET_DEF_KEY_PARAM_FMT " key_index=%d" +diff --git a/drivers/staging/rtl8812au/os_dep/linux/usb_ops_linux.c b/drivers/staging/rtl8812au/os_dep/linux/usb_ops_linux.c +index c7eb7ea40..9ced824fe 100644 +--- a/drivers/staging/rtl8812au/os_dep/linux/usb_ops_linux.c ++++ b/drivers/staging/rtl8812au/os_dep/linux/usb_ops_linux.c +@@ -898,6 +898,7 @@ void usb_recv_tasklet(unsigned long priv) + } + } + ++void usb_read_port_complete(struct urb *purb, struct pt_regs *regs); + void usb_read_port_complete(struct urb *purb, struct pt_regs *regs) + { + struct recv_buf *precvbuf = (struct recv_buf *)purb->context; +-- +2.41.1 + diff --git a/kernel/kernel/files/patches/mageia/0122-Fix-change_beacon-for-kernel-6.7.patch b/kernel/kernel/files/patches/mageia/0122-Fix-change_beacon-for-kernel-6.7.patch new file mode 100644 index 00000000..88ad4964 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/0122-Fix-change_beacon-for-kernel-6.7.patch @@ -0,0 +1,33 @@ +From c0d16813f5af3b464cdb6dd415c83d1f238e3548 Mon Sep 17 00:00:00 2001 +From: CamiKaseM7 +Date: Tue, 16 Jan 2024 03:44:34 -0300 +Subject: [PATCH 122/132] Fix change_beacon for kernel 6.7 + +--- + os_dep/linux/ioctl_cfg80211.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/staging/rtl8812au/os_dep/linux/ioctl_cfg80211.c b/drivers/staging/rtl8812au/os_dep/linux/ioctl_cfg80211.c +index 510fa45..a135804 100644 +--- a/drivers/staging/rtl8812au/os_dep/linux/ioctl_cfg80211.c ++++ b/drivers/staging/rtl8812au/os_dep/linux/ioctl_cfg80211.c +@@ -5283,9 +5283,16 @@ exit: + return ret; + } + ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0)) ++static int cfg80211_rtw_change_beacon(struct wiphy *wiphy, struct net_device *ndev, ++ struct cfg80211_ap_update *params) ++{ ++ struct cfg80211_beacon_data *info = ¶ms->beacon; ++#else + static int cfg80211_rtw_change_beacon(struct wiphy *wiphy, struct net_device *ndev, + struct cfg80211_beacon_data *info) + { ++#endif + int ret = 0; + _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev); + +-- +2.41.1 + diff --git a/kernel/kernel/files/patches/mageia/0123-Update-os_intfs.c-for-kernel-6.8.patch b/kernel/kernel/files/patches/mageia/0123-Update-os_intfs.c-for-kernel-6.8.patch new file mode 100644 index 00000000..c740ce5e --- /dev/null +++ b/kernel/kernel/files/patches/mageia/0123-Update-os_intfs.c-for-kernel-6.8.patch @@ -0,0 +1,27 @@ +From d3feb6ae9398834d7778c0e43ebd1fa757eaecd8 Mon Sep 17 00:00:00 2001 +From: alium +Date: Tue, 12 Mar 2024 07:11:35 +0100 +Subject: [PATCH 123/132] Update os_intfs.c for kernel 6.8 + +--- + os_dep/linux/os_intfs.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/staging/rtl8812au/os_dep/linux/os_intfs.c b/drivers/staging/rtl8812au/os_dep/linux/os_intfs.c +index 2dadae0..f4f2ef9 100644 +--- a/drivers/staging/rtl8812au/os_dep/linux/os_intfs.c ++++ b/drivers/staging/rtl8812au/os_dep/linux/os_intfs.c +@@ -17,6 +17,10 @@ + #include + #include + ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 8, 0)) ++#define strlcpy strscpy ++#endif ++ + MODULE_LICENSE("GPL"); + MODULE_DESCRIPTION("Realtek Wireless Lan Driver"); + MODULE_AUTHOR("Realtek Semiconductor Corp."); +-- +2.41.1 + diff --git a/kernel/kernel/files/patches/mageia/0124-Update-usb_intf.c-for-kernel-6.8.patch b/kernel/kernel/files/patches/mageia/0124-Update-usb_intf.c-for-kernel-6.8.patch new file mode 100644 index 00000000..15e2203b --- /dev/null +++ b/kernel/kernel/files/patches/mageia/0124-Update-usb_intf.c-for-kernel-6.8.patch @@ -0,0 +1,25 @@ +From 88d0f5ca85cb8f6a7970ccca9d06a5aa424a18b2 Mon Sep 17 00:00:00 2001 +From: alium +Date: Tue, 12 Mar 2024 07:14:38 +0100 +Subject: [PATCH 124/132] Update usb_intf.c for kernel 6.8 + +--- + os_dep/linux/usb_intf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/staging/rtl8812au/os_dep/linux/usb_intf.c b/drivers/staging/rtl8812au/os_dep/linux/usb_intf.c +index be0f654..709e935 100644 +--- a/drivers/staging/rtl8812au/os_dep/linux/usb_intf.c ++++ b/drivers/staging/rtl8812au/os_dep/linux/usb_intf.c +@@ -270,7 +270,7 @@ struct rtw_usb_drv usb_drv = { + .usbdrv.supports_autosuspend = 1, + #endif + +-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)) ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)) && (LINUX_VERSION_CODE < KERNEL_VERSION(6, 8, 0)) + .usbdrv.drvwrap.driver.shutdown = rtw_dev_shutdown, + #else + .usbdrv.driver.shutdown = rtw_dev_shutdown, +-- +2.41.1 + diff --git a/kernel/kernel/files/patches/mageia/0128-Update-ioctl_cfg80211.c-support-for-kernel-6.9.patch b/kernel/kernel/files/patches/mageia/0128-Update-ioctl_cfg80211.c-support-for-kernel-6.9.patch new file mode 100644 index 00000000..78fce182 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/0128-Update-ioctl_cfg80211.c-support-for-kernel-6.9.patch @@ -0,0 +1,35 @@ +From 860ccf31655e160ec921190e443f0b532d8d3308 Mon Sep 17 00:00:00 2001 +From: alium +Date: Sat, 30 Mar 2024 09:50:44 +0100 +Subject: [PATCH 128/132] Update ioctl_cfg80211.c - support for kernel 6.9 + + support for kernel 6.9 +--- + drivers/staging/rtl8812au/os_dep/linux/ioctl_cfg80211.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/staging/rtl8812au/os_dep/linux/ioctl_cfg80211.c b/drivers/staging/rtl8812au/os_dep/linux/ioctl_cfg80211.c +index a135804..c1f20e9 100644 +--- a/drivers/staging/rtl8812au/os_dep/linux/ioctl_cfg80211.c ++++ b/drivers/staging/rtl8812au/os_dep/linux/ioctl_cfg80211.c +@@ -460,7 +460,7 @@ u8 rtw_cfg80211_ch_switch_notify(_adapter *adapter, u8 ch, u8 bw, u8 offset, + + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) + if (started) { +-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0)) ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(6, 9, 0)) + cfg80211_ch_switch_started_notify(adapter->pnetdev, &chdef, 0, 0, false, 0); + #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)) + cfg80211_ch_switch_started_notify(adapter->pnetdev, &chdef, 0, 0, false); +@@ -476,7 +476,7 @@ u8 rtw_cfg80211_ch_switch_notify(_adapter *adapter, u8 ch, u8 bw, u8 offset, + if (!rtw_cfg80211_allow_ch_switch_notify(adapter)) + goto exit; + +-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0)) ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(6, 9, 0)) + cfg80211_ch_switch_notify(adapter->pnetdev, &chdef, 0, 0); + #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) + cfg80211_ch_switch_notify(adapter->pnetdev, &chdef, 0); +-- +2.41.1 + diff --git a/kernel/kernel/files/patches/mageia/iwlwifi-cfg-Add-missing-MODULE_FIRMWARE-for-pnvm.patch b/kernel/kernel/files/patches/mageia/iwlwifi-cfg-Add-missing-MODULE_FIRMWARE-for-pnvm.patch index f8b74a34..713de971 100644 --- a/kernel/kernel/files/patches/mageia/iwlwifi-cfg-Add-missing-MODULE_FIRMWARE-for-pnvm.patch +++ b/kernel/kernel/files/patches/mageia/iwlwifi-cfg-Add-missing-MODULE_FIRMWARE-for-pnvm.patch @@ -30,13 +30,11 @@ diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wirele index 3bdd6774716d..3c6dc3601784 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c -@@ -1065,3 +1065,7 @@ MODULE_FIRMWARE(IWL_BNJ_A_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); - MODULE_FIRMWARE(IWL_BZ_A_FM4_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); - MODULE_FIRMWARE(IWL_GL_B_FM_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); - MODULE_FIRMWARE(IWL_BNJ_B_FM_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); +@@ -426,3 +426,7 @@ + MODULE_FIRMWARE(IWL_QUZ_A_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); + MODULE_FIRMWARE(IWL_QUZ_A_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); + MODULE_FIRMWARE(IWL_CC_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); + +MODULE_FIRMWARE("iwlwifi-so-a0-gf4-a0.pnvm"); +MODULE_FIRMWARE("iwlwifi-so-a0-gf-a0.pnvm"); +MODULE_FIRMWARE("iwlwifi-ty-a0-gf-a0.pnvm"); --- -2.35.3 diff --git a/kernel/kernel/files/patches/mageia/mmc-sdio-Add-rename-SDIO-ID-of-the-RTL8723DS-SDIO-wi.patch b/kernel/kernel/files/patches/mageia/mmc-sdio-Add-rename-SDIO-ID-of-the-RTL8723DS-SDIO-wi.patch new file mode 100644 index 00000000..4f38f16d --- /dev/null +++ b/kernel/kernel/files/patches/mageia/mmc-sdio-Add-rename-SDIO-ID-of-the-RTL8723DS-SDIO-wi.patch @@ -0,0 +1,42 @@ +From 09fcdbd28404b7e02cc9fc4862ae5b43b76867c0 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Mon, 22 May 2023 22:24:24 +0200 +Subject: [PATCH] mmc: sdio: Add/rename SDIO ID of the RTL8723DS SDIO wifi + cards + +RTL8723DS comes in two variant and each of them has their own SDIO ID: +- 0xd723 can connect two antennas. The WiFi part is still 1x1 so the + second antenna can be dedicated to Bluetooth +- 0xd724 can only connect one antenna so it's shared between WiFi and + Bluetooth + +Add a new entry for the single antenna RTL8723DS (0xd724) which can be +found on the MangoPi MQ-Quad. Also rename the existing RTL8723DS entry +(0xd723) so it's name reflects that it's the variant with support for +two antennas. + +Reviewed-by: Ping-Ke Shih +Signed-off-by: Martin Blumenstingl +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230522202425.1827005-4-martin.blumenstingl@googlemail.com +--- + include/linux/mmc/sdio_ids.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h +index c653accdc7fd..7fada7a714fe 100644 +--- a/include/linux/mmc/sdio_ids.h ++++ b/include/linux/mmc/sdio_ids.h +@@ -121,7 +121,8 @@ + #define SDIO_DEVICE_ID_REALTEK_RTW8822BS 0xb822 + #define SDIO_DEVICE_ID_REALTEK_RTW8821CS 0xc821 + #define SDIO_DEVICE_ID_REALTEK_RTW8822CS 0xc822 +-#define SDIO_DEVICE_ID_REALTEK_RTW8723DS 0xd723 ++#define SDIO_DEVICE_ID_REALTEK_RTW8723DS_2ANT 0xd723 ++#define SDIO_DEVICE_ID_REALTEK_RTW8723DS_1ANT 0xd724 + #define SDIO_DEVICE_ID_REALTEK_RTW8821DS 0xd821 + + #define SDIO_VENDOR_ID_SIANO 0x039a +-- +2.41.0 + diff --git a/kernel/kernel/files/patches/mageia/platform-x86-add-shuttle-wmi-driver.patch b/kernel/kernel/files/patches/mageia/platform-x86-add-shuttle-wmi-driver.patch index c334c54c..257b0d70 100644 --- a/kernel/kernel/files/patches/mageia/platform-x86-add-shuttle-wmi-driver.patch +++ b/kernel/kernel/files/patches/mageia/platform-x86-add-shuttle-wmi-driver.patch @@ -6,9 +6,9 @@ drivers/platform/x86/shuttle-wmi.c | 1297 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 1393 insertions(+) -diff -Nurp linux-5.15.1/Documentation/ABI/testing/sysfs-platform-shuttle-wmi linux-5.15.1-shuttle/Documentation/ABI/testing/sysfs-platform-shuttle-wmi ---- linux-5.15.1/Documentation/ABI/testing/sysfs-platform-shuttle-wmi 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.15.1-shuttle/Documentation/ABI/testing/sysfs-platform-shuttle-wmi 2021-11-08 23:24:45.468092228 +0200 +diff -up linux-6.11/Documentation/ABI/testing/sysfs-platform-shuttle-wmi.wmi linux-6.11/Documentation/ABI/testing/sysfs-platform-shuttle-wmi +--- linux-6.11/Documentation/ABI/testing/sysfs-platform-shuttle-wmi.wmi 2024-11-18 10:43:15.072608505 +0100 ++++ linux-6.11/Documentation/ABI/testing/sysfs-platform-shuttle-wmi 2024-11-18 10:43:15.072608505 +0100 @@ -0,0 +1,72 @@ +What: /sys/devices/platform/shuttle_wmi/lcd_auto_adjust +Date: December 2010 @@ -82,10 +82,10 @@ diff -Nurp linux-5.15.1/Documentation/ABI/testing/sysfs-platform-shuttle-wmi lin + shuttle wmi documentation. It also starts an auto adjust and + color adjust cycle. The function should only work in shuttle + machines with LCD attached to an analog VGA connector. -diff -Nurp linux-5.15.1/drivers/platform/x86/Kconfig linux-5.15.1-shuttle/drivers/platform/x86/Kconfig ---- linux-5.15.1/drivers/platform/x86/Kconfig 2021-10-31 22:53:10.000000000 +0200 -+++ linux-5.15.1-shuttle/drivers/platform/x86/Kconfig 2021-11-08 23:24:45.469092275 +0200 -@@ -879,6 +879,21 @@ config PANASONIC_LAPTOP +diff -up linux-6.11/drivers/platform/x86/Kconfig.wmi linux-6.11/drivers/platform/x86/Kconfig +--- linux-6.11/drivers/platform/x86/Kconfig.wmi 2024-11-18 00:42:21.841340904 +0100 ++++ linux-6.11/drivers/platform/x86/Kconfig 2024-11-18 10:43:15.072608505 +0100 +@@ -947,6 +947,21 @@ config PANASONIC_LAPTOP If you have a Panasonic Let's note laptop (such as the R1(N variant), R2, R3, R5, T2, W2 and Y2 series), say Y. @@ -107,10 +107,10 @@ diff -Nurp linux-5.15.1/drivers/platform/x86/Kconfig linux-5.15.1-shuttle/driver config SONY_LAPTOP tristate "Sony Laptop Extras" depends on ACPI -diff -Nurp linux-5.15.1/drivers/platform/x86/Makefile linux-5.15.1-shuttle/drivers/platform/x86/Makefile ---- linux-5.15.1/drivers/platform/x86/Makefile 2021-10-31 22:53:10.000000000 +0200 -+++ linux-5.15.1-shuttle/drivers/platform/x86/Makefile 2021-11-08 23:24:45.469092275 +0200 -@@ -84,6 +84,9 @@ obj-$(CONFIG_PCENGINES_APU2) += pcengine +diff -up linux-6.11/drivers/platform/x86/Makefile.wmi linux-6.11/drivers/platform/x86/Makefile +--- linux-6.11/drivers/platform/x86/Makefile.wmi 2024-09-15 16:57:56.000000000 +0200 ++++ linux-6.11/drivers/platform/x86/Makefile 2024-11-18 10:43:15.072608505 +0100 +@@ -98,6 +98,9 @@ obj-$(CONFIG_BARCO_P50_GPIO) += barco-p5 obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop.o obj-$(CONFIG_SAMSUNG_Q10) += samsung-q10.o @@ -120,9 +120,9 @@ diff -Nurp linux-5.15.1/drivers/platform/x86/Makefile linux-5.15.1-shuttle/drive # Toshiba obj-$(CONFIG_TOSHIBA_BT_RFKILL) += toshiba_bluetooth.o obj-$(CONFIG_TOSHIBA_HAPS) += toshiba_haps.o -diff -Nurp linux-5.15.1/drivers/platform/x86/shuttle-wmi.c linux-5.15.1-shuttle/drivers/platform/x86/shuttle-wmi.c ---- linux-5.15.1/drivers/platform/x86/shuttle-wmi.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.15.1-shuttle/drivers/platform/x86/shuttle-wmi.c 2021-11-08 23:24:45.468092228 +0200 +diff -up linux-6.11/drivers/platform/x86/shuttle-wmi.c.wmi linux-6.11/drivers/platform/x86/shuttle-wmi.c +--- linux-6.11/drivers/platform/x86/shuttle-wmi.c.wmi 2024-11-18 10:43:15.072608505 +0100 ++++ linux-6.11/drivers/platform/x86/shuttle-wmi.c 2024-11-18 10:43:15.072608505 +0100 @@ -0,0 +1,1297 @@ +/* + * ACPI-WMI driver for Shuttle WMI interface @@ -1421,10 +1421,10 @@ diff -Nurp linux-5.15.1/drivers/platform/x86/shuttle-wmi.c linux-5.15.1-shuttle/ + +module_init(shuttle_wmi_init); +module_exit(shuttle_wmi_exit); -diff -Nurp linux-5.18/MAINTAINERS.orig linux-5.18/MAINTAINERS ---- linux-5.18/MAINTAINERS.orig -+++ linux-5.18/MAINTAINERS -@@ -17888,6 +17888,12 @@ +diff -up linux-6.11/MAINTAINERS.wmi linux-6.11/MAINTAINERS +--- linux-6.11/MAINTAINERS.wmi 2024-11-18 00:42:21.251332731 +0100 ++++ linux-6.11/MAINTAINERS 2024-11-18 10:43:15.076608549 +0100 +@@ -20958,6 +20958,12 @@ S: Orphan F: drivers/media/platform/renesas/sh_vou.c F: include/media/drv-intf/sh_vou.h @@ -1435,5 +1435,5 @@ diff -Nurp linux-5.18/MAINTAINERS.orig linux-5.18/MAINTAINERS +F: drivers/platform/x86/shuttle-wmi.c + SI2157 MEDIA DRIVER - M: Antti Palosaari L: linux-media@vger.kernel.org + S: Orphan diff --git a/kernel/kernel/files/patches/mageia/wifi-rtw88-Add-support-for-the-SDIO-based-RTL8723DS-.patch b/kernel/kernel/files/patches/mageia/wifi-rtw88-Add-support-for-the-SDIO-based-RTL8723DS-.patch new file mode 100644 index 00000000..e291e885 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/wifi-rtw88-Add-support-for-the-SDIO-based-RTL8723DS-.patch @@ -0,0 +1,105 @@ +From a3b125ceb45e1acd21c9bcb6d3a5c52897d536e6 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Mon, 22 May 2023 22:24:25 +0200 +Subject: [PATCH] wifi: rtw88: Add support for the SDIO based RTL8723DS chipset + +Wire up RTL8723DS chipset support using the rtw88 SDIO HCI code as well +as the existing RTL8723D chipset code. + +Reviewed-by: Ping-Ke Shih +Signed-off-by: Martin Blumenstingl +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230522202425.1827005-5-martin.blumenstingl@googlemail.com +--- + drivers/net/wireless/realtek/rtw88/Kconfig | 11 +++++ + drivers/net/wireless/realtek/rtw88/Makefile | 3 ++ + .../net/wireless/realtek/rtw88/rtw8723ds.c | 41 +++++++++++++++++++ + 3 files changed, 55 insertions(+) + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8723ds.c + +diff --git a/drivers/net/wireless/realtek/rtw88/Kconfig b/drivers/net/wireless/realtek/rtw88/Kconfig +index 29eb2f8e0eb7..cffad1c01249 100644 +--- a/drivers/net/wireless/realtek/rtw88/Kconfig ++++ b/drivers/net/wireless/realtek/rtw88/Kconfig +@@ -111,6 +111,17 @@ config RTW88_8723DE + + 802.11n PCIe wireless network adapter + ++config RTW88_8723DS ++ tristate "Realtek 8723DS SDIO wireless network adapter" ++ depends on MMC ++ select RTW88_CORE ++ select RTW88_SDIO ++ select RTW88_8723D ++ help ++ Select this option will enable support for 8723DS chipset ++ ++ 802.11n SDIO wireless network adapter ++ + config RTW88_8723DU + tristate "Realtek 8723DU USB wireless network adapter" + depends on USB +diff --git a/drivers/net/wireless/realtek/rtw88/Makefile b/drivers/net/wireless/realtek/rtw88/Makefile +index 82979b30ae8d..fd212c09d88a 100644 +--- a/drivers/net/wireless/realtek/rtw88/Makefile ++++ b/drivers/net/wireless/realtek/rtw88/Makefile +@@ -50,6 +50,9 @@ rtw88_8723d-objs := rtw8723d.o rtw8723d_table.o + obj-$(CONFIG_RTW88_8723DE) += rtw88_8723de.o + rtw88_8723de-objs := rtw8723de.o + ++obj-$(CONFIG_RTW88_8723DS) += rtw88_8723ds.o ++rtw88_8723ds-objs := rtw8723ds.o ++ + obj-$(CONFIG_RTW88_8723DU) += rtw88_8723du.o + rtw88_8723du-objs := rtw8723du.o + +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723ds.c b/drivers/net/wireless/realtek/rtw88/rtw8723ds.c +new file mode 100644 +index 000000000000..e5b6960ba0a0 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723ds.c +@@ -0,0 +1,41 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) Martin Blumenstingl ++ */ ++ ++#include ++#include ++#include ++#include "main.h" ++#include "rtw8723d.h" ++#include "sdio.h" ++ ++static const struct sdio_device_id rtw_8723ds_id_table[] = { ++ { ++ SDIO_DEVICE(SDIO_VENDOR_ID_REALTEK, ++ SDIO_DEVICE_ID_REALTEK_RTW8723DS_1ANT), ++ .driver_data = (kernel_ulong_t)&rtw8723d_hw_spec, ++ }, ++ { ++ SDIO_DEVICE(SDIO_VENDOR_ID_REALTEK, ++ SDIO_DEVICE_ID_REALTEK_RTW8723DS_2ANT), ++ .driver_data = (kernel_ulong_t)&rtw8723d_hw_spec, ++ }, ++ {} ++}; ++MODULE_DEVICE_TABLE(sdio, rtw_8723ds_id_table); ++ ++static struct sdio_driver rtw_8723ds_driver = { ++ .name = "rtw_8723ds", ++ .probe = rtw_sdio_probe, ++ .remove = rtw_sdio_remove, ++ .id_table = rtw_8723ds_id_table, ++ .drv = { ++ .pm = &rtw_sdio_pm_ops, ++ .shutdown = rtw_sdio_shutdown, ++ } ++}; ++module_sdio_driver(rtw_8723ds_driver); ++ ++MODULE_AUTHOR("Martin Blumenstingl "); ++MODULE_DESCRIPTION("Realtek 802.11n wireless 8723ds driver"); ++MODULE_LICENSE("Dual BSD/GPL"); +-- +2.41.0 + diff --git a/kernel/kernel/files/patches/mageia/wifi-rtw88-rtw8723d-Implement-RTL8723DS-SDIO-efuse-p.patch b/kernel/kernel/files/patches/mageia/wifi-rtw88-rtw8723d-Implement-RTL8723DS-SDIO-efuse-p.patch new file mode 100644 index 00000000..42cfb47b --- /dev/null +++ b/kernel/kernel/files/patches/mageia/wifi-rtw88-rtw8723d-Implement-RTL8723DS-SDIO-efuse-p.patch @@ -0,0 +1,73 @@ +From 9be20a82232779c59979527dfc8febca3182fee2 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Mon, 22 May 2023 22:24:23 +0200 +Subject: [PATCH] wifi: rtw88: rtw8723d: Implement RTL8723DS (SDIO) efuse + parsing + +The efuse of the SDIO RTL8723DS chip has only one known member: the mac +address is at offset 0x11a. Add a struct rtw8723ds_efuse describing this +and use it for copying the mac address when the SDIO bus is used. + +Reviewed-by: Ping-Ke Shih +Signed-off-by: Martin Blumenstingl +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230522202425.1827005-3-martin.blumenstingl@googlemail.com +--- + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 9 +++++++++ + drivers/net/wireless/realtek/rtw88/rtw8723d.h | 6 ++++++ + 2 files changed, 15 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +index 06e7454c9ca6..cadf66f4e854 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +@@ -216,6 +216,12 @@ static void rtw8723du_efuse_parsing(struct rtw_efuse *efuse, + ether_addr_copy(efuse->addr, map->u.mac_addr); + } + ++static void rtw8723ds_efuse_parsing(struct rtw_efuse *efuse, ++ struct rtw8723d_efuse *map) ++{ ++ ether_addr_copy(efuse->addr, map->s.mac_addr); ++} ++ + static int rtw8723d_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) + { + struct rtw_efuse *efuse = &rtwdev->efuse; +@@ -248,6 +254,9 @@ static int rtw8723d_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) + case RTW_HCI_TYPE_USB: + rtw8723du_efuse_parsing(efuse, map); + break; ++ case RTW_HCI_TYPE_SDIO: ++ rtw8723ds_efuse_parsing(efuse, map); ++ break; + default: + /* unsupported now */ + return -ENOTSUPP; +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.h b/drivers/net/wireless/realtek/rtw88/rtw8723d.h +index a356318a5c15..3642a2c7f80c 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.h ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.h +@@ -49,6 +49,11 @@ struct rtw8723du_efuse { + u8 mac_addr[ETH_ALEN]; /* 0x107 */ + }; + ++struct rtw8723ds_efuse { ++ u8 res4[0x4a]; /* 0xd0 */ ++ u8 mac_addr[ETH_ALEN]; /* 0x11a */ ++}; ++ + struct rtw8723d_efuse { + __le16 rtl_id; + u8 rsvd[2]; +@@ -80,6 +85,7 @@ struct rtw8723d_efuse { + union { + struct rtw8723de_efuse e; + struct rtw8723du_efuse u; ++ struct rtw8723ds_efuse s; + }; + }; + +-- +2.41.0 + diff --git a/kernel/kernel/pspec.xml b/kernel/kernel/pspec.xml index f504c8c1..95267a73 100644 --- a/kernel/kernel/pspec.xml +++ b/kernel/kernel/pspec.xml @@ -12,7 +12,7 @@ kernel The Linux kernel (the core of the Linux operating system) for Pisi Linux kernel contains the Linux kernel, the core of any Linux operating system. The kernel handles the basic functions of the operating system: memory allocation, process allocation, device input and output, etc. - https://mirrors.edge.kernel.org/pub/linux/kernel/v6.x/linux-6.6.tar.gz + https://mirrors.edge.kernel.org/pub/linux/kernel/v6.x/linux-6.12.tar.xz configs/kernel-x86_64-config scripts/generate-module-list @@ -33,10 +33,10 @@ - patches/linux/patch-6.6.92.xz + patches/linux/patch-6.12.40.xz - patches/aufs6/aufs6.6.84-20250414.patch + patches/aufs6/aufs6.12-20250414.patch patches/aufs6/aufs6-base.patch patches/aufs6/aufs6-kbuild.patch @@ -46,23 +46,45 @@ + + + + patches/mageia/platform-x86-add-shuttle-wmi-driver.patch patches/mageia/platform-x86-shuttle-wmi-4.13-buildfix.patch patches/mageia/platform-x86-shuttle-wmi-4.2-buildfix.patch patches/mageia/platform-x86-shuttle-wmi-drop-devinit-exit.patch patches/mageia/platform-x86-shuttle-wmi-kernel-5.5.patch + patches/mageia/staging-rtl8812au.patch patches/mageia/staging-rtl8812au-rename.patch patches/mageia/staging-rtl8812au-Kconfig-Makefile.patch patches/mageia/staging-rtl8812au-20231117.patch + patches/mageia/0001-Pull-device-0x0821-from-list-of-device-supported-by-.patch + patches/mageia/0122-Fix-change_beacon-for-kernel-6.7.patch + patches/mageia/0123-Update-os_intfs.c-for-kernel-6.8.patch + patches/mageia/0124-Update-usb_intf.c-for-kernel-6.8.patch + patches/mageia/0128-Update-ioctl_cfg80211.c-support-for-kernel-6.9.patch + + patches/mageia/0001-rtl8812au-add-missed-prototypes.patch + patches/mageia/0005-rtl8812au-add-missed-prototypes.patch + patches/mageia/0006-rtl8812au-add-suggested-braces-around-empty-body-in-.patch + patches/mageia/0007-rtl8812au-add-suggested-braces-around-empty-body-in-.patch + patches/mageia/0008-rtl8812au-add-suggested-braces-around-empty-body-in-.patch + patches/mageia/0009-rtl8812au-add-suggested-braces-around-empty-body-in-.patch + patches/mageia/0010-rtl8812au-add-missed-prototypes.patch + patches/mageia/0002-rtl8812au-fix-warnings.patch + + patches/mageia/net-wireless-rtw88-add-8723de-alias.patch patches/mageia/net-wireless-rtw88-add-r8822be-alias.patch + patches/mageia/net-wireless-iwlwifi-add-new-pci-id-for-6235.patch patches/mageia/wifi-iwlwifi-pcie-add-support-for-AX101NGW.patch - + patches/mageia/x86-pci-toshiba-equium-a60-assign-busses.patch @@ -123,6 +145,17 @@ + + 2025-07-24 + 6.12.40 + Version bump. + security + + systemRestart + + Mustafa Cinasal + muscnsl@gmail.com + 2025-05-23 6.6.92