From 5cc4ace311de62dd605db8908f53835f46ea45f2 Mon Sep 17 00:00:00 2001 From: Rmys Date: Mon, 1 Mar 2021 20:51:08 +0300 Subject: [PATCH] kernel-5.10.19 --- .../change-default-console-loglevel.patch | 11 - .../fix_CPU0_microcode_on_resume.patch | 21 - .../gentoo/1500_XATTR_USER_PREFIX.patch | 54 - ...ink-security-restrictions-by-default.patch | 22 - ...0_ThinkPad-30-brightness-control-fix.patch | 67 - .../gentoo/2900_dev-root-proc-mount-fix.patch | 30 - .../gentoo/2905_2disk-resume-image-fix.patch | 24 - .../patches/gentoo/4200_fbcondecor-3.19.patch | 2119 - .../gentoo/4567_distro-Gentoo-Kconfig.patch | 143 - ...kconfig-build-bits-for-BFQ-v7r7-3.19.patch | 104 - ...duce-the-BFQ-v7r7-I-O-sched-for-3.19.patch | 6966 --- ...the-BFQ-v7r7-I-O-sched-for-3.19.patch1.txt | 6966 --- ...eue-Merge-EQM-to-BFQ-v7r7-for-3.19.0.patch | 1222 - ...tional-cpu-optimizations-for-gcc-4.9.patch | 387 - .../perf/files/patches/linux/patch-5.10.15.xz | Bin 0 -> 486748 bytes .../perf/files/patches/linux/patch-5.10.19.xz | Bin 0 -> 535612 bytes .../perf/files/patches/linux/patch-5.10.3.xz | Bin 16432 -> 0 bytes .../perf/files/patches/linux/patch-5.9.13.xz | Bin 621916 -> 0 bytes .../patches/mageia/3rd-fix-kconfig.patch | 2 +- .../mageia/3rd-rtl8821ce-kernel-5.10.patch | 162 + .../patches/mageia/fs-aufs-5.6-fix.patch | 39 - .../patches/mageia/fs-aufs-5.6-modular.patch | 312 - .../files/patches/mageia/fs-aufs-5.6.patch | 37834 --------------- .../mageia/fs-aufs5.10-symbol-exports.patch | 284 + .../patches/mageia/fs-aufs5.10-tristate.patch | 24 + .../mageia/{aufs5.patch => fs-aufs5.10.patch} | 836 +- .../perf/files/patches/mageia/fs-aufs5.patch | 37934 ---------------- kernel/tools/perf/pspec.xml | 17 +- 28 files changed, 760 insertions(+), 94820 deletions(-) delete mode 100644 kernel/tools/perf/files/patches/archlinux/change-default-console-loglevel.patch delete mode 100644 kernel/tools/perf/files/patches/archlinux/fix_CPU0_microcode_on_resume.patch delete mode 100644 kernel/tools/perf/files/patches/gentoo/1500_XATTR_USER_PREFIX.patch delete mode 100644 kernel/tools/perf/files/patches/gentoo/1510_fs-enable-link-security-restrictions-by-default.patch delete mode 100644 kernel/tools/perf/files/patches/gentoo/2700_ThinkPad-30-brightness-control-fix.patch delete mode 100644 kernel/tools/perf/files/patches/gentoo/2900_dev-root-proc-mount-fix.patch delete mode 100644 kernel/tools/perf/files/patches/gentoo/2905_2disk-resume-image-fix.patch delete mode 100644 kernel/tools/perf/files/patches/gentoo/4200_fbcondecor-3.19.patch delete mode 100644 kernel/tools/perf/files/patches/gentoo/4567_distro-Gentoo-Kconfig.patch delete mode 100644 kernel/tools/perf/files/patches/gentoo/5001_block-cgroups-kconfig-build-bits-for-BFQ-v7r7-3.19.patch delete mode 100644 kernel/tools/perf/files/patches/gentoo/5002_block-introduce-the-BFQ-v7r7-I-O-sched-for-3.19.patch delete mode 100644 kernel/tools/perf/files/patches/gentoo/5002_block-introduce-the-BFQ-v7r7-I-O-sched-for-3.19.patch1.txt delete mode 100644 kernel/tools/perf/files/patches/gentoo/5003_block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r7-for-3.19.0.patch delete mode 100644 kernel/tools/perf/files/patches/gentoo/5010_enable-additional-cpu-optimizations-for-gcc-4.9.patch create mode 100644 kernel/tools/perf/files/patches/linux/patch-5.10.15.xz create mode 100644 kernel/tools/perf/files/patches/linux/patch-5.10.19.xz delete mode 100644 kernel/tools/perf/files/patches/linux/patch-5.10.3.xz delete mode 100644 kernel/tools/perf/files/patches/linux/patch-5.9.13.xz create mode 100644 kernel/tools/perf/files/patches/mageia/3rd-rtl8821ce-kernel-5.10.patch delete mode 100644 kernel/tools/perf/files/patches/mageia/fs-aufs-5.6-fix.patch delete mode 100644 kernel/tools/perf/files/patches/mageia/fs-aufs-5.6-modular.patch delete mode 100644 kernel/tools/perf/files/patches/mageia/fs-aufs-5.6.patch create mode 100644 kernel/tools/perf/files/patches/mageia/fs-aufs5.10-symbol-exports.patch create mode 100644 kernel/tools/perf/files/patches/mageia/fs-aufs5.10-tristate.patch rename kernel/tools/perf/files/patches/mageia/{aufs5.patch => fs-aufs5.10.patch} (98%) delete mode 100644 kernel/tools/perf/files/patches/mageia/fs-aufs5.patch diff --git a/kernel/tools/perf/files/patches/archlinux/change-default-console-loglevel.patch b/kernel/tools/perf/files/patches/archlinux/change-default-console-loglevel.patch deleted file mode 100644 index 11da2a9d8b..0000000000 --- a/kernel/tools/perf/files/patches/archlinux/change-default-console-loglevel.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- linux-3.16/include/linux/printk.h.old 2014-08-04 18:48:30.686043266 +0200 -+++ linux-3.16/include/linux/printk.h 2014-08-04 18:48:47.706218528 +0200 -@@ -37,7 +37,7 @@ - #define CONSOLE_LOGLEVEL_SILENT 0 /* Mum's the word */ - #define CONSOLE_LOGLEVEL_MIN 1 /* Minimum loglevel we let people use */ - #define CONSOLE_LOGLEVEL_QUIET 4 /* Shhh ..., when booted with "quiet" */ --#define CONSOLE_LOGLEVEL_DEFAULT 7 /* anything MORE serious than KERN_DEBUG */ -+#define CONSOLE_LOGLEVEL_DEFAULT 4 /* anything MORE serious than KERN_DEBUG */ - #define CONSOLE_LOGLEVEL_DEBUG 10 /* issue debug messages */ - #define CONSOLE_LOGLEVEL_MOTORMOUTH 15 /* You can't shut this one up */ - diff --git a/kernel/tools/perf/files/patches/archlinux/fix_CPU0_microcode_on_resume.patch b/kernel/tools/perf/files/patches/archlinux/fix_CPU0_microcode_on_resume.patch deleted file mode 100644 index 56f8094fd6..0000000000 --- a/kernel/tools/perf/files/patches/archlinux/fix_CPU0_microcode_on_resume.patch +++ /dev/null @@ -1,21 +0,0 @@ -diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c -index dd9d6190b08d..181e42bd85d3 100644 ---- a/arch/x86/kernel/cpu/microcode/core.c -+++ b/arch/x86/kernel/cpu/microcode/core.c -@@ -85,6 +85,7 @@ - #include - - #include -+#include - #include - #include - #include -@@ -465,6 +466,8 @@ static void mc_bp_resume(void) - - if (uci->valid && uci->mc) - microcode_ops->apply_microcode(cpu); -+ else if (!uci->mc) -+ load_ucode_intel_ap(); - } - - static struct syscore_ops mc_syscore_ops = { diff --git a/kernel/tools/perf/files/patches/gentoo/1500_XATTR_USER_PREFIX.patch b/kernel/tools/perf/files/patches/gentoo/1500_XATTR_USER_PREFIX.patch deleted file mode 100644 index cc15cd51db..0000000000 --- a/kernel/tools/perf/files/patches/gentoo/1500_XATTR_USER_PREFIX.patch +++ /dev/null @@ -1,54 +0,0 @@ -From: Anthony G. Basile - -This patch adds support for a restricted user-controlled namespace on -tmpfs filesystem used to house PaX flags. The namespace must be of the -form user.pax.* and its value cannot exceed a size of 8 bytes. - -This is needed even on all Gentoo systems so that XATTR_PAX flags -are preserved for users who might build packages using portage on -a tmpfs system with a non-hardened kernel and then switch to a -hardened kernel with XATTR_PAX enabled. - -The namespace is added to any user with Extended Attribute support -enabled for tmpfs. Users who do not enable xattrs will not have -the XATTR_PAX flags preserved. - -diff --git a/include/uapi/linux/xattr.h b/include/uapi/linux/xattr.h -index e4629b9..6958086 100644 ---- a/include/uapi/linux/xattr.h -+++ b/include/uapi/linux/xattr.h -@@ -63,5 +63,9 @@ - #define XATTR_POSIX_ACL_DEFAULT "posix_acl_default" - #define XATTR_NAME_POSIX_ACL_DEFAULT XATTR_SYSTEM_PREFIX XATTR_POSIX_ACL_DEFAULT - -+/* User namespace */ -+#define XATTR_PAX_PREFIX XATTR_USER_PREFIX "pax." -+#define XATTR_PAX_FLAGS_SUFFIX "flags" -+#define XATTR_NAME_PAX_FLAGS XATTR_PAX_PREFIX XATTR_PAX_FLAGS_SUFFIX - - #endif /* _UAPI_LINUX_XATTR_H */ -diff --git a/mm/shmem.c b/mm/shmem.c -index 1c44af7..f23bb1b 100644 ---- a/mm/shmem.c -+++ b/mm/shmem.c -@@ -2201,6 +2201,7 @@ static const struct xattr_handler *shmem_xattr_handlers[] = { - static int shmem_xattr_validate(const char *name) - { - struct { const char *prefix; size_t len; } arr[] = { -+ { XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN}, - { XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN }, - { XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN } - }; -@@ -2256,6 +2257,12 @@ static int shmem_setxattr(struct dentry *dentry, const char *name, - if (err) - return err; - -+ if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) { -+ if (strcmp(name, XATTR_NAME_PAX_FLAGS)) -+ return -EOPNOTSUPP; -+ if (size > 8) -+ return -EINVAL; -+ } - return simple_xattr_set(&info->xattrs, name, value, size, flags); - } - diff --git a/kernel/tools/perf/files/patches/gentoo/1510_fs-enable-link-security-restrictions-by-default.patch b/kernel/tools/perf/files/patches/gentoo/1510_fs-enable-link-security-restrictions-by-default.patch deleted file mode 100644 index 639fb3c348..0000000000 --- a/kernel/tools/perf/files/patches/gentoo/1510_fs-enable-link-security-restrictions-by-default.patch +++ /dev/null @@ -1,22 +0,0 @@ -From: Ben Hutchings -Subject: fs: Enable link security restrictions by default -Date: Fri, 02 Nov 2012 05:32:06 +0000 -Bug-Debian: https://bugs.debian.org/609455 -Forwarded: not-needed - -This reverts commit 561ec64ae67ef25cac8d72bb9c4bfc955edfd415 -('VFS: don't do protected {sym,hard}links by default'). - ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -651,8 +651,8 @@ static inline void put_link(struct namei - path_put(link); - } - --int sysctl_protected_symlinks __read_mostly = 0; --int sysctl_protected_hardlinks __read_mostly = 0; -+int sysctl_protected_symlinks __read_mostly = 1; -+int sysctl_protected_hardlinks __read_mostly = 1; - - /** - * may_follow_link - Check symlink following for unsafe situations diff --git a/kernel/tools/perf/files/patches/gentoo/2700_ThinkPad-30-brightness-control-fix.patch b/kernel/tools/perf/files/patches/gentoo/2700_ThinkPad-30-brightness-control-fix.patch deleted file mode 100644 index b548c6dcf2..0000000000 --- a/kernel/tools/perf/files/patches/gentoo/2700_ThinkPad-30-brightness-control-fix.patch +++ /dev/null @@ -1,67 +0,0 @@ -diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c -index cb96296..6c242ed 100644 ---- a/drivers/acpi/blacklist.c -+++ b/drivers/acpi/blacklist.c -@@ -269,6 +276,61 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { - }, - - /* -+ * The following Lenovo models have a broken workaround in the -+ * acpi_video backlight implementation to meet the Windows 8 -+ * requirement of 101 backlight levels. Reverting to pre-Win8 -+ * behavior fixes the problem. -+ */ -+ { -+ .callback = dmi_disable_osi_win8, -+ .ident = "Lenovo ThinkPad L430", -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), -+ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L430"), -+ }, -+ }, -+ { -+ .callback = dmi_disable_osi_win8, -+ .ident = "Lenovo ThinkPad T430s", -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), -+ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T430s"), -+ }, -+ }, -+ { -+ .callback = dmi_disable_osi_win8, -+ .ident = "Lenovo ThinkPad T530", -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), -+ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T530"), -+ }, -+ }, -+ { -+ .callback = dmi_disable_osi_win8, -+ .ident = "Lenovo ThinkPad W530", -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), -+ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad W530"), -+ }, -+ }, -+ { -+ .callback = dmi_disable_osi_win8, -+ .ident = "Lenovo ThinkPad X1 Carbon", -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), -+ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X1 Carbon"), -+ }, -+ }, -+ { -+ .callback = dmi_disable_osi_win8, -+ .ident = "Lenovo ThinkPad X230", -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), -+ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X230"), -+ }, -+ }, -+ -+ /* - * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. - * Linux ignores it, except for the machines enumerated below. - */ - diff --git a/kernel/tools/perf/files/patches/gentoo/2900_dev-root-proc-mount-fix.patch b/kernel/tools/perf/files/patches/gentoo/2900_dev-root-proc-mount-fix.patch deleted file mode 100644 index 6ea86e29c0..0000000000 --- a/kernel/tools/perf/files/patches/gentoo/2900_dev-root-proc-mount-fix.patch +++ /dev/null @@ -1,30 +0,0 @@ ---- a/init/do_mounts.c 2014-08-26 08:03:30.000013100 -0400 -+++ b/init/do_mounts.c 2014-08-26 08:11:19.720014712 -0400 -@@ -484,7 +484,10 @@ void __init change_floppy(char *fmt, ... - va_start(args, fmt); - vsprintf(buf, fmt, args); - va_end(args); -- fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0); -+ if (saved_root_name[0]) -+ fd = sys_open(saved_root_name, O_RDWR | O_NDELAY, 0); -+ else -+ fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0); - if (fd >= 0) { - sys_ioctl(fd, FDEJECT, 0); - sys_close(fd); -@@ -527,8 +530,13 @@ void __init mount_root(void) - } - #endif - #ifdef CONFIG_BLOCK -- create_dev("/dev/root", ROOT_DEV); -- mount_block_root("/dev/root", root_mountflags); -+ if (saved_root_name[0]) { -+ create_dev(saved_root_name, ROOT_DEV); -+ mount_block_root(saved_root_name, root_mountflags); -+ } else { -+ create_dev("/dev/root", ROOT_DEV); -+ mount_block_root("/dev/root", root_mountflags); -+ } - #endif - } - diff --git a/kernel/tools/perf/files/patches/gentoo/2905_2disk-resume-image-fix.patch b/kernel/tools/perf/files/patches/gentoo/2905_2disk-resume-image-fix.patch deleted file mode 100644 index 7e95d29845..0000000000 --- a/kernel/tools/perf/files/patches/gentoo/2905_2disk-resume-image-fix.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff --git a/kernel/kmod.c b/kernel/kmod.c -index fb32636..d968882 100644 ---- a/kernel/kmod.c -+++ b/kernel/kmod.c -@@ -575,7 +575,8 @@ - call_usermodehelper_freeinfo(sub_info); - return -EINVAL; - } -- helper_lock(); -+ if (!(current->flags & PF_FREEZER_SKIP)) -+ helper_lock(); - if (!khelper_wq || usermodehelper_disabled) { - retval = -EBUSY; - goto out; -@@ -611,7 +612,8 @@ wait_done: - out: - call_usermodehelper_freeinfo(sub_info); - unlock: -- helper_unlock(); -+ if (!(current->flags & PF_FREEZER_SKIP)) -+ helper_unlock(); - return retval; - } - EXPORT_SYMBOL(call_usermodehelper_exec); diff --git a/kernel/tools/perf/files/patches/gentoo/4200_fbcondecor-3.19.patch b/kernel/tools/perf/files/patches/gentoo/4200_fbcondecor-3.19.patch deleted file mode 100644 index 29c379feef..0000000000 --- a/kernel/tools/perf/files/patches/gentoo/4200_fbcondecor-3.19.patch +++ /dev/null @@ -1,2119 +0,0 @@ -diff --git a/Documentation/fb/00-INDEX b/Documentation/fb/00-INDEX -index fe85e7c..2230930 100644 ---- a/Documentation/fb/00-INDEX -+++ b/Documentation/fb/00-INDEX -@@ -23,6 +23,8 @@ ep93xx-fb.txt - - info on the driver for EP93xx LCD controller. - fbcon.txt - - intro to and usage guide for the framebuffer console (fbcon). -+fbcondecor.txt -+ - info on the Framebuffer Console Decoration - framebuffer.txt - - introduction to frame buffer devices. - gxfb.txt -diff --git a/Documentation/fb/fbcondecor.txt b/Documentation/fb/fbcondecor.txt -new file mode 100644 -index 0000000..3388c61 ---- /dev/null -+++ b/Documentation/fb/fbcondecor.txt -@@ -0,0 +1,207 @@ -+What is it? -+----------- -+ -+The framebuffer decorations are a kernel feature which allows displaying a -+background picture on selected consoles. -+ -+What do I need to get it to work? -+--------------------------------- -+ -+To get fbcondecor up-and-running you will have to: -+ 1) get a copy of splashutils [1] or a similar program -+ 2) get some fbcondecor themes -+ 3) build the kernel helper program -+ 4) build your kernel with the FB_CON_DECOR option enabled. -+ -+To get fbcondecor operational right after fbcon initialization is finished, you -+will have to include a theme and the kernel helper into your initramfs image. -+Please refer to splashutils documentation for instructions on how to do that. -+ -+[1] The splashutils package can be downloaded from: -+ http://github.com/alanhaggai/fbsplash -+ -+The userspace helper -+-------------------- -+ -+The userspace fbcondecor helper (by default: /sbin/fbcondecor_helper) is called by the -+kernel whenever an important event occurs and the kernel needs some kind of -+job to be carried out. Important events include console switches and video -+mode switches (the kernel requests background images and configuration -+parameters for the current console). The fbcondecor helper must be accessible at -+all times. If it's not, fbcondecor will be switched off automatically. -+ -+It's possible to set path to the fbcondecor helper by writing it to -+/proc/sys/kernel/fbcondecor. -+ -+***************************************************************************** -+ -+The information below is mostly technical stuff. There's probably no need to -+read it unless you plan to develop a userspace helper. -+ -+The fbcondecor protocol -+----------------------- -+ -+The fbcondecor protocol defines a communication interface between the kernel and -+the userspace fbcondecor helper. -+ -+The kernel side is responsible for: -+ -+ * rendering console text, using an image as a background (instead of a -+ standard solid color fbcon uses), -+ * accepting commands from the user via ioctls on the fbcondecor device, -+ * calling the userspace helper to set things up as soon as the fb subsystem -+ is initialized. -+ -+The userspace helper is responsible for everything else, including parsing -+configuration files, decompressing the image files whenever the kernel needs -+it, and communicating with the kernel if necessary. -+ -+The fbcondecor protocol specifies how communication is done in both ways: -+kernel->userspace and userspace->helper. -+ -+Kernel -> Userspace -+------------------- -+ -+The kernel communicates with the userspace helper by calling it and specifying -+the task to be done in a series of arguments. -+ -+The arguments follow the pattern: -+ -+ -+All commands defined in fbcondecor protocol v2 have the following parameters: -+ virtual console -+ framebuffer number -+ theme -+ -+Fbcondecor protocol v1 specified an additional 'fbcondecor mode' after the -+framebuffer number. Fbcondecor protocol v1 is deprecated and should not be used. -+ -+Fbcondecor protocol v2 specifies the following commands: -+ -+getpic -+------ -+ The kernel issues this command to request image data. It's up to the -+ userspace helper to find a background image appropriate for the specified -+ theme and the current resolution. The userspace helper should respond by -+ issuing the FBIOCONDECOR_SETPIC ioctl. -+ -+init -+---- -+ The kernel issues this command after the fbcondecor device is created and -+ the fbcondecor interface is initialized. Upon receiving 'init', the userspace -+ helper should parse the kernel command line (/proc/cmdline) or otherwise -+ decide whether fbcondecor is to be activated. -+ -+ To activate fbcondecor on the first console the helper should issue the -+ FBIOCONDECOR_SETCFG, FBIOCONDECOR_SETPIC and FBIOCONDECOR_SETSTATE commands, -+ in the above-mentioned order. -+ -+ When the userspace helper is called in an early phase of the boot process -+ (right after the initialization of fbcon), no filesystems will be mounted. -+ The helper program should mount sysfs and then create the appropriate -+ framebuffer, fbcondecor and tty0 devices (if they don't already exist) to get -+ current display settings and to be able to communicate with the kernel side. -+ It should probably also mount the procfs to be able to parse the kernel -+ command line parameters. -+ -+ Note that the console sem is not held when the kernel calls fbcondecor_helper -+ with the 'init' command. The fbcondecor helper should perform all ioctls with -+ origin set to FBCON_DECOR_IO_ORIG_USER. -+ -+modechange -+---------- -+ The kernel issues this command on a mode change. The helper's response should -+ be similar to the response to the 'init' command. Note that this time the -+ console sem is held and all ioctls must be performed with origin set to -+ FBCON_DECOR_IO_ORIG_KERNEL. -+ -+ -+Userspace -> Kernel -+------------------- -+ -+Userspace programs can communicate with fbcondecor via ioctls on the -+fbcondecor device. These ioctls are to be used by both the userspace helper -+(called only by the kernel) and userspace configuration tools (run by the users). -+ -+The fbcondecor helper should set the origin field to FBCON_DECOR_IO_ORIG_KERNEL -+when doing the appropriate ioctls. All userspace configuration tools should -+use FBCON_DECOR_IO_ORIG_USER. Failure to set the appropriate value in the origin -+field when performing ioctls from the kernel helper will most likely result -+in a console deadlock. -+ -+FBCON_DECOR_IO_ORIG_KERNEL instructs fbcondecor not to try to acquire the console -+semaphore. Not surprisingly, FBCON_DECOR_IO_ORIG_USER instructs it to acquire -+the console sem. -+ -+The framebuffer console decoration provides the following ioctls (all defined in -+linux/fb.h): -+ -+FBIOCONDECOR_SETPIC -+description: loads a background picture for a virtual console -+argument: struct fbcon_decor_iowrapper*; data: struct fb_image* -+notes: -+If called for consoles other than the current foreground one, the picture data -+will be ignored. -+ -+If the current virtual console is running in a 8-bpp mode, the cmap substruct -+of fb_image has to be filled appropriately: start should be set to 16 (first -+16 colors are reserved for fbcon), len to a value <= 240 and red, green and -+blue should point to valid cmap data. The transp field is ingored. The fields -+dx, dy, bg_color, fg_color in fb_image are ignored as well. -+ -+FBIOCONDECOR_SETCFG -+description: sets the fbcondecor config for a virtual console -+argument: struct fbcon_decor_iowrapper*; data: struct vc_decor* -+notes: The structure has to be filled with valid data. -+ -+FBIOCONDECOR_GETCFG -+description: gets the fbcondecor config for a virtual console -+argument: struct fbcon_decor_iowrapper*; data: struct vc_decor* -+ -+FBIOCONDECOR_SETSTATE -+description: sets the fbcondecor state for a virtual console -+argument: struct fbcon_decor_iowrapper*; data: unsigned int* -+ values: 0 = disabled, 1 = enabled. -+ -+FBIOCONDECOR_GETSTATE -+description: gets the fbcondecor state for a virtual console -+argument: struct fbcon_decor_iowrapper*; data: unsigned int* -+ values: as in FBIOCONDECOR_SETSTATE -+ -+Info on used structures: -+ -+Definition of struct vc_decor can be found in linux/console_decor.h. It's -+heavily commented. Note that the 'theme' field should point to a string -+no longer than FBCON_DECOR_THEME_LEN. When FBIOCONDECOR_GETCFG call is -+performed, the theme field should point to a char buffer of length -+FBCON_DECOR_THEME_LEN. -+ -+Definition of struct fbcon_decor_iowrapper can be found in linux/fb.h. -+The fields in this struct have the following meaning: -+ -+vc: -+Virtual console number. -+ -+origin: -+Specifies if the ioctl is performed as a response to a kernel request. The -+fbcondecor helper should set this field to FBCON_DECOR_IO_ORIG_KERNEL, userspace -+programs should set it to FBCON_DECOR_IO_ORIG_USER. This field is necessary to -+avoid console semaphore deadlocks. -+ -+data: -+Pointer to a data structure appropriate for the performed ioctl. Type of -+the data struct is specified in the ioctls description. -+ -+***************************************************************************** -+ -+Credit -+------ -+ -+Original 'bootsplash' project & implementation by: -+ Volker Poplawski , Stefan Reinauer , -+ Steffen Winterfeldt , Michael Schroeder , -+ Ken Wimer . -+ -+Fbcondecor, fbcondecor protocol design, current implementation & docs by: -+ Michal Januszewski -+ -diff --git a/drivers/Makefile b/drivers/Makefile -index 7183b6a..d576148 100644 ---- a/drivers/Makefile -+++ b/drivers/Makefile -@@ -17,6 +17,10 @@ obj-y += pwm/ - obj-$(CONFIG_PCI) += pci/ - obj-$(CONFIG_PARISC) += parisc/ - obj-$(CONFIG_RAPIDIO) += rapidio/ -+# tty/ comes before char/ so that the VT console is the boot-time -+# default. -+obj-y += tty/ -+obj-y += char/ - obj-y += video/ - obj-y += idle/ - -@@ -42,11 +46,6 @@ obj-$(CONFIG_REGULATOR) += regulator/ - # reset controllers early, since gpu drivers might rely on them to initialize - obj-$(CONFIG_RESET_CONTROLLER) += reset/ - --# tty/ comes before char/ so that the VT console is the boot-time --# default. --obj-y += tty/ --obj-y += char/ -- - # iommu/ comes before gpu as gpu are using iommu controllers - obj-$(CONFIG_IOMMU_SUPPORT) += iommu/ - -diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig -index fe1cd01..6d2e87a 100644 ---- a/drivers/video/console/Kconfig -+++ b/drivers/video/console/Kconfig -@@ -126,6 +126,19 @@ config FRAMEBUFFER_CONSOLE_ROTATION - such that other users of the framebuffer will remain normally - oriented. - -+config FB_CON_DECOR -+ bool "Support for the Framebuffer Console Decorations" -+ depends on FRAMEBUFFER_CONSOLE=y && !FB_TILEBLITTING -+ default n -+ ---help--- -+ This option enables support for framebuffer console decorations which -+ makes it possible to display images in the background of the system -+ consoles. Note that userspace utilities are necessary in order to take -+ advantage of these features. Refer to Documentation/fb/fbcondecor.txt -+ for more information. -+ -+ If unsure, say N. -+ - config STI_CONSOLE - bool "STI text console" - depends on PARISC -diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile -index 43bfa48..cc104b6f 100644 ---- a/drivers/video/console/Makefile -+++ b/drivers/video/console/Makefile -@@ -16,4 +16,5 @@ obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon_rotate.o fbcon_cw.o fbcon_ud.o \ - fbcon_ccw.o - endif - -+obj-$(CONFIG_FB_CON_DECOR) += fbcondecor.o cfbcondecor.o - obj-$(CONFIG_FB_STI) += sticore.o -diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c -index 61b182b..984384b 100644 ---- a/drivers/video/console/bitblit.c -+++ b/drivers/video/console/bitblit.c -@@ -18,6 +18,7 @@ - #include - #include - #include "fbcon.h" -+#include "fbcondecor.h" - - /* - * Accelerated handlers. -@@ -55,6 +56,13 @@ static void bit_bmove(struct vc_data *vc, struct fb_info *info, int sy, - area.height = height * vc->vc_font.height; - area.width = width * vc->vc_font.width; - -+ if (fbcon_decor_active(info, vc)) { -+ area.sx += vc->vc_decor.tx; -+ area.sy += vc->vc_decor.ty; -+ area.dx += vc->vc_decor.tx; -+ area.dy += vc->vc_decor.ty; -+ } -+ - info->fbops->fb_copyarea(info, &area); - } - -@@ -380,11 +388,15 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode, - cursor.image.depth = 1; - cursor.rop = ROP_XOR; - -- if (info->fbops->fb_cursor) -- err = info->fbops->fb_cursor(info, &cursor); -+ if (fbcon_decor_active(info, vc)) { -+ fbcon_decor_cursor(info, &cursor); -+ } else { -+ if (info->fbops->fb_cursor) -+ err = info->fbops->fb_cursor(info, &cursor); - -- if (err) -- soft_cursor(info, &cursor); -+ if (err) -+ soft_cursor(info, &cursor); -+ } - - ops->cursor_reset = 0; - } -diff --git a/drivers/video/console/cfbcondecor.c b/drivers/video/console/cfbcondecor.c -new file mode 100644 -index 0000000..a2b4497 ---- /dev/null -+++ b/drivers/video/console/cfbcondecor.c -@@ -0,0 +1,471 @@ -+/* -+ * linux/drivers/video/cfbcon_decor.c -- Framebuffer decor render functions -+ * -+ * Copyright (C) 2004 Michal Januszewski -+ * -+ * Code based upon "Bootdecor" (C) 2001-2003 -+ * Volker Poplawski , -+ * Stefan Reinauer , -+ * Steffen Winterfeldt , -+ * Michael Schroeder , -+ * Ken Wimer . -+ * -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file COPYING in the main directory of this archive for -+ * more details. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "fbcon.h" -+#include "fbcondecor.h" -+ -+#define parse_pixel(shift,bpp,type) \ -+ do { \ -+ if (d & (0x80 >> (shift))) \ -+ dd2[(shift)] = fgx; \ -+ else \ -+ dd2[(shift)] = transparent ? *(type *)decor_src : bgx; \ -+ decor_src += (bpp); \ -+ } while (0) \ -+ -+extern int get_color(struct vc_data *vc, struct fb_info *info, -+ u16 c, int is_fg); -+ -+void fbcon_decor_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc) -+{ -+ int i, j, k; -+ int minlen = min(min(info->var.red.length, info->var.green.length), -+ info->var.blue.length); -+ u32 col; -+ -+ for (j = i = 0; i < 16; i++) { -+ k = color_table[i]; -+ -+ col = ((vc->vc_palette[j++] >> (8-minlen)) -+ << info->var.red.offset); -+ col |= ((vc->vc_palette[j++] >> (8-minlen)) -+ << info->var.green.offset); -+ col |= ((vc->vc_palette[j++] >> (8-minlen)) -+ << info->var.blue.offset); -+ ((u32 *)info->pseudo_palette)[k] = col; -+ } -+} -+ -+void fbcon_decor_renderc(struct fb_info *info, int ypos, int xpos, int height, -+ int width, u8* src, u32 fgx, u32 bgx, u8 transparent) -+{ -+ unsigned int x, y; -+ u32 dd; -+ int bytespp = ((info->var.bits_per_pixel + 7) >> 3); -+ unsigned int d = ypos * info->fix.line_length + xpos * bytespp; -+ unsigned int ds = (ypos * info->var.xres + xpos) * bytespp; -+ u16 dd2[4]; -+ -+ u8* decor_src = (u8 *)(info->bgdecor.data + ds); -+ u8* dst = (u8 *)(info->screen_base + d); -+ -+ if ((ypos + height) > info->var.yres || (xpos + width) > info->var.xres) -+ return; -+ -+ for (y = 0; y < height; y++) { -+ switch (info->var.bits_per_pixel) { -+ -+ case 32: -+ for (x = 0; x < width; x++) { -+ -+ if ((x & 7) == 0) -+ d = *src++; -+ if (d & 0x80) -+ dd = fgx; -+ else -+ dd = transparent ? -+ *(u32 *)decor_src : bgx; -+ -+ d <<= 1; -+ decor_src += 4; -+ fb_writel(dd, dst); -+ dst += 4; -+ } -+ break; -+ case 24: -+ for (x = 0; x < width; x++) { -+ -+ if ((x & 7) == 0) -+ d = *src++; -+ if (d & 0x80) -+ dd = fgx; -+ else -+ dd = transparent ? -+ (*(u32 *)decor_src & 0xffffff) : bgx; -+ -+ d <<= 1; -+ decor_src += 3; -+#ifdef __LITTLE_ENDIAN -+ fb_writew(dd & 0xffff, dst); -+ dst += 2; -+ fb_writeb((dd >> 16), dst); -+#else -+ fb_writew(dd >> 8, dst); -+ dst += 2; -+ fb_writeb(dd & 0xff, dst); -+#endif -+ dst++; -+ } -+ break; -+ case 16: -+ for (x = 0; x < width; x += 2) { -+ if ((x & 7) == 0) -+ d = *src++; -+ -+ parse_pixel(0, 2, u16); -+ parse_pixel(1, 2, u16); -+#ifdef __LITTLE_ENDIAN -+ dd = dd2[0] | (dd2[1] << 16); -+#else -+ dd = dd2[1] | (dd2[0] << 16); -+#endif -+ d <<= 2; -+ fb_writel(dd, dst); -+ dst += 4; -+ } -+ break; -+ -+ case 8: -+ for (x = 0; x < width; x += 4) { -+ if ((x & 7) == 0) -+ d = *src++; -+ -+ parse_pixel(0, 1, u8); -+ parse_pixel(1, 1, u8); -+ parse_pixel(2, 1, u8); -+ parse_pixel(3, 1, u8); -+ -+#ifdef __LITTLE_ENDIAN -+ dd = dd2[0] | (dd2[1] << 8) | (dd2[2] << 16) | (dd2[3] << 24); -+#else -+ dd = dd2[3] | (dd2[2] << 8) | (dd2[1] << 16) | (dd2[0] << 24); -+#endif -+ d <<= 4; -+ fb_writel(dd, dst); -+ dst += 4; -+ } -+ } -+ -+ dst += info->fix.line_length - width * bytespp; -+ decor_src += (info->var.xres - width) * bytespp; -+ } -+} -+ -+#define cc2cx(a) \ -+ ((info->fix.visual == FB_VISUAL_TRUECOLOR || \ -+ info->fix.visual == FB_VISUAL_DIRECTCOLOR) ? \ -+ ((u32*)info->pseudo_palette)[a] : a) -+ -+void fbcon_decor_putcs(struct vc_data *vc, struct fb_info *info, -+ const unsigned short *s, int count, int yy, int xx) -+{ -+ unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; -+ struct fbcon_ops *ops = info->fbcon_par; -+ int fg_color, bg_color, transparent; -+ u8 *src; -+ u32 bgx, fgx; -+ u16 c = scr_readw(s); -+ -+ fg_color = get_color(vc, info, c, 1); -+ bg_color = get_color(vc, info, c, 0); -+ -+ /* Don't paint the background image if console is blanked */ -+ transparent = ops->blank_state ? 0 : -+ (vc->vc_decor.bg_color == bg_color); -+ -+ xx = xx * vc->vc_font.width + vc->vc_decor.tx; -+ yy = yy * vc->vc_font.height + vc->vc_decor.ty; -+ -+ fgx = cc2cx(fg_color); -+ bgx = cc2cx(bg_color); -+ -+ while (count--) { -+ c = scr_readw(s++); -+ src = vc->vc_font.data + (c & charmask) * vc->vc_font.height * -+ ((vc->vc_font.width + 7) >> 3); -+ -+ fbcon_decor_renderc(info, yy, xx, vc->vc_font.height, -+ vc->vc_font.width, src, fgx, bgx, transparent); -+ xx += vc->vc_font.width; -+ } -+} -+ -+void fbcon_decor_cursor(struct fb_info *info, struct fb_cursor *cursor) -+{ -+ int i; -+ unsigned int dsize, s_pitch; -+ struct fbcon_ops *ops = info->fbcon_par; -+ struct vc_data* vc; -+ u8 *src; -+ -+ /* we really don't need any cursors while the console is blanked */ -+ if (info->state != FBINFO_STATE_RUNNING || ops->blank_state) -+ return; -+ -+ vc = vc_cons[ops->currcon].d; -+ -+ src = kmalloc(64 + sizeof(struct fb_image), GFP_ATOMIC); -+ if (!src) -+ return; -+ -+ s_pitch = (cursor->image.width + 7) >> 3; -+ dsize = s_pitch * cursor->image.height; -+ if (cursor->enable) { -+ switch (cursor->rop) { -+ case ROP_XOR: -+ for (i = 0; i < dsize; i++) -+ src[i] = cursor->image.data[i] ^ cursor->mask[i]; -+ break; -+ case ROP_COPY: -+ default: -+ for (i = 0; i < dsize; i++) -+ src[i] = cursor->image.data[i] & cursor->mask[i]; -+ break; -+ } -+ } else -+ memcpy(src, cursor->image.data, dsize); -+ -+ fbcon_decor_renderc(info, -+ cursor->image.dy + vc->vc_decor.ty, -+ cursor->image.dx + vc->vc_decor.tx, -+ cursor->image.height, -+ cursor->image.width, -+ (u8*)src, -+ cc2cx(cursor->image.fg_color), -+ cc2cx(cursor->image.bg_color), -+ cursor->image.bg_color == vc->vc_decor.bg_color); -+ -+ kfree(src); -+} -+ -+static void decorset(u8 *dst, int height, int width, int dstbytes, -+ u32 bgx, int bpp) -+{ -+ int i; -+ -+ if (bpp == 8) -+ bgx |= bgx << 8; -+ if (bpp == 16 || bpp == 8) -+ bgx |= bgx << 16; -+ -+ while (height-- > 0) { -+ u8 *p = dst; -+ -+ switch (bpp) { -+ -+ case 32: -+ for (i=0; i < width; i++) { -+ fb_writel(bgx, p); p += 4; -+ } -+ break; -+ case 24: -+ for (i=0; i < width; i++) { -+#ifdef __LITTLE_ENDIAN -+ fb_writew((bgx & 0xffff),(u16*)p); p += 2; -+ fb_writeb((bgx >> 16),p++); -+#else -+ fb_writew((bgx >> 8),(u16*)p); p += 2; -+ fb_writeb((bgx & 0xff),p++); -+#endif -+ } -+ case 16: -+ for (i=0; i < width/4; i++) { -+ fb_writel(bgx,p); p += 4; -+ fb_writel(bgx,p); p += 4; -+ } -+ if (width & 2) { -+ fb_writel(bgx,p); p += 4; -+ } -+ if (width & 1) -+ fb_writew(bgx,(u16*)p); -+ break; -+ case 8: -+ for (i=0; i < width/4; i++) { -+ fb_writel(bgx,p); p += 4; -+ } -+ -+ if (width & 2) { -+ fb_writew(bgx,p); p += 2; -+ } -+ if (width & 1) -+ fb_writeb(bgx,(u8*)p); -+ break; -+ -+ } -+ dst += dstbytes; -+ } -+} -+ -+void fbcon_decor_copy(u8 *dst, u8 *src, int height, int width, int linebytes, -+ int srclinebytes, int bpp) -+{ -+ int i; -+ -+ while (height-- > 0) { -+ u32 *p = (u32 *)dst; -+ u32 *q = (u32 *)src; -+ -+ switch (bpp) { -+ -+ case 32: -+ for (i=0; i < width; i++) -+ fb_writel(*q++, p++); -+ break; -+ case 24: -+ for (i=0; i < (width*3/4); i++) -+ fb_writel(*q++, p++); -+ if ((width*3) % 4) { -+ if (width & 2) { -+ fb_writeb(*(u8*)q, (u8*)p); -+ } else if (width & 1) { -+ fb_writew(*(u16*)q, (u16*)p); -+ fb_writeb(*(u8*)((u16*)q+1),(u8*)((u16*)p+2)); -+ } -+ } -+ break; -+ case 16: -+ for (i=0; i < width/4; i++) { -+ fb_writel(*q++, p++); -+ fb_writel(*q++, p++); -+ } -+ if (width & 2) -+ fb_writel(*q++, p++); -+ if (width & 1) -+ fb_writew(*(u16*)q, (u16*)p); -+ break; -+ case 8: -+ for (i=0; i < width/4; i++) -+ fb_writel(*q++, p++); -+ -+ if (width & 2) { -+ fb_writew(*(u16*)q, (u16*)p); -+ q = (u32*) ((u16*)q + 1); -+ p = (u32*) ((u16*)p + 1); -+ } -+ if (width & 1) -+ fb_writeb(*(u8*)q, (u8*)p); -+ break; -+ } -+ -+ dst += linebytes; -+ src += srclinebytes; -+ } -+} -+ -+static void decorfill(struct fb_info *info, int sy, int sx, int height, -+ int width) -+{ -+ int bytespp = ((info->var.bits_per_pixel + 7) >> 3); -+ int d = sy * info->fix.line_length + sx * bytespp; -+ int ds = (sy * info->var.xres + sx) * bytespp; -+ -+ fbcon_decor_copy((u8 *)(info->screen_base + d), (u8 *)(info->bgdecor.data + ds), -+ height, width, info->fix.line_length, info->var.xres * bytespp, -+ info->var.bits_per_pixel); -+} -+ -+void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, -+ int height, int width) -+{ -+ int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; -+ struct fbcon_ops *ops = info->fbcon_par; -+ u8 *dst; -+ int transparent, bg_color = attr_bgcol_ec(bgshift, vc, info); -+ -+ transparent = (vc->vc_decor.bg_color == bg_color); -+ sy = sy * vc->vc_font.height + vc->vc_decor.ty; -+ sx = sx * vc->vc_font.width + vc->vc_decor.tx; -+ height *= vc->vc_font.height; -+ width *= vc->vc_font.width; -+ -+ /* Don't paint the background image if console is blanked */ -+ if (transparent && !ops->blank_state) { -+ decorfill(info, sy, sx, height, width); -+ } else { -+ dst = (u8 *)(info->screen_base + sy * info->fix.line_length + -+ sx * ((info->var.bits_per_pixel + 7) >> 3)); -+ decorset(dst, height, width, info->fix.line_length, cc2cx(bg_color), -+ info->var.bits_per_pixel); -+ } -+} -+ -+void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info, -+ int bottom_only) -+{ -+ unsigned int tw = vc->vc_cols*vc->vc_font.width; -+ unsigned int th = vc->vc_rows*vc->vc_font.height; -+ -+ if (!bottom_only) { -+ /* top margin */ -+ decorfill(info, 0, 0, vc->vc_decor.ty, info->var.xres); -+ /* left margin */ -+ decorfill(info, vc->vc_decor.ty, 0, th, vc->vc_decor.tx); -+ /* right margin */ -+ decorfill(info, vc->vc_decor.ty, vc->vc_decor.tx + tw, th, -+ info->var.xres - vc->vc_decor.tx - tw); -+ } -+ decorfill(info, vc->vc_decor.ty + th, 0, -+ info->var.yres - vc->vc_decor.ty - th, info->var.xres); -+} -+ -+void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, -+ int sx, int dx, int width) -+{ -+ u16 *d = (u16 *) (vc->vc_origin + vc->vc_size_row * y + dx * 2); -+ u16 *s = d + (dx - sx); -+ u16 *start = d; -+ u16 *ls = d; -+ u16 *le = d + width; -+ u16 c; -+ int x = dx; -+ u16 attr = 1; -+ -+ do { -+ c = scr_readw(d); -+ if (attr != (c & 0xff00)) { -+ attr = c & 0xff00; -+ if (d > start) { -+ fbcon_decor_putcs(vc, info, start, d - start, y, x); -+ x += d - start; -+ start = d; -+ } -+ } -+ if (s >= ls && s < le && c == scr_readw(s)) { -+ if (d > start) { -+ fbcon_decor_putcs(vc, info, start, d - start, y, x); -+ x += d - start + 1; -+ start = d + 1; -+ } else { -+ x++; -+ start++; -+ } -+ } -+ s++; -+ d++; -+ } while (d < le); -+ if (d > start) -+ fbcon_decor_putcs(vc, info, start, d - start, y, x); -+} -+ -+void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank) -+{ -+ if (blank) { -+ decorset((u8 *)info->screen_base, info->var.yres, info->var.xres, -+ info->fix.line_length, 0, info->var.bits_per_pixel); -+ } else { -+ update_screen(vc); -+ fbcon_decor_clear_margins(vc, info, 0); -+ } -+} -+ -diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c -index f447734..da50d61 100644 ---- a/drivers/video/console/fbcon.c -+++ b/drivers/video/console/fbcon.c -@@ -79,6 +79,7 @@ - #include - - #include "fbcon.h" -+#include "../console/fbcondecor.h" - - #ifdef FBCONDEBUG - # define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args) -@@ -94,7 +95,7 @@ enum { - - static struct display fb_display[MAX_NR_CONSOLES]; - --static signed char con2fb_map[MAX_NR_CONSOLES]; -+signed char con2fb_map[MAX_NR_CONSOLES]; - static signed char con2fb_map_boot[MAX_NR_CONSOLES]; - - static int logo_lines; -@@ -286,7 +287,7 @@ static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info) - !vt_force_oops_output(vc); - } - --static int get_color(struct vc_data *vc, struct fb_info *info, -+int get_color(struct vc_data *vc, struct fb_info *info, - u16 c, int is_fg) - { - int depth = fb_get_color_depth(&info->var, &info->fix); -@@ -551,6 +552,9 @@ static int do_fbcon_takeover(int show_logo) - info_idx = -1; - } else { - fbcon_has_console_bind = 1; -+#ifdef CONFIG_FB_CON_DECOR -+ fbcon_decor_init(); -+#endif - } - - return err; -@@ -1007,6 +1011,12 @@ static const char *fbcon_startup(void) - rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); - cols /= vc->vc_font.width; - rows /= vc->vc_font.height; -+ -+ if (fbcon_decor_active(info, vc)) { -+ cols = vc->vc_decor.twidth / vc->vc_font.width; -+ rows = vc->vc_decor.theight / vc->vc_font.height; -+ } -+ - vc_resize(vc, cols, rows); - - DPRINTK("mode: %s\n", info->fix.id); -@@ -1036,7 +1046,7 @@ static void fbcon_init(struct vc_data *vc, int init) - cap = info->flags; - - if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW || -- (info->fix.type == FB_TYPE_TEXT)) -+ (info->fix.type == FB_TYPE_TEXT) || fbcon_decor_active(info, vc)) - logo = 0; - - if (var_to_display(p, &info->var, info)) -@@ -1260,6 +1270,11 @@ static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height, - fbcon_clear_margins(vc, 0); - } - -+ if (fbcon_decor_active(info, vc)) { -+ fbcon_decor_clear(vc, info, sy, sx, height, width); -+ return; -+ } -+ - /* Split blits that cross physical y_wrap boundary */ - - y_break = p->vrows - p->yscroll; -@@ -1279,10 +1294,15 @@ static void fbcon_putcs(struct vc_data *vc, const unsigned short *s, - struct display *p = &fb_display[vc->vc_num]; - struct fbcon_ops *ops = info->fbcon_par; - -- if (!fbcon_is_inactive(vc, info)) -- ops->putcs(vc, info, s, count, real_y(p, ypos), xpos, -- get_color(vc, info, scr_readw(s), 1), -- get_color(vc, info, scr_readw(s), 0)); -+ if (!fbcon_is_inactive(vc, info)) { -+ -+ if (fbcon_decor_active(info, vc)) -+ fbcon_decor_putcs(vc, info, s, count, ypos, xpos); -+ else -+ ops->putcs(vc, info, s, count, real_y(p, ypos), xpos, -+ get_color(vc, info, scr_readw(s), 1), -+ get_color(vc, info, scr_readw(s), 0)); -+ } - } - - static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos) -@@ -1298,8 +1318,13 @@ static void fbcon_clear_margins(struct vc_data *vc, int bottom_only) - struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; - struct fbcon_ops *ops = info->fbcon_par; - -- if (!fbcon_is_inactive(vc, info)) -- ops->clear_margins(vc, info, bottom_only); -+ if (!fbcon_is_inactive(vc, info)) { -+ if (fbcon_decor_active(info, vc)) { -+ fbcon_decor_clear_margins(vc, info, bottom_only); -+ } else { -+ ops->clear_margins(vc, info, bottom_only); -+ } -+ } - } - - static void fbcon_cursor(struct vc_data *vc, int mode) -@@ -1819,7 +1844,7 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, - count = vc->vc_rows; - if (softback_top) - fbcon_softback_note(vc, t, count); -- if (logo_shown >= 0) -+ if (logo_shown >= 0 || fbcon_decor_active(info, vc)) - goto redraw_up; - switch (p->scrollmode) { - case SCROLL_MOVE: -@@ -1912,6 +1937,8 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, - count = vc->vc_rows; - if (logo_shown >= 0) - goto redraw_down; -+ if (fbcon_decor_active(info, vc)) -+ goto redraw_down; - switch (p->scrollmode) { - case SCROLL_MOVE: - fbcon_redraw_blit(vc, info, p, b - 1, b - t - count, -@@ -2060,6 +2087,13 @@ static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int s - } - return; - } -+ -+ if (fbcon_decor_active(info, vc) && sy == dy && height == 1) { -+ /* must use slower redraw bmove to keep background pic intact */ -+ fbcon_decor_bmove_redraw(vc, info, sy, sx, dx, width); -+ return; -+ } -+ - ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx, - height, width); - } -@@ -2130,8 +2164,8 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width, - var.yres = virt_h * virt_fh; - x_diff = info->var.xres - var.xres; - y_diff = info->var.yres - var.yres; -- if (x_diff < 0 || x_diff > virt_fw || -- y_diff < 0 || y_diff > virt_fh) { -+ if ((x_diff < 0 || x_diff > virt_fw || -+ y_diff < 0 || y_diff > virt_fh) && !vc->vc_decor.state) { - const struct fb_videomode *mode; - - DPRINTK("attempting resize %ix%i\n", var.xres, var.yres); -@@ -2167,6 +2201,21 @@ static int fbcon_switch(struct vc_data *vc) - - info = registered_fb[con2fb_map[vc->vc_num]]; - ops = info->fbcon_par; -+ prev_console = ops->currcon; -+ if (prev_console != -1) -+ old_info = registered_fb[con2fb_map[prev_console]]; -+ -+#ifdef CONFIG_FB_CON_DECOR -+ if (!fbcon_decor_active_vc(vc) && info->fix.visual == FB_VISUAL_DIRECTCOLOR) { -+ struct vc_data *vc_curr = vc_cons[prev_console].d; -+ if (vc_curr && fbcon_decor_active_vc(vc_curr)) { -+ /* Clear the screen to avoid displaying funky colors during -+ * palette updates. */ -+ memset((u8*)info->screen_base + info->fix.line_length * info->var.yoffset, -+ 0, info->var.yres * info->fix.line_length); -+ } -+ } -+#endif - - if (softback_top) { - if (softback_lines) -@@ -2185,9 +2234,6 @@ static int fbcon_switch(struct vc_data *vc) - logo_shown = FBCON_LOGO_CANSHOW; - } - -- prev_console = ops->currcon; -- if (prev_console != -1) -- old_info = registered_fb[con2fb_map[prev_console]]; - /* - * FIXME: If we have multiple fbdev's loaded, we need to - * update all info->currcon. Perhaps, we can place this -@@ -2231,6 +2277,18 @@ static int fbcon_switch(struct vc_data *vc) - fbcon_del_cursor_timer(old_info); - } - -+ if (fbcon_decor_active_vc(vc)) { -+ struct vc_data *vc_curr = vc_cons[prev_console].d; -+ -+ if (!vc_curr->vc_decor.theme || -+ strcmp(vc->vc_decor.theme, vc_curr->vc_decor.theme) || -+ (fbcon_decor_active_nores(info, vc_curr) && -+ !fbcon_decor_active(info, vc_curr))) { -+ fbcon_decor_disable(vc, 0); -+ fbcon_decor_call_helper("modechange", vc->vc_num); -+ } -+ } -+ - if (fbcon_is_inactive(vc, info) || - ops->blank_state != FB_BLANK_UNBLANK) - fbcon_del_cursor_timer(info); -@@ -2339,15 +2397,20 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) - } - } - -- if (!fbcon_is_inactive(vc, info)) { -+ if (!fbcon_is_inactive(vc, info)) { - if (ops->blank_state != blank) { - ops->blank_state = blank; - fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW); - ops->cursor_flash = (!blank); - -- if (!(info->flags & FBINFO_MISC_USEREVENT)) -- if (fb_blank(info, blank)) -- fbcon_generic_blank(vc, info, blank); -+ if (!(info->flags & FBINFO_MISC_USEREVENT)) { -+ if (fb_blank(info, blank)) { -+ if (fbcon_decor_active(info, vc)) -+ fbcon_decor_blank(vc, info, blank); -+ else -+ fbcon_generic_blank(vc, info, blank); -+ } -+ } - } - - if (!blank) -@@ -2522,13 +2585,22 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, - } - - if (resize) { -+ /* reset wrap/pan */ - int cols, rows; - - cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); - rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); -+ -+ if (fbcon_decor_active(info, vc)) { -+ info->var.xoffset = info->var.yoffset = p->yscroll = 0; -+ cols = vc->vc_decor.twidth; -+ rows = vc->vc_decor.theight; -+ } - cols /= w; - rows /= h; -+ - vc_resize(vc, cols, rows); -+ - if (CON_IS_VISIBLE(vc) && softback_buf) - fbcon_update_softback(vc); - } else if (CON_IS_VISIBLE(vc) -@@ -2657,7 +2729,11 @@ static int fbcon_set_palette(struct vc_data *vc, unsigned char *table) - int i, j, k, depth; - u8 val; - -- if (fbcon_is_inactive(vc, info)) -+ if (fbcon_is_inactive(vc, info) -+#ifdef CONFIG_FB_CON_DECOR -+ || vc->vc_num != fg_console -+#endif -+ ) - return -EINVAL; - - if (!CON_IS_VISIBLE(vc)) -@@ -2683,14 +2759,56 @@ static int fbcon_set_palette(struct vc_data *vc, unsigned char *table) - } else - fb_copy_cmap(fb_default_cmap(1 << depth), &palette_cmap); - -- return fb_set_cmap(&palette_cmap, info); -+ if (fbcon_decor_active(info, vc_cons[fg_console].d) && -+ info->fix.visual == FB_VISUAL_DIRECTCOLOR) { -+ -+ u16 *red, *green, *blue; -+ int minlen = min(min(info->var.red.length, info->var.green.length), -+ info->var.blue.length); -+ int h; -+ -+ struct fb_cmap cmap = { -+ .start = 0, -+ .len = (1 << minlen), -+ .red = NULL, -+ .green = NULL, -+ .blue = NULL, -+ .transp = NULL -+ }; -+ -+ red = kmalloc(256 * sizeof(u16) * 3, GFP_KERNEL); -+ -+ if (!red) -+ goto out; -+ -+ green = red + 256; -+ blue = green + 256; -+ cmap.red = red; -+ cmap.green = green; -+ cmap.blue = blue; -+ -+ for (i = 0; i < cmap.len; i++) { -+ red[i] = green[i] = blue[i] = (0xffff * i)/(cmap.len-1); -+ } -+ -+ h = fb_set_cmap(&cmap, info); -+ fbcon_decor_fix_pseudo_pal(info, vc_cons[fg_console].d); -+ kfree(red); -+ -+ return h; -+ -+ } else if (fbcon_decor_active(info, vc_cons[fg_console].d) && -+ info->var.bits_per_pixel == 8 && info->bgdecor.cmap.red != NULL) -+ fb_set_cmap(&info->bgdecor.cmap, info); -+ -+out: return fb_set_cmap(&palette_cmap, info); - } - - static u16 *fbcon_screen_pos(struct vc_data *vc, int offset) - { - unsigned long p; - int line; -- -+ - if (vc->vc_num != fg_console || !softback_lines) - return (u16 *) (vc->vc_origin + offset); - line = offset / vc->vc_size_row; -@@ -2909,7 +3027,14 @@ static void fbcon_modechanged(struct fb_info *info) - rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); - cols /= vc->vc_font.width; - rows /= vc->vc_font.height; -- vc_resize(vc, cols, rows); -+ -+ if (!fbcon_decor_active_nores(info, vc)) { -+ vc_resize(vc, cols, rows); -+ } else { -+ fbcon_decor_disable(vc, 0); -+ fbcon_decor_call_helper("modechange", vc->vc_num); -+ } -+ - updatescrollmode(p, info, vc); - scrollback_max = 0; - scrollback_current = 0; -@@ -2954,7 +3079,9 @@ static void fbcon_set_all_vcs(struct fb_info *info) - rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); - cols /= vc->vc_font.width; - rows /= vc->vc_font.height; -- vc_resize(vc, cols, rows); -+ if (!fbcon_decor_active_nores(info, vc)) { -+ vc_resize(vc, cols, rows); -+ } - } - - if (fg != -1) -@@ -3596,6 +3723,7 @@ static void fbcon_exit(void) - } - } - -+ fbcon_decor_exit(); - fbcon_has_exited = 1; - } - -diff --git a/drivers/video/console/fbcondecor.c b/drivers/video/console/fbcondecor.c -new file mode 100644 -index 0000000..babc8c5 ---- /dev/null -+++ b/drivers/video/console/fbcondecor.c -@@ -0,0 +1,555 @@ -+/* -+ * linux/drivers/video/console/fbcondecor.c -- Framebuffer console decorations -+ * -+ * Copyright (C) 2004-2009 Michal Januszewski -+ * -+ * Code based upon "Bootsplash" (C) 2001-2003 -+ * Volker Poplawski , -+ * Stefan Reinauer , -+ * Steffen Winterfeldt , -+ * Michael Schroeder , -+ * Ken Wimer . -+ * -+ * Compat ioctl support by Thorsten Klein . -+ * -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file COPYING in the main directory of this archive for -+ * more details. -+ * -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "fbcon.h" -+#include "fbcondecor.h" -+ -+extern signed char con2fb_map[]; -+static int fbcon_decor_enable(struct vc_data *vc); -+char fbcon_decor_path[KMOD_PATH_LEN] = "/sbin/fbcondecor_helper"; -+static int initialized = 0; -+ -+int fbcon_decor_call_helper(char* cmd, unsigned short vc) -+{ -+ char *envp[] = { -+ "HOME=/", -+ "PATH=/sbin:/bin", -+ NULL -+ }; -+ -+ char tfb[5]; -+ char tcons[5]; -+ unsigned char fb = (int) con2fb_map[vc]; -+ -+ char *argv[] = { -+ fbcon_decor_path, -+ "2", -+ cmd, -+ tcons, -+ tfb, -+ vc_cons[vc].d->vc_decor.theme, -+ NULL -+ }; -+ -+ snprintf(tfb,5,"%d",fb); -+ snprintf(tcons,5,"%d",vc); -+ -+ return call_usermodehelper(fbcon_decor_path, argv, envp, UMH_WAIT_EXEC); -+} -+ -+/* Disables fbcondecor on a virtual console; called with console sem held. */ -+int fbcon_decor_disable(struct vc_data *vc, unsigned char redraw) -+{ -+ struct fb_info* info; -+ -+ if (!vc->vc_decor.state) -+ return -EINVAL; -+ -+ info = registered_fb[(int) con2fb_map[vc->vc_num]]; -+ -+ if (info == NULL) -+ return -EINVAL; -+ -+ vc->vc_decor.state = 0; -+ vc_resize(vc, info->var.xres / vc->vc_font.width, -+ info->var.yres / vc->vc_font.height); -+ -+ if (fg_console == vc->vc_num && redraw) { -+ redraw_screen(vc, 0); -+ update_region(vc, vc->vc_origin + -+ vc->vc_size_row * vc->vc_top, -+ vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2); -+ } -+ -+ printk(KERN_INFO "fbcondecor: switched decor state to 'off' on console %d\n", -+ vc->vc_num); -+ -+ return 0; -+} -+ -+/* Enables fbcondecor on a virtual console; called with console sem held. */ -+static int fbcon_decor_enable(struct vc_data *vc) -+{ -+ struct fb_info* info; -+ -+ info = registered_fb[(int) con2fb_map[vc->vc_num]]; -+ -+ if (vc->vc_decor.twidth == 0 || vc->vc_decor.theight == 0 || -+ info == NULL || vc->vc_decor.state || (!info->bgdecor.data && -+ vc->vc_num == fg_console)) -+ return -EINVAL; -+ -+ vc->vc_decor.state = 1; -+ vc_resize(vc, vc->vc_decor.twidth / vc->vc_font.width, -+ vc->vc_decor.theight / vc->vc_font.height); -+ -+ if (fg_console == vc->vc_num) { -+ redraw_screen(vc, 0); -+ update_region(vc, vc->vc_origin + -+ vc->vc_size_row * vc->vc_top, -+ vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2); -+ fbcon_decor_clear_margins(vc, info, 0); -+ } -+ -+ printk(KERN_INFO "fbcondecor: switched decor state to 'on' on console %d\n", -+ vc->vc_num); -+ -+ return 0; -+} -+ -+static inline int fbcon_decor_ioctl_dosetstate(struct vc_data *vc, unsigned int state, unsigned char origin) -+{ -+ int ret; -+ -+// if (origin == FBCON_DECOR_IO_ORIG_USER) -+ console_lock(); -+ if (!state) -+ ret = fbcon_decor_disable(vc, 1); -+ else -+ ret = fbcon_decor_enable(vc); -+// if (origin == FBCON_DECOR_IO_ORIG_USER) -+ console_unlock(); -+ -+ return ret; -+} -+ -+static inline void fbcon_decor_ioctl_dogetstate(struct vc_data *vc, unsigned int *state) -+{ -+ *state = vc->vc_decor.state; -+} -+ -+static int fbcon_decor_ioctl_dosetcfg(struct vc_data *vc, struct vc_decor *cfg, unsigned char origin) -+{ -+ struct fb_info *info; -+ int len; -+ char *tmp; -+ -+ info = registered_fb[(int) con2fb_map[vc->vc_num]]; -+ -+ if (info == NULL || !cfg->twidth || !cfg->theight || -+ cfg->tx + cfg->twidth > info->var.xres || -+ cfg->ty + cfg->theight > info->var.yres) -+ return -EINVAL; -+ -+ len = strlen_user(cfg->theme); -+ if (!len || len > FBCON_DECOR_THEME_LEN) -+ return -EINVAL; -+ tmp = kmalloc(len, GFP_KERNEL); -+ if (!tmp) -+ return -ENOMEM; -+ if (copy_from_user(tmp, (void __user *)cfg->theme, len)) -+ return -EFAULT; -+ cfg->theme = tmp; -+ cfg->state = 0; -+ -+ /* If this ioctl is a response to a request from kernel, the console sem -+ * is already held; we also don't need to disable decor because either the -+ * new config and background picture will be successfully loaded, and the -+ * decor will stay on, or in case of a failure it'll be turned off in fbcon. */ -+// if (origin == FBCON_DECOR_IO_ORIG_USER) { -+ console_lock(); -+ if (vc->vc_decor.state) -+ fbcon_decor_disable(vc, 1); -+// } -+ -+ if (vc->vc_decor.theme) -+ kfree(vc->vc_decor.theme); -+ -+ vc->vc_decor = *cfg; -+ -+// if (origin == FBCON_DECOR_IO_ORIG_USER) -+ console_unlock(); -+ -+ printk(KERN_INFO "fbcondecor: console %d using theme '%s'\n", -+ vc->vc_num, vc->vc_decor.theme); -+ return 0; -+} -+ -+static int fbcon_decor_ioctl_dogetcfg(struct vc_data *vc, struct vc_decor *decor) -+{ -+ char __user *tmp; -+ -+ tmp = decor->theme; -+ *decor = vc->vc_decor; -+ decor->theme = tmp; -+ -+ if (vc->vc_decor.theme) { -+ if (copy_to_user(tmp, vc->vc_decor.theme, strlen(vc->vc_decor.theme) + 1)) -+ return -EFAULT; -+ } else -+ if (put_user(0, tmp)) -+ return -EFAULT; -+ -+ return 0; -+} -+ -+static int fbcon_decor_ioctl_dosetpic(struct vc_data *vc, struct fb_image *img, unsigned char origin) -+{ -+ struct fb_info *info; -+ int len; -+ u8 *tmp; -+ -+ if (vc->vc_num != fg_console) -+ return -EINVAL; -+ -+ info = registered_fb[(int) con2fb_map[vc->vc_num]]; -+ -+ if (info == NULL) -+ return -EINVAL; -+ -+ if (img->width != info->var.xres || img->height != info->var.yres) { -+ printk(KERN_ERR "fbcondecor: picture dimensions mismatch\n"); -+ printk(KERN_ERR "%dx%d vs %dx%d\n", img->width, img->height, info->var.xres, info->var.yres); -+ return -EINVAL; -+ } -+ -+ if (img->depth != info->var.bits_per_pixel) { -+ printk(KERN_ERR "fbcondecor: picture depth mismatch\n"); -+ return -EINVAL; -+ } -+ -+ if (img->depth == 8) { -+ if (!img->cmap.len || !img->cmap.red || !img->cmap.green || -+ !img->cmap.blue) -+ return -EINVAL; -+ -+ tmp = vmalloc(img->cmap.len * 3 * 2); -+ if (!tmp) -+ return -ENOMEM; -+ -+ if (copy_from_user(tmp, -+ (void __user*)img->cmap.red, (img->cmap.len << 1)) || -+ copy_from_user(tmp + (img->cmap.len << 1), -+ (void __user*)img->cmap.green, (img->cmap.len << 1)) || -+ copy_from_user(tmp + (img->cmap.len << 2), -+ (void __user*)img->cmap.blue, (img->cmap.len << 1))) { -+ vfree(tmp); -+ return -EFAULT; -+ } -+ -+ img->cmap.transp = NULL; -+ img->cmap.red = (u16*)tmp; -+ img->cmap.green = img->cmap.red + img->cmap.len; -+ img->cmap.blue = img->cmap.green + img->cmap.len; -+ } else { -+ img->cmap.red = NULL; -+ } -+ -+ len = ((img->depth + 7) >> 3) * img->width * img->height; -+ -+ /* -+ * Allocate an additional byte so that we never go outside of the -+ * buffer boundaries in the rendering functions in a 24 bpp mode. -+ */ -+ tmp = vmalloc(len + 1); -+ -+ if (!tmp) -+ goto out; -+ -+ if (copy_from_user(tmp, (void __user*)img->data, len)) -+ goto out; -+ -+ img->data = tmp; -+ -+ /* If this ioctl is a response to a request from kernel, the console sem -+ * is already held. */ -+// if (origin == FBCON_DECOR_IO_ORIG_USER) -+ console_lock(); -+ -+ if (info->bgdecor.data) -+ vfree((u8*)info->bgdecor.data); -+ if (info->bgdecor.cmap.red) -+ vfree(info->bgdecor.cmap.red); -+ -+ info->bgdecor = *img; -+ -+ if (fbcon_decor_active_vc(vc) && fg_console == vc->vc_num) { -+ redraw_screen(vc, 0); -+ update_region(vc, vc->vc_origin + -+ vc->vc_size_row * vc->vc_top, -+ vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2); -+ fbcon_decor_clear_margins(vc, info, 0); -+ } -+ -+// if (origin == FBCON_DECOR_IO_ORIG_USER) -+ console_unlock(); -+ -+ return 0; -+ -+out: if (img->cmap.red) -+ vfree(img->cmap.red); -+ -+ if (tmp) -+ vfree(tmp); -+ return -ENOMEM; -+} -+ -+static long fbcon_decor_ioctl(struct file *filp, u_int cmd, u_long arg) -+{ -+ struct fbcon_decor_iowrapper __user *wrapper = (void __user*) arg; -+ struct vc_data *vc = NULL; -+ unsigned short vc_num = 0; -+ unsigned char origin = 0; -+ void __user *data = NULL; -+ -+ if (!access_ok(VERIFY_READ, wrapper, -+ sizeof(struct fbcon_decor_iowrapper))) -+ return -EFAULT; -+ -+ __get_user(vc_num, &wrapper->vc); -+ __get_user(origin, &wrapper->origin); -+ __get_user(data, &wrapper->data); -+ -+ if (!vc_cons_allocated(vc_num)) -+ return -EINVAL; -+ -+ vc = vc_cons[vc_num].d; -+ -+ switch (cmd) { -+ case FBIOCONDECOR_SETPIC: -+ { -+ struct fb_image img; -+ if (copy_from_user(&img, (struct fb_image __user *)data, sizeof(struct fb_image))) -+ return -EFAULT; -+ -+ return fbcon_decor_ioctl_dosetpic(vc, &img, origin); -+ } -+ case FBIOCONDECOR_SETCFG: -+ { -+ struct vc_decor cfg; -+ if (copy_from_user(&cfg, (struct vc_decor __user *)data, sizeof(struct vc_decor))) -+ return -EFAULT; -+ -+ return fbcon_decor_ioctl_dosetcfg(vc, &cfg, origin); -+ } -+ case FBIOCONDECOR_GETCFG: -+ { -+ int rval; -+ struct vc_decor cfg; -+ -+ if (copy_from_user(&cfg, (struct vc_decor __user *)data, sizeof(struct vc_decor))) -+ return -EFAULT; -+ -+ rval = fbcon_decor_ioctl_dogetcfg(vc, &cfg); -+ -+ if (copy_to_user(data, &cfg, sizeof(struct vc_decor))) -+ return -EFAULT; -+ return rval; -+ } -+ case FBIOCONDECOR_SETSTATE: -+ { -+ unsigned int state = 0; -+ if (get_user(state, (unsigned int __user *)data)) -+ return -EFAULT; -+ return fbcon_decor_ioctl_dosetstate(vc, state, origin); -+ } -+ case FBIOCONDECOR_GETSTATE: -+ { -+ unsigned int state = 0; -+ fbcon_decor_ioctl_dogetstate(vc, &state); -+ return put_user(state, (unsigned int __user *)data); -+ } -+ -+ default: -+ return -ENOIOCTLCMD; -+ } -+} -+ -+#ifdef CONFIG_COMPAT -+ -+static long fbcon_decor_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { -+ -+ struct fbcon_decor_iowrapper32 __user *wrapper = (void __user *)arg; -+ struct vc_data *vc = NULL; -+ unsigned short vc_num = 0; -+ unsigned char origin = 0; -+ compat_uptr_t data_compat = 0; -+ void __user *data = NULL; -+ -+ if (!access_ok(VERIFY_READ, wrapper, -+ sizeof(struct fbcon_decor_iowrapper32))) -+ return -EFAULT; -+ -+ __get_user(vc_num, &wrapper->vc); -+ __get_user(origin, &wrapper->origin); -+ __get_user(data_compat, &wrapper->data); -+ data = compat_ptr(data_compat); -+ -+ if (!vc_cons_allocated(vc_num)) -+ return -EINVAL; -+ -+ vc = vc_cons[vc_num].d; -+ -+ switch (cmd) { -+ case FBIOCONDECOR_SETPIC32: -+ { -+ struct fb_image32 img_compat; -+ struct fb_image img; -+ -+ if (copy_from_user(&img_compat, (struct fb_image32 __user *)data, sizeof(struct fb_image32))) -+ return -EFAULT; -+ -+ fb_image_from_compat(img, img_compat); -+ -+ return fbcon_decor_ioctl_dosetpic(vc, &img, origin); -+ } -+ -+ case FBIOCONDECOR_SETCFG32: -+ { -+ struct vc_decor32 cfg_compat; -+ struct vc_decor cfg; -+ -+ if (copy_from_user(&cfg_compat, (struct vc_decor32 __user *)data, sizeof(struct vc_decor32))) -+ return -EFAULT; -+ -+ vc_decor_from_compat(cfg, cfg_compat); -+ -+ return fbcon_decor_ioctl_dosetcfg(vc, &cfg, origin); -+ } -+ -+ case FBIOCONDECOR_GETCFG32: -+ { -+ int rval; -+ struct vc_decor32 cfg_compat; -+ struct vc_decor cfg; -+ -+ if (copy_from_user(&cfg_compat, (struct vc_decor32 __user *)data, sizeof(struct vc_decor32))) -+ return -EFAULT; -+ cfg.theme = compat_ptr(cfg_compat.theme); -+ -+ rval = fbcon_decor_ioctl_dogetcfg(vc, &cfg); -+ -+ vc_decor_to_compat(cfg_compat, cfg); -+ -+ if (copy_to_user((struct vc_decor32 __user *)data, &cfg_compat, sizeof(struct vc_decor32))) -+ return -EFAULT; -+ return rval; -+ } -+ -+ case FBIOCONDECOR_SETSTATE32: -+ { -+ compat_uint_t state_compat = 0; -+ unsigned int state = 0; -+ -+ if (get_user(state_compat, (compat_uint_t __user *)data)) -+ return -EFAULT; -+ -+ state = (unsigned int)state_compat; -+ -+ return fbcon_decor_ioctl_dosetstate(vc, state, origin); -+ } -+ -+ case FBIOCONDECOR_GETSTATE32: -+ { -+ compat_uint_t state_compat = 0; -+ unsigned int state = 0; -+ -+ fbcon_decor_ioctl_dogetstate(vc, &state); -+ state_compat = (compat_uint_t)state; -+ -+ return put_user(state_compat, (compat_uint_t __user *)data); -+ } -+ -+ default: -+ return -ENOIOCTLCMD; -+ } -+} -+#else -+ #define fbcon_decor_compat_ioctl NULL -+#endif -+ -+static struct file_operations fbcon_decor_ops = { -+ .owner = THIS_MODULE, -+ .unlocked_ioctl = fbcon_decor_ioctl, -+ .compat_ioctl = fbcon_decor_compat_ioctl -+}; -+ -+static struct miscdevice fbcon_decor_dev = { -+ .minor = MISC_DYNAMIC_MINOR, -+ .name = "fbcondecor", -+ .fops = &fbcon_decor_ops -+}; -+ -+void fbcon_decor_reset(void) -+{ -+ int i; -+ -+ for (i = 0; i < num_registered_fb; i++) { -+ registered_fb[i]->bgdecor.data = NULL; -+ registered_fb[i]->bgdecor.cmap.red = NULL; -+ } -+ -+ for (i = 0; i < MAX_NR_CONSOLES && vc_cons[i].d; i++) { -+ vc_cons[i].d->vc_decor.state = vc_cons[i].d->vc_decor.twidth = -+ vc_cons[i].d->vc_decor.theight = 0; -+ vc_cons[i].d->vc_decor.theme = NULL; -+ } -+ -+ return; -+} -+ -+int fbcon_decor_init(void) -+{ -+ int i; -+ -+ fbcon_decor_reset(); -+ -+ if (initialized) -+ return 0; -+ -+ i = misc_register(&fbcon_decor_dev); -+ if (i) { -+ printk(KERN_ERR "fbcondecor: failed to register device\n"); -+ return i; -+ } -+ -+ fbcon_decor_call_helper("init", 0); -+ initialized = 1; -+ return 0; -+} -+ -+int fbcon_decor_exit(void) -+{ -+ fbcon_decor_reset(); -+ return 0; -+} -+ -+EXPORT_SYMBOL(fbcon_decor_path); -diff --git a/drivers/video/console/fbcondecor.h b/drivers/video/console/fbcondecor.h -new file mode 100644 -index 0000000..3b3724b ---- /dev/null -+++ b/drivers/video/console/fbcondecor.h -@@ -0,0 +1,78 @@ -+/* -+ * linux/drivers/video/console/fbcondecor.h -- Framebuffer Console Decoration headers -+ * -+ * Copyright (C) 2004 Michal Januszewski -+ * -+ */ -+ -+#ifndef __FBCON_DECOR_H -+#define __FBCON_DECOR_H -+ -+#ifndef _LINUX_FB_H -+#include -+#endif -+ -+/* This is needed for vc_cons in fbcmap.c */ -+#include -+ -+struct fb_cursor; -+struct fb_info; -+struct vc_data; -+ -+#ifdef CONFIG_FB_CON_DECOR -+/* fbcondecor.c */ -+int fbcon_decor_init(void); -+int fbcon_decor_exit(void); -+int fbcon_decor_call_helper(char* cmd, unsigned short cons); -+int fbcon_decor_disable(struct vc_data *vc, unsigned char redraw); -+ -+/* cfbcondecor.c */ -+void fbcon_decor_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx); -+void fbcon_decor_cursor(struct fb_info *info, struct fb_cursor *cursor); -+void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width); -+void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only); -+void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank); -+void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width); -+void fbcon_decor_copy(u8 *dst, u8 *src, int height, int width, int linebytes, int srclinesbytes, int bpp); -+void fbcon_decor_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc); -+ -+/* vt.c */ -+void acquire_console_sem(void); -+void release_console_sem(void); -+void do_unblank_screen(int entering_gfx); -+ -+/* struct vc_data *y */ -+#define fbcon_decor_active_vc(y) (y->vc_decor.state && y->vc_decor.theme) -+ -+/* struct fb_info *x, struct vc_data *y */ -+#define fbcon_decor_active_nores(x,y) (x->bgdecor.data && fbcon_decor_active_vc(y)) -+ -+/* struct fb_info *x, struct vc_data *y */ -+#define fbcon_decor_active(x,y) (fbcon_decor_active_nores(x,y) && \ -+ x->bgdecor.width == x->var.xres && \ -+ x->bgdecor.height == x->var.yres && \ -+ x->bgdecor.depth == x->var.bits_per_pixel) -+ -+ -+#else /* CONFIG_FB_CON_DECOR */ -+ -+static inline void fbcon_decor_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx) {} -+static inline void fbcon_decor_putc(struct vc_data *vc, struct fb_info *info, int c, int ypos, int xpos) {} -+static inline void fbcon_decor_cursor(struct fb_info *info, struct fb_cursor *cursor) {} -+static inline void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width) {} -+static inline void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only) {} -+static inline void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank) {} -+static inline void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width) {} -+static inline void fbcon_decor_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc) {} -+static inline int fbcon_decor_call_helper(char* cmd, unsigned short cons) { return 0; } -+static inline int fbcon_decor_init(void) { return 0; } -+static inline int fbcon_decor_exit(void) { return 0; } -+static inline int fbcon_decor_disable(struct vc_data *vc, unsigned char redraw) { return 0; } -+ -+#define fbcon_decor_active_vc(y) (0) -+#define fbcon_decor_active_nores(x,y) (0) -+#define fbcon_decor_active(x,y) (0) -+ -+#endif /* CONFIG_FB_CON_DECOR */ -+ -+#endif /* __FBCON_DECOR_H */ -diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig -index e1f4727..2952e33 100644 ---- a/drivers/video/fbdev/Kconfig -+++ b/drivers/video/fbdev/Kconfig -@@ -1204,7 +1204,6 @@ config FB_MATROX - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT -- select FB_TILEBLITTING - select FB_MACMODES if PPC_PMAC - ---help--- - Say Y here if you have a Matrox Millennium, Matrox Millennium II, -diff --git a/drivers/video/fbdev/core/fbcmap.c b/drivers/video/fbdev/core/fbcmap.c -index f89245b..05e036c 100644 ---- a/drivers/video/fbdev/core/fbcmap.c -+++ b/drivers/video/fbdev/core/fbcmap.c -@@ -17,6 +17,8 @@ - #include - #include - -+#include "../../console/fbcondecor.h" -+ - static u16 red2[] __read_mostly = { - 0x0000, 0xaaaa - }; -@@ -249,14 +251,17 @@ int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info) - if (transp) - htransp = *transp++; - if (info->fbops->fb_setcolreg(start++, -- hred, hgreen, hblue, -+ hred, hgreen, hblue, - htransp, info)) - break; - } - } -- if (rc == 0) -+ if (rc == 0) { - fb_copy_cmap(cmap, &info->cmap); -- -+ if (fbcon_decor_active(info, vc_cons[fg_console].d) && -+ info->fix.visual == FB_VISUAL_DIRECTCOLOR) -+ fbcon_decor_fix_pseudo_pal(info, vc_cons[fg_console].d); -+ } - return rc; - } - -diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c -index b6d5008..d6703f2 100644 ---- a/drivers/video/fbdev/core/fbmem.c -+++ b/drivers/video/fbdev/core/fbmem.c -@@ -1250,15 +1250,6 @@ struct fb_fix_screeninfo32 { - u16 reserved[3]; - }; - --struct fb_cmap32 { -- u32 start; -- u32 len; -- compat_caddr_t red; -- compat_caddr_t green; -- compat_caddr_t blue; -- compat_caddr_t transp; --}; -- - static int fb_getput_cmap(struct fb_info *info, unsigned int cmd, - unsigned long arg) - { -diff --git a/include/linux/console_decor.h b/include/linux/console_decor.h -new file mode 100644 -index 0000000..04b8d80 ---- /dev/null -+++ b/include/linux/console_decor.h -@@ -0,0 +1,46 @@ -+#ifndef _LINUX_CONSOLE_DECOR_H_ -+#define _LINUX_CONSOLE_DECOR_H_ 1 -+ -+/* A structure used by the framebuffer console decorations (drivers/video/console/fbcondecor.c) */ -+struct vc_decor { -+ __u8 bg_color; /* The color that is to be treated as transparent */ -+ __u8 state; /* Current decor state: 0 = off, 1 = on */ -+ __u16 tx, ty; /* Top left corner coordinates of the text field */ -+ __u16 twidth, theight; /* Width and height of the text field */ -+ char* theme; -+}; -+ -+#ifdef __KERNEL__ -+#ifdef CONFIG_COMPAT -+#include -+ -+struct vc_decor32 { -+ __u8 bg_color; /* The color that is to be treated as transparent */ -+ __u8 state; /* Current decor state: 0 = off, 1 = on */ -+ __u16 tx, ty; /* Top left corner coordinates of the text field */ -+ __u16 twidth, theight; /* Width and height of the text field */ -+ compat_uptr_t theme; -+}; -+ -+#define vc_decor_from_compat(to, from) \ -+ (to).bg_color = (from).bg_color; \ -+ (to).state = (from).state; \ -+ (to).tx = (from).tx; \ -+ (to).ty = (from).ty; \ -+ (to).twidth = (from).twidth; \ -+ (to).theight = (from).theight; \ -+ (to).theme = compat_ptr((from).theme) -+ -+#define vc_decor_to_compat(to, from) \ -+ (to).bg_color = (from).bg_color; \ -+ (to).state = (from).state; \ -+ (to).tx = (from).tx; \ -+ (to).ty = (from).ty; \ -+ (to).twidth = (from).twidth; \ -+ (to).theight = (from).theight; \ -+ (to).theme = ptr_to_compat((from).theme) -+ -+#endif /* CONFIG_COMPAT */ -+#endif /* __KERNEL__ */ -+ -+#endif -diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h -index 7f0c329..98f5d60 100644 ---- a/include/linux/console_struct.h -+++ b/include/linux/console_struct.h -@@ -19,6 +19,7 @@ - struct vt_struct; - - #define NPAR 16 -+#include - - struct vc_data { - struct tty_port port; /* Upper level data */ -@@ -107,6 +108,8 @@ struct vc_data { - unsigned long vc_uni_pagedir; - unsigned long *vc_uni_pagedir_loc; /* [!] Location of uni_pagedir variable for this console */ - bool vc_panic_force_write; /* when oops/panic this VC can accept forced output/blanking */ -+ -+ struct vc_decor vc_decor; - /* additional information is in vt_kern.h */ - }; - -diff --git a/include/linux/fb.h b/include/linux/fb.h -index fe6ac95..1e36b03 100644 ---- a/include/linux/fb.h -+++ b/include/linux/fb.h -@@ -219,6 +219,34 @@ struct fb_deferred_io { - }; - #endif - -+#ifdef __KERNEL__ -+#ifdef CONFIG_COMPAT -+struct fb_image32 { -+ __u32 dx; /* Where to place image */ -+ __u32 dy; -+ __u32 width; /* Size of image */ -+ __u32 height; -+ __u32 fg_color; /* Only used when a mono bitmap */ -+ __u32 bg_color; -+ __u8 depth; /* Depth of the image */ -+ const compat_uptr_t data; /* Pointer to image data */ -+ struct fb_cmap32 cmap; /* color map info */ -+}; -+ -+#define fb_image_from_compat(to, from) \ -+ (to).dx = (from).dx; \ -+ (to).dy = (from).dy; \ -+ (to).width = (from).width; \ -+ (to).height = (from).height; \ -+ (to).fg_color = (from).fg_color; \ -+ (to).bg_color = (from).bg_color; \ -+ (to).depth = (from).depth; \ -+ (to).data = compat_ptr((from).data); \ -+ fb_cmap_from_compat((to).cmap, (from).cmap) -+ -+#endif /* CONFIG_COMPAT */ -+#endif /* __KERNEL__ */ -+ - /* - * Frame buffer operations - * -@@ -489,6 +517,9 @@ struct fb_info { - #define FBINFO_STATE_SUSPENDED 1 - u32 state; /* Hardware state i.e suspend */ - void *fbcon_par; /* fbcon use-only private area */ -+ -+ struct fb_image bgdecor; -+ - /* From here on everything is device dependent */ - void *par; - /* we need the PCI or similar aperture base/size not -diff --git a/include/uapi/linux/fb.h b/include/uapi/linux/fb.h -index fb795c3..dc77a03 100644 ---- a/include/uapi/linux/fb.h -+++ b/include/uapi/linux/fb.h -@@ -8,6 +8,25 @@ - - #define FB_MAX 32 /* sufficient for now */ - -+struct fbcon_decor_iowrapper -+{ -+ unsigned short vc; /* Virtual console */ -+ unsigned char origin; /* Point of origin of the request */ -+ void *data; -+}; -+ -+#ifdef __KERNEL__ -+#ifdef CONFIG_COMPAT -+#include -+struct fbcon_decor_iowrapper32 -+{ -+ unsigned short vc; /* Virtual console */ -+ unsigned char origin; /* Point of origin of the request */ -+ compat_uptr_t data; -+}; -+#endif /* CONFIG_COMPAT */ -+#endif /* __KERNEL__ */ -+ - /* ioctls - 0x46 is 'F' */ - #define FBIOGET_VSCREENINFO 0x4600 -@@ -35,6 +54,25 @@ - #define FBIOGET_DISPINFO 0x4618 - #define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) - -+#define FBIOCONDECOR_SETCFG _IOWR('F', 0x19, struct fbcon_decor_iowrapper) -+#define FBIOCONDECOR_GETCFG _IOR('F', 0x1A, struct fbcon_decor_iowrapper) -+#define FBIOCONDECOR_SETSTATE _IOWR('F', 0x1B, struct fbcon_decor_iowrapper) -+#define FBIOCONDECOR_GETSTATE _IOR('F', 0x1C, struct fbcon_decor_iowrapper) -+#define FBIOCONDECOR_SETPIC _IOWR('F', 0x1D, struct fbcon_decor_iowrapper) -+#ifdef __KERNEL__ -+#ifdef CONFIG_COMPAT -+#define FBIOCONDECOR_SETCFG32 _IOWR('F', 0x19, struct fbcon_decor_iowrapper32) -+#define FBIOCONDECOR_GETCFG32 _IOR('F', 0x1A, struct fbcon_decor_iowrapper32) -+#define FBIOCONDECOR_SETSTATE32 _IOWR('F', 0x1B, struct fbcon_decor_iowrapper32) -+#define FBIOCONDECOR_GETSTATE32 _IOR('F', 0x1C, struct fbcon_decor_iowrapper32) -+#define FBIOCONDECOR_SETPIC32 _IOWR('F', 0x1D, struct fbcon_decor_iowrapper32) -+#endif /* CONFIG_COMPAT */ -+#endif /* __KERNEL__ */ -+ -+#define FBCON_DECOR_THEME_LEN 128 /* Maximum lenght of a theme name */ -+#define FBCON_DECOR_IO_ORIG_KERNEL 0 /* Kernel ioctl origin */ -+#define FBCON_DECOR_IO_ORIG_USER 1 /* User ioctl origin */ -+ - #define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */ - #define FB_TYPE_PLANES 1 /* Non interleaved planes */ - #define FB_TYPE_INTERLEAVED_PLANES 2 /* Interleaved planes */ -@@ -277,6 +315,29 @@ struct fb_var_screeninfo { - __u32 reserved[4]; /* Reserved for future compatibility */ - }; - -+#ifdef __KERNEL__ -+#ifdef CONFIG_COMPAT -+struct fb_cmap32 { -+ __u32 start; -+ __u32 len; /* Number of entries */ -+ compat_uptr_t red; /* Red values */ -+ compat_uptr_t green; -+ compat_uptr_t blue; -+ compat_uptr_t transp; /* transparency, can be NULL */ -+}; -+ -+#define fb_cmap_from_compat(to, from) \ -+ (to).start = (from).start; \ -+ (to).len = (from).len; \ -+ (to).red = compat_ptr((from).red); \ -+ (to).green = compat_ptr((from).green); \ -+ (to).blue = compat_ptr((from).blue); \ -+ (to).transp = compat_ptr((from).transp) -+ -+#endif /* CONFIG_COMPAT */ -+#endif /* __KERNEL__ */ -+ -+ - struct fb_cmap { - __u32 start; /* First entry */ - __u32 len; /* Number of entries */ -diff --git a/kernel/sysctl.c b/kernel/sysctl.c -index 74f5b58..6386ab0 100644 ---- a/kernel/sysctl.c -+++ b/kernel/sysctl.c -@@ -146,6 +146,10 @@ static const int cap_last_cap = CAP_LAST_CAP; - static unsigned long hung_task_timeout_max = (LONG_MAX/HZ); - #endif - -+#ifdef CONFIG_FB_CON_DECOR -+extern char fbcon_decor_path[]; -+#endif -+ - #ifdef CONFIG_INOTIFY_USER - #include - #endif -@@ -255,6 +259,15 @@ static struct ctl_table sysctl_base_table[] = { - .mode = 0555, - .child = dev_table, - }, -+#ifdef CONFIG_FB_CON_DECOR -+ { -+ .procname = "fbcondecor", -+ .data = &fbcon_decor_path, -+ .maxlen = KMOD_PATH_LEN, -+ .mode = 0644, -+ .proc_handler = &proc_dostring, -+ }, -+#endif - { } - }; - diff --git a/kernel/tools/perf/files/patches/gentoo/4567_distro-Gentoo-Kconfig.patch b/kernel/tools/perf/files/patches/gentoo/4567_distro-Gentoo-Kconfig.patch deleted file mode 100644 index c7af596c94..0000000000 --- a/kernel/tools/perf/files/patches/gentoo/4567_distro-Gentoo-Kconfig.patch +++ /dev/null @@ -1,143 +0,0 @@ ---- a/Kconfig -+++ b/Kconfig -@@ -8,4 +8,6 @@ config SRCARCH - string - option env="SRCARCH" - -+source "distro/Kconfig" -+ - source "arch/$SRCARCH/Kconfig" ---- /dev/null -+++ b/distro/Kconfig -@@ -0,0 +1,131 @@ -+menu "Gentoo Linux" -+ -+config GENTOO_LINUX -+ bool "Gentoo Linux support" -+ -+ default y -+ -+ help -+ In order to boot Gentoo Linux a minimal set of config settings needs to -+ be enabled in the kernel; to avoid the users from having to enable them -+ manually as part of a Gentoo Linux installation or a new clean config, -+ we enable these config settings by default for convenience. -+ -+ See the settings that become available for more details and fine-tuning. -+ -+config GENTOO_LINUX_UDEV -+ bool "Linux dynamic and persistent device naming (userspace devfs) support" -+ -+ depends on GENTOO_LINUX -+ default y if GENTOO_LINUX -+ -+ select DEVTMPFS -+ select TMPFS -+ -+ select MMU -+ select SHMEM -+ -+ help -+ In order to boot Gentoo Linux a minimal set of config settings needs to -+ be enabled in the kernel; to avoid the users from having to enable them -+ manually as part of a Gentoo Linux installation or a new clean config, -+ we enable these config settings by default for convenience. -+ -+ Currently this only selects TMPFS, DEVTMPFS and their dependencies. -+ TMPFS is enabled to maintain a tmpfs file system at /dev/shm, /run and -+ /sys/fs/cgroup; DEVTMPFS to maintain a devtmpfs file system at /dev. -+ -+ Some of these are critical files that need to be available early in the -+ boot process; if not available, it causes sysfs and udev to malfunction. -+ -+ To ensure Gentoo Linux boots, it is best to leave this setting enabled; -+ if you run a custom setup, you could consider whether to disable this. -+ -+config GENTOO_LINUX_PORTAGE -+ bool "Select options required by Portage features" -+ -+ depends on GENTOO_LINUX -+ default y if GENTOO_LINUX -+ -+ select CGROUPS -+ select NAMESPACES -+ select IPC_NS -+ select NET_NS -+ -+ help -+ This enables options required by various Portage FEATURES. -+ Currently this selects: -+ -+ CGROUPS (required for FEATURES=cgroup) -+ IPC_NS (required for FEATURES=ipc-sandbox) -+ NET_NS (required for FEATURES=network-sandbox) -+ -+ It is highly recommended that you leave this enabled as these FEATURES -+ are, or will soon be, enabled by default. -+ -+menu "Support for init systems, system and service managers" -+ visible if GENTOO_LINUX -+ -+config GENTOO_LINUX_INIT_SCRIPT -+ bool "OpenRC, runit and other script based systems and managers" -+ -+ default y if GENTOO_LINUX -+ -+ depends on GENTOO_LINUX -+ -+ select BINFMT_SCRIPT -+ -+ help -+ The init system is the first thing that loads after the kernel booted. -+ -+ These config settings allow you to select which init systems to support; -+ instead of having to select all the individual settings all over the -+ place, these settings allows you to select all the settings at once. -+ -+ This particular setting enables all the known requirements for OpenRC, -+ runit and similar script based systems and managers. -+ -+ If you are unsure about this, it is best to leave this setting enabled. -+ -+config GENTOO_LINUX_INIT_SYSTEMD -+ bool "systemd" -+ -+ default n -+ -+ depends on GENTOO_LINUX && GENTOO_LINUX_UDEV -+ -+ select AUTOFS4_FS -+ select BLK_DEV_BSG -+ select CGROUPS -+ select DEVPTS_MULTIPLE_INSTANCES -+ select EPOLL -+ select FANOTIFY -+ select FHANDLE -+ select INOTIFY_USER -+ select NET -+ select NET_NS -+ select PROC_FS -+ select SIGNALFD -+ select SYSFS -+ select TIMERFD -+ -+ select ANON_INODES -+ select BLOCK -+ select EVENTFD -+ select FSNOTIFY -+ select INET -+ select NLATTR -+ -+ help -+ The init system is the first thing that loads after the kernel booted. -+ -+ These config settings allow you to select which init systems to support; -+ instead of having to select all the individual settings all over the -+ place, these settings allows you to select all the settings at once. -+ -+ This particular setting enables all the known requirements for systemd; -+ it also enables suggested optional settings, as the package suggests to. -+ -+endmenu -+ -+endmenu diff --git a/kernel/tools/perf/files/patches/gentoo/5001_block-cgroups-kconfig-build-bits-for-BFQ-v7r7-3.19.patch b/kernel/tools/perf/files/patches/gentoo/5001_block-cgroups-kconfig-build-bits-for-BFQ-v7r7-3.19.patch deleted file mode 100644 index b36d572c7c..0000000000 --- a/kernel/tools/perf/files/patches/gentoo/5001_block-cgroups-kconfig-build-bits-for-BFQ-v7r7-3.19.patch +++ /dev/null @@ -1,104 +0,0 @@ -From a828d56aebc0735676be23734cccf31e279c0d1b Mon Sep 17 00:00:00 2001 -From: Paolo Valente -Date: Mon, 8 Dec 2014 16:04:25 +0100 -Subject: [PATCH 1/3] block: cgroups, kconfig, build bits for BFQ-v7r7-3.19 - -Update Kconfig.iosched and do the related Makefile changes to include -kernel configuration options for BFQ. Also add the bfqio controller -to the cgroups subsystem. - -Signed-off-by: Paolo Valente -Signed-off-by: Arianna Avanzini ---- - block/Kconfig.iosched | 32 ++++++++++++++++++++++++++++++++ - block/Makefile | 1 + - include/linux/cgroup_subsys.h | 4 ++++ - 3 files changed, 37 insertions(+) - -diff --git a/block/Kconfig.iosched b/block/Kconfig.iosched -index 421bef9..0ee5f0f 100644 ---- a/block/Kconfig.iosched -+++ b/block/Kconfig.iosched -@@ -39,6 +39,27 @@ config CFQ_GROUP_IOSCHED - ---help--- - Enable group IO scheduling in CFQ. - -+config IOSCHED_BFQ -+ tristate "BFQ I/O scheduler" -+ default n -+ ---help--- -+ The BFQ I/O scheduler tries to distribute bandwidth among -+ all processes according to their weights. -+ It aims at distributing the bandwidth as desired, independently of -+ the disk parameters and with any workload. It also tries to -+ guarantee low latency to interactive and soft real-time -+ applications. If compiled built-in (saying Y here), BFQ can -+ be configured to support hierarchical scheduling. -+ -+config CGROUP_BFQIO -+ bool "BFQ hierarchical scheduling support" -+ depends on CGROUPS && IOSCHED_BFQ=y -+ default n -+ ---help--- -+ Enable hierarchical scheduling in BFQ, using the cgroups -+ filesystem interface. The name of the subsystem will be -+ bfqio. -+ - choice - prompt "Default I/O scheduler" - default DEFAULT_CFQ -@@ -52,6 +73,16 @@ choice - config DEFAULT_CFQ - bool "CFQ" if IOSCHED_CFQ=y - -+ config DEFAULT_BFQ -+ bool "BFQ" if IOSCHED_BFQ=y -+ help -+ Selects BFQ as the default I/O scheduler which will be -+ used by default for all block devices. -+ The BFQ I/O scheduler aims at distributing the bandwidth -+ as desired, independently of the disk parameters and with -+ any workload. It also tries to guarantee low latency to -+ interactive and soft real-time applications. -+ - config DEFAULT_NOOP - bool "No-op" - -@@ -61,6 +92,7 @@ config DEFAULT_IOSCHED - string - default "deadline" if DEFAULT_DEADLINE - default "cfq" if DEFAULT_CFQ -+ default "bfq" if DEFAULT_BFQ - default "noop" if DEFAULT_NOOP - - endmenu -diff --git a/block/Makefile b/block/Makefile -index 00ecc97..1ed86d5 100644 ---- a/block/Makefile -+++ b/block/Makefile -@@ -18,6 +18,7 @@ obj-$(CONFIG_BLK_DEV_THROTTLING) += blk-throttle.o - obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o - obj-$(CONFIG_IOSCHED_DEADLINE) += deadline-iosched.o - obj-$(CONFIG_IOSCHED_CFQ) += cfq-iosched.o -+obj-$(CONFIG_IOSCHED_BFQ) += bfq-iosched.o - - obj-$(CONFIG_BLOCK_COMPAT) += compat_ioctl.o - obj-$(CONFIG_BLK_CMDLINE_PARSER) += cmdline-parser.o -diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h -index 98c4f9b..13b010d 100644 ---- a/include/linux/cgroup_subsys.h -+++ b/include/linux/cgroup_subsys.h -@@ -35,6 +35,10 @@ SUBSYS(net_cls) - SUBSYS(blkio) - #endif - -+#if IS_ENABLED(CONFIG_CGROUP_BFQIO) -+SUBSYS(bfqio) -+#endif -+ - #if IS_ENABLED(CONFIG_CGROUP_PERF) - SUBSYS(perf_event) - #endif --- -2.3.0 - diff --git a/kernel/tools/perf/files/patches/gentoo/5002_block-introduce-the-BFQ-v7r7-I-O-sched-for-3.19.patch b/kernel/tools/perf/files/patches/gentoo/5002_block-introduce-the-BFQ-v7r7-I-O-sched-for-3.19.patch deleted file mode 100644 index fb96ff28b3..0000000000 --- a/kernel/tools/perf/files/patches/gentoo/5002_block-introduce-the-BFQ-v7r7-I-O-sched-for-3.19.patch +++ /dev/null @@ -1,6966 +0,0 @@ -From 5bfaaa91a51940efaccb66bc5cd562ba3b9d4053 Mon Sep 17 00:00:00 2001 -From: Paolo Valente -Date: Thu, 9 May 2013 19:10:02 +0200 -Subject: [PATCH 2/3] block: introduce the BFQ-v7r7 I/O sched for 3.19 - -Add the BFQ-v7r7 I/O scheduler to 3.19. -The general structure is borrowed from CFQ, as much of the code for -handling I/O contexts. Over time, several useful features have been -ported from CFQ as well (details in the changelog in README.BFQ). A -(bfq_)queue is associated to each task doing I/O on a device, and each -time a scheduling decision has to be made a queue is selected and served -until it expires. - - - Slices are given in the service domain: tasks are assigned - budgets, measured in number of sectors. Once got the disk, a task - must however consume its assigned budget within a configurable - maximum time (by default, the maximum possible value of the - budgets is automatically computed to comply with this timeout). - This allows the desired latency vs "throughput boosting" tradeoff - to be set. - - - Budgets are scheduled according to a variant of WF2Q+, implemented - using an augmented rb-tree to take eligibility into account while - preserving an O(log N) overall complexity. - - - A low-latency tunable is provided; if enabled, both interactive - and soft real-time applications are guaranteed a very low latency. - - - Latency guarantees are preserved also in the presence of NCQ. - - - Also with flash-based devices, a high throughput is achieved - while still preserving latency guarantees. - - - BFQ features Early Queue Merge (EQM), a sort of fusion of the - cooperating-queue-merging and the preemption mechanisms present - in CFQ. EQM is in fact a unified mechanism that tries to get a - sequential read pattern, and hence a high throughput, with any - set of processes performing interleaved I/O over a contiguous - sequence of sectors. - - - BFQ supports full hierarchical scheduling, exporting a cgroups - interface. Since each node has a full scheduler, each group can - be assigned its own weight. - - - If the cgroups interface is not used, only I/O priorities can be - assigned to processes, with ioprio values mapped to weights - with the relation weight = IOPRIO_BE_NR - ioprio. - - - ioprio classes are served in strict priority order, i.e., lower - priority queues are not served as long as there are higher - priority queues. Among queues in the same class the bandwidth is - distributed in proportion to the weight of each queue. A very - thin extra bandwidth is however guaranteed to the Idle class, to - prevent it from starving. - -Signed-off-by: Paolo Valente -Signed-off-by: Arianna Avanzini ---- - block/bfq-cgroup.c | 936 ++++++++++++ - block/bfq-ioc.c | 36 + - block/bfq-iosched.c | 3902 +++++++++++++++++++++++++++++++++++++++++++++++++++ - block/bfq-sched.c | 1214 ++++++++++++++++ - block/bfq.h | 775 ++++++++++ - 5 files changed, 6863 insertions(+) - create mode 100644 block/bfq-cgroup.c - create mode 100644 block/bfq-ioc.c - create mode 100644 block/bfq-iosched.c - create mode 100644 block/bfq-sched.c - create mode 100644 block/bfq.h - -diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c -new file mode 100644 -index 0000000..11e2f1d ---- /dev/null -+++ b/block/bfq-cgroup.c -@@ -0,0 +1,936 @@ -+/* -+ * BFQ: CGROUPS support. -+ * -+ * Based on ideas and code from CFQ: -+ * Copyright (C) 2003 Jens Axboe -+ * -+ * Copyright (C) 2008 Fabio Checconi -+ * Paolo Valente -+ * -+ * Copyright (C) 2010 Paolo Valente -+ * -+ * Licensed under the GPL-2 as detailed in the accompanying COPYING.BFQ -+ * file. -+ */ -+ -+#ifdef CONFIG_CGROUP_BFQIO -+ -+static DEFINE_MUTEX(bfqio_mutex); -+ -+static bool bfqio_is_removed(struct bfqio_cgroup *bgrp) -+{ -+ return bgrp ? !bgrp->online : false; -+} -+ -+static struct bfqio_cgroup bfqio_root_cgroup = { -+ .weight = BFQ_DEFAULT_GRP_WEIGHT, -+ .ioprio = BFQ_DEFAULT_GRP_IOPRIO, -+ .ioprio_class = BFQ_DEFAULT_GRP_CLASS, -+}; -+ -+static inline void bfq_init_entity(struct bfq_entity *entity, -+ struct bfq_group *bfqg) -+{ -+ entity->weight = entity->new_weight; -+ entity->orig_weight = entity->new_weight; -+ entity->ioprio = entity->new_ioprio; -+ entity->ioprio_class = entity->new_ioprio_class; -+ entity->parent = bfqg->my_entity; -+ entity->sched_data = &bfqg->sched_data; -+} -+ -+static struct bfqio_cgroup *css_to_bfqio(struct cgroup_subsys_state *css) -+{ -+ return css ? container_of(css, struct bfqio_cgroup, css) : NULL; -+} -+ -+/* -+ * Search the bfq_group for bfqd into the hash table (by now only a list) -+ * of bgrp. Must be called under rcu_read_lock(). -+ */ -+static struct bfq_group *bfqio_lookup_group(struct bfqio_cgroup *bgrp, -+ struct bfq_data *bfqd) -+{ -+ struct bfq_group *bfqg; -+ void *key; -+ -+ hlist_for_each_entry_rcu(bfqg, &bgrp->group_data, group_node) { -+ key = rcu_dereference(bfqg->bfqd); -+ if (key == bfqd) -+ return bfqg; -+ } -+ -+ return NULL; -+} -+ -+static inline void bfq_group_init_entity(struct bfqio_cgroup *bgrp, -+ struct bfq_group *bfqg) -+{ -+ struct bfq_entity *entity = &bfqg->entity; -+ -+ /* -+ * If the weight of the entity has never been set via the sysfs -+ * interface, then bgrp->weight == 0. In this case we initialize -+ * the weight from the current ioprio value. Otherwise, the group -+ * weight, if set, has priority over the ioprio value. -+ */ -+ if (bgrp->weight == 0) { -+ entity->new_weight = bfq_ioprio_to_weight(bgrp->ioprio); -+ entity->new_ioprio = bgrp->ioprio; -+ } else { -+ if (bgrp->weight < BFQ_MIN_WEIGHT || -+ bgrp->weight > BFQ_MAX_WEIGHT) { -+ printk(KERN_CRIT "bfq_group_init_entity: " -+ "bgrp->weight %d\n", bgrp->weight); -+ BUG(); -+ } -+ entity->new_weight = bgrp->weight; -+ entity->new_ioprio = bfq_weight_to_ioprio(bgrp->weight); -+ } -+ entity->orig_weight = entity->weight = entity->new_weight; -+ entity->ioprio = entity->new_ioprio; -+ entity->ioprio_class = entity->new_ioprio_class = bgrp->ioprio_class; -+ entity->my_sched_data = &bfqg->sched_data; -+ bfqg->active_entities = 0; -+} -+ -+static inline void bfq_group_set_parent(struct bfq_group *bfqg, -+ struct bfq_group *parent) -+{ -+ struct bfq_entity *entity; -+ -+ BUG_ON(parent == NULL); -+ BUG_ON(bfqg == NULL); -+ -+ entity = &bfqg->entity; -+ entity->parent = parent->my_entity; -+ entity->sched_data = &parent->sched_data; -+} -+ -+/** -+ * bfq_group_chain_alloc - allocate a chain of groups. -+ * @bfqd: queue descriptor. -+ * @css: the leaf cgroup_subsys_state this chain starts from. -+ * -+ * Allocate a chain of groups starting from the one belonging to -+ * @cgroup up to the root cgroup. Stop if a cgroup on the chain -+ * to the root has already an allocated group on @bfqd. -+ */ -+static struct bfq_group *bfq_group_chain_alloc(struct bfq_data *bfqd, -+ struct cgroup_subsys_state *css) -+{ -+ struct bfqio_cgroup *bgrp; -+ struct bfq_group *bfqg, *prev = NULL, *leaf = NULL; -+ -+ for (; css != NULL; css = css->parent) { -+ bgrp = css_to_bfqio(css); -+ -+ bfqg = bfqio_lookup_group(bgrp, bfqd); -+ if (bfqg != NULL) { -+ /* -+ * All the cgroups in the path from there to the -+ * root must have a bfq_group for bfqd, so we don't -+ * need any more allocations. -+ */ -+ break; -+ } -+ -+ bfqg = kzalloc(sizeof(*bfqg), GFP_ATOMIC); -+ if (bfqg == NULL) -+ goto cleanup; -+ -+ bfq_group_init_entity(bgrp, bfqg); -+ bfqg->my_entity = &bfqg->entity; -+ -+ if (leaf == NULL) { -+ leaf = bfqg; -+ prev = leaf; -+ } else { -+ bfq_group_set_parent(prev, bfqg); -+ /* -+ * Build a list of allocated nodes using the bfqd -+ * filed, that is still unused and will be -+ * initialized only after the node will be -+ * connected. -+ */ -+ prev->bfqd = bfqg; -+ prev = bfqg; -+ } -+ } -+ -+ return leaf; -+ -+cleanup: -+ while (leaf != NULL) { -+ prev = leaf; -+ leaf = leaf->bfqd; -+ kfree(prev); -+ } -+ -+ return NULL; -+} -+ -+/** -+ * bfq_group_chain_link - link an allocated group chain to a cgroup -+ * hierarchy. -+ * @bfqd: the queue descriptor. -+ * @css: the leaf cgroup_subsys_state to start from. -+ * @leaf: the leaf group (to be associated to @cgroup). -+ * -+ * Try to link a chain of groups to a cgroup hierarchy, connecting the -+ * nodes bottom-up, so we can be sure that when we find a cgroup in the -+ * hierarchy that already as a group associated to @bfqd all the nodes -+ * in the path to the root cgroup have one too. -+ * -+ * On locking: the queue lock protects the hierarchy (there is a hierarchy -+ * per device) while the bfqio_cgroup lock protects the list of groups -+ * belonging to the same cgroup. -+ */ -+static void bfq_group_chain_link(struct bfq_data *bfqd, -+ struct cgroup_subsys_state *css, -+ struct bfq_group *leaf) -+{ -+ struct bfqio_cgroup *bgrp; -+ struct bfq_group *bfqg, *next, *prev = NULL; -+ unsigned long flags; -+ -+ assert_spin_locked(bfqd->queue->queue_lock); -+ -+ for (; css != NULL && leaf != NULL; css = css->parent) { -+ bgrp = css_to_bfqio(css); -+ next = leaf->bfqd; -+ -+ bfqg = bfqio_lookup_group(bgrp, bfqd); -+ BUG_ON(bfqg != NULL); -+ -+ spin_lock_irqsave(&bgrp->lock, flags); -+ -+ rcu_assign_pointer(leaf->bfqd, bfqd); -+ hlist_add_head_rcu(&leaf->group_node, &bgrp->group_data); -+ hlist_add_head(&leaf->bfqd_node, &bfqd->group_list); -+ -+ spin_unlock_irqrestore(&bgrp->lock, flags); -+ -+ prev = leaf; -+ leaf = next; -+ } -+ -+ BUG_ON(css == NULL && leaf != NULL); -+ if (css != NULL && prev != NULL) { -+ bgrp = css_to_bfqio(css); -+ bfqg = bfqio_lookup_group(bgrp, bfqd); -+ bfq_group_set_parent(prev, bfqg); -+ } -+} -+ -+/** -+ * bfq_find_alloc_group - return the group associated to @bfqd in @cgroup. -+ * @bfqd: queue descriptor. -+ * @cgroup: cgroup being searched for. -+ * -+ * Return a group associated to @bfqd in @cgroup, allocating one if -+ * necessary. When a group is returned all the cgroups in the path -+ * to the root have a group associated to @bfqd. -+ * -+ * If the allocation fails, return the root group: this breaks guarantees -+ * but is a safe fallback. If this loss becomes a problem it can be -+ * mitigated using the equivalent weight (given by the product of the -+ * weights of the groups in the path from @group to the root) in the -+ * root scheduler. -+ * -+ * We allocate all the missing nodes in the path from the leaf cgroup -+ * to the root and we connect the nodes only after all the allocations -+ * have been successful. -+ */ -+static struct bfq_group *bfq_find_alloc_group(struct bfq_data *bfqd, -+ struct cgroup_subsys_state *css) -+{ -+ struct bfqio_cgroup *bgrp = css_to_bfqio(css); -+ struct bfq_group *bfqg; -+ -+ bfqg = bfqio_lookup_group(bgrp, bfqd); -+ if (bfqg != NULL) -+ return bfqg; -+ -+ bfqg = bfq_group_chain_alloc(bfqd, css); -+ if (bfqg != NULL) -+ bfq_group_chain_link(bfqd, css, bfqg); -+ else -+ bfqg = bfqd->root_group; -+ -+ return bfqg; -+} -+ -+/** -+ * bfq_bfqq_move - migrate @bfqq to @bfqg. -+ * @bfqd: queue descriptor. -+ * @bfqq: the queue to move. -+ * @entity: @bfqq's entity. -+ * @bfqg: the group to move to. -+ * -+ * Move @bfqq to @bfqg, deactivating it from its old group and reactivating -+ * it on the new one. Avoid putting the entity on the old group idle tree. -+ * -+ * Must be called under the queue lock; the cgroup owning @bfqg must -+ * not disappear (by now this just means that we are called under -+ * rcu_read_lock()). -+ */ -+static void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq, -+ struct bfq_entity *entity, struct bfq_group *bfqg) -+{ -+ int busy, resume; -+ -+ busy = bfq_bfqq_busy(bfqq); -+ resume = !RB_EMPTY_ROOT(&bfqq->sort_list); -+ -+ BUG_ON(resume && !entity->on_st); -+ BUG_ON(busy && !resume && entity->on_st && -+ bfqq != bfqd->in_service_queue); -+ -+ if (busy) { -+ BUG_ON(atomic_read(&bfqq->ref) < 2); -+ -+ if (!resume) -+ bfq_del_bfqq_busy(bfqd, bfqq, 0); -+ else -+ bfq_deactivate_bfqq(bfqd, bfqq, 0); -+ } else if (entity->on_st) -+ bfq_put_idle_entity(bfq_entity_service_tree(entity), entity); -+ -+ /* -+ * Here we use a reference to bfqg. We don't need a refcounter -+ * as the cgroup reference will not be dropped, so that its -+ * destroy() callback will not be invoked. -+ */ -+ entity->parent = bfqg->my_entity; -+ entity->sched_data = &bfqg->sched_data; -+ -+ if (busy && resume) -+ bfq_activate_bfqq(bfqd, bfqq); -+ -+ if (bfqd->in_service_queue == NULL && !bfqd->rq_in_driver) -+ bfq_schedule_dispatch(bfqd); -+} -+ -+/** -+ * __bfq_bic_change_cgroup - move @bic to @cgroup. -+ * @bfqd: the queue descriptor. -+ * @bic: the bic to move. -+ * @cgroup: the cgroup to move to. -+ * -+ * Move bic to cgroup, assuming that bfqd->queue is locked; the caller -+ * has to make sure that the reference to cgroup is valid across the call. -+ * -+ * NOTE: an alternative approach might have been to store the current -+ * cgroup in bfqq and getting a reference to it, reducing the lookup -+ * time here, at the price of slightly more complex code. -+ */ -+static struct bfq_group *__bfq_bic_change_cgroup(struct bfq_data *bfqd, -+ struct bfq_io_cq *bic, -+ struct cgroup_subsys_state *css) -+{ -+ struct bfq_queue *async_bfqq = bic_to_bfqq(bic, 0); -+ struct bfq_queue *sync_bfqq = bic_to_bfqq(bic, 1); -+ struct bfq_entity *entity; -+ struct bfq_group *bfqg; -+ struct bfqio_cgroup *bgrp; -+ -+ bgrp = css_to_bfqio(css); -+ -+ bfqg = bfq_find_alloc_group(bfqd, css); -+ if (async_bfqq != NULL) { -+ entity = &async_bfqq->entity; -+ -+ if (entity->sched_data != &bfqg->sched_data) { -+ bic_set_bfqq(bic, NULL, 0); -+ bfq_log_bfqq(bfqd, async_bfqq, -+ "bic_change_group: %p %d", -+ async_bfqq, atomic_read(&async_bfqq->ref)); -+ bfq_put_queue(async_bfqq); -+ } -+ } -+ -+ if (sync_bfqq != NULL) { -+ entity = &sync_bfqq->entity; -+ if (entity->sched_data != &bfqg->sched_data) -+ bfq_bfqq_move(bfqd, sync_bfqq, entity, bfqg); -+ } -+ -+ return bfqg; -+} -+ -+/** -+ * bfq_bic_change_cgroup - move @bic to @cgroup. -+ * @bic: the bic being migrated. -+ * @cgroup: the destination cgroup. -+ * -+ * When the task owning @bic is moved to @cgroup, @bic is immediately -+ * moved into its new parent group. -+ */ -+static void bfq_bic_change_cgroup(struct bfq_io_cq *bic, -+ struct cgroup_subsys_state *css) -+{ -+ struct bfq_data *bfqd; -+ unsigned long uninitialized_var(flags); -+ -+ bfqd = bfq_get_bfqd_locked(&(bic->icq.q->elevator->elevator_data), -+ &flags); -+ if (bfqd != NULL) { -+ __bfq_bic_change_cgroup(bfqd, bic, css); -+ bfq_put_bfqd_unlock(bfqd, &flags); -+ } -+} -+ -+/** -+ * bfq_bic_update_cgroup - update the cgroup of @bic. -+ * @bic: the @bic to update. -+ * -+ * Make sure that @bic is enqueued in the cgroup of the current task. -+ * We need this in addition to moving bics during the cgroup attach -+ * phase because the task owning @bic could be at its first disk -+ * access or we may end up in the root cgroup as the result of a -+ * memory allocation failure and here we try to move to the right -+ * group. -+ * -+ * Must be called under the queue lock. It is safe to use the returned -+ * value even after the rcu_read_unlock() as the migration/destruction -+ * paths act under the queue lock too. IOW it is impossible to race with -+ * group migration/destruction and end up with an invalid group as: -+ * a) here cgroup has not yet been destroyed, nor its destroy callback -+ * has started execution, as current holds a reference to it, -+ * b) if it is destroyed after rcu_read_unlock() [after current is -+ * migrated to a different cgroup] its attach() callback will have -+ * taken care of remove all the references to the old cgroup data. -+ */ -+static struct bfq_group *bfq_bic_update_cgroup(struct bfq_io_cq *bic) -+{ -+ struct bfq_data *bfqd = bic_to_bfqd(bic); -+ struct bfq_group *bfqg; -+ struct cgroup_subsys_state *css; -+ -+ BUG_ON(bfqd == NULL); -+ -+ rcu_read_lock(); -+ css = task_css(current, bfqio_cgrp_id); -+ bfqg = __bfq_bic_change_cgroup(bfqd, bic, css); -+ rcu_read_unlock(); -+ -+ return bfqg; -+} -+ -+/** -+ * bfq_flush_idle_tree - deactivate any entity on the idle tree of @st. -+ * @st: the service tree being flushed. -+ */ -+static inline void bfq_flush_idle_tree(struct bfq_service_tree *st) -+{ -+ struct bfq_entity *entity = st->first_idle; -+ -+ for (; entity != NULL; entity = st->first_idle) -+ __bfq_deactivate_entity(entity, 0); -+} -+ -+/** -+ * bfq_reparent_leaf_entity - move leaf entity to the root_group. -+ * @bfqd: the device data structure with the root group. -+ * @entity: the entity to move. -+ */ -+static inline void bfq_reparent_leaf_entity(struct bfq_data *bfqd, -+ struct bfq_entity *entity) -+{ -+ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); -+ -+ BUG_ON(bfqq == NULL); -+ bfq_bfqq_move(bfqd, bfqq, entity, bfqd->root_group); -+ return; -+} -+ -+/** -+ * bfq_reparent_active_entities - move to the root group all active -+ * entities. -+ * @bfqd: the device data structure with the root group. -+ * @bfqg: the group to move from. -+ * @st: the service tree with the entities. -+ * -+ * Needs queue_lock to be taken and reference to be valid over the call. -+ */ -+static inline void bfq_reparent_active_entities(struct bfq_data *bfqd, -+ struct bfq_group *bfqg, -+ struct bfq_service_tree *st) -+{ -+ struct rb_root *active = &st->active; -+ struct bfq_entity *entity = NULL; -+ -+ if (!RB_EMPTY_ROOT(&st->active)) -+ entity = bfq_entity_of(rb_first(active)); -+ -+ for (; entity != NULL; entity = bfq_entity_of(rb_first(active))) -+ bfq_reparent_leaf_entity(bfqd, entity); -+ -+ if (bfqg->sched_data.in_service_entity != NULL) -+ bfq_reparent_leaf_entity(bfqd, -+ bfqg->sched_data.in_service_entity); -+ -+ return; -+} -+ -+/** -+ * bfq_destroy_group - destroy @bfqg. -+ * @bgrp: the bfqio_cgroup containing @bfqg. -+ * @bfqg: the group being destroyed. -+ * -+ * Destroy @bfqg, making sure that it is not referenced from its parent. -+ */ -+static void bfq_destroy_group(struct bfqio_cgroup *bgrp, struct bfq_group *bfqg) -+{ -+ struct bfq_data *bfqd; -+ struct bfq_service_tree *st; -+ struct bfq_entity *entity = bfqg->my_entity; -+ unsigned long uninitialized_var(flags); -+ int i; -+ -+ hlist_del(&bfqg->group_node); -+ -+ /* -+ * Empty all service_trees belonging to this group before -+ * deactivating the group itself. -+ */ -+ for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) { -+ st = bfqg->sched_data.service_tree + i; -+ -+ /* -+ * The idle tree may still contain bfq_queues belonging -+ * to exited task because they never migrated to a different -+ * cgroup from the one being destroyed now. No one else -+ * can access them so it's safe to act without any lock. -+ */ -+ bfq_flush_idle_tree(st); -+ -+ /* -+ * It may happen that some queues are still active -+ * (busy) upon group destruction (if the corresponding -+ * processes have been forced to terminate). We move -+ * all the leaf entities corresponding to these queues -+ * to the root_group. -+ * Also, it may happen that the group has an entity -+ * in service, which is disconnected from the active -+ * tree: it must be moved, too. -+ * There is no need to put the sync queues, as the -+ * scheduler has taken no reference. -+ */ -+ bfqd = bfq_get_bfqd_locked(&bfqg->bfqd, &flags); -+ if (bfqd != NULL) { -+ bfq_reparent_active_entities(bfqd, bfqg, st); -+ bfq_put_bfqd_unlock(bfqd, &flags); -+ } -+ BUG_ON(!RB_EMPTY_ROOT(&st->active)); -+ BUG_ON(!RB_EMPTY_ROOT(&st->idle)); -+ } -+ BUG_ON(bfqg->sched_data.next_in_service != NULL); -+ BUG_ON(bfqg->sched_data.in_service_entity != NULL); -+ -+ /* -+ * We may race with device destruction, take extra care when -+ * dereferencing bfqg->bfqd. -+ */ -+ bfqd = bfq_get_bfqd_locked(&bfqg->bfqd, &flags); -+ if (bfqd != NULL) { -+ hlist_del(&bfqg->bfqd_node); -+ __bfq_deactivate_entity(entity, 0); -+ bfq_put_async_queues(bfqd, bfqg); -+ bfq_put_bfqd_unlock(bfqd, &flags); -+ } -+ BUG_ON(entity->tree != NULL); -+ -+ /* -+ * No need to defer the kfree() to the end of the RCU grace -+ * period: we are called from the destroy() callback of our -+ * cgroup, so we can be sure that no one is a) still using -+ * this cgroup or b) doing lookups in it. -+ */ -+ kfree(bfqg); -+} -+ -+static void bfq_end_wr_async(struct bfq_data *bfqd) -+{ -+ struct hlist_node *tmp; -+ struct bfq_group *bfqg; -+ -+ hlist_for_each_entry_safe(bfqg, tmp, &bfqd->group_list, bfqd_node) -+ bfq_end_wr_async_queues(bfqd, bfqg); -+ bfq_end_wr_async_queues(bfqd, bfqd->root_group); -+} -+ -+/** -+ * bfq_disconnect_groups - disconnect @bfqd from all its groups. -+ * @bfqd: the device descriptor being exited. -+ * -+ * When the device exits we just make sure that no lookup can return -+ * the now unused group structures. They will be deallocated on cgroup -+ * destruction. -+ */ -+static void bfq_disconnect_groups(struct bfq_data *bfqd) -+{ -+ struct hlist_node *tmp; -+ struct bfq_group *bfqg; -+ -+ bfq_log(bfqd, "disconnect_groups beginning"); -+ hlist_for_each_entry_safe(bfqg, tmp, &bfqd->group_list, bfqd_node) { -+ hlist_del(&bfqg->bfqd_node); -+ -+ __bfq_deactivate_entity(bfqg->my_entity, 0); -+ -+ /* -+ * Don't remove from the group hash, just set an -+ * invalid key. No lookups can race with the -+ * assignment as bfqd is being destroyed; this -+ * implies also that new elements cannot be added -+ * to the list. -+ */ -+ rcu_assign_pointer(bfqg->bfqd, NULL); -+ -+ bfq_log(bfqd, "disconnect_groups: put async for group %p", -+ bfqg); -+ bfq_put_async_queues(bfqd, bfqg); -+ } -+} -+ -+static inline void bfq_free_root_group(struct bfq_data *bfqd) -+{ -+ struct bfqio_cgroup *bgrp = &bfqio_root_cgroup; -+ struct bfq_group *bfqg = bfqd->root_group; -+ -+ bfq_put_async_queues(bfqd, bfqg); -+ -+ spin_lock_irq(&bgrp->lock); -+ hlist_del_rcu(&bfqg->group_node); -+ spin_unlock_irq(&bgrp->lock); -+ -+ /* -+ * No need to synchronize_rcu() here: since the device is gone -+ * there cannot be any read-side access to its root_group. -+ */ -+ kfree(bfqg); -+} -+ -+static struct bfq_group *bfq_alloc_root_group(struct bfq_data *bfqd, int node) -+{ -+ struct bfq_group *bfqg; -+ struct bfqio_cgroup *bgrp; -+ int i; -+ -+ bfqg = kzalloc_node(sizeof(*bfqg), GFP_KERNEL, node); -+ if (bfqg == NULL) -+ return NULL; -+ -+ bfqg->entity.parent = NULL; -+ for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) -+ bfqg->sched_data.service_tree[i] = BFQ_SERVICE_TREE_INIT; -+ -+ bgrp = &bfqio_root_cgroup; -+ spin_lock_irq(&bgrp->lock); -+ rcu_assign_pointer(bfqg->bfqd, bfqd); -+ hlist_add_head_rcu(&bfqg->group_node, &bgrp->group_data); -+ spin_unlock_irq(&bgrp->lock); -+ -+ return bfqg; -+} -+ -+#define SHOW_FUNCTION(__VAR) \ -+static u64 bfqio_cgroup_##__VAR##_read(struct cgroup_subsys_state *css, \ -+ struct cftype *cftype) \ -+{ \ -+ struct bfqio_cgroup *bgrp = css_to_bfqio(css); \ -+ u64 ret = -ENODEV; \ -+ \ -+ mutex_lock(&bfqio_mutex); \ -+ if (bfqio_is_removed(bgrp)) \ -+ goto out_unlock; \ -+ \ -+ spin_lock_irq(&bgrp->lock); \ -+ ret = bgrp->__VAR; \ -+ spin_unlock_irq(&bgrp->lock); \ -+ \ -+out_unlock: \ -+ mutex_unlock(&bfqio_mutex); \ -+ return ret; \ -+} -+ -+SHOW_FUNCTION(weight); -+SHOW_FUNCTION(ioprio); -+SHOW_FUNCTION(ioprio_class); -+#undef SHOW_FUNCTION -+ -+#define STORE_FUNCTION(__VAR, __MIN, __MAX) \ -+static int bfqio_cgroup_##__VAR##_write(struct cgroup_subsys_state *css,\ -+ struct cftype *cftype, \ -+ u64 val) \ -+{ \ -+ struct bfqio_cgroup *bgrp = css_to_bfqio(css); \ -+ struct bfq_group *bfqg; \ -+ int ret = -EINVAL; \ -+ \ -+ if (val < (__MIN) || val > (__MAX)) \ -+ return ret; \ -+ \ -+ ret = -ENODEV; \ -+ mutex_lock(&bfqio_mutex); \ -+ if (bfqio_is_removed(bgrp)) \ -+ goto out_unlock; \ -+ ret = 0; \ -+ \ -+ spin_lock_irq(&bgrp->lock); \ -+ bgrp->__VAR = (unsigned short)val; \ -+ hlist_for_each_entry(bfqg, &bgrp->group_data, group_node) { \ -+ /* \ -+ * Setting the ioprio_changed flag of the entity \ -+ * to 1 with new_##__VAR == ##__VAR would re-set \ -+ * the value of the weight to its ioprio mapping. \ -+ * Set the flag only if necessary. \ -+ */ \ -+ if ((unsigned short)val != bfqg->entity.new_##__VAR) { \ -+ bfqg->entity.new_##__VAR = (unsigned short)val; \ -+ /* \ -+ * Make sure that the above new value has been \ -+ * stored in bfqg->entity.new_##__VAR before \ -+ * setting the ioprio_changed flag. In fact, \ -+ * this flag may be read asynchronously (in \ -+ * critical sections protected by a different \ -+ * lock than that held here), and finding this \ -+ * flag set may cause the execution of the code \ -+ * for updating parameters whose value may \ -+ * depend also on bfqg->entity.new_##__VAR (in \ -+ * __bfq_entity_update_weight_prio). \ -+ * This barrier makes sure that the new value \ -+ * of bfqg->entity.new_##__VAR is correctly \ -+ * seen in that code. \ -+ */ \ -+ smp_wmb(); \ -+ bfqg->entity.ioprio_changed = 1; \ -+ } \ -+ } \ -+ spin_unlock_irq(&bgrp->lock); \ -+ \ -+out_unlock: \ -+ mutex_unlock(&bfqio_mutex); \ -+ return ret; \ -+} -+ -+STORE_FUNCTION(weight, BFQ_MIN_WEIGHT, BFQ_MAX_WEIGHT); -+STORE_FUNCTION(ioprio, 0, IOPRIO_BE_NR - 1); -+STORE_FUNCTION(ioprio_class, IOPRIO_CLASS_RT, IOPRIO_CLASS_IDLE); -+#undef STORE_FUNCTION -+ -+static struct cftype bfqio_files[] = { -+ { -+ .name = "weight", -+ .read_u64 = bfqio_cgroup_weight_read, -+ .write_u64 = bfqio_cgroup_weight_write, -+ }, -+ { -+ .name = "ioprio", -+ .read_u64 = bfqio_cgroup_ioprio_read, -+ .write_u64 = bfqio_cgroup_ioprio_write, -+ }, -+ { -+ .name = "ioprio_class", -+ .read_u64 = bfqio_cgroup_ioprio_class_read, -+ .write_u64 = bfqio_cgroup_ioprio_class_write, -+ }, -+ { }, /* terminate */ -+}; -+ -+static struct cgroup_subsys_state *bfqio_create(struct cgroup_subsys_state -+ *parent_css) -+{ -+ struct bfqio_cgroup *bgrp; -+ -+ if (parent_css != NULL) { -+ bgrp = kzalloc(sizeof(*bgrp), GFP_KERNEL); -+ if (bgrp == NULL) -+ return ERR_PTR(-ENOMEM); -+ } else -+ bgrp = &bfqio_root_cgroup; -+ -+ spin_lock_init(&bgrp->lock); -+ INIT_HLIST_HEAD(&bgrp->group_data); -+ bgrp->ioprio = BFQ_DEFAULT_GRP_IOPRIO; -+ bgrp->ioprio_class = BFQ_DEFAULT_GRP_CLASS; -+ -+ return &bgrp->css; -+} -+ -+/* -+ * We cannot support shared io contexts, as we have no means to support -+ * two tasks with the same ioc in two different groups without major rework -+ * of the main bic/bfqq data structures. By now we allow a task to change -+ * its cgroup only if it's the only owner of its ioc; the drawback of this -+ * behavior is that a group containing a task that forked using CLONE_IO -+ * will not be destroyed until the tasks sharing the ioc die. -+ */ -+static int bfqio_can_attach(struct cgroup_subsys_state *css, -+ struct cgroup_taskset *tset) -+{ -+ struct task_struct *task; -+ struct io_context *ioc; -+ int ret = 0; -+ -+ cgroup_taskset_for_each(task, tset) { -+ /* -+ * task_lock() is needed to avoid races with -+ * exit_io_context() -+ */ -+ task_lock(task); -+ ioc = task->io_context; -+ if (ioc != NULL && atomic_read(&ioc->nr_tasks) > 1) -+ /* -+ * ioc == NULL means that the task is either too -+ * young or exiting: if it has still no ioc the -+ * ioc can't be shared, if the task is exiting the -+ * attach will fail anyway, no matter what we -+ * return here. -+ */ -+ ret = -EINVAL; -+ task_unlock(task); -+ if (ret) -+ break; -+ } -+ -+ return ret; -+} -+ -+static void bfqio_attach(struct cgroup_subsys_state *css, -+ struct cgroup_taskset *tset) -+{ -+ struct task_struct *task; -+ struct io_context *ioc; -+ struct io_cq *icq; -+ -+ /* -+ * IMPORTANT NOTE: The move of more than one process at a time to a -+ * new group has not yet been tested. -+ */ -+ cgroup_taskset_for_each(task, tset) { -+ ioc = get_task_io_context(task, GFP_ATOMIC, NUMA_NO_NODE); -+ if (ioc) { -+ /* -+ * Handle cgroup change here. -+ */ -+ rcu_read_lock(); -+ hlist_for_each_entry_rcu(icq, &ioc->icq_list, ioc_node) -+ if (!strncmp( -+ icq->q->elevator->type->elevator_name, -+ "bfq", ELV_NAME_MAX)) -+ bfq_bic_change_cgroup(icq_to_bic(icq), -+ css); -+ rcu_read_unlock(); -+ put_io_context(ioc); -+ } -+ } -+} -+ -+static void bfqio_destroy(struct cgroup_subsys_state *css) -+{ -+ struct bfqio_cgroup *bgrp = css_to_bfqio(css); -+ struct hlist_node *tmp; -+ struct bfq_group *bfqg; -+ -+ /* -+ * Since we are destroying the cgroup, there are no more tasks -+ * referencing it, and all the RCU grace periods that may have -+ * referenced it are ended (as the destruction of the parent -+ * cgroup is RCU-safe); bgrp->group_data will not be accessed by -+ * anything else and we don't need any synchronization. -+ */ -+ hlist_for_each_entry_safe(bfqg, tmp, &bgrp->group_data, group_node) -+ bfq_destroy_group(bgrp, bfqg); -+ -+ BUG_ON(!hlist_empty(&bgrp->group_data)); -+ -+ kfree(bgrp); -+} -+ -+static int bfqio_css_online(struct cgroup_subsys_state *css) -+{ -+ struct bfqio_cgroup *bgrp = css_to_bfqio(css); -+ -+ mutex_lock(&bfqio_mutex); -+ bgrp->online = true; -+ mutex_unlock(&bfqio_mutex); -+ -+ return 0; -+} -+ -+static void bfqio_css_offline(struct cgroup_subsys_state *css) -+{ -+ struct bfqio_cgroup *bgrp = css_to_bfqio(css); -+ -+ mutex_lock(&bfqio_mutex); -+ bgrp->online = false; -+ mutex_unlock(&bfqio_mutex); -+} -+ -+struct cgroup_subsys bfqio_cgrp_subsys = { -+ .css_alloc = bfqio_create, -+ .css_online = bfqio_css_online, -+ .css_offline = bfqio_css_offline, -+ .can_attach = bfqio_can_attach, -+ .attach = bfqio_attach, -+ .css_free = bfqio_destroy, -+ .legacy_cftypes = bfqio_files, -+}; -+#else -+static inline void bfq_init_entity(struct bfq_entity *entity, -+ struct bfq_group *bfqg) -+{ -+ entity->weight = entity->new_weight; -+ entity->orig_weight = entity->new_weight; -+ entity->ioprio = entity->new_ioprio; -+ entity->ioprio_class = entity->new_ioprio_class; -+ entity->sched_data = &bfqg->sched_data; -+} -+ -+static inline struct bfq_group * -+bfq_bic_update_cgroup(struct bfq_io_cq *bic) -+{ -+ struct bfq_data *bfqd = bic_to_bfqd(bic); -+ return bfqd->root_group; -+} -+ -+static inline void bfq_bfqq_move(struct bfq_data *bfqd, -+ struct bfq_queue *bfqq, -+ struct bfq_entity *entity, -+ struct bfq_group *bfqg) -+{ -+} -+ -+static void bfq_end_wr_async(struct bfq_data *bfqd) -+{ -+ bfq_end_wr_async_queues(bfqd, bfqd->root_group); -+} -+ -+static inline void bfq_disconnect_groups(struct bfq_data *bfqd) -+{ -+ bfq_put_async_queues(bfqd, bfqd->root_group); -+} -+ -+static inline void bfq_free_root_group(struct bfq_data *bfqd) -+{ -+ kfree(bfqd->root_group); -+} -+ -+static struct bfq_group *bfq_alloc_root_group(struct bfq_data *bfqd, int node) -+{ -+ struct bfq_group *bfqg; -+ int i; -+ -+ bfqg = kmalloc_node(sizeof(*bfqg), GFP_KERNEL | __GFP_ZERO, node); -+ if (bfqg == NULL) -+ return NULL; -+ -+ for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) -+ bfqg->sched_data.service_tree[i] = BFQ_SERVICE_TREE_INIT; -+ -+ return bfqg; -+} -+#endif -diff --git a/block/bfq-ioc.c b/block/bfq-ioc.c -new file mode 100644 -index 0000000..7f6b000 ---- /dev/null -+++ b/block/bfq-ioc.c -@@ -0,0 +1,36 @@ -+/* -+ * BFQ: I/O context handling. -+ * -+ * Based on ideas and code from CFQ: -+ * Copyright (C) 2003 Jens Axboe -+ * -+ * Copyright (C) 2008 Fabio Checconi -+ * Paolo Valente -+ * -+ * Copyright (C) 2010 Paolo Valente -+ */ -+ -+/** -+ * icq_to_bic - convert iocontext queue structure to bfq_io_cq. -+ * @icq: the iocontext queue. -+ */ -+static inline struct bfq_io_cq *icq_to_bic(struct io_cq *icq) -+{ -+ /* bic->icq is the first member, %NULL will convert to %NULL */ -+ return container_of(icq, struct bfq_io_cq, icq); -+} -+ -+/** -+ * bfq_bic_lookup - search into @ioc a bic associated to @bfqd. -+ * @bfqd: the lookup key. -+ * @ioc: the io_context of the process doing I/O. -+ * -+ * Queue lock must be held. -+ */ -+static inline struct bfq_io_cq *bfq_bic_lookup(struct bfq_data *bfqd, -+ struct io_context *ioc) -+{ -+ if (ioc) -+ return icq_to_bic(ioc_lookup_icq(ioc, bfqd->queue)); -+ return NULL; -+} -diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c -new file mode 100644 -index 0000000..97ee934 ---- /dev/null -+++ b/block/bfq-iosched.c -@@ -0,0 +1,3902 @@ -+/* -+ * Budget Fair Queueing (BFQ) disk scheduler. -+ * -+ * Based on ideas and code from CFQ: -+ * Copyright (C) 2003 Jens Axboe -+ * -+ * Copyright (C) 2008 Fabio Checconi -+ * Paolo Valente -+ * -+ * Copyright (C) 2010 Paolo Valente -+ * -+ * Licensed under the GPL-2 as detailed in the accompanying COPYING.BFQ -+ * file. -+ * -+ * BFQ is a proportional-share storage-I/O scheduling algorithm based on -+ * the slice-by-slice service scheme of CFQ. But BFQ assigns budgets, -+ * measured in number of sectors, to processes instead of time slices. The -+ * device is not granted to the in-service process for a given time slice, -+ * but until it has exhausted its assigned budget. This change from the time -+ * to the service domain allows BFQ to distribute the device throughput -+ * among processes as desired, without any distortion due to ZBR, workload -+ * fluctuations or other factors. BFQ uses an ad hoc internal scheduler, -+ * called B-WF2Q+, to schedule processes according to their budgets. More -+ * precisely, BFQ schedules queues associated to processes. Thanks to the -+ * accurate policy of B-WF2Q+, BFQ can afford to assign high budgets to -+ * I/O-bound processes issuing sequential requests (to boost the -+ * throughput), and yet guarantee a low latency to interactive and soft -+ * real-time applications. -+ * -+ * BFQ is described in [1], where also a reference to the initial, more -+ * theoretical paper on BFQ can be found. The interested reader can find -+ * in the latter paper full details on the main algorithm, as well as -+ * formulas of the guarantees and formal proofs of all the properties. -+ * With respect to the version of BFQ presented in these papers, this -+ * implementation adds a few more heuristics, such as the one that -+ * guarantees a low latency to soft real-time applications, and a -+ * hierarchical extension based on H-WF2Q+. -+ * -+ * B-WF2Q+ is based on WF2Q+, that is described in [2], together with -+ * H-WF2Q+, while the augmented tree used to implement B-WF2Q+ with O(log N) -+ * complexity derives from the one introduced with EEVDF in [3]. -+ * -+ * [1] P. Valente and M. Andreolini, ``Improving Application Responsiveness -+ * with the BFQ Disk I/O Scheduler'', -+ * Proceedings of the 5th Annual International Systems and Storage -+ * Conference (SYSTOR '12), June 2012. -+ * -+ * http://algogroup.unimo.it/people/paolo/disk_sched/bf1-v1-suite-results.pdf -+ * -+ * [2] Jon C.R. Bennett and H. Zhang, ``Hierarchical Packet Fair Queueing -+ * Algorithms,'' IEEE/ACM Transactions on Networking, 5(5):675-689, -+ * Oct 1997. -+ * -+ * http://www.cs.cmu.edu/~hzhang/papers/TON-97-Oct.ps.gz -+ * -+ * [3] I. Stoica and H. Abdel-Wahab, ``Earliest Eligible Virtual Deadline -+ * First: A Flexible and Accurate Mechanism for Proportional Share -+ * Resource Allocation,'' technical report. -+ * -+ * http://www.cs.berkeley.edu/~istoica/papers/eevdf-tr-95.pdf -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "bfq.h" -+#include "blk.h" -+ -+/* Max number of dispatches in one round of service. */ -+static const int bfq_quantum = 4; -+ -+/* Expiration time of sync (0) and async (1) requests, in jiffies. */ -+static const int bfq_fifo_expire[2] = { HZ / 4, HZ / 8 }; -+ -+/* Maximum backwards seek, in KiB. */ -+static const int bfq_back_max = 16 * 1024; -+ -+/* Penalty of a backwards seek, in number of sectors. */ -+static const int bfq_back_penalty = 2; -+ -+/* Idling period duration, in jiffies. */ -+static int bfq_slice_idle = HZ / 125; -+ -+/* Default maximum budget values, in sectors and number of requests. */ -+static const int bfq_default_max_budget = 16 * 1024; -+static const int bfq_max_budget_async_rq = 4; -+ -+/* -+ * Async to sync throughput distribution is controlled as follows: -+ * when an async request is served, the entity is charged the number -+ * of sectors of the request, multiplied by the factor below -+ */ -+static const int bfq_async_charge_factor = 10; -+ -+/* Default timeout values, in jiffies, approximating CFQ defaults. */ -+static const int bfq_timeout_sync = HZ / 8; -+static int bfq_timeout_async = HZ / 25; -+ -+struct kmem_cache *bfq_pool; -+ -+/* Below this threshold (in ms), we consider thinktime immediate. */ -+#define BFQ_MIN_TT 2 -+ -+/* hw_tag detection: parallel requests threshold and min samples needed. */ -+#define BFQ_HW_QUEUE_THRESHOLD 4 -+#define BFQ_HW_QUEUE_SAMPLES 32 -+ -+#define BFQQ_SEEK_THR (sector_t)(8 * 1024) -+#define BFQQ_SEEKY(bfqq) ((bfqq)->seek_mean > BFQQ_SEEK_THR) -+ -+/* Min samples used for peak rate estimation (for autotuning). */ -+#define BFQ_PEAK_RATE_SAMPLES 32 -+ -+/* Shift used for peak rate fixed precision calculations. */ -+#define BFQ_RATE_SHIFT 16 -+ -+/* -+ * By default, BFQ computes the duration of the weight raising for -+ * interactive applications automatically, using the following formula: -+ * duration = (R / r) * T, where r is the peak rate of the device, and -+ * R and T are two reference parameters. -+ * In particular, R is the peak rate of the reference device (see below), -+ * and T is a reference time: given the systems that are likely to be -+ * installed on the reference device according to its speed class, T is -+ * about the maximum time needed, under BFQ and while reading two files in -+ * parallel, to load typical large applications on these systems. -+ * In practice, the slower/faster the device at hand is, the more/less it -+ * takes to load applications with respect to the reference device. -+ * Accordingly, the longer/shorter BFQ grants weight raising to interactive -+ * applications. -+ * -+ * BFQ uses four different reference pairs (R, T), depending on: -+ * . whether the device is rotational or non-rotational; -+ * . whether the device is slow, such as old or portable HDDs, as well as -+ * SD cards, or fast, such as newer HDDs and SSDs. -+ * -+ * The device's speed class is dynamically (re)detected in -+ * bfq_update_peak_rate() every time the estimated peak rate is updated. -+ * -+ * In the following definitions, R_slow[0]/R_fast[0] and T_slow[0]/T_fast[0] -+ * are the reference values for a slow/fast rotational device, whereas -+ * R_slow[1]/R_fast[1] and T_slow[1]/T_fast[1] are the reference values for -+ * a slow/fast non-rotational device. Finally, device_speed_thresh are the -+ * thresholds used to switch between speed classes. -+ * Both the reference peak rates and the thresholds are measured in -+ * sectors/usec, left-shifted by BFQ_RATE_SHIFT. -+ */ -+static int R_slow[2] = {1536, 10752}; -+static int R_fast[2] = {17415, 34791}; -+/* -+ * To improve readability, a conversion function is used to initialize the -+ * following arrays, which entails that they can be initialized only in a -+ * function. -+ */ -+static int T_slow[2]; -+static int T_fast[2]; -+static int device_speed_thresh[2]; -+ -+#define BFQ_SERVICE_TREE_INIT ((struct bfq_service_tree) \ -+ { RB_ROOT, RB_ROOT, NULL, NULL, 0, 0 }) -+ -+#define RQ_BIC(rq) ((struct bfq_io_cq *) (rq)->elv.priv[0]) -+#define RQ_BFQQ(rq) ((rq)->elv.priv[1]) -+ -+static inline void bfq_schedule_dispatch(struct bfq_data *bfqd); -+ -+#include "bfq-ioc.c" -+#include "bfq-sched.c" -+#include "bfq-cgroup.c" -+ -+#define bfq_class_idle(bfqq) ((bfqq)->entity.ioprio_class ==\ -+ IOPRIO_CLASS_IDLE) -+#define bfq_class_rt(bfqq) ((bfqq)->entity.ioprio_class ==\ -+ IOPRIO_CLASS_RT) -+ -+#define bfq_sample_valid(samples) ((samples) > 80) -+ -+/* -+ * We regard a request as SYNC, if either it's a read or has the SYNC bit -+ * set (in which case it could also be a direct WRITE). -+ */ -+static inline int bfq_bio_sync(struct bio *bio) -+{ -+ if (bio_data_dir(bio) == READ || (bio->bi_rw & REQ_SYNC)) -+ return 1; -+ -+ return 0; -+} -+ -+/* -+ * Scheduler run of queue, if there are requests pending and no one in the -+ * driver that will restart queueing. -+ */ -+static inline void bfq_schedule_dispatch(struct bfq_data *bfqd) -+{ -+ if (bfqd->queued != 0) { -+ bfq_log(bfqd, "schedule dispatch"); -+ kblockd_schedule_work(&bfqd->unplug_work); -+ } -+} -+ -+/* -+ * Lifted from AS - choose which of rq1 and rq2 that is best served now. -+ * We choose the request that is closesr to the head right now. Distance -+ * behind the head is penalized and only allowed to a certain extent. -+ */ -+static struct request *bfq_choose_req(struct bfq_data *bfqd, -+ struct request *rq1, -+ struct request *rq2, -+ sector_t last) -+{ -+ sector_t s1, s2, d1 = 0, d2 = 0; -+ unsigned long back_max; -+#define BFQ_RQ1_WRAP 0x01 /* request 1 wraps */ -+#define BFQ_RQ2_WRAP 0x02 /* request 2 wraps */ -+ unsigned wrap = 0; /* bit mask: requests behind the disk head? */ -+ -+ if (rq1 == NULL || rq1 == rq2) -+ return rq2; -+ if (rq2 == NULL) -+ return rq1; -+ -+ if (rq_is_sync(rq1) && !rq_is_sync(rq2)) -+ return rq1; -+ else if (rq_is_sync(rq2) && !rq_is_sync(rq1)) -+ return rq2; -+ if ((rq1->cmd_flags & REQ_META) && !(rq2->cmd_flags & REQ_META)) -+ return rq1; -+ else if ((rq2->cmd_flags & REQ_META) && !(rq1->cmd_flags & REQ_META)) -+ return rq2; -+ -+ s1 = blk_rq_pos(rq1); -+ s2 = blk_rq_pos(rq2); -+ -+ /* -+ * By definition, 1KiB is 2 sectors. -+ */ -+ back_max = bfqd->bfq_back_max * 2; -+ -+ /* -+ * Strict one way elevator _except_ in the case where we allow -+ * short backward seeks which are biased as twice the cost of a -+ * similar forward seek. -+ */ -+ if (s1 >= last) -+ d1 = s1 - last; -+ else if (s1 + back_max >= last) -+ d1 = (last - s1) * bfqd->bfq_back_penalty; -+ else -+ wrap |= BFQ_RQ1_WRAP; -+ -+ if (s2 >= last) -+ d2 = s2 - last; -+ else if (s2 + back_max >= last) -+ d2 = (last - s2) * bfqd->bfq_back_penalty; -+ else -+ wrap |= BFQ_RQ2_WRAP; -+ -+ /* Found required data */ -+ -+ /* -+ * By doing switch() on the bit mask "wrap" we avoid having to -+ * check two variables for all permutations: --> faster! -+ */ -+ switch (wrap) { -+ case 0: /* common case for CFQ: rq1 and rq2 not wrapped */ -+ if (d1 < d2) -+ return rq1; -+ else if (d2 < d1) -+ return rq2; -+ else { -+ if (s1 >= s2) -+ return rq1; -+ else -+ return rq2; -+ } -+ -+ case BFQ_RQ2_WRAP: -+ return rq1; -+ case BFQ_RQ1_WRAP: -+ return rq2; -+ case (BFQ_RQ1_WRAP|BFQ_RQ2_WRAP): /* both rqs wrapped */ -+ default: -+ /* -+ * Since both rqs are wrapped, -+ * start with the one that's further behind head -+ * (--> only *one* back seek required), -+ * since back seek takes more time than forward. -+ */ -+ if (s1 <= s2) -+ return rq1; -+ else -+ return rq2; -+ } -+} -+ -+static struct bfq_queue * -+bfq_rq_pos_tree_lookup(struct bfq_data *bfqd, struct rb_root *root, -+ sector_t sector, struct rb_node **ret_parent, -+ struct rb_node ***rb_link) -+{ -+ struct rb_node **p, *parent; -+ struct bfq_queue *bfqq = NULL; -+ -+ parent = NULL; -+ p = &root->rb_node; -+ while (*p) { -+ struct rb_node **n; -+ -+ parent = *p; -+ bfqq = rb_entry(parent, struct bfq_queue, pos_node); -+ -+ /* -+ * Sort strictly based on sector. Smallest to the left, -+ * largest to the right. -+ */ -+ if (sector > blk_rq_pos(bfqq->next_rq)) -+ n = &(*p)->rb_right; -+ else if (sector < blk_rq_pos(bfqq->next_rq)) -+ n = &(*p)->rb_left; -+ else -+ break; -+ p = n; -+ bfqq = NULL; -+ } -+ -+ *ret_parent = parent; -+ if (rb_link) -+ *rb_link = p; -+ -+ bfq_log(bfqd, "rq_pos_tree_lookup %llu: returning %d", -+ (long long unsigned)sector, -+ bfqq != NULL ? bfqq->pid : 0); -+ -+ return bfqq; -+} -+ -+static void bfq_rq_pos_tree_add(struct bfq_data *bfqd, struct bfq_queue *bfqq) -+{ -+ struct rb_node **p, *parent; -+ struct bfq_queue *__bfqq; -+ -+ if (bfqq->pos_root != NULL) { -+ rb_erase(&bfqq->pos_node, bfqq->pos_root); -+ bfqq->pos_root = NULL; -+ } -+ -+ if (bfq_class_idle(bfqq)) -+ return; -+ if (!bfqq->next_rq) -+ return; -+ -+ bfqq->pos_root = &bfqd->rq_pos_tree; -+ __bfqq = bfq_rq_pos_tree_lookup(bfqd, bfqq->pos_root, -+ blk_rq_pos(bfqq->next_rq), &parent, &p); -+ if (__bfqq == NULL) { -+ rb_link_node(&bfqq->pos_node, parent, p); -+ rb_insert_color(&bfqq->pos_node, bfqq->pos_root); -+ } else -+ bfqq->pos_root = NULL; -+} -+ -+/* -+ * Tell whether there are active queues or groups with differentiated weights. -+ */ -+static inline bool bfq_differentiated_weights(struct bfq_data *bfqd) -+{ -+ BUG_ON(!bfqd->hw_tag); -+ /* -+ * For weights to differ, at least one of the trees must contain -+ * at least two nodes. -+ */ -+ return (!RB_EMPTY_ROOT(&bfqd->queue_weights_tree) && -+ (bfqd->queue_weights_tree.rb_node->rb_left || -+ bfqd->queue_weights_tree.rb_node->rb_right) -+#ifdef CONFIG_CGROUP_BFQIO -+ ) || -+ (!RB_EMPTY_ROOT(&bfqd->group_weights_tree) && -+ (bfqd->group_weights_tree.rb_node->rb_left || -+ bfqd->group_weights_tree.rb_node->rb_right) -+#endif -+ ); -+} -+ -+/* -+ * If the weight-counter tree passed as input contains no counter for -+ * the weight of the input entity, then add that counter; otherwise just -+ * increment the existing counter. -+ * -+ * Note that weight-counter trees contain few nodes in mostly symmetric -+ * scenarios. For example, if all queues have the same weight, then the -+ * weight-counter tree for the queues may contain at most one node. -+ * This holds even if low_latency is on, because weight-raised queues -+ * are not inserted in the tree. -+ * In most scenarios, the rate at which nodes are created/destroyed -+ * should be low too. -+ */ -+static void bfq_weights_tree_add(struct bfq_data *bfqd, -+ struct bfq_entity *entity, -+ struct rb_root *root) -+{ -+ struct rb_node **new = &(root->rb_node), *parent = NULL; -+ -+ /* -+ * Do not insert if: -+ * - the device does not support queueing; -+ * - the entity is already associated with a counter, which happens if: -+ * 1) the entity is associated with a queue, 2) a request arrival -+ * has caused the queue to become both non-weight-raised, and hence -+ * change its weight, and backlogged; in this respect, each -+ * of the two events causes an invocation of this function, -+ * 3) this is the invocation of this function caused by the second -+ * event. This second invocation is actually useless, and we handle -+ * this fact by exiting immediately. More efficient or clearer -+ * solutions might possibly be adopted. -+ */ -+ if (!bfqd->hw_tag || entity->weight_counter) -+ return; -+ -+ while (*new) { -+ struct bfq_weight_counter *__counter = container_of(*new, -+ struct bfq_weight_counter, -+ weights_node); -+ parent = *new; -+ -+ if (entity->weight == __counter->weight) { -+ entity->weight_counter = __counter; -+ goto inc_counter; -+ } -+ if (entity->weight < __counter->weight) -+ new = &((*new)->rb_left); -+ else -+ new = &((*new)->rb_right); -+ } -+ -+ entity->weight_counter = kzalloc(sizeof(struct bfq_weight_counter), -+ GFP_ATOMIC); -+ entity->weight_counter->weight = entity->weight; -+ rb_link_node(&entity->weight_counter->weights_node, parent, new); -+ rb_insert_color(&entity->weight_counter->weights_node, root); -+ -+inc_counter: -+ entity->weight_counter->num_active++; -+} -+ -+/* -+ * Decrement the weight counter associated with the entity, and, if the -+ * counter reaches 0, remove the counter from the tree. -+ * See the comments to the function bfq_weights_tree_add() for considerations -+ * about overhead. -+ */ -+static void bfq_weights_tree_remove(struct bfq_data *bfqd, -+ struct bfq_entity *entity, -+ struct rb_root *root) -+{ -+ /* -+ * Check whether the entity is actually associated with a counter. -+ * In fact, the device may not be considered NCQ-capable for a while, -+ * which implies that no insertion in the weight trees is performed, -+ * after which the device may start to be deemed NCQ-capable, and hence -+ * this function may start to be invoked. This may cause the function -+ * to be invoked for entities that are not associated with any counter. -+ */ -+ if (!entity->weight_counter) -+ return; -+ -+ BUG_ON(RB_EMPTY_ROOT(root)); -+ BUG_ON(entity->weight_counter->weight != entity->weight); -+ -+ BUG_ON(!entity->weight_counter->num_active); -+ entity->weight_counter->num_active--; -+ if (entity->weight_counter->num_active > 0) -+ goto reset_entity_pointer; -+ -+ rb_erase(&entity->weight_counter->weights_node, root); -+ kfree(entity->weight_counter); -+ -+reset_entity_pointer: -+ entity->weight_counter = NULL; -+} -+ -+static struct request *bfq_find_next_rq(struct bfq_data *bfqd, -+ struct bfq_queue *bfqq, -+ struct request *last) -+{ -+ struct rb_node *rbnext = rb_next(&last->rb_node); -+ struct rb_node *rbprev = rb_prev(&last->rb_node); -+ struct request *next = NULL, *prev = NULL; -+ -+ BUG_ON(RB_EMPTY_NODE(&last->rb_node)); -+ -+ if (rbprev != NULL) -+ prev = rb_entry_rq(rbprev); -+ -+ if (rbnext != NULL) -+ next = rb_entry_rq(rbnext); -+ else { -+ rbnext = rb_first(&bfqq->sort_list); -+ if (rbnext && rbnext != &last->rb_node) -+ next = rb_entry_rq(rbnext); -+ } -+ -+ return bfq_choose_req(bfqd, next, prev, blk_rq_pos(last)); -+} -+ -+/* see the definition of bfq_async_charge_factor for details */ -+static inline unsigned long bfq_serv_to_charge(struct request *rq, -+ struct bfq_queue *bfqq) -+{ -+ return blk_rq_sectors(rq) * -+ (1 + ((!bfq_bfqq_sync(bfqq)) * (bfqq->wr_coeff == 1) * -+ bfq_async_charge_factor)); -+} -+ -+/** -+ * bfq_updated_next_req - update the queue after a new next_rq selection. -+ * @bfqd: the device data the queue belongs to. -+ * @bfqq: the queue to update. -+ * -+ * If the first request of a queue changes we make sure that the queue -+ * has enough budget to serve at least its first request (if the -+ * request has grown). We do this because if the queue has not enough -+ * budget for its first request, it has to go through two dispatch -+ * rounds to actually get it dispatched. -+ */ -+static void bfq_updated_next_req(struct bfq_data *bfqd, -+ struct bfq_queue *bfqq) -+{ -+ struct bfq_entity *entity = &bfqq->entity; -+ struct bfq_service_tree *st = bfq_entity_service_tree(entity); -+ struct request *next_rq = bfqq->next_rq; -+ unsigned long new_budget; -+ -+ if (next_rq == NULL) -+ return; -+ -+ if (bfqq == bfqd->in_service_queue) -+ /* -+ * In order not to break guarantees, budgets cannot be -+ * changed after an entity has been selected. -+ */ -+ return; -+ -+ BUG_ON(entity->tree != &st->active); -+ BUG_ON(entity == entity->sched_data->in_service_entity); -+ -+ new_budget = max_t(unsigned long, bfqq->max_budget, -+ bfq_serv_to_charge(next_rq, bfqq)); -+ if (entity->budget != new_budget) { -+ entity->budget = new_budget; -+ bfq_log_bfqq(bfqd, bfqq, "updated next rq: new budget %lu", -+ new_budget); -+ bfq_activate_bfqq(bfqd, bfqq); -+ } -+} -+ -+static inline unsigned int bfq_wr_duration(struct bfq_data *bfqd) -+{ -+ u64 dur; -+ -+ if (bfqd->bfq_wr_max_time > 0) -+ return bfqd->bfq_wr_max_time; -+ -+ dur = bfqd->RT_prod; -+ do_div(dur, bfqd->peak_rate); -+ -+ return dur; -+} -+ -+/* Empty burst list and add just bfqq (see comments to bfq_handle_burst) */ -+static inline void bfq_reset_burst_list(struct bfq_data *bfqd, -+ struct bfq_queue *bfqq) -+{ -+ struct bfq_queue *item; -+ struct hlist_node *n; -+ -+ hlist_for_each_entry_safe(item, n, &bfqd->burst_list, burst_list_node) -+ hlist_del_init(&item->burst_list_node); -+ hlist_add_head(&bfqq->burst_list_node, &bfqd->burst_list); -+ bfqd->burst_size = 1; -+} -+ -+/* Add bfqq to the list of queues in current burst (see bfq_handle_burst) */ -+static void bfq_add_to_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq) -+{ -+ /* Increment burst size to take into account also bfqq */ -+ bfqd->burst_size++; -+ -+ if (bfqd->burst_size == bfqd->bfq_large_burst_thresh) { -+ struct bfq_queue *pos, *bfqq_item; -+ struct hlist_node *n; -+ -+ /* -+ * Enough queues have been activated shortly after each -+ * other to consider this burst as large. -+ */ -+ bfqd->large_burst = true; -+ -+ /* -+ * We can now mark all queues in the burst list as -+ * belonging to a large burst. -+ */ -+ hlist_for_each_entry(bfqq_item, &bfqd->burst_list, -+ burst_list_node) -+ bfq_mark_bfqq_in_large_burst(bfqq_item); -+ bfq_mark_bfqq_in_large_burst(bfqq); -+ -+ /* -+ * From now on, and until the current burst finishes, any -+ * new queue being activated shortly after the last queue -+ * was inserted in the burst can be immediately marked as -+ * belonging to a large burst. So the burst list is not -+ * needed any more. Remove it. -+ */ -+ hlist_for_each_entry_safe(pos, n, &bfqd->burst_list, -+ burst_list_node) -+ hlist_del_init(&pos->burst_list_node); -+ } else /* burst not yet large: add bfqq to the burst list */ -+ hlist_add_head(&bfqq->burst_list_node, &bfqd->burst_list); -+} -+ -+/* -+ * If many queues happen to become active shortly after each other, then, -+ * to help the processes associated to these queues get their job done as -+ * soon as possible, it is usually better to not grant either weight-raising -+ * or device idling to these queues. In this comment we describe, firstly, -+ * the reasons why this fact holds, and, secondly, the next function, which -+ * implements the main steps needed to properly mark these queues so that -+ * they can then be treated in a different way. -+ * -+ * As for the terminology, we say that a queue becomes active, i.e., -+ * switches from idle to backlogged, either when it is created (as a -+ * consequence of the arrival of an I/O request), or, if already existing, -+ * when a new request for the queue arrives while the queue is idle. -+ * Bursts of activations, i.e., activations of different queues occurring -+ * shortly after each other, are typically caused by services or applications -+ * that spawn or reactivate many parallel threads/processes. Examples are -+ * systemd during boot or git grep. -+ * -+ * These services or applications benefit mostly from a high throughput: -+ * the quicker the requests of the activated queues are cumulatively served, -+ * the sooner the target job of these queues gets completed. As a consequence, -+ * weight-raising any of these queues, which also implies idling the device -+ * for it, is almost always counterproductive: in most cases it just lowers -+ * throughput. -+ * -+ * On the other hand, a burst of activations may be also caused by the start -+ * of an application that does not consist in a lot of parallel I/O-bound -+ * threads. In fact, with a complex application, the burst may be just a -+ * consequence of the fact that several processes need to be executed to -+ * start-up the application. To start an application as quickly as possible, -+ * the best thing to do is to privilege the I/O related to the application -+ * with respect to all other I/O. Therefore, the best strategy to start as -+ * quickly as possible an application that causes a burst of activations is -+ * to weight-raise all the queues activated during the burst. This is the -+ * exact opposite of the best strategy for the other type of bursts. -+ * -+ * In the end, to take the best action for each of the two cases, the two -+ * types of bursts need to be distinguished. Fortunately, this seems -+ * relatively easy to do, by looking at the sizes of the bursts. In -+ * particular, we found a threshold such that bursts with a larger size -+ * than that threshold are apparently caused only by services or commands -+ * such as systemd or git grep. For brevity, hereafter we call just 'large' -+ * these bursts. BFQ *does not* weight-raise queues whose activations occur -+ * in a large burst. In addition, for each of these queues BFQ performs or -+ * does not perform idling depending on which choice boosts the throughput -+ * most. The exact choice depends on the device and request pattern at -+ * hand. -+ * -+ * Turning back to the next function, it implements all the steps needed -+ * to detect the occurrence of a large burst and to properly mark all the -+ * queues belonging to it (so that they can then be treated in a different -+ * way). This goal is achieved by maintaining a special "burst list" that -+ * holds, temporarily, the queues that belong to the burst in progress. The -+ * list is then used to mark these queues as belonging to a large burst if -+ * the burst does become large. The main steps are the following. -+ * -+ * . when the very first queue is activated, the queue is inserted into the -+ * list (as it could be the first queue in a possible burst) -+ * -+ * . if the current burst has not yet become large, and a queue Q that does -+ * not yet belong to the burst is activated shortly after the last time -+ * at which a new queue entered the burst list, then the function appends -+ * Q to the burst list -+ * -+ * . if, as a consequence of the previous step, the burst size reaches -+ * the large-burst threshold, then -+ * -+ * . all the queues in the burst list are marked as belonging to a -+ * large burst -+ * -+ * . the burst list is deleted; in fact, the burst list already served -+ * its purpose (keeping temporarily track of the queues in a burst, -+ * so as to be able to mark them as belonging to a large burst in the -+ * previous sub-step), and now is not needed any more -+ * -+ * . the device enters a large-burst mode -+ * -+ * . if a queue Q that does not belong to the burst is activated while -+ * the device is in large-burst mode and shortly after the last time -+ * at which a queue either entered the burst list or was marked as -+ * belonging to the current large burst, then Q is immediately marked -+ * as belonging to a large burst. -+ * -+ * . if a queue Q that does not belong to the burst is activated a while -+ * later, i.e., not shortly after, than the last time at which a queue -+ * either entered the burst list or was marked as belonging to the -+ * current large burst, then the current burst is deemed as finished and: -+ * -+ * . the large-burst mode is reset if set -+ * -+ * . the burst list is emptied -+ * -+ * . Q is inserted in the burst list, as Q may be the first queue -+ * in a possible new burst (then the burst list contains just Q -+ * after this step). -+ */ -+static void bfq_handle_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq, -+ bool idle_for_long_time) -+{ -+ /* -+ * If bfqq happened to be activated in a burst, but has been idle -+ * for at least as long as an interactive queue, then we assume -+ * that, in the overall I/O initiated in the burst, the I/O -+ * associated to bfqq is finished. So bfqq does not need to be -+ * treated as a queue belonging to a burst anymore. Accordingly, -+ * we reset bfqq's in_large_burst flag if set, and remove bfqq -+ * from the burst list if it's there. We do not decrement instead -+ * burst_size, because the fact that bfqq does not need to belong -+ * to the burst list any more does not invalidate the fact that -+ * bfqq may have been activated during the current burst. -+ */ -+ if (idle_for_long_time) { -+ hlist_del_init(&bfqq->burst_list_node); -+ bfq_clear_bfqq_in_large_burst(bfqq); -+ } -+ -+ /* -+ * If bfqq is already in the burst list or is part of a large -+ * burst, then there is nothing else to do. -+ */ -+ if (!hlist_unhashed(&bfqq->burst_list_node) || -+ bfq_bfqq_in_large_burst(bfqq)) -+ return; -+ -+ /* -+ * If bfqq's activation happens late enough, then the current -+ * burst is finished, and related data structures must be reset. -+ * -+ * In this respect, consider the special case where bfqq is the very -+ * first queue being activated. In this case, last_ins_in_burst is -+ * not yet significant when we get here. But it is easy to verify -+ * that, whether or not the following condition is true, bfqq will -+ * end up being inserted into the burst list. In particular the -+ * list will happen to contain only bfqq. And this is exactly what -+ * has to happen, as bfqq may be the first queue in a possible -+ * burst. -+ */ -+ if (time_is_before_jiffies(bfqd->last_ins_in_burst + -+ bfqd->bfq_burst_interval)) { -+ bfqd->large_burst = false; -+ bfq_reset_burst_list(bfqd, bfqq); -+ return; -+ } -+ -+ /* -+ * If we get here, then bfqq is being activated shortly after the -+ * last queue. So, if the current burst is also large, we can mark -+ * bfqq as belonging to this large burst immediately. -+ */ -+ if (bfqd->large_burst) { -+ bfq_mark_bfqq_in_large_burst(bfqq); -+ return; -+ } -+ -+ /* -+ * If we get here, then a large-burst state has not yet been -+ * reached, but bfqq is being activated shortly after the last -+ * queue. Then we add bfqq to the burst. -+ */ -+ bfq_add_to_burst(bfqd, bfqq); -+} -+ -+static void bfq_add_request(struct request *rq) -+{ -+ struct bfq_queue *bfqq = RQ_BFQQ(rq); -+ struct bfq_entity *entity = &bfqq->entity; -+ struct bfq_data *bfqd = bfqq->bfqd; -+ struct request *next_rq, *prev; -+ unsigned long old_wr_coeff = bfqq->wr_coeff; -+ bool interactive = false; -+ -+ bfq_log_bfqq(bfqd, bfqq, "add_request %d", rq_is_sync(rq)); -+ bfqq->queued[rq_is_sync(rq)]++; -+ bfqd->queued++; -+ -+ elv_rb_add(&bfqq->sort_list, rq); -+ -+ /* -+ * Check if this request is a better next-serve candidate. -+ */ -+ prev = bfqq->next_rq; -+ next_rq = bfq_choose_req(bfqd, bfqq->next_rq, rq, bfqd->last_position); -+ BUG_ON(next_rq == NULL); -+ bfqq->next_rq = next_rq; -+ -+ /* -+ * Adjust priority tree position, if next_rq changes. -+ */ -+ if (prev != bfqq->next_rq) -+ bfq_rq_pos_tree_add(bfqd, bfqq); -+ -+ if (!bfq_bfqq_busy(bfqq)) { -+ bool soft_rt, -+ idle_for_long_time = time_is_before_jiffies( -+ bfqq->budget_timeout + -+ bfqd->bfq_wr_min_idle_time); -+ -+ if (bfq_bfqq_sync(bfqq)) { -+ bool already_in_burst = -+ !hlist_unhashed(&bfqq->burst_list_node) || -+ bfq_bfqq_in_large_burst(bfqq); -+ bfq_handle_burst(bfqd, bfqq, idle_for_long_time); -+ /* -+ * If bfqq was not already in the current burst, -+ * then, at this point, bfqq either has been -+ * added to the current burst or has caused the -+ * current burst to terminate. In particular, in -+ * the second case, bfqq has become the first -+ * queue in a possible new burst. -+ * In both cases last_ins_in_burst needs to be -+ * moved forward. -+ */ -+ if (!already_in_burst) -+ bfqd->last_ins_in_burst = jiffies; -+ } -+ -+ soft_rt = bfqd->bfq_wr_max_softrt_rate > 0 && -+ !bfq_bfqq_in_large_burst(bfqq) && -+ time_is_before_jiffies(bfqq->soft_rt_next_start); -+ interactive = !bfq_bfqq_in_large_burst(bfqq) && -+ idle_for_long_time; -+ entity->budget = max_t(unsigned long, bfqq->max_budget, -+ bfq_serv_to_charge(next_rq, bfqq)); -+ -+ if (!bfq_bfqq_IO_bound(bfqq)) { -+ if (time_before(jiffies, -+ RQ_BIC(rq)->ttime.last_end_request + -+ bfqd->bfq_slice_idle)) { -+ bfqq->requests_within_timer++; -+ if (bfqq->requests_within_timer >= -+ bfqd->bfq_requests_within_timer) -+ bfq_mark_bfqq_IO_bound(bfqq); -+ } else -+ bfqq->requests_within_timer = 0; -+ } -+ -+ if (!bfqd->low_latency) -+ goto add_bfqq_busy; -+ -+ /* -+ * If the queue is not being boosted and has been idle -+ * for enough time, start a weight-raising period -+ */ -+ if (old_wr_coeff == 1 && (interactive || soft_rt)) { -+ bfqq->wr_coeff = bfqd->bfq_wr_coeff; -+ if (interactive) -+ bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); -+ else -+ bfqq->wr_cur_max_time = -+ bfqd->bfq_wr_rt_max_time; -+ bfq_log_bfqq(bfqd, bfqq, -+ "wrais starting at %lu, rais_max_time %u", -+ jiffies, -+ jiffies_to_msecs(bfqq->wr_cur_max_time)); -+ } else if (old_wr_coeff > 1) { -+ if (interactive) -+ bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); -+ else if (bfq_bfqq_in_large_burst(bfqq) || -+ (bfqq->wr_cur_max_time == -+ bfqd->bfq_wr_rt_max_time && -+ !soft_rt)) { -+ bfqq->wr_coeff = 1; -+ bfq_log_bfqq(bfqd, bfqq, -+ "wrais ending at %lu, rais_max_time %u", -+ jiffies, -+ jiffies_to_msecs(bfqq-> -+ wr_cur_max_time)); -+ } else if (time_before( -+ bfqq->last_wr_start_finish + -+ bfqq->wr_cur_max_time, -+ jiffies + -+ bfqd->bfq_wr_rt_max_time) && -+ soft_rt) { -+ /* -+ * -+ * The remaining weight-raising time is lower -+ * than bfqd->bfq_wr_rt_max_time, which -+ * means that the application is enjoying -+ * weight raising either because deemed soft- -+ * rt in the near past, or because deemed -+ * interactive a long ago. In both cases, -+ * resetting now the current remaining weight- -+ * raising time for the application to the -+ * weight-raising duration for soft rt -+ * applications would not cause any latency -+ * increase for the application (as the new -+ * duration would be higher than the remaining -+ * time). -+ * -+ * In addition, the application is now meeting -+ * the requirements for being deemed soft rt. -+ * In the end we can correctly and safely -+ * (re)charge the weight-raising duration for -+ * the application with the weight-raising -+ * duration for soft rt applications. -+ * -+ * In particular, doing this recharge now, i.e., -+ * before the weight-raising period for the -+ * application finishes, reduces the probability -+ * of the following negative scenario: -+ * 1) the weight of a soft rt application is -+ * raised at startup (as for any newly -+ * created application), -+ * 2) since the application is not interactive, -+ * at a certain time weight-raising is -+ * stopped for the application, -+ * 3) at that time the application happens to -+ * still have pending requests, and hence -+ * is destined to not have a chance to be -+ * deemed soft rt before these requests are -+ * completed (see the comments to the -+ * function bfq_bfqq_softrt_next_start() -+ * for details on soft rt detection), -+ * 4) these pending requests experience a high -+ * latency because the application is not -+ * weight-raised while they are pending. -+ */ -+ bfqq->last_wr_start_finish = jiffies; -+ bfqq->wr_cur_max_time = -+ bfqd->bfq_wr_rt_max_time; -+ } -+ } -+ if (old_wr_coeff != bfqq->wr_coeff) -+ entity->ioprio_changed = 1; -+add_bfqq_busy: -+ bfqq->last_idle_bklogged = jiffies; -+ bfqq->service_from_backlogged = 0; -+ bfq_clear_bfqq_softrt_update(bfqq); -+ bfq_add_bfqq_busy(bfqd, bfqq); -+ } else { -+ if (bfqd->low_latency && old_wr_coeff == 1 && !rq_is_sync(rq) && -+ time_is_before_jiffies( -+ bfqq->last_wr_start_finish + -+ bfqd->bfq_wr_min_inter_arr_async)) { -+ bfqq->wr_coeff = bfqd->bfq_wr_coeff; -+ bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); -+ -+ bfqd->wr_busy_queues++; -+ entity->ioprio_changed = 1; -+ bfq_log_bfqq(bfqd, bfqq, -+ "non-idle wrais starting at %lu, rais_max_time %u", -+ jiffies, -+ jiffies_to_msecs(bfqq->wr_cur_max_time)); -+ } -+ if (prev != bfqq->next_rq) -+ bfq_updated_next_req(bfqd, bfqq); -+ } -+ -+ if (bfqd->low_latency && -+ (old_wr_coeff == 1 || bfqq->wr_coeff == 1 || interactive)) -+ bfqq->last_wr_start_finish = jiffies; -+} -+ -+static struct request *bfq_find_rq_fmerge(struct bfq_data *bfqd, -+ struct bio *bio) -+{ -+ struct task_struct *tsk = current; -+ struct bfq_io_cq *bic; -+ struct bfq_queue *bfqq; -+ -+ bic = bfq_bic_lookup(bfqd, tsk->io_context); -+ if (bic == NULL) -+ return NULL; -+ -+ bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio)); -+ if (bfqq != NULL) -+ return elv_rb_find(&bfqq->sort_list, bio_end_sector(bio)); -+ -+ return NULL; -+} -+ -+static void bfq_activate_request(struct request_queue *q, struct request *rq) -+{ -+ struct bfq_data *bfqd = q->elevator->elevator_data; -+ -+ bfqd->rq_in_driver++; -+ bfqd->last_position = blk_rq_pos(rq) + blk_rq_sectors(rq); -+ bfq_log(bfqd, "activate_request: new bfqd->last_position %llu", -+ (long long unsigned)bfqd->last_position); -+} -+ -+static inline void bfq_deactivate_request(struct request_queue *q, -+ struct request *rq) -+{ -+ struct bfq_data *bfqd = q->elevator->elevator_data; -+ -+ BUG_ON(bfqd->rq_in_driver == 0); -+ bfqd->rq_in_driver--; -+} -+ -+static void bfq_remove_request(struct request *rq) -+{ -+ struct bfq_queue *bfqq = RQ_BFQQ(rq); -+ struct bfq_data *bfqd = bfqq->bfqd; -+ const int sync = rq_is_sync(rq); -+ -+ if (bfqq->next_rq == rq) { -+ bfqq->next_rq = bfq_find_next_rq(bfqd, bfqq, rq); -+ bfq_updated_next_req(bfqd, bfqq); -+ } -+ -+ list_del_init(&rq->queuelist); -+ BUG_ON(bfqq->queued[sync] == 0); -+ bfqq->queued[sync]--; -+ bfqd->queued--; -+ elv_rb_del(&bfqq->sort_list, rq); -+ -+ if (RB_EMPTY_ROOT(&bfqq->sort_list)) { -+ if (bfq_bfqq_busy(bfqq) && bfqq != bfqd->in_service_queue) -+ bfq_del_bfqq_busy(bfqd, bfqq, 1); -+ /* -+ * Remove queue from request-position tree as it is empty. -+ */ -+ if (bfqq->pos_root != NULL) { -+ rb_erase(&bfqq->pos_node, bfqq->pos_root); -+ bfqq->pos_root = NULL; -+ } -+ } -+ -+ if (rq->cmd_flags & REQ_META) { -+ BUG_ON(bfqq->meta_pending == 0); -+ bfqq->meta_pending--; -+ } -+} -+ -+static int bfq_merge(struct request_queue *q, struct request **req, -+ struct bio *bio) -+{ -+ struct bfq_data *bfqd = q->elevator->elevator_data; -+ struct request *__rq; -+ -+ __rq = bfq_find_rq_fmerge(bfqd, bio); -+ if (__rq != NULL && elv_rq_merge_ok(__rq, bio)) { -+ *req = __rq; -+ return ELEVATOR_FRONT_MERGE; -+ } -+ -+ return ELEVATOR_NO_MERGE; -+} -+ -+static void bfq_merged_request(struct request_queue *q, struct request *req, -+ int type) -+{ -+ if (type == ELEVATOR_FRONT_MERGE && -+ rb_prev(&req->rb_node) && -+ blk_rq_pos(req) < -+ blk_rq_pos(container_of(rb_prev(&req->rb_node), -+ struct request, rb_node))) { -+ struct bfq_queue *bfqq = RQ_BFQQ(req); -+ struct bfq_data *bfqd = bfqq->bfqd; -+ struct request *prev, *next_rq; -+ -+ /* Reposition request in its sort_list */ -+ elv_rb_del(&bfqq->sort_list, req); -+ elv_rb_add(&bfqq->sort_list, req); -+ /* Choose next request to be served for bfqq */ -+ prev = bfqq->next_rq; -+ next_rq = bfq_choose_req(bfqd, bfqq->next_rq, req, -+ bfqd->last_position); -+ BUG_ON(next_rq == NULL); -+ bfqq->next_rq = next_rq; -+ /* -+ * If next_rq changes, update both the queue's budget to -+ * fit the new request and the queue's position in its -+ * rq_pos_tree. -+ */ -+ if (prev != bfqq->next_rq) { -+ bfq_updated_next_req(bfqd, bfqq); -+ bfq_rq_pos_tree_add(bfqd, bfqq); -+ } -+ } -+} -+ -+static void bfq_merged_requests(struct request_queue *q, struct request *rq, -+ struct request *next) -+{ -+ struct bfq_queue *bfqq = RQ_BFQQ(rq); -+ -+ /* -+ * Reposition in fifo if next is older than rq. -+ */ -+ if (!list_empty(&rq->queuelist) && !list_empty(&next->queuelist) && -+ time_before(next->fifo_time, rq->fifo_time)) { -+ list_move(&rq->queuelist, &next->queuelist); -+ rq->fifo_time = next->fifo_time; -+ } -+ -+ if (bfqq->next_rq == next) -+ bfqq->next_rq = rq; -+ -+ bfq_remove_request(next); -+} -+ -+/* Must be called with bfqq != NULL */ -+static inline void bfq_bfqq_end_wr(struct bfq_queue *bfqq) -+{ -+ BUG_ON(bfqq == NULL); -+ if (bfq_bfqq_busy(bfqq)) -+ bfqq->bfqd->wr_busy_queues--; -+ bfqq->wr_coeff = 1; -+ bfqq->wr_cur_max_time = 0; -+ /* Trigger a weight change on the next activation of the queue */ -+ bfqq->entity.ioprio_changed = 1; -+} -+ -+static void bfq_end_wr_async_queues(struct bfq_data *bfqd, -+ struct bfq_group *bfqg) -+{ -+ int i, j; -+ -+ for (i = 0; i < 2; i++) -+ for (j = 0; j < IOPRIO_BE_NR; j++) -+ if (bfqg->async_bfqq[i][j] != NULL) -+ bfq_bfqq_end_wr(bfqg->async_bfqq[i][j]); -+ if (bfqg->async_idle_bfqq != NULL) -+ bfq_bfqq_end_wr(bfqg->async_idle_bfqq); -+} -+ -+static void bfq_end_wr(struct bfq_data *bfqd) -+{ -+ struct bfq_queue *bfqq; -+ -+ spin_lock_irq(bfqd->queue->queue_lock); -+ -+ list_for_each_entry(bfqq, &bfqd->active_list, bfqq_list) -+ bfq_bfqq_end_wr(bfqq); -+ list_for_each_entry(bfqq, &bfqd->idle_list, bfqq_list) -+ bfq_bfqq_end_wr(bfqq); -+ bfq_end_wr_async(bfqd); -+ -+ spin_unlock_irq(bfqd->queue->queue_lock); -+} -+ -+static int bfq_allow_merge(struct request_queue *q, struct request *rq, -+ struct bio *bio) -+{ -+ struct bfq_data *bfqd = q->elevator->elevator_data; -+ struct bfq_io_cq *bic; -+ struct bfq_queue *bfqq; -+ -+ /* -+ * Disallow merge of a sync bio into an async request. -+ */ -+ if (bfq_bio_sync(bio) && !rq_is_sync(rq)) -+ return 0; -+ -+ /* -+ * Lookup the bfqq that this bio will be queued with. Allow -+ * merge only if rq is queued there. -+ * Queue lock is held here. -+ */ -+ bic = bfq_bic_lookup(bfqd, current->io_context); -+ if (bic == NULL) -+ return 0; -+ -+ bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio)); -+ return bfqq == RQ_BFQQ(rq); -+} -+ -+static void __bfq_set_in_service_queue(struct bfq_data *bfqd, -+ struct bfq_queue *bfqq) -+{ -+ if (bfqq != NULL) { -+ bfq_mark_bfqq_must_alloc(bfqq); -+ bfq_mark_bfqq_budget_new(bfqq); -+ bfq_clear_bfqq_fifo_expire(bfqq); -+ -+ bfqd->budgets_assigned = (bfqd->budgets_assigned*7 + 256) / 8; -+ -+ bfq_log_bfqq(bfqd, bfqq, -+ "set_in_service_queue, cur-budget = %lu", -+ bfqq->entity.budget); -+ } -+ -+ bfqd->in_service_queue = bfqq; -+} -+ -+/* -+ * Get and set a new queue for service. -+ */ -+static struct bfq_queue *bfq_set_in_service_queue(struct bfq_data *bfqd, -+ struct bfq_queue *bfqq) -+{ -+ if (!bfqq) -+ bfqq = bfq_get_next_queue(bfqd); -+ else -+ bfq_get_next_queue_forced(bfqd, bfqq); -+ -+ __bfq_set_in_service_queue(bfqd, bfqq); -+ return bfqq; -+} -+ -+static inline sector_t bfq_dist_from_last(struct bfq_data *bfqd, -+ struct request *rq) -+{ -+ if (blk_rq_pos(rq) >= bfqd->last_position) -+ return blk_rq_pos(rq) - bfqd->last_position; -+ else -+ return bfqd->last_position - blk_rq_pos(rq); -+} -+ -+/* -+ * Return true if bfqq has no request pending and rq is close enough to -+ * bfqd->last_position, or if rq is closer to bfqd->last_position than -+ * bfqq->next_rq -+ */ -+static inline int bfq_rq_close(struct bfq_data *bfqd, struct request *rq) -+{ -+ return bfq_dist_from_last(bfqd, rq) <= BFQQ_SEEK_THR; -+} -+ -+static struct bfq_queue *bfqq_close(struct bfq_data *bfqd) -+{ -+ struct rb_root *root = &bfqd->rq_pos_tree; -+ struct rb_node *parent, *node; -+ struct bfq_queue *__bfqq; -+ sector_t sector = bfqd->last_position; -+ -+ if (RB_EMPTY_ROOT(root)) -+ return NULL; -+ -+ /* -+ * First, if we find a request starting at the end of the last -+ * request, choose it. -+ */ -+ __bfqq = bfq_rq_pos_tree_lookup(bfqd, root, sector, &parent, NULL); -+ if (__bfqq != NULL) -+ return __bfqq; -+ -+ /* -+ * If the exact sector wasn't found, the parent of the NULL leaf -+ * will contain the closest sector (rq_pos_tree sorted by -+ * next_request position). -+ */ -+ __bfqq = rb_entry(parent, struct bfq_queue, pos_node); -+ if (bfq_rq_close(bfqd, __bfqq->next_rq)) -+ return __bfqq; -+ -+ if (blk_rq_pos(__bfqq->next_rq) < sector) -+ node = rb_next(&__bfqq->pos_node); -+ else -+ node = rb_prev(&__bfqq->pos_node); -+ if (node == NULL) -+ return NULL; -+ -+ __bfqq = rb_entry(node, struct bfq_queue, pos_node); -+ if (bfq_rq_close(bfqd, __bfqq->next_rq)) -+ return __bfqq; -+ -+ return NULL; -+} -+ -+/* -+ * bfqd - obvious -+ * cur_bfqq - passed in so that we don't decide that the current queue -+ * is closely cooperating with itself. -+ * -+ * We are assuming that cur_bfqq has dispatched at least one request, -+ * and that bfqd->last_position reflects a position on the disk associated -+ * with the I/O issued by cur_bfqq. -+ */ -+static struct bfq_queue *bfq_close_cooperator(struct bfq_data *bfqd, -+ struct bfq_queue *cur_bfqq) -+{ -+ struct bfq_queue *bfqq; -+ -+ if (bfq_class_idle(cur_bfqq)) -+ return NULL; -+ if (!bfq_bfqq_sync(cur_bfqq)) -+ return NULL; -+ if (BFQQ_SEEKY(cur_bfqq)) -+ return NULL; -+ -+ /* If device has only one backlogged bfq_queue, don't search. */ -+ if (bfqd->busy_queues == 1) -+ return NULL; -+ -+ /* -+ * We should notice if some of the queues are cooperating, e.g. -+ * working closely on the same area of the disk. In that case, -+ * we can group them together and don't waste time idling. -+ */ -+ bfqq = bfqq_close(bfqd); -+ if (bfqq == NULL || bfqq == cur_bfqq) -+ return NULL; -+ -+ /* -+ * Do not merge queues from different bfq_groups. -+ */ -+ if (bfqq->entity.parent != cur_bfqq->entity.parent) -+ return NULL; -+ -+ /* -+ * It only makes sense to merge sync queues. -+ */ -+ if (!bfq_bfqq_sync(bfqq)) -+ return NULL; -+ if (BFQQ_SEEKY(bfqq)) -+ return NULL; -+ -+ /* -+ * Do not merge queues of different priority classes. -+ */ -+ if (bfq_class_rt(bfqq) != bfq_class_rt(cur_bfqq)) -+ return NULL; -+ -+ return bfqq; -+} -+ -+/* -+ * If enough samples have been computed, return the current max budget -+ * stored in bfqd, which is dynamically updated according to the -+ * estimated disk peak rate; otherwise return the default max budget -+ */ -+static inline unsigned long bfq_max_budget(struct bfq_data *bfqd) -+{ -+ if (bfqd->budgets_assigned < 194) -+ return bfq_default_max_budget; -+ else -+ return bfqd->bfq_max_budget; -+} -+ -+/* -+ * Return min budget, which is a fraction of the current or default -+ * max budget (trying with 1/32) -+ */ -+static inline unsigned long bfq_min_budget(struct bfq_data *bfqd) -+{ -+ if (bfqd->budgets_assigned < 194) -+ return bfq_default_max_budget / 32; -+ else -+ return bfqd->bfq_max_budget / 32; -+} -+ -+static void bfq_arm_slice_timer(struct bfq_data *bfqd) -+{ -+ struct bfq_queue *bfqq = bfqd->in_service_queue; -+ struct bfq_io_cq *bic; -+ unsigned long sl; -+ -+ BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list)); -+ -+ /* Processes have exited, don't wait. */ -+ bic = bfqd->in_service_bic; -+ if (bic == NULL || atomic_read(&bic->icq.ioc->active_ref) == 0) -+ return; -+ -+ bfq_mark_bfqq_wait_request(bfqq); -+ -+ /* -+ * We don't want to idle for seeks, but we do want to allow -+ * fair distribution of slice time for a process doing back-to-back -+ * seeks. So allow a little bit of time for him to submit a new rq. -+ * -+ * To prevent processes with (partly) seeky workloads from -+ * being too ill-treated, grant them a small fraction of the -+ * assigned budget before reducing the waiting time to -+ * BFQ_MIN_TT. This happened to help reduce latency. -+ */ -+ sl = bfqd->bfq_slice_idle; -+ /* -+ * Unless the queue is being weight-raised, grant only minimum idle -+ * time if the queue either has been seeky for long enough or has -+ * already proved to be constantly seeky. -+ */ -+ if (bfq_sample_valid(bfqq->seek_samples) && -+ ((BFQQ_SEEKY(bfqq) && bfqq->entity.service > -+ bfq_max_budget(bfqq->bfqd) / 8) || -+ bfq_bfqq_constantly_seeky(bfqq)) && bfqq->wr_coeff == 1) -+ sl = min(sl, msecs_to_jiffies(BFQ_MIN_TT)); -+ else if (bfqq->wr_coeff > 1) -+ sl = sl * 3; -+ bfqd->last_idling_start = ktime_get(); -+ mod_timer(&bfqd->idle_slice_timer, jiffies + sl); -+ bfq_log(bfqd, "arm idle: %u/%u ms", -+ jiffies_to_msecs(sl), jiffies_to_msecs(bfqd->bfq_slice_idle)); -+} -+ -+/* -+ * Set the maximum time for the in-service queue to consume its -+ * budget. This prevents seeky processes from lowering the disk -+ * throughput (always guaranteed with a time slice scheme as in CFQ). -+ */ -+static void bfq_set_budget_timeout(struct bfq_data *bfqd) -+{ -+ struct bfq_queue *bfqq = bfqd->in_service_queue; -+ unsigned int timeout_coeff; -+ if (bfqq->wr_cur_max_time == bfqd->bfq_wr_rt_max_time) -+ timeout_coeff = 1; -+ else -+ timeout_coeff = bfqq->entity.weight / bfqq->entity.orig_weight; -+ -+ bfqd->last_budget_start = ktime_get(); -+ -+ bfq_clear_bfqq_budget_new(bfqq); -+ bfqq->budget_timeout = jiffies + -+ bfqd->bfq_timeout[bfq_bfqq_sync(bfqq)] * timeout_coeff; -+ -+ bfq_log_bfqq(bfqd, bfqq, "set budget_timeout %u", -+ jiffies_to_msecs(bfqd->bfq_timeout[bfq_bfqq_sync(bfqq)] * -+ timeout_coeff)); -+} -+ -+/* -+ * Move request from internal lists to the request queue dispatch list. -+ */ -+static void bfq_dispatch_insert(struct request_queue *q, struct request *rq) -+{ -+ struct bfq_data *bfqd = q->elevator->elevator_data; -+ struct bfq_queue *bfqq = RQ_BFQQ(rq); -+ -+ /* -+ * For consistency, the next instruction should have been executed -+ * after removing the request from the queue and dispatching it. -+ * We execute instead this instruction before bfq_remove_request() -+ * (and hence introduce a temporary inconsistency), for efficiency. -+ * In fact, in a forced_dispatch, this prevents two counters related -+ * to bfqq->dispatched to risk to be uselessly decremented if bfqq -+ * is not in service, and then to be incremented again after -+ * incrementing bfqq->dispatched. -+ */ -+ bfqq->dispatched++; -+ bfq_remove_request(rq); -+ elv_dispatch_sort(q, rq); -+ -+ if (bfq_bfqq_sync(bfqq)) -+ bfqd->sync_flight++; -+} -+ -+/* -+ * Return expired entry, or NULL to just start from scratch in rbtree. -+ */ -+static struct request *bfq_check_fifo(struct bfq_queue *bfqq) -+{ -+ struct request *rq = NULL; -+ -+ if (bfq_bfqq_fifo_expire(bfqq)) -+ return NULL; -+ -+ bfq_mark_bfqq_fifo_expire(bfqq); -+ -+ if (list_empty(&bfqq->fifo)) -+ return NULL; -+ -+ rq = rq_entry_fifo(bfqq->fifo.next); -+ -+ if (time_before(jiffies, rq->fifo_time)) -+ return NULL; -+ -+ return rq; -+} -+ -+/* Must be called with the queue_lock held. */ -+static int bfqq_process_refs(struct bfq_queue *bfqq) -+{ -+ int process_refs, io_refs; -+ -+ io_refs = bfqq->allocated[READ] + bfqq->allocated[WRITE]; -+ process_refs = atomic_read(&bfqq->ref) - io_refs - bfqq->entity.on_st; -+ BUG_ON(process_refs < 0); -+ return process_refs; -+} -+ -+static void bfq_setup_merge(struct bfq_queue *bfqq, struct bfq_queue *new_bfqq) -+{ -+ int process_refs, new_process_refs; -+ struct bfq_queue *__bfqq; -+ -+ /* -+ * If there are no process references on the new_bfqq, then it is -+ * unsafe to follow the ->new_bfqq chain as other bfqq's in the chain -+ * may have dropped their last reference (not just their last process -+ * reference). -+ */ -+ if (!bfqq_process_refs(new_bfqq)) -+ return; -+ -+ /* Avoid a circular list and skip interim queue merges. */ -+ while ((__bfqq = new_bfqq->new_bfqq)) { -+ if (__bfqq == bfqq) -+ return; -+ new_bfqq = __bfqq; -+ } -+ -+ process_refs = bfqq_process_refs(bfqq); -+ new_process_refs = bfqq_process_refs(new_bfqq); -+ /* -+ * If the process for the bfqq has gone away, there is no -+ * sense in merging the queues. -+ */ -+ if (process_refs == 0 || new_process_refs == 0) -+ return; -+ -+ /* -+ * Merge in the direction of the lesser amount of work. -+ */ -+ if (new_process_refs >= process_refs) { -+ bfqq->new_bfqq = new_bfqq; -+ atomic_add(process_refs, &new_bfqq->ref); -+ } else { -+ new_bfqq->new_bfqq = bfqq; -+ atomic_add(new_process_refs, &bfqq->ref); -+ } -+ bfq_log_bfqq(bfqq->bfqd, bfqq, "scheduling merge with queue %d", -+ new_bfqq->pid); -+} -+ -+static inline unsigned long bfq_bfqq_budget_left(struct bfq_queue *bfqq) -+{ -+ struct bfq_entity *entity = &bfqq->entity; -+ return entity->budget - entity->service; -+} -+ -+static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq) -+{ -+ BUG_ON(bfqq != bfqd->in_service_queue); -+ -+ __bfq_bfqd_reset_in_service(bfqd); -+ -+ /* -+ * If this bfqq is shared between multiple processes, check -+ * to make sure that those processes are still issuing I/Os -+ * within the mean seek distance. If not, it may be time to -+ * break the queues apart again. -+ */ -+ if (bfq_bfqq_coop(bfqq) && BFQQ_SEEKY(bfqq)) -+ bfq_mark_bfqq_split_coop(bfqq); -+ -+ if (RB_EMPTY_ROOT(&bfqq->sort_list)) { -+ /* -+ * Overloading budget_timeout field to store the time -+ * at which the queue remains with no backlog; used by -+ * the weight-raising mechanism. -+ */ -+ bfqq->budget_timeout = jiffies; -+ bfq_del_bfqq_busy(bfqd, bfqq, 1); -+ } else { -+ bfq_activate_bfqq(bfqd, bfqq); -+ /* -+ * Resort priority tree of potential close cooperators. -+ */ -+ bfq_rq_pos_tree_add(bfqd, bfqq); -+ } -+} -+ -+/** -+ * __bfq_bfqq_recalc_budget - try to adapt the budget to the @bfqq behavior. -+ * @bfqd: device data. -+ * @bfqq: queue to update. -+ * @reason: reason for expiration. -+ * -+ * Handle the feedback on @bfqq budget. See the body for detailed -+ * comments. -+ */ -+static void __bfq_bfqq_recalc_budget(struct bfq_data *bfqd, -+ struct bfq_queue *bfqq, -+ enum bfqq_expiration reason) -+{ -+ struct request *next_rq; -+ unsigned long budget, min_budget; -+ -+ budget = bfqq->max_budget; -+ min_budget = bfq_min_budget(bfqd); -+ -+ BUG_ON(bfqq != bfqd->in_service_queue); -+ -+ bfq_log_bfqq(bfqd, bfqq, "recalc_budg: last budg %lu, budg left %lu", -+ bfqq->entity.budget, bfq_bfqq_budget_left(bfqq)); -+ bfq_log_bfqq(bfqd, bfqq, "recalc_budg: last max_budg %lu, min budg %lu", -+ budget, bfq_min_budget(bfqd)); -+ bfq_log_bfqq(bfqd, bfqq, "recalc_budg: sync %d, seeky %d", -+ bfq_bfqq_sync(bfqq), BFQQ_SEEKY(bfqd->in_service_queue)); -+ -+ if (bfq_bfqq_sync(bfqq)) { -+ switch (reason) { -+ /* -+ * Caveat: in all the following cases we trade latency -+ * for throughput. -+ */ -+ case BFQ_BFQQ_TOO_IDLE: -+ /* -+ * This is the only case where we may reduce -+ * the budget: if there is no request of the -+ * process still waiting for completion, then -+ * we assume (tentatively) that the timer has -+ * expired because the batch of requests of -+ * the process could have been served with a -+ * smaller budget. Hence, betting that -+ * process will behave in the same way when it -+ * becomes backlogged again, we reduce its -+ * next budget. As long as we guess right, -+ * this budget cut reduces the latency -+ * experienced by the process. -+ * -+ * However, if there are still outstanding -+ * requests, then the process may have not yet -+ * issued its next request just because it is -+ * still waiting for the completion of some of -+ * the still outstanding ones. So in this -+ * subcase we do not reduce its budget, on the -+ * contrary we increase it to possibly boost -+ * the throughput, as discussed in the -+ * comments to the BUDGET_TIMEOUT case. -+ */ -+ if (bfqq->dispatched > 0) /* still outstanding reqs */ -+ budget = min(budget * 2, bfqd->bfq_max_budget); -+ else { -+ if (budget > 5 * min_budget) -+ budget -= 4 * min_budget; -+ else -+ budget = min_budget; -+ } -+ break; -+ case BFQ_BFQQ_BUDGET_TIMEOUT: -+ /* -+ * We double the budget here because: 1) it -+ * gives the chance to boost the throughput if -+ * this is not a seeky process (which may have -+ * bumped into this timeout because of, e.g., -+ * ZBR), 2) together with charge_full_budget -+ * it helps give seeky processes higher -+ * timestamps, and hence be served less -+ * frequently. -+ */ -+ budget = min(budget * 2, bfqd->bfq_max_budget); -+ break; -+ case BFQ_BFQQ_BUDGET_EXHAUSTED: -+ /* -+ * The process still has backlog, and did not -+ * let either the budget timeout or the disk -+ * idling timeout expire. Hence it is not -+ * seeky, has a short thinktime and may be -+ * happy with a higher budget too. So -+ * definitely increase the budget of this good -+ * candidate to boost the disk throughput. -+ */ -+ budget = min(budget * 4, bfqd->bfq_max_budget); -+ break; -+ case BFQ_BFQQ_NO_MORE_REQUESTS: -+ /* -+ * Leave the budget unchanged. -+ */ -+ default: -+ return; -+ } -+ } else /* async queue */ -+ /* async queues get always the maximum possible budget -+ * (their ability to dispatch is limited by -+ * @bfqd->bfq_max_budget_async_rq). -+ */ -+ budget = bfqd->bfq_max_budget; -+ -+ bfqq->max_budget = budget; -+ -+ if (bfqd->budgets_assigned >= 194 && bfqd->bfq_user_max_budget == 0 && -+ bfqq->max_budget > bfqd->bfq_max_budget) -+ bfqq->max_budget = bfqd->bfq_max_budget; -+ -+ /* -+ * Make sure that we have enough budget for the next request. -+ * Since the finish time of the bfqq must be kept in sync with -+ * the budget, be sure to call __bfq_bfqq_expire() after the -+ * update. -+ */ -+ next_rq = bfqq->next_rq; -+ if (next_rq != NULL) -+ bfqq->entity.budget = max_t(unsigned long, bfqq->max_budget, -+ bfq_serv_to_charge(next_rq, bfqq)); -+ else -+ bfqq->entity.budget = bfqq->max_budget; -+ -+ bfq_log_bfqq(bfqd, bfqq, "head sect: %u, new budget %lu", -+ next_rq != NULL ? blk_rq_sectors(next_rq) : 0, -+ bfqq->entity.budget); -+} -+ -+static unsigned long bfq_calc_max_budget(u64 peak_rate, u64 timeout) -+{ -+ unsigned long max_budget; -+ -+ /* -+ * The max_budget calculated when autotuning is equal to the -+ * amount of sectors transfered in timeout_sync at the -+ * estimated peak rate. -+ */ -+ max_budget = (unsigned long)(peak_rate * 1000 * -+ timeout >> BFQ_RATE_SHIFT); -+ -+ return max_budget; -+} -+ -+/* -+ * In addition to updating the peak rate, checks whether the process -+ * is "slow", and returns 1 if so. This slow flag is used, in addition -+ * to the budget timeout, to reduce the amount of service provided to -+ * seeky processes, and hence reduce their chances to lower the -+ * throughput. See the code for more details. -+ */ -+static int bfq_update_peak_rate(struct bfq_data *bfqd, struct bfq_queue *bfqq, -+ int compensate, enum bfqq_expiration reason) -+{ -+ u64 bw, usecs, expected, timeout; -+ ktime_t delta; -+ int update = 0; -+ -+ if (!bfq_bfqq_sync(bfqq) || bfq_bfqq_budget_new(bfqq)) -+ return 0; -+ -+ if (compensate) -+ delta = bfqd->last_idling_start; -+ else -+ delta = ktime_get(); -+ delta = ktime_sub(delta, bfqd->last_budget_start); -+ usecs = ktime_to_us(delta); -+ -+ /* Don't trust short/unrealistic values. */ -+ if (usecs < 100 || usecs >= LONG_MAX) -+ return 0; -+ -+ /* -+ * Calculate the bandwidth for the last slice. We use a 64 bit -+ * value to store the peak rate, in sectors per usec in fixed -+ * point math. We do so to have enough precision in the estimate -+ * and to avoid overflows. -+ */ -+ bw = (u64)bfqq->entity.service << BFQ_RATE_SHIFT; -+ do_div(bw, (unsigned long)usecs); -+ -+ timeout = jiffies_to_msecs(bfqd->bfq_timeout[BLK_RW_SYNC]); -+ -+ /* -+ * Use only long (> 20ms) intervals to filter out spikes for -+ * the peak rate estimation. -+ */ -+ if (usecs > 20000) { -+ if (bw > bfqd->peak_rate || -+ (!BFQQ_SEEKY(bfqq) && -+ reason == BFQ_BFQQ_BUDGET_TIMEOUT)) { -+ bfq_log(bfqd, "measured bw =%llu", bw); -+ /* -+ * To smooth oscillations use a low-pass filter with -+ * alpha=7/8, i.e., -+ * new_rate = (7/8) * old_rate + (1/8) * bw -+ */ -+ do_div(bw, 8); -+ if (bw == 0) -+ return 0; -+ bfqd->peak_rate *= 7; -+ do_div(bfqd->peak_rate, 8); -+ bfqd->peak_rate += bw; -+ update = 1; -+ bfq_log(bfqd, "new peak_rate=%llu", bfqd->peak_rate); -+ } -+ -+ update |= bfqd->peak_rate_samples == BFQ_PEAK_RATE_SAMPLES - 1; -+ -+ if (bfqd->peak_rate_samples < BFQ_PEAK_RATE_SAMPLES) -+ bfqd->peak_rate_samples++; -+ -+ if (bfqd->peak_rate_samples == BFQ_PEAK_RATE_SAMPLES && -+ update) { -+ int dev_type = blk_queue_nonrot(bfqd->queue); -+ if (bfqd->bfq_user_max_budget == 0) { -+ bfqd->bfq_max_budget = -+ bfq_calc_max_budget(bfqd->peak_rate, -+ timeout); -+ bfq_log(bfqd, "new max_budget=%lu", -+ bfqd->bfq_max_budget); -+ } -+ if (bfqd->device_speed == BFQ_BFQD_FAST && -+ bfqd->peak_rate < device_speed_thresh[dev_type]) { -+ bfqd->device_speed = BFQ_BFQD_SLOW; -+ bfqd->RT_prod = R_slow[dev_type] * -+ T_slow[dev_type]; -+ } else if (bfqd->device_speed == BFQ_BFQD_SLOW && -+ bfqd->peak_rate > device_speed_thresh[dev_type]) { -+ bfqd->device_speed = BFQ_BFQD_FAST; -+ bfqd->RT_prod = R_fast[dev_type] * -+ T_fast[dev_type]; -+ } -+ } -+ } -+ -+ /* -+ * If the process has been served for a too short time -+ * interval to let its possible sequential accesses prevail on -+ * the initial seek time needed to move the disk head on the -+ * first sector it requested, then give the process a chance -+ * and for the moment return false. -+ */ -+ if (bfqq->entity.budget <= bfq_max_budget(bfqd) / 8) -+ return 0; -+ -+ /* -+ * A process is considered ``slow'' (i.e., seeky, so that we -+ * cannot treat it fairly in the service domain, as it would -+ * slow down too much the other processes) if, when a slice -+ * ends for whatever reason, it has received service at a -+ * rate that would not be high enough to complete the budget -+ * before the budget timeout expiration. -+ */ -+ expected = bw * 1000 * timeout >> BFQ_RATE_SHIFT; -+ -+ /* -+ * Caveat: processes doing IO in the slower disk zones will -+ * tend to be slow(er) even if not seeky. And the estimated -+ * peak rate will actually be an average over the disk -+ * surface. Hence, to not be too harsh with unlucky processes, -+ * we keep a budget/3 margin of safety before declaring a -+ * process slow. -+ */ -+ return expected > (4 * bfqq->entity.budget) / 3; -+} -+ -+/* -+ * To be deemed as soft real-time, an application must meet two -+ * requirements. First, the application must not require an average -+ * bandwidth higher than the approximate bandwidth required to playback or -+ * record a compressed high-definition video. -+ * The next function is invoked on the completion of the last request of a -+ * batch, to compute the next-start time instant, soft_rt_next_start, such -+ * that, if the next request of the application does not arrive before -+ * soft_rt_next_start, then the above requirement on the bandwidth is met. -+ * -+ * The second requirement is that the request pattern of the application is -+ * isochronous, i.e., that, after issuing a request or a batch of requests, -+ * the application stops issuing new requests until all its pending requests -+ * have been completed. After that, the application may issue a new batch, -+ * and so on. -+ * For this reason the next function is invoked to compute -+ * soft_rt_next_start only for applications that meet this requirement, -+ * whereas soft_rt_next_start is set to infinity for applications that do -+ * not. -+ * -+ * Unfortunately, even a greedy application may happen to behave in an -+ * isochronous way if the CPU load is high. In fact, the application may -+ * stop issuing requests while the CPUs are busy serving other processes, -+ * then restart, then stop again for a while, and so on. In addition, if -+ * the disk achieves a low enough throughput with the request pattern -+ * issued by the application (e.g., because the request pattern is random -+ * and/or the device is slow), then the application may meet the above -+ * bandwidth requirement too. To prevent such a greedy application to be -+ * deemed as soft real-time, a further rule is used in the computation of -+ * soft_rt_next_start: soft_rt_next_start must be higher than the current -+ * time plus the maximum time for which the arrival of a request is waited -+ * for when a sync queue becomes idle, namely bfqd->bfq_slice_idle. -+ * This filters out greedy applications, as the latter issue instead their -+ * next request as soon as possible after the last one has been completed -+ * (in contrast, when a batch of requests is completed, a soft real-time -+ * application spends some time processing data). -+ * -+ * Unfortunately, the last filter may easily generate false positives if -+ * only bfqd->bfq_slice_idle is used as a reference time interval and one -+ * or both the following cases occur: -+ * 1) HZ is so low that the duration of a jiffy is comparable to or higher -+ * than bfqd->bfq_slice_idle. This happens, e.g., on slow devices with -+ * HZ=100. -+ * 2) jiffies, instead of increasing at a constant rate, may stop increasing -+ * for a while, then suddenly 'jump' by several units to recover the lost -+ * increments. This seems to happen, e.g., inside virtual machines. -+ * To address this issue, we do not use as a reference time interval just -+ * bfqd->bfq_slice_idle, but bfqd->bfq_slice_idle plus a few jiffies. In -+ * particular we add the minimum number of jiffies for which the filter -+ * seems to be quite precise also in embedded systems and KVM/QEMU virtual -+ * machines. -+ */ -+static inline unsigned long bfq_bfqq_softrt_next_start(struct bfq_data *bfqd, -+ struct bfq_queue *bfqq) -+{ -+ return max(bfqq->last_idle_bklogged + -+ HZ * bfqq->service_from_backlogged / -+ bfqd->bfq_wr_max_softrt_rate, -+ jiffies + bfqq->bfqd->bfq_slice_idle + 4); -+} -+ -+/* -+ * Return the largest-possible time instant such that, for as long as possible, -+ * the current time will be lower than this time instant according to the macro -+ * time_is_before_jiffies(). -+ */ -+static inline unsigned long bfq_infinity_from_now(unsigned long now) -+{ -+ return now + ULONG_MAX / 2; -+} -+ -+/** -+ * bfq_bfqq_expire - expire a queue. -+ * @bfqd: device owning the queue. -+ * @bfqq: the queue to expire. -+ * @compensate: if true, compensate for the time spent idling. -+ * @reason: the reason causing the expiration. -+ * -+ * -+ * If the process associated to the queue is slow (i.e., seeky), or in -+ * case of budget timeout, or, finally, if it is async, we -+ * artificially charge it an entire budget (independently of the -+ * actual service it received). As a consequence, the queue will get -+ * higher timestamps than the correct ones upon reactivation, and -+ * hence it will be rescheduled as if it had received more service -+ * than what it actually received. In the end, this class of processes -+ * will receive less service in proportion to how slowly they consume -+ * their budgets (and hence how seriously they tend to lower the -+ * throughput). -+ * -+ * In contrast, when a queue expires because it has been idling for -+ * too much or because it exhausted its budget, we do not touch the -+ * amount of service it has received. Hence when the queue will be -+ * reactivated and its timestamps updated, the latter will be in sync -+ * with the actual service received by the queue until expiration. -+ * -+ * Charging a full budget to the first type of queues and the exact -+ * service to the others has the effect of using the WF2Q+ policy to -+ * schedule the former on a timeslice basis, without violating the -+ * service domain guarantees of the latter. -+ */ -+static void bfq_bfqq_expire(struct bfq_data *bfqd, -+ struct bfq_queue *bfqq, -+ int compensate, -+ enum bfqq_expiration reason) -+{ -+ int slow; -+ BUG_ON(bfqq != bfqd->in_service_queue); -+ -+ /* Update disk peak rate for autotuning and check whether the -+ * process is slow (see bfq_update_peak_rate). -+ */ -+ slow = bfq_update_peak_rate(bfqd, bfqq, compensate, reason); -+ -+ /* -+ * As above explained, 'punish' slow (i.e., seeky), timed-out -+ * and async queues, to favor sequential sync workloads. -+ * -+ * Processes doing I/O in the slower disk zones will tend to be -+ * slow(er) even if not seeky. Hence, since the estimated peak -+ * rate is actually an average over the disk surface, these -+ * processes may timeout just for bad luck. To avoid punishing -+ * them we do not charge a full budget to a process that -+ * succeeded in consuming at least 2/3 of its budget. -+ */ -+ if (slow || (reason == BFQ_BFQQ_BUDGET_TIMEOUT && -+ bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3)) -+ bfq_bfqq_charge_full_budget(bfqq); -+ -+ bfqq->service_from_backlogged += bfqq->entity.service; -+ -+ if (BFQQ_SEEKY(bfqq) && reason == BFQ_BFQQ_BUDGET_TIMEOUT && -+ !bfq_bfqq_constantly_seeky(bfqq)) { -+ bfq_mark_bfqq_constantly_seeky(bfqq); -+ if (!blk_queue_nonrot(bfqd->queue)) -+ bfqd->const_seeky_busy_in_flight_queues++; -+ } -+ -+ if (reason == BFQ_BFQQ_TOO_IDLE && -+ bfqq->entity.service <= 2 * bfqq->entity.budget / 10 ) -+ bfq_clear_bfqq_IO_bound(bfqq); -+ -+ if (bfqd->low_latency && bfqq->wr_coeff == 1) -+ bfqq->last_wr_start_finish = jiffies; -+ -+ if (bfqd->low_latency && bfqd->bfq_wr_max_softrt_rate > 0 && -+ RB_EMPTY_ROOT(&bfqq->sort_list)) { -+ /* -+ * If we get here, and there are no outstanding requests, -+ * then the request pattern is isochronous (see the comments -+ * to the function bfq_bfqq_softrt_next_start()). Hence we -+ * can compute soft_rt_next_start. If, instead, the queue -+ * still has outstanding requests, then we have to wait -+ * for the completion of all the outstanding requests to -+ * discover whether the request pattern is actually -+ * isochronous. -+ */ -+ if (bfqq->dispatched == 0) -+ bfqq->soft_rt_next_start = -+ bfq_bfqq_softrt_next_start(bfqd, bfqq); -+ else { -+ /* -+ * The application is still waiting for the -+ * completion of one or more requests: -+ * prevent it from possibly being incorrectly -+ * deemed as soft real-time by setting its -+ * soft_rt_next_start to infinity. In fact, -+ * without this assignment, the application -+ * would be incorrectly deemed as soft -+ * real-time if: -+ * 1) it issued a new request before the -+ * completion of all its in-flight -+ * requests, and -+ * 2) at that time, its soft_rt_next_start -+ * happened to be in the past. -+ */ -+ bfqq->soft_rt_next_start = -+ bfq_infinity_from_now(jiffies); -+ /* -+ * Schedule an update of soft_rt_next_start to when -+ * the task may be discovered to be isochronous. -+ */ -+ bfq_mark_bfqq_softrt_update(bfqq); -+ } -+ } -+ -+ bfq_log_bfqq(bfqd, bfqq, -+ "expire (%d, slow %d, num_disp %d, idle_win %d)", reason, -+ slow, bfqq->dispatched, bfq_bfqq_idle_window(bfqq)); -+ -+ /* -+ * Increase, decrease or leave budget unchanged according to -+ * reason. -+ */ -+ __bfq_bfqq_recalc_budget(bfqd, bfqq, reason); -+ __bfq_bfqq_expire(bfqd, bfqq); -+} -+ -+/* -+ * Budget timeout is not implemented through a dedicated timer, but -+ * just checked on request arrivals and completions, as well as on -+ * idle timer expirations. -+ */ -+static int bfq_bfqq_budget_timeout(struct bfq_queue *bfqq) -+{ -+ if (bfq_bfqq_budget_new(bfqq) || -+ time_before(jiffies, bfqq->budget_timeout)) -+ return 0; -+ return 1; -+} -+ -+/* -+ * If we expire a queue that is waiting for the arrival of a new -+ * request, we may prevent the fictitious timestamp back-shifting that -+ * allows the guarantees of the queue to be preserved (see [1] for -+ * this tricky aspect). Hence we return true only if this condition -+ * does not hold, or if the queue is slow enough to deserve only to be -+ * kicked off for preserving a high throughput. -+*/ -+static inline int bfq_may_expire_for_budg_timeout(struct bfq_queue *bfqq) -+{ -+ bfq_log_bfqq(bfqq->bfqd, bfqq, -+ "may_budget_timeout: wait_request %d left %d timeout %d", -+ bfq_bfqq_wait_request(bfqq), -+ bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3, -+ bfq_bfqq_budget_timeout(bfqq)); -+ -+ return (!bfq_bfqq_wait_request(bfqq) || -+ bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3) -+ && -+ bfq_bfqq_budget_timeout(bfqq); -+} -+ -+/* -+ * Device idling is allowed only for the queues for which this function -+ * returns true. For this reason, the return value of this function plays a -+ * critical role for both throughput boosting and service guarantees. The -+ * return value is computed through a logical expression. In this rather -+ * long comment, we try to briefly describe all the details and motivations -+ * behind the components of this logical expression. -+ * -+ * First, the expression is false if bfqq is not sync, or if: bfqq happened -+ * to become active during a large burst of queue activations, and the -+ * pattern of requests bfqq contains boosts the throughput if bfqq is -+ * expired. In fact, queues that became active during a large burst benefit -+ * only from throughput, as discussed in the comments to bfq_handle_burst. -+ * In this respect, expiring bfqq certainly boosts the throughput on NCQ- -+ * capable flash-based devices, whereas, on rotational devices, it boosts -+ * the throughput only if bfqq contains random requests. -+ * -+ * On the opposite end, if (a) bfqq is sync, (b) the above burst-related -+ * condition does not hold, and (c) bfqq is being weight-raised, then the -+ * expression always evaluates to true, as device idling is instrumental -+ * for preserving low-latency guarantees (see [1]). If, instead, conditions -+ * (a) and (b) do hold, but (c) does not, then the expression evaluates to -+ * true only if: (1) bfqq is I/O-bound and has a non-null idle window, and -+ * (2) at least one of the following two conditions holds. -+ * The first condition is that the device is not performing NCQ, because -+ * idling the device most certainly boosts the throughput if this condition -+ * holds and bfqq is I/O-bound and has been granted a non-null idle window. -+ * The second compound condition is made of the logical AND of two components. -+ * -+ * The first component is true only if there is no weight-raised busy -+ * queue. This guarantees that the device is not idled for a sync non- -+ * weight-raised queue when there are busy weight-raised queues. The former -+ * is then expired immediately if empty. Combined with the timestamping -+ * rules of BFQ (see [1] for details), this causes sync non-weight-raised -+ * queues to get a lower number of requests served, and hence to ask for a -+ * lower number of requests from the request pool, before the busy weight- -+ * raised queues get served again. -+ * -+ * This is beneficial for the processes associated with weight-raised -+ * queues, when the request pool is saturated (e.g., in the presence of -+ * write hogs). In fact, if the processes associated with the other queues -+ * ask for requests at a lower rate, then weight-raised processes have a -+ * higher probability to get a request from the pool immediately (or at -+ * least soon) when they need one. Hence they have a higher probability to -+ * actually get a fraction of the disk throughput proportional to their -+ * high weight. This is especially true with NCQ-capable drives, which -+ * enqueue several requests in advance and further reorder internally- -+ * queued requests. -+ * -+ * In the end, mistreating non-weight-raised queues when there are busy -+ * weight-raised queues seems to mitigate starvation problems in the -+ * presence of heavy write workloads and NCQ, and hence to guarantee a -+ * higher application and system responsiveness in these hostile scenarios. -+ * -+ * If the first component of the compound condition is instead true, i.e., -+ * there is no weight-raised busy queue, then the second component of the -+ * compound condition takes into account service-guarantee and throughput -+ * issues related to NCQ (recall that the compound condition is evaluated -+ * only if the device is detected as supporting NCQ). -+ * -+ * As for service guarantees, allowing the drive to enqueue more than one -+ * request at a time, and hence delegating de facto final scheduling -+ * decisions to the drive's internal scheduler, causes loss of control on -+ * the actual request service order. In this respect, when the drive is -+ * allowed to enqueue more than one request at a time, the service -+ * distribution enforced by the drive's internal scheduler is likely to -+ * coincide with the desired device-throughput distribution only in the -+ * following, perfectly symmetric, scenario: -+ * 1) all active queues have the same weight, -+ * 2) all active groups at the same level in the groups tree have the same -+ * weight, -+ * 3) all active groups at the same level in the groups tree have the same -+ * number of children. -+ * -+ * Even in such a scenario, sequential I/O may still receive a preferential -+ * treatment, but this is not likely to be a big issue with flash-based -+ * devices, because of their non-dramatic loss of throughput with random -+ * I/O. Things do differ with HDDs, for which additional care is taken, as -+ * explained after completing the discussion for flash-based devices. -+ * -+ * Unfortunately, keeping the necessary state for evaluating exactly the -+ * above symmetry conditions would be quite complex and time-consuming. -+ * Therefore BFQ evaluates instead the following stronger sub-conditions, -+ * for which it is much easier to maintain the needed state: -+ * 1) all active queues have the same weight, -+ * 2) all active groups have the same weight, -+ * 3) all active groups have at most one active child each. -+ * In particular, the last two conditions are always true if hierarchical -+ * support and the cgroups interface are not enabled, hence no state needs -+ * to be maintained in this case. -+ * -+ * According to the above considerations, the second component of the -+ * compound condition evaluates to true if any of the above symmetry -+ * sub-condition does not hold, or the device is not flash-based. Therefore, -+ * if also the first component is true, then idling is allowed for a sync -+ * queue. These are the only sub-conditions considered if the device is -+ * flash-based, as, for such a device, it is sensible to force idling only -+ * for service-guarantee issues. In fact, as for throughput, idling -+ * NCQ-capable flash-based devices would not boost the throughput even -+ * with sequential I/O; rather it would lower the throughput in proportion -+ * to how fast the device is. In the end, (only) if all the three -+ * sub-conditions hold and the device is flash-based, the compound -+ * condition evaluates to false and therefore no idling is performed. -+ * -+ * As already said, things change with a rotational device, where idling -+ * boosts the throughput with sequential I/O (even with NCQ). Hence, for -+ * such a device the second component of the compound condition evaluates -+ * to true also if the following additional sub-condition does not hold: -+ * the queue is constantly seeky. Unfortunately, this different behavior -+ * with respect to flash-based devices causes an additional asymmetry: if -+ * some sync queues enjoy idling and some other sync queues do not, then -+ * the latter get a low share of the device throughput, simply because the -+ * former get many requests served after being set as in service, whereas -+ * the latter do not. As a consequence, to guarantee the desired throughput -+ * distribution, on HDDs the compound expression evaluates to true (and -+ * hence device idling is performed) also if the following last symmetry -+ * condition does not hold: no other queue is benefiting from idling. Also -+ * this last condition is actually replaced with a simpler-to-maintain and -+ * stronger condition: there is no busy queue which is not constantly seeky -+ * (and hence may also benefit from idling). -+ * -+ * To sum up, when all the required symmetry and throughput-boosting -+ * sub-conditions hold, the second component of the compound condition -+ * evaluates to false, and hence no idling is performed. This helps to -+ * keep the drives' internal queues full on NCQ-capable devices, and hence -+ * to boost the throughput, without causing 'almost' any loss of service -+ * guarantees. The 'almost' follows from the fact that, if the internal -+ * queue of one such device is filled while all the sub-conditions hold, -+ * but at some point in time some sub-condition stops to hold, then it may -+ * become impossible to let requests be served in the new desired order -+ * until all the requests already queued in the device have been served. -+ */ -+static inline bool bfq_bfqq_must_not_expire(struct bfq_queue *bfqq) -+{ -+ struct bfq_data *bfqd = bfqq->bfqd; -+#ifdef CONFIG_CGROUP_BFQIO -+#define symmetric_scenario (!bfqd->active_numerous_groups && \ -+ !bfq_differentiated_weights(bfqd)) -+#else -+#define symmetric_scenario (!bfq_differentiated_weights(bfqd)) -+#endif -+#define cond_for_seeky_on_ncq_hdd (bfq_bfqq_constantly_seeky(bfqq) && \ -+ bfqd->busy_in_flight_queues == \ -+ bfqd->const_seeky_busy_in_flight_queues) -+ -+#define cond_for_expiring_in_burst (bfq_bfqq_in_large_burst(bfqq) && \ -+ bfqd->hw_tag && \ -+ (blk_queue_nonrot(bfqd->queue) || \ -+ bfq_bfqq_constantly_seeky(bfqq))) -+ -+/* -+ * Condition for expiring a non-weight-raised queue (and hence not idling -+ * the device). -+ */ -+#define cond_for_expiring_non_wr (bfqd->hw_tag && \ -+ (bfqd->wr_busy_queues > 0 || \ -+ (symmetric_scenario && \ -+ (blk_queue_nonrot(bfqd->queue) || \ -+ cond_for_seeky_on_ncq_hdd)))) -+ -+ return bfq_bfqq_sync(bfqq) && -+ !cond_for_expiring_in_burst && -+ (bfqq->wr_coeff > 1 || -+ (bfq_bfqq_IO_bound(bfqq) && bfq_bfqq_idle_window(bfqq) && -+ !cond_for_expiring_non_wr) -+ ); -+} -+ -+/* -+ * If the in-service queue is empty but sync, and the function -+ * bfq_bfqq_must_not_expire returns true, then: -+ * 1) the queue must remain in service and cannot be expired, and -+ * 2) the disk must be idled to wait for the possible arrival of a new -+ * request for the queue. -+ * See the comments to the function bfq_bfqq_must_not_expire for the reasons -+ * why performing device idling is the best choice to boost the throughput -+ * and preserve service guarantees when bfq_bfqq_must_not_expire itself -+ * returns true. -+ */ -+static inline bool bfq_bfqq_must_idle(struct bfq_queue *bfqq) -+{ -+ struct bfq_data *bfqd = bfqq->bfqd; -+ -+ return RB_EMPTY_ROOT(&bfqq->sort_list) && bfqd->bfq_slice_idle != 0 && -+ bfq_bfqq_must_not_expire(bfqq); -+} -+ -+/* -+ * Select a queue for service. If we have a current queue in service, -+ * check whether to continue servicing it, or retrieve and set a new one. -+ */ -+static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd) -+{ -+ struct bfq_queue *bfqq, *new_bfqq = NULL; -+ struct request *next_rq; -+ enum bfqq_expiration reason = BFQ_BFQQ_BUDGET_TIMEOUT; -+ -+ bfqq = bfqd->in_service_queue; -+ if (bfqq == NULL) -+ goto new_queue; -+ -+ bfq_log_bfqq(bfqd, bfqq, "select_queue: already in-service queue"); -+ -+ /* -+ * If another queue has a request waiting within our mean seek -+ * distance, let it run. The expire code will check for close -+ * cooperators and put the close queue at the front of the -+ * service tree. If possible, merge the expiring queue with the -+ * new bfqq. -+ */ -+ new_bfqq = bfq_close_cooperator(bfqd, bfqq); -+ if (new_bfqq != NULL && bfqq->new_bfqq == NULL) -+ bfq_setup_merge(bfqq, new_bfqq); -+ -+ if (bfq_may_expire_for_budg_timeout(bfqq) && -+ !timer_pending(&bfqd->idle_slice_timer) && -+ !bfq_bfqq_must_idle(bfqq)) -+ goto expire; -+ -+ next_rq = bfqq->next_rq; -+ /* -+ * If bfqq has requests queued and it has enough budget left to -+ * serve them, keep the queue, otherwise expire it. -+ */ -+ if (next_rq != NULL) { -+ if (bfq_serv_to_charge(next_rq, bfqq) > -+ bfq_bfqq_budget_left(bfqq)) { -+ reason = BFQ_BFQQ_BUDGET_EXHAUSTED; -+ goto expire; -+ } else { -+ /* -+ * The idle timer may be pending because we may -+ * not disable disk idling even when a new request -+ * arrives. -+ */ -+ if (timer_pending(&bfqd->idle_slice_timer)) { -+ /* -+ * If we get here: 1) at least a new request -+ * has arrived but we have not disabled the -+ * timer because the request was too small, -+ * 2) then the block layer has unplugged -+ * the device, causing the dispatch to be -+ * invoked. -+ * -+ * Since the device is unplugged, now the -+ * requests are probably large enough to -+ * provide a reasonable throughput. -+ * So we disable idling. -+ */ -+ bfq_clear_bfqq_wait_request(bfqq); -+ del_timer(&bfqd->idle_slice_timer); -+ } -+ if (new_bfqq == NULL) -+ goto keep_queue; -+ else -+ goto expire; -+ } -+ } -+ -+ /* -+ * No requests pending. If the in-service queue still has requests -+ * in flight (possibly waiting for a completion) or is idling for a -+ * new request, then keep it. -+ */ -+ if (new_bfqq == NULL && (timer_pending(&bfqd->idle_slice_timer) || -+ (bfqq->dispatched != 0 && bfq_bfqq_must_not_expire(bfqq)))) { -+ bfqq = NULL; -+ goto keep_queue; -+ } else if (new_bfqq != NULL && timer_pending(&bfqd->idle_slice_timer)) { -+ /* -+ * Expiring the queue because there is a close cooperator, -+ * cancel timer. -+ */ -+ bfq_clear_bfqq_wait_request(bfqq); -+ del_timer(&bfqd->idle_slice_timer); -+ } -+ -+ reason = BFQ_BFQQ_NO_MORE_REQUESTS; -+expire: -+ bfq_bfqq_expire(bfqd, bfqq, 0, reason); -+new_queue: -+ bfqq = bfq_set_in_service_queue(bfqd, new_bfqq); -+ bfq_log(bfqd, "select_queue: new queue %d returned", -+ bfqq != NULL ? bfqq->pid : 0); -+keep_queue: -+ return bfqq; -+} -+ -+static void bfq_update_wr_data(struct bfq_data *bfqd, -+ struct bfq_queue *bfqq) -+{ -+ if (bfqq->wr_coeff > 1) { /* queue is being boosted */ -+ struct bfq_entity *entity = &bfqq->entity; -+ -+ bfq_log_bfqq(bfqd, bfqq, -+ "raising period dur %u/%u msec, old coeff %u, w %d(%d)", -+ jiffies_to_msecs(jiffies - -+ bfqq->last_wr_start_finish), -+ jiffies_to_msecs(bfqq->wr_cur_max_time), -+ bfqq->wr_coeff, -+ bfqq->entity.weight, bfqq->entity.orig_weight); -+ -+ BUG_ON(bfqq != bfqd->in_service_queue && entity->weight != -+ entity->orig_weight * bfqq->wr_coeff); -+ if (entity->ioprio_changed) -+ bfq_log_bfqq(bfqd, bfqq, "WARN: pending prio change"); -+ /* -+ * If the queue was activated in a burst, or -+ * too much time has elapsed from the beginning -+ * of this weight-raising, then end weight raising. -+ */ -+ if (bfq_bfqq_in_large_burst(bfqq) || -+ time_is_before_jiffies(bfqq->last_wr_start_finish + -+ bfqq->wr_cur_max_time)) { -+ bfqq->last_wr_start_finish = jiffies; -+ bfq_log_bfqq(bfqd, bfqq, -+ "wrais ending at %lu, rais_max_time %u", -+ bfqq->last_wr_start_finish, -+ jiffies_to_msecs(bfqq->wr_cur_max_time)); -+ bfq_bfqq_end_wr(bfqq); -+ __bfq_entity_update_weight_prio( -+ bfq_entity_service_tree(entity), -+ entity); -+ } -+ } -+} -+ -+/* -+ * Dispatch one request from bfqq, moving it to the request queue -+ * dispatch list. -+ */ -+static int bfq_dispatch_request(struct bfq_data *bfqd, -+ struct bfq_queue *bfqq) -+{ -+ int dispatched = 0; -+ struct request *rq; -+ unsigned long service_to_charge; -+ -+ BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list)); -+ -+ /* Follow expired path, else get first next available. */ -+ rq = bfq_check_fifo(bfqq); -+ if (rq == NULL) -+ rq = bfqq->next_rq; -+ service_to_charge = bfq_serv_to_charge(rq, bfqq); -+ -+ if (service_to_charge > bfq_bfqq_budget_left(bfqq)) { -+ /* -+ * This may happen if the next rq is chosen in fifo order -+ * instead of sector order. The budget is properly -+ * dimensioned to be always sufficient to serve the next -+ * request only if it is chosen in sector order. The reason -+ * is that it would be quite inefficient and little useful -+ * to always make sure that the budget is large enough to -+ * serve even the possible next rq in fifo order. -+ * In fact, requests are seldom served in fifo order. -+ * -+ * Expire the queue for budget exhaustion, and make sure -+ * that the next act_budget is enough to serve the next -+ * request, even if it comes from the fifo expired path. -+ */ -+ bfqq->next_rq = rq; -+ /* -+ * Since this dispatch is failed, make sure that -+ * a new one will be performed -+ */ -+ if (!bfqd->rq_in_driver) -+ bfq_schedule_dispatch(bfqd); -+ goto expire; -+ } -+ -+ /* Finally, insert request into driver dispatch list. */ -+ bfq_bfqq_served(bfqq, service_to_charge); -+ bfq_dispatch_insert(bfqd->queue, rq); -+ -+ bfq_update_wr_data(bfqd, bfqq); -+ -+ bfq_log_bfqq(bfqd, bfqq, -+ "dispatched %u sec req (%llu), budg left %lu", -+ blk_rq_sectors(rq), -+ (long long unsigned)blk_rq_pos(rq), -+ bfq_bfqq_budget_left(bfqq)); -+ -+ dispatched++; -+ -+ if (bfqd->in_service_bic == NULL) { -+ atomic_long_inc(&RQ_BIC(rq)->icq.ioc->refcount); -+ bfqd->in_service_bic = RQ_BIC(rq); -+ } -+ -+ if (bfqd->busy_queues > 1 && ((!bfq_bfqq_sync(bfqq) && -+ dispatched >= bfqd->bfq_max_budget_async_rq) || -+ bfq_class_idle(bfqq))) -+ goto expire; -+ -+ return dispatched; -+ -+expire: -+ bfq_bfqq_expire(bfqd, bfqq, 0, BFQ_BFQQ_BUDGET_EXHAUSTED); -+ return dispatched; -+} -+ -+static int __bfq_forced_dispatch_bfqq(struct bfq_queue *bfqq) -+{ -+ int dispatched = 0; -+ -+ while (bfqq->next_rq != NULL) { -+ bfq_dispatch_insert(bfqq->bfqd->queue, bfqq->next_rq); -+ dispatched++; -+ } -+ -+ BUG_ON(!list_empty(&bfqq->fifo)); -+ return dispatched; -+} -+ -+/* -+ * Drain our current requests. -+ * Used for barriers and when switching io schedulers on-the-fly. -+ */ -+static int bfq_forced_dispatch(struct bfq_data *bfqd) -+{ -+ struct bfq_queue *bfqq, *n; -+ struct bfq_service_tree *st; -+ int dispatched = 0; -+ -+ bfqq = bfqd->in_service_queue; -+ if (bfqq != NULL) -+ __bfq_bfqq_expire(bfqd, bfqq); -+ -+ /* -+ * Loop through classes, and be careful to leave the scheduler -+ * in a consistent state, as feedback mechanisms and vtime -+ * updates cannot be disabled during the process. -+ */ -+ list_for_each_entry_safe(bfqq, n, &bfqd->active_list, bfqq_list) { -+ st = bfq_entity_service_tree(&bfqq->entity); -+ -+ dispatched += __bfq_forced_dispatch_bfqq(bfqq); -+ bfqq->max_budget = bfq_max_budget(bfqd); -+ -+ bfq_forget_idle(st); -+ } -+ -+ BUG_ON(bfqd->busy_queues != 0); -+ -+ return dispatched; -+} -+ -+static int bfq_dispatch_requests(struct request_queue *q, int force) -+{ -+ struct bfq_data *bfqd = q->elevator->elevator_data; -+ struct bfq_queue *bfqq; -+ int max_dispatch; -+ -+ bfq_log(bfqd, "dispatch requests: %d busy queues", bfqd->busy_queues); -+ if (bfqd->busy_queues == 0) -+ return 0; -+ -+ if (unlikely(force)) -+ return bfq_forced_dispatch(bfqd); -+ -+ bfqq = bfq_select_queue(bfqd); -+ if (bfqq == NULL) -+ return 0; -+ -+ max_dispatch = bfqd->bfq_quantum; -+ if (bfq_class_idle(bfqq)) -+ max_dispatch = 1; -+ -+ if (!bfq_bfqq_sync(bfqq)) -+ max_dispatch = bfqd->bfq_max_budget_async_rq; -+ -+ if (bfqq->dispatched >= max_dispatch) { -+ if (bfqd->busy_queues > 1) -+ return 0; -+ if (bfqq->dispatched >= 4 * max_dispatch) -+ return 0; -+ } -+ -+ if (bfqd->sync_flight != 0 && !bfq_bfqq_sync(bfqq)) -+ return 0; -+ -+ bfq_clear_bfqq_wait_request(bfqq); -+ BUG_ON(timer_pending(&bfqd->idle_slice_timer)); -+ -+ if (!bfq_dispatch_request(bfqd, bfqq)) -+ return 0; -+ -+ bfq_log_bfqq(bfqd, bfqq, "dispatched one request of %d (max_disp %d)", -+ bfqq->pid, max_dispatch); -+ -+ return 1; -+} -+ -+/* -+ * Task holds one reference to the queue, dropped when task exits. Each rq -+ * in-flight on this queue also holds a reference, dropped when rq is freed. -+ * -+ * Queue lock must be held here. -+ */ -+static void bfq_put_queue(struct bfq_queue *bfqq) -+{ -+ struct bfq_data *bfqd = bfqq->bfqd; -+ -+ BUG_ON(atomic_read(&bfqq->ref) <= 0); -+ -+ bfq_log_bfqq(bfqd, bfqq, "put_queue: %p %d", bfqq, -+ atomic_read(&bfqq->ref)); -+ if (!atomic_dec_and_test(&bfqq->ref)) -+ return; -+ -+ BUG_ON(rb_first(&bfqq->sort_list) != NULL); -+ BUG_ON(bfqq->allocated[READ] + bfqq->allocated[WRITE] != 0); -+ BUG_ON(bfqq->entity.tree != NULL); -+ BUG_ON(bfq_bfqq_busy(bfqq)); -+ BUG_ON(bfqd->in_service_queue == bfqq); -+ -+ if (bfq_bfqq_sync(bfqq)) -+ /* -+ * The fact that this queue is being destroyed does not -+ * invalidate the fact that this queue may have been -+ * activated during the current burst. As a consequence, -+ * although the queue does not exist anymore, and hence -+ * needs to be removed from the burst list if there, -+ * the burst size has not to be decremented. -+ */ -+ hlist_del_init(&bfqq->burst_list_node); -+ -+ bfq_log_bfqq(bfqd, bfqq, "put_queue: %p freed", bfqq); -+ -+ kmem_cache_free(bfq_pool, bfqq); -+} -+ -+static void bfq_put_cooperator(struct bfq_queue *bfqq) -+{ -+ struct bfq_queue *__bfqq, *next; -+ -+ /* -+ * If this queue was scheduled to merge with another queue, be -+ * sure to drop the reference taken on that queue (and others in -+ * the merge chain). See bfq_setup_merge and bfq_merge_bfqqs. -+ */ -+ __bfqq = bfqq->new_bfqq; -+ while (__bfqq) { -+ if (__bfqq == bfqq) -+ break; -+ next = __bfqq->new_bfqq; -+ bfq_put_queue(__bfqq); -+ __bfqq = next; -+ } -+} -+ -+static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq) -+{ -+ if (bfqq == bfqd->in_service_queue) { -+ __bfq_bfqq_expire(bfqd, bfqq); -+ bfq_schedule_dispatch(bfqd); -+ } -+ -+ bfq_log_bfqq(bfqd, bfqq, "exit_bfqq: %p, %d", bfqq, -+ atomic_read(&bfqq->ref)); -+ -+ bfq_put_cooperator(bfqq); -+ -+ bfq_put_queue(bfqq); -+} -+ -+static inline void bfq_init_icq(struct io_cq *icq) -+{ -+ struct bfq_io_cq *bic = icq_to_bic(icq); -+ -+ bic->ttime.last_end_request = jiffies; -+} -+ -+static void bfq_exit_icq(struct io_cq *icq) -+{ -+ struct bfq_io_cq *bic = icq_to_bic(icq); -+ struct bfq_data *bfqd = bic_to_bfqd(bic); -+ -+ if (bic->bfqq[BLK_RW_ASYNC]) { -+ bfq_exit_bfqq(bfqd, bic->bfqq[BLK_RW_ASYNC]); -+ bic->bfqq[BLK_RW_ASYNC] = NULL; -+ } -+ -+ if (bic->bfqq[BLK_RW_SYNC]) { -+ bfq_exit_bfqq(bfqd, bic->bfqq[BLK_RW_SYNC]); -+ bic->bfqq[BLK_RW_SYNC] = NULL; -+ } -+} -+ -+/* -+ * Update the entity prio values; note that the new values will not -+ * be used until the next (re)activation. -+ */ -+static void bfq_init_prio_data(struct bfq_queue *bfqq, struct bfq_io_cq *bic) -+{ -+ struct task_struct *tsk = current; -+ int ioprio_class; -+ -+ if (!bfq_bfqq_prio_changed(bfqq)) -+ return; -+ -+ ioprio_class = IOPRIO_PRIO_CLASS(bic->ioprio); -+ switch (ioprio_class) { -+ default: -+ dev_err(bfqq->bfqd->queue->backing_dev_info.dev, -+ "bfq: bad prio class %d\n", ioprio_class); -+ case IOPRIO_CLASS_NONE: -+ /* -+ * No prio set, inherit CPU scheduling settings. -+ */ -+ bfqq->entity.new_ioprio = task_nice_ioprio(tsk); -+ bfqq->entity.new_ioprio_class = task_nice_ioclass(tsk); -+ break; -+ case IOPRIO_CLASS_RT: -+ bfqq->entity.new_ioprio = IOPRIO_PRIO_DATA(bic->ioprio); -+ bfqq->entity.new_ioprio_class = IOPRIO_CLASS_RT; -+ break; -+ case IOPRIO_CLASS_BE: -+ bfqq->entity.new_ioprio = IOPRIO_PRIO_DATA(bic->ioprio); -+ bfqq->entity.new_ioprio_class = IOPRIO_CLASS_BE; -+ break; -+ case IOPRIO_CLASS_IDLE: -+ bfqq->entity.new_ioprio_class = IOPRIO_CLASS_IDLE; -+ bfqq->entity.new_ioprio = 7; -+ bfq_clear_bfqq_idle_window(bfqq); -+ break; -+ } -+ -+ if (bfqq->entity.new_ioprio < 0 || -+ bfqq->entity.new_ioprio >= IOPRIO_BE_NR) { -+ printk(KERN_CRIT "bfq_init_prio_data: new_ioprio %d\n", -+ bfqq->entity.new_ioprio); -+ BUG(); -+ } -+ -+ bfqq->entity.ioprio_changed = 1; -+ -+ bfq_clear_bfqq_prio_changed(bfqq); -+} -+ -+static void bfq_changed_ioprio(struct bfq_io_cq *bic) -+{ -+ struct bfq_data *bfqd; -+ struct bfq_queue *bfqq, *new_bfqq; -+ struct bfq_group *bfqg; -+ unsigned long uninitialized_var(flags); -+ int ioprio = bic->icq.ioc->ioprio; -+ -+ bfqd = bfq_get_bfqd_locked(&(bic->icq.q->elevator->elevator_data), -+ &flags); -+ /* -+ * This condition may trigger on a newly created bic, be sure to -+ * drop the lock before returning. -+ */ -+ if (unlikely(bfqd == NULL) || likely(bic->ioprio == ioprio)) -+ goto out; -+ -+ bfqq = bic->bfqq[BLK_RW_ASYNC]; -+ if (bfqq != NULL) { -+ bfqg = container_of(bfqq->entity.sched_data, struct bfq_group, -+ sched_data); -+ new_bfqq = bfq_get_queue(bfqd, bfqg, BLK_RW_ASYNC, bic, -+ GFP_ATOMIC); -+ if (new_bfqq != NULL) { -+ bic->bfqq[BLK_RW_ASYNC] = new_bfqq; -+ bfq_log_bfqq(bfqd, bfqq, -+ "changed_ioprio: bfqq %p %d", -+ bfqq, atomic_read(&bfqq->ref)); -+ bfq_put_queue(bfqq); -+ } -+ } -+ -+ bfqq = bic->bfqq[BLK_RW_SYNC]; -+ if (bfqq != NULL) -+ bfq_mark_bfqq_prio_changed(bfqq); -+ -+ bic->ioprio = ioprio; -+ -+out: -+ bfq_put_bfqd_unlock(bfqd, &flags); -+} -+ -+static void bfq_init_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, -+ pid_t pid, int is_sync) -+{ -+ RB_CLEAR_NODE(&bfqq->entity.rb_node); -+ INIT_LIST_HEAD(&bfqq->fifo); -+ INIT_HLIST_NODE(&bfqq->burst_list_node); -+ -+ atomic_set(&bfqq->ref, 0); -+ bfqq->bfqd = bfqd; -+ -+ bfq_mark_bfqq_prio_changed(bfqq); -+ -+ if (is_sync) { -+ if (!bfq_class_idle(bfqq)) -+ bfq_mark_bfqq_idle_window(bfqq); -+ bfq_mark_bfqq_sync(bfqq); -+ } -+ bfq_mark_bfqq_IO_bound(bfqq); -+ -+ /* Tentative initial value to trade off between thr and lat */ -+ bfqq->max_budget = (2 * bfq_max_budget(bfqd)) / 3; -+ bfqq->pid = pid; -+ -+ bfqq->wr_coeff = 1; -+ bfqq->last_wr_start_finish = 0; -+ /* -+ * Set to the value for which bfqq will not be deemed as -+ * soft rt when it becomes backlogged. -+ */ -+ bfqq->soft_rt_next_start = bfq_infinity_from_now(jiffies); -+} -+ -+static struct bfq_queue *bfq_find_alloc_queue(struct bfq_data *bfqd, -+ struct bfq_group *bfqg, -+ int is_sync, -+ struct bfq_io_cq *bic, -+ gfp_t gfp_mask) -+{ -+ struct bfq_queue *bfqq, *new_bfqq = NULL; -+ -+retry: -+ /* bic always exists here */ -+ bfqq = bic_to_bfqq(bic, is_sync); -+ -+ /* -+ * Always try a new alloc if we fall back to the OOM bfqq -+ * originally, since it should just be a temporary situation. -+ */ -+ if (bfqq == NULL || bfqq == &bfqd->oom_bfqq) { -+ bfqq = NULL; -+ if (new_bfqq != NULL) { -+ bfqq = new_bfqq; -+ new_bfqq = NULL; -+ } else if (gfp_mask & __GFP_WAIT) { -+ spin_unlock_irq(bfqd->queue->queue_lock); -+ new_bfqq = kmem_cache_alloc_node(bfq_pool, -+ gfp_mask | __GFP_ZERO, -+ bfqd->queue->node); -+ spin_lock_irq(bfqd->queue->queue_lock); -+ if (new_bfqq != NULL) -+ goto retry; -+ } else { -+ bfqq = kmem_cache_alloc_node(bfq_pool, -+ gfp_mask | __GFP_ZERO, -+ bfqd->queue->node); -+ } -+ -+ if (bfqq != NULL) { -+ bfq_init_bfqq(bfqd, bfqq, current->pid, is_sync); -+ bfq_init_prio_data(bfqq, bic); -+ bfq_init_entity(&bfqq->entity, bfqg); -+ bfq_log_bfqq(bfqd, bfqq, "allocated"); -+ } else { -+ bfqq = &bfqd->oom_bfqq; -+ bfq_log_bfqq(bfqd, bfqq, "using oom bfqq"); -+ } -+ } -+ -+ if (new_bfqq != NULL) -+ kmem_cache_free(bfq_pool, new_bfqq); -+ -+ return bfqq; -+} -+ -+static struct bfq_queue **bfq_async_queue_prio(struct bfq_data *bfqd, -+ struct bfq_group *bfqg, -+ int ioprio_class, int ioprio) -+{ -+ switch (ioprio_class) { -+ case IOPRIO_CLASS_RT: -+ return &bfqg->async_bfqq[0][ioprio]; -+ case IOPRIO_CLASS_NONE: -+ ioprio = IOPRIO_NORM; -+ /* fall through */ -+ case IOPRIO_CLASS_BE: -+ return &bfqg->async_bfqq[1][ioprio]; -+ case IOPRIO_CLASS_IDLE: -+ return &bfqg->async_idle_bfqq; -+ default: -+ BUG(); -+ } -+} -+ -+static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd, -+ struct bfq_group *bfqg, int is_sync, -+ struct bfq_io_cq *bic, gfp_t gfp_mask) -+{ -+ const int ioprio = IOPRIO_PRIO_DATA(bic->ioprio); -+ const int ioprio_class = IOPRIO_PRIO_CLASS(bic->ioprio); -+ struct bfq_queue **async_bfqq = NULL; -+ struct bfq_queue *bfqq = NULL; -+ -+ if (!is_sync) { -+ async_bfqq = bfq_async_queue_prio(bfqd, bfqg, ioprio_class, -+ ioprio); -+ bfqq = *async_bfqq; -+ } -+ -+ if (bfqq == NULL) -+ bfqq = bfq_find_alloc_queue(bfqd, bfqg, is_sync, bic, gfp_mask); -+ -+ /* -+ * Pin the queue now that it's allocated, scheduler exit will -+ * prune it. -+ */ -+ if (!is_sync && *async_bfqq == NULL) { -+ atomic_inc(&bfqq->ref); -+ bfq_log_bfqq(bfqd, bfqq, "get_queue, bfqq not in async: %p, %d", -+ bfqq, atomic_read(&bfqq->ref)); -+ *async_bfqq = bfqq; -+ } -+ -+ atomic_inc(&bfqq->ref); -+ bfq_log_bfqq(bfqd, bfqq, "get_queue, at end: %p, %d", bfqq, -+ atomic_read(&bfqq->ref)); -+ return bfqq; -+} -+ -+static void bfq_update_io_thinktime(struct bfq_data *bfqd, -+ struct bfq_io_cq *bic) -+{ -+ unsigned long elapsed = jiffies - bic->ttime.last_end_request; -+ unsigned long ttime = min(elapsed, 2UL * bfqd->bfq_slice_idle); -+ -+ bic->ttime.ttime_samples = (7*bic->ttime.ttime_samples + 256) / 8; -+ bic->ttime.ttime_total = (7*bic->ttime.ttime_total + 256*ttime) / 8; -+ bic->ttime.ttime_mean = (bic->ttime.ttime_total + 128) / -+ bic->ttime.ttime_samples; -+} -+ -+static void bfq_update_io_seektime(struct bfq_data *bfqd, -+ struct bfq_queue *bfqq, -+ struct request *rq) -+{ -+ sector_t sdist; -+ u64 total; -+ -+ if (bfqq->last_request_pos < blk_rq_pos(rq)) -+ sdist = blk_rq_pos(rq) - bfqq->last_request_pos; -+ else -+ sdist = bfqq->last_request_pos - blk_rq_pos(rq); -+ -+ /* -+ * Don't allow the seek distance to get too large from the -+ * odd fragment, pagein, etc. -+ */ -+ if (bfqq->seek_samples == 0) /* first request, not really a seek */ -+ sdist = 0; -+ else if (bfqq->seek_samples <= 60) /* second & third seek */ -+ sdist = min(sdist, (bfqq->seek_mean * 4) + 2*1024*1024); -+ else -+ sdist = min(sdist, (bfqq->seek_mean * 4) + 2*1024*64); -+ -+ bfqq->seek_samples = (7*bfqq->seek_samples + 256) / 8; -+ bfqq->seek_total = (7*bfqq->seek_total + (u64)256*sdist) / 8; -+ total = bfqq->seek_total + (bfqq->seek_samples/2); -+ do_div(total, bfqq->seek_samples); -+ bfqq->seek_mean = (sector_t)total; -+ -+ bfq_log_bfqq(bfqd, bfqq, "dist=%llu mean=%llu", (u64)sdist, -+ (u64)bfqq->seek_mean); -+} -+ -+/* -+ * Disable idle window if the process thinks too long or seeks so much that -+ * it doesn't matter. -+ */ -+static void bfq_update_idle_window(struct bfq_data *bfqd, -+ struct bfq_queue *bfqq, -+ struct bfq_io_cq *bic) -+{ -+ int enable_idle; -+ -+ /* Don't idle for async or idle io prio class. */ -+ if (!bfq_bfqq_sync(bfqq) || bfq_class_idle(bfqq)) -+ return; -+ -+ enable_idle = bfq_bfqq_idle_window(bfqq); -+ -+ if (atomic_read(&bic->icq.ioc->active_ref) == 0 || -+ bfqd->bfq_slice_idle == 0 || -+ (bfqd->hw_tag && BFQQ_SEEKY(bfqq) && -+ bfqq->wr_coeff == 1)) -+ enable_idle = 0; -+ else if (bfq_sample_valid(bic->ttime.ttime_samples)) { -+ if (bic->ttime.ttime_mean > bfqd->bfq_slice_idle && -+ bfqq->wr_coeff == 1) -+ enable_idle = 0; -+ else -+ enable_idle = 1; -+ } -+ bfq_log_bfqq(bfqd, bfqq, "update_idle_window: enable_idle %d", -+ enable_idle); -+ -+ if (enable_idle) -+ bfq_mark_bfqq_idle_window(bfqq); -+ else -+ bfq_clear_bfqq_idle_window(bfqq); -+} -+ -+/* -+ * Called when a new fs request (rq) is added to bfqq. Check if there's -+ * something we should do about it. -+ */ -+static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq, -+ struct request *rq) -+{ -+ struct bfq_io_cq *bic = RQ_BIC(rq); -+ -+ if (rq->cmd_flags & REQ_META) -+ bfqq->meta_pending++; -+ -+ bfq_update_io_thinktime(bfqd, bic); -+ bfq_update_io_seektime(bfqd, bfqq, rq); -+ if (!BFQQ_SEEKY(bfqq) && bfq_bfqq_constantly_seeky(bfqq)) { -+ bfq_clear_bfqq_constantly_seeky(bfqq); -+ if (!blk_queue_nonrot(bfqd->queue)) { -+ BUG_ON(!bfqd->const_seeky_busy_in_flight_queues); -+ bfqd->const_seeky_busy_in_flight_queues--; -+ } -+ } -+ if (bfqq->entity.service > bfq_max_budget(bfqd) / 8 || -+ !BFQQ_SEEKY(bfqq)) -+ bfq_update_idle_window(bfqd, bfqq, bic); -+ -+ bfq_log_bfqq(bfqd, bfqq, -+ "rq_enqueued: idle_window=%d (seeky %d, mean %llu)", -+ bfq_bfqq_idle_window(bfqq), BFQQ_SEEKY(bfqq), -+ (long long unsigned)bfqq->seek_mean); -+ -+ bfqq->last_request_pos = blk_rq_pos(rq) + blk_rq_sectors(rq); -+ -+ if (bfqq == bfqd->in_service_queue && bfq_bfqq_wait_request(bfqq)) { -+ int small_req = bfqq->queued[rq_is_sync(rq)] == 1 && -+ blk_rq_sectors(rq) < 32; -+ int budget_timeout = bfq_bfqq_budget_timeout(bfqq); -+ -+ /* -+ * There is just this request queued: if the request -+ * is small and the queue is not to be expired, then -+ * just exit. -+ * -+ * In this way, if the disk is being idled to wait for -+ * a new request from the in-service queue, we avoid -+ * unplugging the device and committing the disk to serve -+ * just a small request. On the contrary, we wait for -+ * the block layer to decide when to unplug the device: -+ * hopefully, new requests will be merged to this one -+ * quickly, then the device will be unplugged and -+ * larger requests will be dispatched. -+ */ -+ if (small_req && !budget_timeout) -+ return; -+ -+ /* -+ * A large enough request arrived, or the queue is to -+ * be expired: in both cases disk idling is to be -+ * stopped, so clear wait_request flag and reset -+ * timer. -+ */ -+ bfq_clear_bfqq_wait_request(bfqq); -+ del_timer(&bfqd->idle_slice_timer); -+ -+ /* -+ * The queue is not empty, because a new request just -+ * arrived. Hence we can safely expire the queue, in -+ * case of budget timeout, without risking that the -+ * timestamps of the queue are not updated correctly. -+ * See [1] for more details. -+ */ -+ if (budget_timeout) -+ bfq_bfqq_expire(bfqd, bfqq, 0, BFQ_BFQQ_BUDGET_TIMEOUT); -+ -+ /* -+ * Let the request rip immediately, or let a new queue be -+ * selected if bfqq has just been expired. -+ */ -+ __blk_run_queue(bfqd->queue); -+ } -+} -+ -+static void bfq_insert_request(struct request_queue *q, struct request *rq) -+{ -+ struct bfq_data *bfqd = q->elevator->elevator_data; -+ struct bfq_queue *bfqq = RQ_BFQQ(rq); -+ -+ assert_spin_locked(bfqd->queue->queue_lock); -+ bfq_init_prio_data(bfqq, RQ_BIC(rq)); -+ -+ bfq_add_request(rq); -+ -+ rq->fifo_time = jiffies + bfqd->bfq_fifo_expire[rq_is_sync(rq)]; -+ list_add_tail(&rq->queuelist, &bfqq->fifo); -+ -+ bfq_rq_enqueued(bfqd, bfqq, rq); -+} -+ -+static void bfq_update_hw_tag(struct bfq_data *bfqd) -+{ -+ bfqd->max_rq_in_driver = max(bfqd->max_rq_in_driver, -+ bfqd->rq_in_driver); -+ -+ if (bfqd->hw_tag == 1) -+ return; -+ -+ /* -+ * This sample is valid if the number of outstanding requests -+ * is large enough to allow a queueing behavior. Note that the -+ * sum is not exact, as it's not taking into account deactivated -+ * requests. -+ */ -+ if (bfqd->rq_in_driver + bfqd->queued < BFQ_HW_QUEUE_THRESHOLD) -+ return; -+ -+ if (bfqd->hw_tag_samples++ < BFQ_HW_QUEUE_SAMPLES) -+ return; -+ -+ bfqd->hw_tag = bfqd->max_rq_in_driver > BFQ_HW_QUEUE_THRESHOLD; -+ bfqd->max_rq_in_driver = 0; -+ bfqd->hw_tag_samples = 0; -+} -+ -+static void bfq_completed_request(struct request_queue *q, struct request *rq) -+{ -+ struct bfq_queue *bfqq = RQ_BFQQ(rq); -+ struct bfq_data *bfqd = bfqq->bfqd; -+ bool sync = bfq_bfqq_sync(bfqq); -+ -+ bfq_log_bfqq(bfqd, bfqq, "completed one req with %u sects left (%d)", -+ blk_rq_sectors(rq), sync); -+ -+ bfq_update_hw_tag(bfqd); -+ -+ BUG_ON(!bfqd->rq_in_driver); -+ BUG_ON(!bfqq->dispatched); -+ bfqd->rq_in_driver--; -+ bfqq->dispatched--; -+ -+ if (!bfqq->dispatched && !bfq_bfqq_busy(bfqq)) { -+ bfq_weights_tree_remove(bfqd, &bfqq->entity, -+ &bfqd->queue_weights_tree); -+ if (!blk_queue_nonrot(bfqd->queue)) { -+ BUG_ON(!bfqd->busy_in_flight_queues); -+ bfqd->busy_in_flight_queues--; -+ if (bfq_bfqq_constantly_seeky(bfqq)) { -+ BUG_ON(!bfqd-> -+ const_seeky_busy_in_flight_queues); -+ bfqd->const_seeky_busy_in_flight_queues--; -+ } -+ } -+ } -+ -+ if (sync) { -+ bfqd->sync_flight--; -+ RQ_BIC(rq)->ttime.last_end_request = jiffies; -+ } -+ -+ /* -+ * If we are waiting to discover whether the request pattern of the -+ * task associated with the queue is actually isochronous, and -+ * both requisites for this condition to hold are satisfied, then -+ * compute soft_rt_next_start (see the comments to the function -+ * bfq_bfqq_softrt_next_start()). -+ */ -+ if (bfq_bfqq_softrt_update(bfqq) && bfqq->dispatched == 0 && -+ RB_EMPTY_ROOT(&bfqq->sort_list)) -+ bfqq->soft_rt_next_start = -+ bfq_bfqq_softrt_next_start(bfqd, bfqq); -+ -+ /* -+ * If this is the in-service queue, check if it needs to be expired, -+ * or if we want to idle in case it has no pending requests. -+ */ -+ if (bfqd->in_service_queue == bfqq) { -+ if (bfq_bfqq_budget_new(bfqq)) -+ bfq_set_budget_timeout(bfqd); -+ -+ if (bfq_bfqq_must_idle(bfqq)) { -+ bfq_arm_slice_timer(bfqd); -+ goto out; -+ } else if (bfq_may_expire_for_budg_timeout(bfqq)) -+ bfq_bfqq_expire(bfqd, bfqq, 0, BFQ_BFQQ_BUDGET_TIMEOUT); -+ else if (RB_EMPTY_ROOT(&bfqq->sort_list) && -+ (bfqq->dispatched == 0 || -+ !bfq_bfqq_must_not_expire(bfqq))) -+ bfq_bfqq_expire(bfqd, bfqq, 0, -+ BFQ_BFQQ_NO_MORE_REQUESTS); -+ } -+ -+ if (!bfqd->rq_in_driver) -+ bfq_schedule_dispatch(bfqd); -+ -+out: -+ return; -+} -+ -+static inline int __bfq_may_queue(struct bfq_queue *bfqq) -+{ -+ if (bfq_bfqq_wait_request(bfqq) && bfq_bfqq_must_alloc(bfqq)) { -+ bfq_clear_bfqq_must_alloc(bfqq); -+ return ELV_MQUEUE_MUST; -+ } -+ -+ return ELV_MQUEUE_MAY; -+} -+ -+static int bfq_may_queue(struct request_queue *q, int rw) -+{ -+ struct bfq_data *bfqd = q->elevator->elevator_data; -+ struct task_struct *tsk = current; -+ struct bfq_io_cq *bic; -+ struct bfq_queue *bfqq; -+ -+ /* -+ * Don't force setup of a queue from here, as a call to may_queue -+ * does not necessarily imply that a request actually will be -+ * queued. So just lookup a possibly existing queue, or return -+ * 'may queue' if that fails. -+ */ -+ bic = bfq_bic_lookup(bfqd, tsk->io_context); -+ if (bic == NULL) -+ return ELV_MQUEUE_MAY; -+ -+ bfqq = bic_to_bfqq(bic, rw_is_sync(rw)); -+ if (bfqq != NULL) { -+ bfq_init_prio_data(bfqq, bic); -+ -+ return __bfq_may_queue(bfqq); -+ } -+ -+ return ELV_MQUEUE_MAY; -+} -+ -+/* -+ * Queue lock held here. -+ */ -+static void bfq_put_request(struct request *rq) -+{ -+ struct bfq_queue *bfqq = RQ_BFQQ(rq); -+ -+ if (bfqq != NULL) { -+ const int rw = rq_data_dir(rq); -+ -+ BUG_ON(!bfqq->allocated[rw]); -+ bfqq->allocated[rw]--; -+ -+ rq->elv.priv[0] = NULL; -+ rq->elv.priv[1] = NULL; -+ -+ bfq_log_bfqq(bfqq->bfqd, bfqq, "put_request %p, %d", -+ bfqq, atomic_read(&bfqq->ref)); -+ bfq_put_queue(bfqq); -+ } -+} -+ -+static struct bfq_queue * -+bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic, -+ struct bfq_queue *bfqq) -+{ -+ bfq_log_bfqq(bfqd, bfqq, "merging with queue %lu", -+ (long unsigned)bfqq->new_bfqq->pid); -+ bic_set_bfqq(bic, bfqq->new_bfqq, 1); -+ bfq_mark_bfqq_coop(bfqq->new_bfqq); -+ bfq_put_queue(bfqq); -+ return bic_to_bfqq(bic, 1); -+} -+ -+/* -+ * Returns NULL if a new bfqq should be allocated, or the old bfqq if this -+ * was the last process referring to said bfqq. -+ */ -+static struct bfq_queue * -+bfq_split_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq) -+{ -+ bfq_log_bfqq(bfqq->bfqd, bfqq, "splitting queue"); -+ if (bfqq_process_refs(bfqq) == 1) { -+ bfqq->pid = current->pid; -+ bfq_clear_bfqq_coop(bfqq); -+ bfq_clear_bfqq_split_coop(bfqq); -+ return bfqq; -+ } -+ -+ bic_set_bfqq(bic, NULL, 1); -+ -+ bfq_put_cooperator(bfqq); -+ -+ bfq_put_queue(bfqq); -+ return NULL; -+} -+ -+/* -+ * Allocate bfq data structures associated with this request. -+ */ -+static int bfq_set_request(struct request_queue *q, struct request *rq, -+ struct bio *bio, gfp_t gfp_mask) -+{ -+ struct bfq_data *bfqd = q->elevator->elevator_data; -+ struct bfq_io_cq *bic = icq_to_bic(rq->elv.icq); -+ const int rw = rq_data_dir(rq); -+ const int is_sync = rq_is_sync(rq); -+ struct bfq_queue *bfqq; -+ struct bfq_group *bfqg; -+ unsigned long flags; -+ -+ might_sleep_if(gfp_mask & __GFP_WAIT); -+ -+ bfq_changed_ioprio(bic); -+ -+ spin_lock_irqsave(q->queue_lock, flags); -+ -+ if (bic == NULL) -+ goto queue_fail; -+ -+ bfqg = bfq_bic_update_cgroup(bic); -+ -+new_queue: -+ bfqq = bic_to_bfqq(bic, is_sync); -+ if (bfqq == NULL || bfqq == &bfqd->oom_bfqq) { -+ bfqq = bfq_get_queue(bfqd, bfqg, is_sync, bic, gfp_mask); -+ bic_set_bfqq(bic, bfqq, is_sync); -+ } else { -+ /* -+ * If the queue was seeky for too long, break it apart. -+ */ -+ if (bfq_bfqq_coop(bfqq) && bfq_bfqq_split_coop(bfqq)) { -+ bfq_log_bfqq(bfqd, bfqq, "breaking apart bfqq"); -+ bfqq = bfq_split_bfqq(bic, bfqq); -+ if (!bfqq) -+ goto new_queue; -+ } -+ -+ /* -+ * Check to see if this queue is scheduled to merge with -+ * another closely cooperating queue. The merging of queues -+ * happens here as it must be done in process context. -+ * The reference on new_bfqq was taken in merge_bfqqs. -+ */ -+ if (bfqq->new_bfqq != NULL) -+ bfqq = bfq_merge_bfqqs(bfqd, bic, bfqq); -+ } -+ -+ bfqq->allocated[rw]++; -+ atomic_inc(&bfqq->ref); -+ bfq_log_bfqq(bfqd, bfqq, "set_request: bfqq %p, %d", bfqq, -+ atomic_read(&bfqq->ref)); -+ -+ rq->elv.priv[0] = bic; -+ rq->elv.priv[1] = bfqq; -+ -+ spin_unlock_irqrestore(q->queue_lock, flags); -+ -+ return 0; -+ -+queue_fail: -+ bfq_schedule_dispatch(bfqd); -+ spin_unlock_irqrestore(q->queue_lock, flags); -+ -+ return 1; -+} -+ -+static void bfq_kick_queue(struct work_struct *work) -+{ -+ struct bfq_data *bfqd = -+ container_of(work, struct bfq_data, unplug_work); -+ struct request_queue *q = bfqd->queue; -+ -+ spin_lock_irq(q->queue_lock); -+ __blk_run_queue(q); -+ spin_unlock_irq(q->queue_lock); -+} -+ -+/* -+ * Handler of the expiration of the timer running if the in-service queue -+ * is idling inside its time slice. -+ */ -+static void bfq_idle_slice_timer(unsigned long data) -+{ -+ struct bfq_data *bfqd = (struct bfq_data *)data; -+ struct bfq_queue *bfqq; -+ unsigned long flags; -+ enum bfqq_expiration reason; -+ -+ spin_lock_irqsave(bfqd->queue->queue_lock, flags); -+ -+ bfqq = bfqd->in_service_queue; -+ /* -+ * Theoretical race here: the in-service queue can be NULL or -+ * different from the queue that was idling if the timer handler -+ * spins on the queue_lock and a new request arrives for the -+ * current queue and there is a full dispatch cycle that changes -+ * the in-service queue. This can hardly happen, but in the worst -+ * case we just expire a queue too early. -+ */ -+ if (bfqq != NULL) { -+ bfq_log_bfqq(bfqd, bfqq, "slice_timer expired"); -+ if (bfq_bfqq_budget_timeout(bfqq)) -+ /* -+ * Also here the queue can be safely expired -+ * for budget timeout without wasting -+ * guarantees -+ */ -+ reason = BFQ_BFQQ_BUDGET_TIMEOUT; -+ else if (bfqq->queued[0] == 0 && bfqq->queued[1] == 0) -+ /* -+ * The queue may not be empty upon timer expiration, -+ * because we may not disable the timer when the -+ * first request of the in-service queue arrives -+ * during disk idling. -+ */ -+ reason = BFQ_BFQQ_TOO_IDLE; -+ else -+ goto schedule_dispatch; -+ -+ bfq_bfqq_expire(bfqd, bfqq, 1, reason); -+ } -+ -+schedule_dispatch: -+ bfq_schedule_dispatch(bfqd); -+ -+ spin_unlock_irqrestore(bfqd->queue->queue_lock, flags); -+} -+ -+static void bfq_shutdown_timer_wq(struct bfq_data *bfqd) -+{ -+ del_timer_sync(&bfqd->idle_slice_timer); -+ cancel_work_sync(&bfqd->unplug_work); -+} -+ -+static inline void __bfq_put_async_bfqq(struct bfq_data *bfqd, -+ struct bfq_queue **bfqq_ptr) -+{ -+ struct bfq_group *root_group = bfqd->root_group; -+ struct bfq_queue *bfqq = *bfqq_ptr; -+ -+ bfq_log(bfqd, "put_async_bfqq: %p", bfqq); -+ if (bfqq != NULL) { -+ bfq_bfqq_move(bfqd, bfqq, &bfqq->entity, root_group); -+ bfq_log_bfqq(bfqd, bfqq, "put_async_bfqq: putting %p, %d", -+ bfqq, atomic_read(&bfqq->ref)); -+ bfq_put_queue(bfqq); -+ *bfqq_ptr = NULL; -+ } -+} -+ -+/* -+ * Release all the bfqg references to its async queues. If we are -+ * deallocating the group these queues may still contain requests, so -+ * we reparent them to the root cgroup (i.e., the only one that will -+ * exist for sure until all the requests on a device are gone). -+ */ -+static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg) -+{ -+ int i, j; -+ -+ for (i = 0; i < 2; i++) -+ for (j = 0; j < IOPRIO_BE_NR; j++) -+ __bfq_put_async_bfqq(bfqd, &bfqg->async_bfqq[i][j]); -+ -+ __bfq_put_async_bfqq(bfqd, &bfqg->async_idle_bfqq); -+} -+ -+static void bfq_exit_queue(struct elevator_queue *e) -+{ -+ struct bfq_data *bfqd = e->elevator_data; -+ struct request_queue *q = bfqd->queue; -+ struct bfq_queue *bfqq, *n; -+ -+ bfq_shutdown_timer_wq(bfqd); -+ -+ spin_lock_irq(q->queue_lock); -+ -+ BUG_ON(bfqd->in_service_queue != NULL); -+ list_for_each_entry_safe(bfqq, n, &bfqd->idle_list, bfqq_list) -+ bfq_deactivate_bfqq(bfqd, bfqq, 0); -+ -+ bfq_disconnect_groups(bfqd); -+ spin_unlock_irq(q->queue_lock); -+ -+ bfq_shutdown_timer_wq(bfqd); -+ -+ synchronize_rcu(); -+ -+ BUG_ON(timer_pending(&bfqd->idle_slice_timer)); -+ -+ bfq_free_root_group(bfqd); -+ kfree(bfqd); -+} -+ -+static int bfq_init_queue(struct request_queue *q, struct elevator_type *e) -+{ -+ struct bfq_group *bfqg; -+ struct bfq_data *bfqd; -+ struct elevator_queue *eq; -+ -+ eq = elevator_alloc(q, e); -+ if (eq == NULL) -+ return -ENOMEM; -+ -+ bfqd = kzalloc_node(sizeof(*bfqd), GFP_KERNEL, q->node); -+ if (bfqd == NULL) { -+ kobject_put(&eq->kobj); -+ return -ENOMEM; -+ } -+ eq->elevator_data = bfqd; -+ -+ /* -+ * Our fallback bfqq if bfq_find_alloc_queue() runs into OOM issues. -+ * Grab a permanent reference to it, so that the normal code flow -+ * will not attempt to free it. -+ */ -+ bfq_init_bfqq(bfqd, &bfqd->oom_bfqq, 1, 0); -+ atomic_inc(&bfqd->oom_bfqq.ref); -+ bfqd->oom_bfqq.entity.new_ioprio = BFQ_DEFAULT_QUEUE_IOPRIO; -+ bfqd->oom_bfqq.entity.new_ioprio_class = IOPRIO_CLASS_BE; -+ /* -+ * Trigger weight initialization, according to ioprio, at the -+ * oom_bfqq's first activation. The oom_bfqq's ioprio and ioprio -+ * class won't be changed any more. -+ */ -+ bfqd->oom_bfqq.entity.ioprio_changed = 1; -+ -+ bfqd->queue = q; -+ -+ spin_lock_irq(q->queue_lock); -+ q->elevator = eq; -+ spin_unlock_irq(q->queue_lock); -+ -+ bfqg = bfq_alloc_root_group(bfqd, q->node); -+ if (bfqg == NULL) { -+ kfree(bfqd); -+ kobject_put(&eq->kobj); -+ return -ENOMEM; -+ } -+ -+ bfqd->root_group = bfqg; -+ bfq_init_entity(&bfqd->oom_bfqq.entity, bfqd->root_group); -+#ifdef CONFIG_CGROUP_BFQIO -+ bfqd->active_numerous_groups = 0; -+#endif -+ -+ init_timer(&bfqd->idle_slice_timer); -+ bfqd->idle_slice_timer.function = bfq_idle_slice_timer; -+ bfqd->idle_slice_timer.data = (unsigned long)bfqd; -+ -+ bfqd->rq_pos_tree = RB_ROOT; -+ bfqd->queue_weights_tree = RB_ROOT; -+ bfqd->group_weights_tree = RB_ROOT; -+ -+ INIT_WORK(&bfqd->unplug_work, bfq_kick_queue); -+ -+ INIT_LIST_HEAD(&bfqd->active_list); -+ INIT_LIST_HEAD(&bfqd->idle_list); -+ INIT_HLIST_HEAD(&bfqd->burst_list); -+ -+ bfqd->hw_tag = -1; -+ -+ bfqd->bfq_max_budget = bfq_default_max_budget; -+ -+ bfqd->bfq_quantum = bfq_quantum; -+ bfqd->bfq_fifo_expire[0] = bfq_fifo_expire[0]; -+ bfqd->bfq_fifo_expire[1] = bfq_fifo_expire[1]; -+ bfqd->bfq_back_max = bfq_back_max; -+ bfqd->bfq_back_penalty = bfq_back_penalty; -+ bfqd->bfq_slice_idle = bfq_slice_idle; -+ bfqd->bfq_class_idle_last_service = 0; -+ bfqd->bfq_max_budget_async_rq = bfq_max_budget_async_rq; -+ bfqd->bfq_timeout[BLK_RW_ASYNC] = bfq_timeout_async; -+ bfqd->bfq_timeout[BLK_RW_SYNC] = bfq_timeout_sync; -+ -+ bfqd->bfq_coop_thresh = 2; -+ bfqd->bfq_failed_cooperations = 7000; -+ bfqd->bfq_requests_within_timer = 120; -+ -+ bfqd->bfq_large_burst_thresh = 11; -+ bfqd->bfq_burst_interval = msecs_to_jiffies(500); -+ -+ bfqd->low_latency = true; -+ -+ bfqd->bfq_wr_coeff = 20; -+ bfqd->bfq_wr_rt_max_time = msecs_to_jiffies(300); -+ bfqd->bfq_wr_max_time = 0; -+ bfqd->bfq_wr_min_idle_time = msecs_to_jiffies(2000); -+ bfqd->bfq_wr_min_inter_arr_async = msecs_to_jiffies(500); -+ bfqd->bfq_wr_max_softrt_rate = 7000; /* -+ * Approximate rate required -+ * to playback or record a -+ * high-definition compressed -+ * video. -+ */ -+ bfqd->wr_busy_queues = 0; -+ bfqd->busy_in_flight_queues = 0; -+ bfqd->const_seeky_busy_in_flight_queues = 0; -+ -+ /* -+ * Begin by assuming, optimistically, that the device peak rate is -+ * equal to the highest reference rate. -+ */ -+ bfqd->RT_prod = R_fast[blk_queue_nonrot(bfqd->queue)] * -+ T_fast[blk_queue_nonrot(bfqd->queue)]; -+ bfqd->peak_rate = R_fast[blk_queue_nonrot(bfqd->queue)]; -+ bfqd->device_speed = BFQ_BFQD_FAST; -+ -+ return 0; -+} -+ -+static void bfq_slab_kill(void) -+{ -+ if (bfq_pool != NULL) -+ kmem_cache_destroy(bfq_pool); -+} -+ -+static int __init bfq_slab_setup(void) -+{ -+ bfq_pool = KMEM_CACHE(bfq_queue, 0); -+ if (bfq_pool == NULL) -+ return -ENOMEM; -+ return 0; -+} -+ -+static ssize_t bfq_var_show(unsigned int var, char *page) -+{ -+ return sprintf(page, "%d\n", var); -+} -+ -+static ssize_t bfq_var_store(unsigned long *var, const char *page, -+ size_t count) -+{ -+ unsigned long new_val; -+ int ret = kstrtoul(page, 10, &new_val); -+ -+ if (ret == 0) -+ *var = new_val; -+ -+ return count; -+} -+ -+static ssize_t bfq_wr_max_time_show(struct elevator_queue *e, char *page) -+{ -+ struct bfq_data *bfqd = e->elevator_data; -+ return sprintf(page, "%d\n", bfqd->bfq_wr_max_time > 0 ? -+ jiffies_to_msecs(bfqd->bfq_wr_max_time) : -+ jiffies_to_msecs(bfq_wr_duration(bfqd))); -+} -+ -+static ssize_t bfq_weights_show(struct elevator_queue *e, char *page) -+{ -+ struct bfq_queue *bfqq; -+ struct bfq_data *bfqd = e->elevator_data; -+ ssize_t num_char = 0; -+ -+ num_char += sprintf(page + num_char, "Tot reqs queued %d\n\n", -+ bfqd->queued); -+ -+ spin_lock_irq(bfqd->queue->queue_lock); -+ -+ num_char += sprintf(page + num_char, "Active:\n"); -+ list_for_each_entry(bfqq, &bfqd->active_list, bfqq_list) { -+ num_char += sprintf(page + num_char, -+ "pid%d: weight %hu, nr_queued %d %d, dur %d/%u\n", -+ bfqq->pid, -+ bfqq->entity.weight, -+ bfqq->queued[0], -+ bfqq->queued[1], -+ jiffies_to_msecs(jiffies - bfqq->last_wr_start_finish), -+ jiffies_to_msecs(bfqq->wr_cur_max_time)); -+ } -+ -+ num_char += sprintf(page + num_char, "Idle:\n"); -+ list_for_each_entry(bfqq, &bfqd->idle_list, bfqq_list) { -+ num_char += sprintf(page + num_char, -+ "pid%d: weight %hu, dur %d/%u\n", -+ bfqq->pid, -+ bfqq->entity.weight, -+ jiffies_to_msecs(jiffies - -+ bfqq->last_wr_start_finish), -+ jiffies_to_msecs(bfqq->wr_cur_max_time)); -+ } -+ -+ spin_unlock_irq(bfqd->queue->queue_lock); -+ -+ return num_char; -+} -+ -+#define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \ -+static ssize_t __FUNC(struct elevator_queue *e, char *page) \ -+{ \ -+ struct bfq_data *bfqd = e->elevator_data; \ -+ unsigned int __data = __VAR; \ -+ if (__CONV) \ -+ __data = jiffies_to_msecs(__data); \ -+ return bfq_var_show(__data, (page)); \ -+} -+SHOW_FUNCTION(bfq_quantum_show, bfqd->bfq_quantum, 0); -+SHOW_FUNCTION(bfq_fifo_expire_sync_show, bfqd->bfq_fifo_expire[1], 1); -+SHOW_FUNCTION(bfq_fifo_expire_async_show, bfqd->bfq_fifo_expire[0], 1); -+SHOW_FUNCTION(bfq_back_seek_max_show, bfqd->bfq_back_max, 0); -+SHOW_FUNCTION(bfq_back_seek_penalty_show, bfqd->bfq_back_penalty, 0); -+SHOW_FUNCTION(bfq_slice_idle_show, bfqd->bfq_slice_idle, 1); -+SHOW_FUNCTION(bfq_max_budget_show, bfqd->bfq_user_max_budget, 0); -+SHOW_FUNCTION(bfq_max_budget_async_rq_show, -+ bfqd->bfq_max_budget_async_rq, 0); -+SHOW_FUNCTION(bfq_timeout_sync_show, bfqd->bfq_timeout[BLK_RW_SYNC], 1); -+SHOW_FUNCTION(bfq_timeout_async_show, bfqd->bfq_timeout[BLK_RW_ASYNC], 1); -+SHOW_FUNCTION(bfq_low_latency_show, bfqd->low_latency, 0); -+SHOW_FUNCTION(bfq_wr_coeff_show, bfqd->bfq_wr_coeff, 0); -+SHOW_FUNCTION(bfq_wr_rt_max_time_show, bfqd->bfq_wr_rt_max_time, 1); -+SHOW_FUNCTION(bfq_wr_min_idle_time_show, bfqd->bfq_wr_min_idle_time, 1); -+SHOW_FUNCTION(bfq_wr_min_inter_arr_async_show, bfqd->bfq_wr_min_inter_arr_async, -+ 1); -+SHOW_FUNCTION(bfq_wr_max_softrt_rate_show, bfqd->bfq_wr_max_softrt_rate, 0); -+#undef SHOW_FUNCTION -+ -+#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \ -+static ssize_t \ -+__FUNC(struct elevator_queue *e, const char *page, size_t count) \ -+{ \ -+ struct bfq_data *bfqd = e->elevator_data; \ -+ unsigned long uninitialized_var(__data); \ -+ int ret = bfq_var_store(&__data, (page), count); \ -+ if (__data < (MIN)) \ -+ __data = (MIN); \ -+ else if (__data > (MAX)) \ -+ __data = (MAX); \ -+ if (__CONV) \ -+ *(__PTR) = msecs_to_jiffies(__data); \ -+ else \ -+ *(__PTR) = __data; \ -+ return ret; \ -+} -+STORE_FUNCTION(bfq_quantum_store, &bfqd->bfq_quantum, 1, INT_MAX, 0); -+STORE_FUNCTION(bfq_fifo_expire_sync_store, &bfqd->bfq_fifo_expire[1], 1, -+ INT_MAX, 1); -+STORE_FUNCTION(bfq_fifo_expire_async_store, &bfqd->bfq_fifo_expire[0], 1, -+ INT_MAX, 1); -+STORE_FUNCTION(bfq_back_seek_max_store, &bfqd->bfq_back_max, 0, INT_MAX, 0); -+STORE_FUNCTION(bfq_back_seek_penalty_store, &bfqd->bfq_back_penalty, 1, -+ INT_MAX, 0); -+STORE_FUNCTION(bfq_slice_idle_store, &bfqd->bfq_slice_idle, 0, INT_MAX, 1); -+STORE_FUNCTION(bfq_max_budget_async_rq_store, &bfqd->bfq_max_budget_async_rq, -+ 1, INT_MAX, 0); -+STORE_FUNCTION(bfq_timeout_async_store, &bfqd->bfq_timeout[BLK_RW_ASYNC], 0, -+ INT_MAX, 1); -+STORE_FUNCTION(bfq_wr_coeff_store, &bfqd->bfq_wr_coeff, 1, INT_MAX, 0); -+STORE_FUNCTION(bfq_wr_max_time_store, &bfqd->bfq_wr_max_time, 0, INT_MAX, 1); -+STORE_FUNCTION(bfq_wr_rt_max_time_store, &bfqd->bfq_wr_rt_max_time, 0, INT_MAX, -+ 1); -+STORE_FUNCTION(bfq_wr_min_idle_time_store, &bfqd->bfq_wr_min_idle_time, 0, -+ INT_MAX, 1); -+STORE_FUNCTION(bfq_wr_min_inter_arr_async_store, -+ &bfqd->bfq_wr_min_inter_arr_async, 0, INT_MAX, 1); -+STORE_FUNCTION(bfq_wr_max_softrt_rate_store, &bfqd->bfq_wr_max_softrt_rate, 0, -+ INT_MAX, 0); -+#undef STORE_FUNCTION -+ -+/* do nothing for the moment */ -+static ssize_t bfq_weights_store(struct elevator_queue *e, -+ const char *page, size_t count) -+{ -+ return count; -+} -+ -+static inline unsigned long bfq_estimated_max_budget(struct bfq_data *bfqd) -+{ -+ u64 timeout = jiffies_to_msecs(bfqd->bfq_timeout[BLK_RW_SYNC]); -+ -+ if (bfqd->peak_rate_samples >= BFQ_PEAK_RATE_SAMPLES) -+ return bfq_calc_max_budget(bfqd->peak_rate, timeout); -+ else -+ return bfq_default_max_budget; -+} -+ -+static ssize_t bfq_max_budget_store(struct elevator_queue *e, -+ const char *page, size_t count) -+{ -+ struct bfq_data *bfqd = e->elevator_data; -+ unsigned long uninitialized_var(__data); -+ int ret = bfq_var_store(&__data, (page), count); -+ -+ if (__data == 0) -+ bfqd->bfq_max_budget = bfq_estimated_max_budget(bfqd); -+ else { -+ if (__data > INT_MAX) -+ __data = INT_MAX; -+ bfqd->bfq_max_budget = __data; -+ } -+ -+ bfqd->bfq_user_max_budget = __data; -+ -+ return ret; -+} -+ -+static ssize_t bfq_timeout_sync_store(struct elevator_queue *e, -+ const char *page, size_t count) -+{ -+ struct bfq_data *bfqd = e->elevator_data; -+ unsigned long uninitialized_var(__data); -+ int ret = bfq_var_store(&__data, (page), count); -+ -+ if (__data < 1) -+ __data = 1; -+ else if (__data > INT_MAX) -+ __data = INT_MAX; -+ -+ bfqd->bfq_timeout[BLK_RW_SYNC] = msecs_to_jiffies(__data); -+ if (bfqd->bfq_user_max_budget == 0) -+ bfqd->bfq_max_budget = bfq_estimated_max_budget(bfqd); -+ -+ return ret; -+} -+ -+static ssize_t bfq_low_latency_store(struct elevator_queue *e, -+ const char *page, size_t count) -+{ -+ struct bfq_data *bfqd = e->elevator_data; -+ unsigned long uninitialized_var(__data); -+ int ret = bfq_var_store(&__data, (page), count); -+ -+ if (__data > 1) -+ __data = 1; -+ if (__data == 0 && bfqd->low_latency != 0) -+ bfq_end_wr(bfqd); -+ bfqd->low_latency = __data; -+ -+ return ret; -+} -+ -+#define BFQ_ATTR(name) \ -+ __ATTR(name, S_IRUGO|S_IWUSR, bfq_##name##_show, bfq_##name##_store) -+ -+static struct elv_fs_entry bfq_attrs[] = { -+ BFQ_ATTR(quantum), -+ BFQ_ATTR(fifo_expire_sync), -+ BFQ_ATTR(fifo_expire_async), -+ BFQ_ATTR(back_seek_max), -+ BFQ_ATTR(back_seek_penalty), -+ BFQ_ATTR(slice_idle), -+ BFQ_ATTR(max_budget), -+ BFQ_ATTR(max_budget_async_rq), -+ BFQ_ATTR(timeout_sync), -+ BFQ_ATTR(timeout_async), -+ BFQ_ATTR(low_latency), -+ BFQ_ATTR(wr_coeff), -+ BFQ_ATTR(wr_max_time), -+ BFQ_ATTR(wr_rt_max_time), -+ BFQ_ATTR(wr_min_idle_time), -+ BFQ_ATTR(wr_min_inter_arr_async), -+ BFQ_ATTR(wr_max_softrt_rate), -+ BFQ_ATTR(weights), -+ __ATTR_NULL -+}; -+ -+static struct elevator_type iosched_bfq = { -+ .ops = { -+ .elevator_merge_fn = bfq_merge, -+ .elevator_merged_fn = bfq_merged_request, -+ .elevator_merge_req_fn = bfq_merged_requests, -+ .elevator_allow_merge_fn = bfq_allow_merge, -+ .elevator_dispatch_fn = bfq_dispatch_requests, -+ .elevator_add_req_fn = bfq_insert_request, -+ .elevator_activate_req_fn = bfq_activate_request, -+ .elevator_deactivate_req_fn = bfq_deactivate_request, -+ .elevator_completed_req_fn = bfq_completed_request, -+ .elevator_former_req_fn = elv_rb_former_request, -+ .elevator_latter_req_fn = elv_rb_latter_request, -+ .elevator_init_icq_fn = bfq_init_icq, -+ .elevator_exit_icq_fn = bfq_exit_icq, -+ .elevator_set_req_fn = bfq_set_request, -+ .elevator_put_req_fn = bfq_put_request, -+ .elevator_may_queue_fn = bfq_may_queue, -+ .elevator_init_fn = bfq_init_queue, -+ .elevator_exit_fn = bfq_exit_queue, -+ }, -+ .icq_size = sizeof(struct bfq_io_cq), -+ .icq_align = __alignof__(struct bfq_io_cq), -+ .elevator_attrs = bfq_attrs, -+ .elevator_name = "bfq", -+ .elevator_owner = THIS_MODULE, -+}; -+ -+static int __init bfq_init(void) -+{ -+ /* -+ * Can be 0 on HZ < 1000 setups. -+ */ -+ if (bfq_slice_idle == 0) -+ bfq_slice_idle = 1; -+ -+ if (bfq_timeout_async == 0) -+ bfq_timeout_async = 1; -+ -+ if (bfq_slab_setup()) -+ return -ENOMEM; -+ -+ /* -+ * Times to load large popular applications for the typical systems -+ * installed on the reference devices (see the comments before the -+ * definitions of the two arrays). -+ */ -+ T_slow[0] = msecs_to_jiffies(2600); -+ T_slow[1] = msecs_to_jiffies(1000); -+ T_fast[0] = msecs_to_jiffies(5500); -+ T_fast[1] = msecs_to_jiffies(2000); -+ -+ /* -+ * Thresholds that determine the switch between speed classes (see -+ * the comments before the definition of the array). -+ */ -+ device_speed_thresh[0] = (R_fast[0] + R_slow[0]) / 2; -+ device_speed_thresh[1] = (R_fast[1] + R_slow[1]) / 2; -+ -+ elv_register(&iosched_bfq); -+ pr_info("BFQ I/O-scheduler version: v7r7"); -+ -+ return 0; -+} -+ -+static void __exit bfq_exit(void) -+{ -+ elv_unregister(&iosched_bfq); -+ bfq_slab_kill(); -+} -+ -+module_init(bfq_init); -+module_exit(bfq_exit); -+ -+MODULE_AUTHOR("Fabio Checconi, Paolo Valente"); -+MODULE_LICENSE("GPL"); -diff --git a/block/bfq-sched.c b/block/bfq-sched.c -new file mode 100644 -index 0000000..2931563 ---- /dev/null -+++ b/block/bfq-sched.c -@@ -0,0 +1,1214 @@ -+/* -+ * BFQ: Hierarchical B-WF2Q+ scheduler. -+ * -+ * Based on ideas and code from CFQ: -+ * Copyright (C) 2003 Jens Axboe -+ * -+ * Copyright (C) 2008 Fabio Checconi -+ * Paolo Valente -+ * -+ * Copyright (C) 2010 Paolo Valente -+ */ -+ -+#ifdef CONFIG_CGROUP_BFQIO -+#define for_each_entity(entity) \ -+ for (; entity != NULL; entity = entity->parent) -+ -+#define for_each_entity_safe(entity, parent) \ -+ for (; entity && ({ parent = entity->parent; 1; }); entity = parent) -+ -+static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd, -+ int extract, -+ struct bfq_data *bfqd); -+ -+static inline void bfq_update_budget(struct bfq_entity *next_in_service) -+{ -+ struct bfq_entity *bfqg_entity; -+ struct bfq_group *bfqg; -+ struct bfq_sched_data *group_sd; -+ -+ BUG_ON(next_in_service == NULL); -+ -+ group_sd = next_in_service->sched_data; -+ -+ bfqg = container_of(group_sd, struct bfq_group, sched_data); -+ /* -+ * bfq_group's my_entity field is not NULL only if the group -+ * is not the root group. We must not touch the root entity -+ * as it must never become an in-service entity. -+ */ -+ bfqg_entity = bfqg->my_entity; -+ if (bfqg_entity != NULL) -+ bfqg_entity->budget = next_in_service->budget; -+} -+ -+static int bfq_update_next_in_service(struct bfq_sched_data *sd) -+{ -+ struct bfq_entity *next_in_service; -+ -+ if (sd->in_service_entity != NULL) -+ /* will update/requeue at the end of service */ -+ return 0; -+ -+ /* -+ * NOTE: this can be improved in many ways, such as returning -+ * 1 (and thus propagating upwards the update) only when the -+ * budget changes, or caching the bfqq that will be scheduled -+ * next from this subtree. By now we worry more about -+ * correctness than about performance... -+ */ -+ next_in_service = bfq_lookup_next_entity(sd, 0, NULL); -+ sd->next_in_service = next_in_service; -+ -+ if (next_in_service != NULL) -+ bfq_update_budget(next_in_service); -+ -+ return 1; -+} -+ -+static inline void bfq_check_next_in_service(struct bfq_sched_data *sd, -+ struct bfq_entity *entity) -+{ -+ BUG_ON(sd->next_in_service != entity); -+} -+#else -+#define for_each_entity(entity) \ -+ for (; entity != NULL; entity = NULL) -+ -+#define for_each_entity_safe(entity, parent) \ -+ for (parent = NULL; entity != NULL; entity = parent) -+ -+static inline int bfq_update_next_in_service(struct bfq_sched_data *sd) -+{ -+ return 0; -+} -+ -+static inline void bfq_check_next_in_service(struct bfq_sched_data *sd, -+ struct bfq_entity *entity) -+{ -+} -+ -+static inline void bfq_update_budget(struct bfq_entity *next_in_service) -+{ -+} -+#endif -+ -+/* -+ * Shift for timestamp calculations. This actually limits the maximum -+ * service allowed in one timestamp delta (small shift values increase it), -+ * the maximum total weight that can be used for the queues in the system -+ * (big shift values increase it), and the period of virtual time -+ * wraparounds. -+ */ -+#define WFQ_SERVICE_SHIFT 22 -+ -+/** -+ * bfq_gt - compare two timestamps. -+ * @a: first ts. -+ * @b: second ts. -+ * -+ * Return @a > @b, dealing with wrapping correctly. -+ */ -+static inline int bfq_gt(u64 a, u64 b) -+{ -+ return (s64)(a - b) > 0; -+} -+ -+static inline struct bfq_queue *bfq_entity_to_bfqq(struct bfq_entity *entity) -+{ -+ struct bfq_queue *bfqq = NULL; -+ -+ BUG_ON(entity == NULL); -+ -+ if (entity->my_sched_data == NULL) -+ bfqq = container_of(entity, struct bfq_queue, entity); -+ -+ return bfqq; -+} -+ -+ -+/** -+ * bfq_delta - map service into the virtual time domain. -+ * @service: amount of service. -+ * @weight: scale factor (weight of an entity or weight sum). -+ */ -+static inline u64 bfq_delta(unsigned long service, -+ unsigned long weight) -+{ -+ u64 d = (u64)service << WFQ_SERVICE_SHIFT; -+ -+ do_div(d, weight); -+ return d; -+} -+ -+/** -+ * bfq_calc_finish - assign the finish time to an entity. -+ * @entity: the entity to act upon. -+ * @service: the service to be charged to the entity. -+ */ -+static inline void bfq_calc_finish(struct bfq_entity *entity, -+ unsigned long service) -+{ -+ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); -+ -+ BUG_ON(entity->weight == 0); -+ -+ entity->finish = entity->start + -+ bfq_delta(service, entity->weight); -+ -+ if (bfqq != NULL) { -+ bfq_log_bfqq(bfqq->bfqd, bfqq, -+ "calc_finish: serv %lu, w %d", -+ service, entity->weight); -+ bfq_log_bfqq(bfqq->bfqd, bfqq, -+ "calc_finish: start %llu, finish %llu, delta %llu", -+ entity->start, entity->finish, -+ bfq_delta(service, entity->weight)); -+ } -+} -+ -+/** -+ * bfq_entity_of - get an entity from a node. -+ * @node: the node field of the entity. -+ * -+ * Convert a node pointer to the relative entity. This is used only -+ * to simplify the logic of some functions and not as the generic -+ * conversion mechanism because, e.g., in the tree walking functions, -+ * the check for a %NULL value would be redundant. -+ */ -+static inline struct bfq_entity *bfq_entity_of(struct rb_node *node) -+{ -+ struct bfq_entity *entity = NULL; -+ -+ if (node != NULL) -+ entity = rb_entry(node, struct bfq_entity, rb_node); -+ -+ return entity; -+} -+ -+/** -+ * bfq_extract - remove an entity from a tree. -+ * @root: the tree root. -+ * @entity: the entity to remove. -+ */ -+static inline void bfq_extract(struct rb_root *root, -+ struct bfq_entity *entity) -+{ -+ BUG_ON(entity->tree != root); -+ -+ entity->tree = NULL; -+ rb_erase(&entity->rb_node, root); -+} -+ -+/** -+ * bfq_idle_extract - extract an entity from the idle tree. -+ * @st: the service tree of the owning @entity. -+ * @entity: the entity being removed. -+ */ -+static void bfq_idle_extract(struct bfq_service_tree *st, -+ struct bfq_entity *entity) -+{ -+ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); -+ struct rb_node *next; -+ -+ BUG_ON(entity->tree != &st->idle); -+ -+ if (entity == st->first_idle) { -+ next = rb_next(&entity->rb_node); -+ st->first_idle = bfq_entity_of(next); -+ } -+ -+ if (entity == st->last_idle) { -+ next = rb_prev(&entity->rb_node); -+ st->last_idle = bfq_entity_of(next); -+ } -+ -+ bfq_extract(&st->idle, entity); -+ -+ if (bfqq != NULL) -+ list_del(&bfqq->bfqq_list); -+} -+ -+/** -+ * bfq_insert - generic tree insertion. -+ * @root: tree root. -+ * @entity: entity to insert. -+ * -+ * This is used for the idle and the active tree, since they are both -+ * ordered by finish time. -+ */ -+static void bfq_insert(struct rb_root *root, struct bfq_entity *entity) -+{ -+ struct bfq_entity *entry; -+ struct rb_node **node = &root->rb_node; -+ struct rb_node *parent = NULL; -+ -+ BUG_ON(entity->tree != NULL); -+ -+ while (*node != NULL) { -+ parent = *node; -+ entry = rb_entry(parent, struct bfq_entity, rb_node); -+ -+ if (bfq_gt(entry->finish, entity->finish)) -+ node = &parent->rb_left; -+ else -+ node = &parent->rb_right; -+ } -+ -+ rb_link_node(&entity->rb_node, parent, node); -+ rb_insert_color(&entity->rb_node, root); -+ -+ entity->tree = root; -+} -+ -+/** -+ * bfq_update_min - update the min_start field of a entity. -+ * @entity: the entity to update. -+ * @node: one of its children. -+ * -+ * This function is called when @entity may store an invalid value for -+ * min_start due to updates to the active tree. The function assumes -+ * that the subtree rooted at @node (which may be its left or its right -+ * child) has a valid min_start value. -+ */ -+static inline void bfq_update_min(struct bfq_entity *entity, -+ struct rb_node *node) -+{ -+ struct bfq_entity *child; -+ -+ if (node != NULL) { -+ child = rb_entry(node, struct bfq_entity, rb_node); -+ if (bfq_gt(entity->min_start, child->min_start)) -+ entity->min_start = child->min_start; -+ } -+} -+ -+/** -+ * bfq_update_active_node - recalculate min_start. -+ * @node: the node to update. -+ * -+ * @node may have changed position or one of its children may have moved, -+ * this function updates its min_start value. The left and right subtrees -+ * are assumed to hold a correct min_start value. -+ */ -+static inline void bfq_update_active_node(struct rb_node *node) -+{ -+ struct bfq_entity *entity = rb_entry(node, struct bfq_entity, rb_node); -+ -+ entity->min_start = entity->start; -+ bfq_update_min(entity, node->rb_right); -+ bfq_update_min(entity, node->rb_left); -+} -+ -+/** -+ * bfq_update_active_tree - update min_start for the whole active tree. -+ * @node: the starting node. -+ * -+ * @node must be the deepest modified node after an update. This function -+ * updates its min_start using the values held by its children, assuming -+ * that they did not change, and then updates all the nodes that may have -+ * changed in the path to the root. The only nodes that may have changed -+ * are the ones in the path or their siblings. -+ */ -+static void bfq_update_active_tree(struct rb_node *node) -+{ -+ struct rb_node *parent; -+ -+up: -+ bfq_update_active_node(node); -+ -+ parent = rb_parent(node); -+ if (parent == NULL) -+ return; -+ -+ if (node == parent->rb_left && parent->rb_right != NULL) -+ bfq_update_active_node(parent->rb_right); -+ else if (parent->rb_left != NULL) -+ bfq_update_active_node(parent->rb_left); -+ -+ node = parent; -+ goto up; -+} -+ -+static void bfq_weights_tree_add(struct bfq_data *bfqd, -+ struct bfq_entity *entity, -+ struct rb_root *root); -+ -+static void bfq_weights_tree_remove(struct bfq_data *bfqd, -+ struct bfq_entity *entity, -+ struct rb_root *root); -+ -+ -+/** -+ * bfq_active_insert - insert an entity in the active tree of its -+ * group/device. -+ * @st: the service tree of the entity. -+ * @entity: the entity being inserted. -+ * -+ * The active tree is ordered by finish time, but an extra key is kept -+ * per each node, containing the minimum value for the start times of -+ * its children (and the node itself), so it's possible to search for -+ * the eligible node with the lowest finish time in logarithmic time. -+ */ -+static void bfq_active_insert(struct bfq_service_tree *st, -+ struct bfq_entity *entity) -+{ -+ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); -+ struct rb_node *node = &entity->rb_node; -+#ifdef CONFIG_CGROUP_BFQIO -+ struct bfq_sched_data *sd = NULL; -+ struct bfq_group *bfqg = NULL; -+ struct bfq_data *bfqd = NULL; -+#endif -+ -+ bfq_insert(&st->active, entity); -+ -+ if (node->rb_left != NULL) -+ node = node->rb_left; -+ else if (node->rb_right != NULL) -+ node = node->rb_right; -+ -+ bfq_update_active_tree(node); -+ -+#ifdef CONFIG_CGROUP_BFQIO -+ sd = entity->sched_data; -+ bfqg = container_of(sd, struct bfq_group, sched_data); -+ BUG_ON(!bfqg); -+ bfqd = (struct bfq_data *)bfqg->bfqd; -+#endif -+ if (bfqq != NULL) -+ list_add(&bfqq->bfqq_list, &bfqq->bfqd->active_list); -+#ifdef CONFIG_CGROUP_BFQIO -+ else { /* bfq_group */ -+ BUG_ON(!bfqd); -+ bfq_weights_tree_add(bfqd, entity, &bfqd->group_weights_tree); -+ } -+ if (bfqg != bfqd->root_group) { -+ BUG_ON(!bfqg); -+ BUG_ON(!bfqd); -+ bfqg->active_entities++; -+ if (bfqg->active_entities == 2) -+ bfqd->active_numerous_groups++; -+ } -+#endif -+} -+ -+/** -+ * bfq_ioprio_to_weight - calc a weight from an ioprio. -+ * @ioprio: the ioprio value to convert. -+ */ -+static inline unsigned short bfq_ioprio_to_weight(int ioprio) -+{ -+ BUG_ON(ioprio < 0 || ioprio >= IOPRIO_BE_NR); -+ return IOPRIO_BE_NR - ioprio; -+} -+ -+/** -+ * bfq_weight_to_ioprio - calc an ioprio from a weight. -+ * @weight: the weight value to convert. -+ * -+ * To preserve as mush as possible the old only-ioprio user interface, -+ * 0 is used as an escape ioprio value for weights (numerically) equal or -+ * larger than IOPRIO_BE_NR -+ */ -+static inline unsigned short bfq_weight_to_ioprio(int weight) -+{ -+ BUG_ON(weight < BFQ_MIN_WEIGHT || weight > BFQ_MAX_WEIGHT); -+ return IOPRIO_BE_NR - weight < 0 ? 0 : IOPRIO_BE_NR - weight; -+} -+ -+static inline void bfq_get_entity(struct bfq_entity *entity) -+{ -+ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); -+ -+ if (bfqq != NULL) { -+ atomic_inc(&bfqq->ref); -+ bfq_log_bfqq(bfqq->bfqd, bfqq, "get_entity: %p %d", -+ bfqq, atomic_read(&bfqq->ref)); -+ } -+} -+ -+/** -+ * bfq_find_deepest - find the deepest node that an extraction can modify. -+ * @node: the node being removed. -+ * -+ * Do the first step of an extraction in an rb tree, looking for the -+ * node that will replace @node, and returning the deepest node that -+ * the following modifications to the tree can touch. If @node is the -+ * last node in the tree return %NULL. -+ */ -+static struct rb_node *bfq_find_deepest(struct rb_node *node) -+{ -+ struct rb_node *deepest; -+ -+ if (node->rb_right == NULL && node->rb_left == NULL) -+ deepest = rb_parent(node); -+ else if (node->rb_right == NULL) -+ deepest = node->rb_left; -+ else if (node->rb_left == NULL) -+ deepest = node->rb_right; -+ else { -+ deepest = rb_next(node); -+ if (deepest->rb_right != NULL) -+ deepest = deepest->rb_right; -+ else if (rb_parent(deepest) != node) -+ deepest = rb_parent(deepest); -+ } -+ -+ return deepest; -+} -+ -+/** -+ * bfq_active_extract - remove an entity from the active tree. -+ * @st: the service_tree containing the tree. -+ * @entity: the entity being removed. -+ */ -+static void bfq_active_extract(struct bfq_service_tree *st, -+ struct bfq_entity *entity) -+{ -+ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); -+ struct rb_node *node; -+#ifdef CONFIG_CGROUP_BFQIO -+ struct bfq_sched_data *sd = NULL; -+ struct bfq_group *bfqg = NULL; -+ struct bfq_data *bfqd = NULL; -+#endif -+ -+ node = bfq_find_deepest(&entity->rb_node); -+ bfq_extract(&st->active, entity); -+ -+ if (node != NULL) -+ bfq_update_active_tree(node); -+ -+#ifdef CONFIG_CGROUP_BFQIO -+ sd = entity->sched_data; -+ bfqg = container_of(sd, struct bfq_group, sched_data); -+ BUG_ON(!bfqg); -+ bfqd = (struct bfq_data *)bfqg->bfqd; -+#endif -+ if (bfqq != NULL) -+ list_del(&bfqq->bfqq_list); -+#ifdef CONFIG_CGROUP_BFQIO -+ else { /* bfq_group */ -+ BUG_ON(!bfqd); -+ bfq_weights_tree_remove(bfqd, entity, -+ &bfqd->group_weights_tree); -+ } -+ if (bfqg != bfqd->root_group) { -+ BUG_ON(!bfqg); -+ BUG_ON(!bfqd); -+ BUG_ON(!bfqg->active_entities); -+ bfqg->active_entities--; -+ if (bfqg->active_entities == 1) { -+ BUG_ON(!bfqd->active_numerous_groups); -+ bfqd->active_numerous_groups--; -+ } -+ } -+#endif -+} -+ -+/** -+ * bfq_idle_insert - insert an entity into the idle tree. -+ * @st: the service tree containing the tree. -+ * @entity: the entity to insert. -+ */ -+static void bfq_idle_insert(struct bfq_service_tree *st, -+ struct bfq_entity *entity) -+{ -+ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); -+ struct bfq_entity *first_idle = st->first_idle; -+ struct bfq_entity *last_idle = st->last_idle; -+ -+ if (first_idle == NULL || bfq_gt(first_idle->finish, entity->finish)) -+ st->first_idle = entity; -+ if (last_idle == NULL || bfq_gt(entity->finish, last_idle->finish)) -+ st->last_idle = entity; -+ -+ bfq_insert(&st->idle, entity); -+ -+ if (bfqq != NULL) -+ list_add(&bfqq->bfqq_list, &bfqq->bfqd->idle_list); -+} -+ -+/** -+ * bfq_forget_entity - remove an entity from the wfq trees. -+ * @st: the service tree. -+ * @entity: the entity being removed. -+ * -+ * Update the device status and forget everything about @entity, putting -+ * the device reference to it, if it is a queue. Entities belonging to -+ * groups are not refcounted. -+ */ -+static void bfq_forget_entity(struct bfq_service_tree *st, -+ struct bfq_entity *entity) -+{ -+ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); -+ struct bfq_sched_data *sd; -+ -+ BUG_ON(!entity->on_st); -+ -+ entity->on_st = 0; -+ st->wsum -= entity->weight; -+ if (bfqq != NULL) { -+ sd = entity->sched_data; -+ bfq_log_bfqq(bfqq->bfqd, bfqq, "forget_entity: %p %d", -+ bfqq, atomic_read(&bfqq->ref)); -+ bfq_put_queue(bfqq); -+ } -+} -+ -+/** -+ * bfq_put_idle_entity - release the idle tree ref of an entity. -+ * @st: service tree for the entity. -+ * @entity: the entity being released. -+ */ -+static void bfq_put_idle_entity(struct bfq_service_tree *st, -+ struct bfq_entity *entity) -+{ -+ bfq_idle_extract(st, entity); -+ bfq_forget_entity(st, entity); -+} -+ -+/** -+ * bfq_forget_idle - update the idle tree if necessary. -+ * @st: the service tree to act upon. -+ * -+ * To preserve the global O(log N) complexity we only remove one entry here; -+ * as the idle tree will not grow indefinitely this can be done safely. -+ */ -+static void bfq_forget_idle(struct bfq_service_tree *st) -+{ -+ struct bfq_entity *first_idle = st->first_idle; -+ struct bfq_entity *last_idle = st->last_idle; -+ -+ if (RB_EMPTY_ROOT(&st->active) && last_idle != NULL && -+ !bfq_gt(last_idle->finish, st->vtime)) { -+ /* -+ * Forget the whole idle tree, increasing the vtime past -+ * the last finish time of idle entities. -+ */ -+ st->vtime = last_idle->finish; -+ } -+ -+ if (first_idle != NULL && !bfq_gt(first_idle->finish, st->vtime)) -+ bfq_put_idle_entity(st, first_idle); -+} -+ -+static struct bfq_service_tree * -+__bfq_entity_update_weight_prio(struct bfq_service_tree *old_st, -+ struct bfq_entity *entity) -+{ -+ struct bfq_service_tree *new_st = old_st; -+ -+ if (entity->ioprio_changed) { -+ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); -+ unsigned short prev_weight, new_weight; -+ struct bfq_data *bfqd = NULL; -+ struct rb_root *root; -+#ifdef CONFIG_CGROUP_BFQIO -+ struct bfq_sched_data *sd; -+ struct bfq_group *bfqg; -+#endif -+ -+ if (bfqq != NULL) -+ bfqd = bfqq->bfqd; -+#ifdef CONFIG_CGROUP_BFQIO -+ else { -+ sd = entity->my_sched_data; -+ bfqg = container_of(sd, struct bfq_group, sched_data); -+ BUG_ON(!bfqg); -+ bfqd = (struct bfq_data *)bfqg->bfqd; -+ BUG_ON(!bfqd); -+ } -+#endif -+ -+ BUG_ON(old_st->wsum < entity->weight); -+ old_st->wsum -= entity->weight; -+ -+ if (entity->new_weight != entity->orig_weight) { -+ if (entity->new_weight < BFQ_MIN_WEIGHT || -+ entity->new_weight > BFQ_MAX_WEIGHT) { -+ printk(KERN_CRIT "update_weight_prio: " -+ "new_weight %d\n", -+ entity->new_weight); -+ BUG(); -+ } -+ entity->orig_weight = entity->new_weight; -+ entity->ioprio = -+ bfq_weight_to_ioprio(entity->orig_weight); -+ } else if (entity->new_ioprio != entity->ioprio) { -+ entity->ioprio = entity->new_ioprio; -+ entity->orig_weight = -+ bfq_ioprio_to_weight(entity->ioprio); -+ } else -+ entity->new_weight = entity->orig_weight = -+ bfq_ioprio_to_weight(entity->ioprio); -+ -+ entity->ioprio_class = entity->new_ioprio_class; -+ entity->ioprio_changed = 0; -+ -+ /* -+ * NOTE: here we may be changing the weight too early, -+ * this will cause unfairness. The correct approach -+ * would have required additional complexity to defer -+ * weight changes to the proper time instants (i.e., -+ * when entity->finish <= old_st->vtime). -+ */ -+ new_st = bfq_entity_service_tree(entity); -+ -+ prev_weight = entity->weight; -+ new_weight = entity->orig_weight * -+ (bfqq != NULL ? bfqq->wr_coeff : 1); -+ /* -+ * If the weight of the entity changes, remove the entity -+ * from its old weight counter (if there is a counter -+ * associated with the entity), and add it to the counter -+ * associated with its new weight. -+ */ -+ if (prev_weight != new_weight) { -+ root = bfqq ? &bfqd->queue_weights_tree : -+ &bfqd->group_weights_tree; -+ bfq_weights_tree_remove(bfqd, entity, root); -+ } -+ entity->weight = new_weight; -+ /* -+ * Add the entity to its weights tree only if it is -+ * not associated with a weight-raised queue. -+ */ -+ if (prev_weight != new_weight && -+ (bfqq ? bfqq->wr_coeff == 1 : 1)) -+ /* If we get here, root has been initialized. */ -+ bfq_weights_tree_add(bfqd, entity, root); -+ -+ new_st->wsum += entity->weight; -+ -+ if (new_st != old_st) -+ entity->start = new_st->vtime; -+ } -+ -+ return new_st; -+} -+ -+/** -+ * bfq_bfqq_served - update the scheduler status after selection for -+ * service. -+ * @bfqq: the queue being served. -+ * @served: bytes to transfer. -+ * -+ * NOTE: this can be optimized, as the timestamps of upper level entities -+ * are synchronized every time a new bfqq is selected for service. By now, -+ * we keep it to better check consistency. -+ */ -+static void bfq_bfqq_served(struct bfq_queue *bfqq, unsigned long served) -+{ -+ struct bfq_entity *entity = &bfqq->entity; -+ struct bfq_service_tree *st; -+ -+ for_each_entity(entity) { -+ st = bfq_entity_service_tree(entity); -+ -+ entity->service += served; -+ BUG_ON(entity->service > entity->budget); -+ BUG_ON(st->wsum == 0); -+ -+ st->vtime += bfq_delta(served, st->wsum); -+ bfq_forget_idle(st); -+ } -+ bfq_log_bfqq(bfqq->bfqd, bfqq, "bfqq_served %lu secs", served); -+} -+ -+/** -+ * bfq_bfqq_charge_full_budget - set the service to the entity budget. -+ * @bfqq: the queue that needs a service update. -+ * -+ * When it's not possible to be fair in the service domain, because -+ * a queue is not consuming its budget fast enough (the meaning of -+ * fast depends on the timeout parameter), we charge it a full -+ * budget. In this way we should obtain a sort of time-domain -+ * fairness among all the seeky/slow queues. -+ */ -+static inline void bfq_bfqq_charge_full_budget(struct bfq_queue *bfqq) -+{ -+ struct bfq_entity *entity = &bfqq->entity; -+ -+ bfq_log_bfqq(bfqq->bfqd, bfqq, "charge_full_budget"); -+ -+ bfq_bfqq_served(bfqq, entity->budget - entity->service); -+} -+ -+/** -+ * __bfq_activate_entity - activate an entity. -+ * @entity: the entity being activated. -+ * -+ * Called whenever an entity is activated, i.e., it is not active and one -+ * of its children receives a new request, or has to be reactivated due to -+ * budget exhaustion. It uses the current budget of the entity (and the -+ * service received if @entity is active) of the queue to calculate its -+ * timestamps. -+ */ -+static void __bfq_activate_entity(struct bfq_entity *entity) -+{ -+ struct bfq_sched_data *sd = entity->sched_data; -+ struct bfq_service_tree *st = bfq_entity_service_tree(entity); -+ -+ if (entity == sd->in_service_entity) { -+ BUG_ON(entity->tree != NULL); -+ /* -+ * If we are requeueing the current entity we have -+ * to take care of not charging to it service it has -+ * not received. -+ */ -+ bfq_calc_finish(entity, entity->service); -+ entity->start = entity->finish; -+ sd->in_service_entity = NULL; -+ } else if (entity->tree == &st->active) { -+ /* -+ * Requeueing an entity due to a change of some -+ * next_in_service entity below it. We reuse the -+ * old start time. -+ */ -+ bfq_active_extract(st, entity); -+ } else if (entity->tree == &st->idle) { -+ /* -+ * Must be on the idle tree, bfq_idle_extract() will -+ * check for that. -+ */ -+ bfq_idle_extract(st, entity); -+ entity->start = bfq_gt(st->vtime, entity->finish) ? -+ st->vtime : entity->finish; -+ } else { -+ /* -+ * The finish time of the entity may be invalid, and -+ * it is in the past for sure, otherwise the queue -+ * would have been on the idle tree. -+ */ -+ entity->start = st->vtime; -+ st->wsum += entity->weight; -+ bfq_get_entity(entity); -+ -+ BUG_ON(entity->on_st); -+ entity->on_st = 1; -+ } -+ -+ st = __bfq_entity_update_weight_prio(st, entity); -+ bfq_calc_finish(entity, entity->budget); -+ bfq_active_insert(st, entity); -+} -+ -+/** -+ * bfq_activate_entity - activate an entity and its ancestors if necessary. -+ * @entity: the entity to activate. -+ * -+ * Activate @entity and all the entities on the path from it to the root. -+ */ -+static void bfq_activate_entity(struct bfq_entity *entity) -+{ -+ struct bfq_sched_data *sd; -+ -+ for_each_entity(entity) { -+ __bfq_activate_entity(entity); -+ -+ sd = entity->sched_data; -+ if (!bfq_update_next_in_service(sd)) -+ /* -+ * No need to propagate the activation to the -+ * upper entities, as they will be updated when -+ * the in-service entity is rescheduled. -+ */ -+ break; -+ } -+} -+ -+/** -+ * __bfq_deactivate_entity - deactivate an entity from its service tree. -+ * @entity: the entity to deactivate. -+ * @requeue: if false, the entity will not be put into the idle tree. -+ * -+ * Deactivate an entity, independently from its previous state. If the -+ * entity was not on a service tree just return, otherwise if it is on -+ * any scheduler tree, extract it from that tree, and if necessary -+ * and if the caller did not specify @requeue, put it on the idle tree. -+ * -+ * Return %1 if the caller should update the entity hierarchy, i.e., -+ * if the entity was in service or if it was the next_in_service for -+ * its sched_data; return %0 otherwise. -+ */ -+static int __bfq_deactivate_entity(struct bfq_entity *entity, int requeue) -+{ -+ struct bfq_sched_data *sd = entity->sched_data; -+ struct bfq_service_tree *st = bfq_entity_service_tree(entity); -+ int was_in_service = entity == sd->in_service_entity; -+ int ret = 0; -+ -+ if (!entity->on_st) -+ return 0; -+ -+ BUG_ON(was_in_service && entity->tree != NULL); -+ -+ if (was_in_service) { -+ bfq_calc_finish(entity, entity->service); -+ sd->in_service_entity = NULL; -+ } else if (entity->tree == &st->active) -+ bfq_active_extract(st, entity); -+ else if (entity->tree == &st->idle) -+ bfq_idle_extract(st, entity); -+ else if (entity->tree != NULL) -+ BUG(); -+ -+ if (was_in_service || sd->next_in_service == entity) -+ ret = bfq_update_next_in_service(sd); -+ -+ if (!requeue || !bfq_gt(entity->finish, st->vtime)) -+ bfq_forget_entity(st, entity); -+ else -+ bfq_idle_insert(st, entity); -+ -+ BUG_ON(sd->in_service_entity == entity); -+ BUG_ON(sd->next_in_service == entity); -+ -+ return ret; -+} -+ -+/** -+ * bfq_deactivate_entity - deactivate an entity. -+ * @entity: the entity to deactivate. -+ * @requeue: true if the entity can be put on the idle tree -+ */ -+static void bfq_deactivate_entity(struct bfq_entity *entity, int requeue) -+{ -+ struct bfq_sched_data *sd; -+ struct bfq_entity *parent; -+ -+ for_each_entity_safe(entity, parent) { -+ sd = entity->sched_data; -+ -+ if (!__bfq_deactivate_entity(entity, requeue)) -+ /* -+ * The parent entity is still backlogged, and -+ * we don't need to update it as it is still -+ * in service. -+ */ -+ break; -+ -+ if (sd->next_in_service != NULL) -+ /* -+ * The parent entity is still backlogged and -+ * the budgets on the path towards the root -+ * need to be updated. -+ */ -+ goto update; -+ -+ /* -+ * If we reach there the parent is no more backlogged and -+ * we want to propagate the dequeue upwards. -+ */ -+ requeue = 1; -+ } -+ -+ return; -+ -+update: -+ entity = parent; -+ for_each_entity(entity) { -+ __bfq_activate_entity(entity); -+ -+ sd = entity->sched_data; -+ if (!bfq_update_next_in_service(sd)) -+ break; -+ } -+} -+ -+/** -+ * bfq_update_vtime - update vtime if necessary. -+ * @st: the service tree to act upon. -+ * -+ * If necessary update the service tree vtime to have at least one -+ * eligible entity, skipping to its start time. Assumes that the -+ * active tree of the device is not empty. -+ * -+ * NOTE: this hierarchical implementation updates vtimes quite often, -+ * we may end up with reactivated processes getting timestamps after a -+ * vtime skip done because we needed a ->first_active entity on some -+ * intermediate node. -+ */ -+static void bfq_update_vtime(struct bfq_service_tree *st) -+{ -+ struct bfq_entity *entry; -+ struct rb_node *node = st->active.rb_node; -+ -+ entry = rb_entry(node, struct bfq_entity, rb_node); -+ if (bfq_gt(entry->min_start, st->vtime)) { -+ st->vtime = entry->min_start; -+ bfq_forget_idle(st); -+ } -+} -+ -+/** -+ * bfq_first_active_entity - find the eligible entity with -+ * the smallest finish time -+ * @st: the service tree to select from. -+ * -+ * This function searches the first schedulable entity, starting from the -+ * root of the tree and going on the left every time on this side there is -+ * a subtree with at least one eligible (start >= vtime) entity. The path on -+ * the right is followed only if a) the left subtree contains no eligible -+ * entities and b) no eligible entity has been found yet. -+ */ -+static struct bfq_entity *bfq_first_active_entity(struct bfq_service_tree *st) -+{ -+ struct bfq_entity *entry, *first = NULL; -+ struct rb_node *node = st->active.rb_node; -+ -+ while (node != NULL) { -+ entry = rb_entry(node, struct bfq_entity, rb_node); -+left: -+ if (!bfq_gt(entry->start, st->vtime)) -+ first = entry; -+ -+ BUG_ON(bfq_gt(entry->min_start, st->vtime)); -+ -+ if (node->rb_left != NULL) { -+ entry = rb_entry(node->rb_left, -+ struct bfq_entity, rb_node); -+ if (!bfq_gt(entry->min_start, st->vtime)) { -+ node = node->rb_left; -+ goto left; -+ } -+ } -+ if (first != NULL) -+ break; -+ node = node->rb_right; -+ } -+ -+ BUG_ON(first == NULL && !RB_EMPTY_ROOT(&st->active)); -+ return first; -+} -+ -+/** -+ * __bfq_lookup_next_entity - return the first eligible entity in @st. -+ * @st: the service tree. -+ * -+ * Update the virtual time in @st and return the first eligible entity -+ * it contains. -+ */ -+static struct bfq_entity *__bfq_lookup_next_entity(struct bfq_service_tree *st, -+ bool force) -+{ -+ struct bfq_entity *entity, *new_next_in_service = NULL; -+ -+ if (RB_EMPTY_ROOT(&st->active)) -+ return NULL; -+ -+ bfq_update_vtime(st); -+ entity = bfq_first_active_entity(st); -+ BUG_ON(bfq_gt(entity->start, st->vtime)); -+ -+ /* -+ * If the chosen entity does not match with the sched_data's -+ * next_in_service and we are forcedly serving the IDLE priority -+ * class tree, bubble up budget update. -+ */ -+ if (unlikely(force && entity != entity->sched_data->next_in_service)) { -+ new_next_in_service = entity; -+ for_each_entity(new_next_in_service) -+ bfq_update_budget(new_next_in_service); -+ } -+ -+ return entity; -+} -+ -+/** -+ * bfq_lookup_next_entity - return the first eligible entity in @sd. -+ * @sd: the sched_data. -+ * @extract: if true the returned entity will be also extracted from @sd. -+ * -+ * NOTE: since we cache the next_in_service entity at each level of the -+ * hierarchy, the complexity of the lookup can be decreased with -+ * absolutely no effort just returning the cached next_in_service value; -+ * we prefer to do full lookups to test the consistency of * the data -+ * structures. -+ */ -+static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd, -+ int extract, -+ struct bfq_data *bfqd) -+{ -+ struct bfq_service_tree *st = sd->service_tree; -+ struct bfq_entity *entity; -+ int i = 0; -+ -+ BUG_ON(sd->in_service_entity != NULL); -+ -+ if (bfqd != NULL && -+ jiffies - bfqd->bfq_class_idle_last_service > BFQ_CL_IDLE_TIMEOUT) { -+ entity = __bfq_lookup_next_entity(st + BFQ_IOPRIO_CLASSES - 1, -+ true); -+ if (entity != NULL) { -+ i = BFQ_IOPRIO_CLASSES - 1; -+ bfqd->bfq_class_idle_last_service = jiffies; -+ sd->next_in_service = entity; -+ } -+ } -+ for (; i < BFQ_IOPRIO_CLASSES; i++) { -+ entity = __bfq_lookup_next_entity(st + i, false); -+ if (entity != NULL) { -+ if (extract) { -+ bfq_check_next_in_service(sd, entity); -+ bfq_active_extract(st + i, entity); -+ sd->in_service_entity = entity; -+ sd->next_in_service = NULL; -+ } -+ break; -+ } -+ } -+ -+ return entity; -+} -+ -+/* -+ * Get next queue for service. -+ */ -+static struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd) -+{ -+ struct bfq_entity *entity = NULL; -+ struct bfq_sched_data *sd; -+ struct bfq_queue *bfqq; -+ -+ BUG_ON(bfqd->in_service_queue != NULL); -+ -+ if (bfqd->busy_queues == 0) -+ return NULL; -+ -+ sd = &bfqd->root_group->sched_data; -+ for (; sd != NULL; sd = entity->my_sched_data) { -+ entity = bfq_lookup_next_entity(sd, 1, bfqd); -+ BUG_ON(entity == NULL); -+ entity->service = 0; -+ } -+ -+ bfqq = bfq_entity_to_bfqq(entity); -+ BUG_ON(bfqq == NULL); -+ -+ return bfqq; -+} -+ -+/* -+ * Forced extraction of the given queue. -+ */ -+static void bfq_get_next_queue_forced(struct bfq_data *bfqd, -+ struct bfq_queue *bfqq) -+{ -+ struct bfq_entity *entity; -+ struct bfq_sched_data *sd; -+ -+ BUG_ON(bfqd->in_service_queue != NULL); -+ -+ entity = &bfqq->entity; -+ /* -+ * Bubble up extraction/update from the leaf to the root. -+ */ -+ for_each_entity(entity) { -+ sd = entity->sched_data; -+ bfq_update_budget(entity); -+ bfq_update_vtime(bfq_entity_service_tree(entity)); -+ bfq_active_extract(bfq_entity_service_tree(entity), entity); -+ sd->in_service_entity = entity; -+ sd->next_in_service = NULL; -+ entity->service = 0; -+ } -+ -+ return; -+} -+ -+static void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd) -+{ -+ if (bfqd->in_service_bic != NULL) { -+ put_io_context(bfqd->in_service_bic->icq.ioc); -+ bfqd->in_service_bic = NULL; -+ } -+ -+ bfqd->in_service_queue = NULL; -+ del_timer(&bfqd->idle_slice_timer); -+} -+ -+static void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, -+ int requeue) -+{ -+ struct bfq_entity *entity = &bfqq->entity; -+ -+ if (bfqq == bfqd->in_service_queue) -+ __bfq_bfqd_reset_in_service(bfqd); -+ -+ bfq_deactivate_entity(entity, requeue); -+} -+ -+static void bfq_activate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq) -+{ -+ struct bfq_entity *entity = &bfqq->entity; -+ -+ bfq_activate_entity(entity); -+} -+ -+/* -+ * Called when the bfqq no longer has requests pending, remove it from -+ * the service tree. -+ */ -+static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq, -+ int requeue) -+{ -+ BUG_ON(!bfq_bfqq_busy(bfqq)); -+ BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list)); -+ -+ bfq_log_bfqq(bfqd, bfqq, "del from busy"); -+ -+ bfq_clear_bfqq_busy(bfqq); -+ -+ BUG_ON(bfqd->busy_queues == 0); -+ bfqd->busy_queues--; -+ -+ if (!bfqq->dispatched) { -+ bfq_weights_tree_remove(bfqd, &bfqq->entity, -+ &bfqd->queue_weights_tree); -+ if (!blk_queue_nonrot(bfqd->queue)) { -+ BUG_ON(!bfqd->busy_in_flight_queues); -+ bfqd->busy_in_flight_queues--; -+ if (bfq_bfqq_constantly_seeky(bfqq)) { -+ BUG_ON(!bfqd-> -+ const_seeky_busy_in_flight_queues); -+ bfqd->const_seeky_busy_in_flight_queues--; -+ } -+ } -+ } -+ if (bfqq->wr_coeff > 1) -+ bfqd->wr_busy_queues--; -+ -+ bfq_deactivate_bfqq(bfqd, bfqq, requeue); -+} -+ -+/* -+ * Called when an inactive queue receives a new request. -+ */ -+static void bfq_add_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq) -+{ -+ BUG_ON(bfq_bfqq_busy(bfqq)); -+ BUG_ON(bfqq == bfqd->in_service_queue); -+ -+ bfq_log_bfqq(bfqd, bfqq, "add to busy"); -+ -+ bfq_activate_bfqq(bfqd, bfqq); -+ -+ bfq_mark_bfqq_busy(bfqq); -+ bfqd->busy_queues++; -+ -+ if (!bfqq->dispatched) { -+ if (bfqq->wr_coeff == 1) -+ bfq_weights_tree_add(bfqd, &bfqq->entity, -+ &bfqd->queue_weights_tree); -+ if (!blk_queue_nonrot(bfqd->queue)) { -+ bfqd->busy_in_flight_queues++; -+ if (bfq_bfqq_constantly_seeky(bfqq)) -+ bfqd->const_seeky_busy_in_flight_queues++; -+ } -+ } -+ if (bfqq->wr_coeff > 1) -+ bfqd->wr_busy_queues++; -+} -diff --git a/block/bfq.h b/block/bfq.h -new file mode 100644 -index 0000000..3c5d85e ---- /dev/null -+++ b/block/bfq.h -@@ -0,0 +1,775 @@ -+/* -+ * BFQ-v7r7 for 3.19.0: data structures and common functions prototypes. -+ * -+ * Based on ideas and code from CFQ: -+ * Copyright (C) 2003 Jens Axboe -+ * -+ * Copyright (C) 2008 Fabio Checconi -+ * Paolo Valente -+ * -+ * Copyright (C) 2010 Paolo Valente -+ */ -+ -+#ifndef _BFQ_H -+#define _BFQ_H -+ -+#include -+#include -+#include -+#include -+ -+#define BFQ_IOPRIO_CLASSES 3 -+#define BFQ_CL_IDLE_TIMEOUT (HZ/5) -+ -+#define BFQ_MIN_WEIGHT 1 -+#define BFQ_MAX_WEIGHT 1000 -+ -+#define BFQ_DEFAULT_QUEUE_IOPRIO 4 -+ -+#define BFQ_DEFAULT_GRP_WEIGHT 10 -+#define BFQ_DEFAULT_GRP_IOPRIO 0 -+#define BFQ_DEFAULT_GRP_CLASS IOPRIO_CLASS_BE -+ -+struct bfq_entity; -+ -+/** -+ * struct bfq_service_tree - per ioprio_class service tree. -+ * @active: tree for active entities (i.e., those backlogged). -+ * @idle: tree for idle entities (i.e., those not backlogged, with V <= F_i). -+ * @first_idle: idle entity with minimum F_i. -+ * @last_idle: idle entity with maximum F_i. -+ * @vtime: scheduler virtual time. -+ * @wsum: scheduler weight sum; active and idle entities contribute to it. -+ * -+ * Each service tree represents a B-WF2Q+ scheduler on its own. Each -+ * ioprio_class has its own independent scheduler, and so its own -+ * bfq_service_tree. All the fields are protected by the queue lock -+ * of the containing bfqd. -+ */ -+struct bfq_service_tree { -+ struct rb_root active; -+ struct rb_root idle; -+ -+ struct bfq_entity *first_idle; -+ struct bfq_entity *last_idle; -+ -+ u64 vtime; -+ unsigned long wsum; -+}; -+ -+/** -+ * struct bfq_sched_data - multi-class scheduler. -+ * @in_service_entity: entity in service. -+ * @next_in_service: head-of-the-line entity in the scheduler. -+ * @service_tree: array of service trees, one per ioprio_class. -+ * -+ * bfq_sched_data is the basic scheduler queue. It supports three -+ * ioprio_classes, and can be used either as a toplevel queue or as -+ * an intermediate queue on a hierarchical setup. -+ * @next_in_service points to the active entity of the sched_data -+ * service trees that will be scheduled next. -+ * -+ * The supported ioprio_classes are the same as in CFQ, in descending -+ * priority order, IOPRIO_CLASS_RT, IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE. -+ * Requests from higher priority queues are served before all the -+ * requests from lower priority queues; among requests of the same -+ * queue requests are served according to B-WF2Q+. -+ * All the fields are protected by the queue lock of the containing bfqd. -+ */ -+struct bfq_sched_data { -+ struct bfq_entity *in_service_entity; -+ struct bfq_entity *next_in_service; -+ struct bfq_service_tree service_tree[BFQ_IOPRIO_CLASSES]; -+}; -+ -+/** -+ * struct bfq_weight_counter - counter of the number of all active entities -+ * with a given weight. -+ * @weight: weight of the entities that this counter refers to. -+ * @num_active: number of active entities with this weight. -+ * @weights_node: weights tree member (see bfq_data's @queue_weights_tree -+ * and @group_weights_tree). -+ */ -+struct bfq_weight_counter { -+ short int weight; -+ unsigned int num_active; -+ struct rb_node weights_node; -+}; -+ -+/** -+ * struct bfq_entity - schedulable entity. -+ * @rb_node: service_tree member. -+ * @weight_counter: pointer to the weight counter associated with this entity. -+ * @on_st: flag, true if the entity is on a tree (either the active or -+ * the idle one of its service_tree). -+ * @finish: B-WF2Q+ finish timestamp (aka F_i). -+ * @start: B-WF2Q+ start timestamp (aka S_i). -+ * @tree: tree the entity is enqueued into; %NULL if not on a tree. -+ * @min_start: minimum start time of the (active) subtree rooted at -+ * this entity; used for O(log N) lookups into active trees. -+ * @service: service received during the last round of service. -+ * @budget: budget used to calculate F_i; F_i = S_i + @budget / @weight. -+ * @weight: weight of the queue -+ * @parent: parent entity, for hierarchical scheduling. -+ * @my_sched_data: for non-leaf nodes in the cgroup hierarchy, the -+ * associated scheduler queue, %NULL on leaf nodes. -+ * @sched_data: the scheduler queue this entity belongs to. -+ * @ioprio: the ioprio in use. -+ * @new_weight: when a weight change is requested, the new weight value. -+ * @orig_weight: original weight, used to implement weight boosting -+ * @new_ioprio: when an ioprio change is requested, the new ioprio value. -+ * @ioprio_class: the ioprio_class in use. -+ * @new_ioprio_class: when an ioprio_class change is requested, the new -+ * ioprio_class value. -+ * @ioprio_changed: flag, true when the user requested a weight, ioprio or -+ * ioprio_class change. -+ * -+ * A bfq_entity is used to represent either a bfq_queue (leaf node in the -+ * cgroup hierarchy) or a bfq_group into the upper level scheduler. Each -+ * entity belongs to the sched_data of the parent group in the cgroup -+ * hierarchy. Non-leaf entities have also their own sched_data, stored -+ * in @my_sched_data. -+ * -+ * Each entity stores independently its priority values; this would -+ * allow different weights on different devices, but this -+ * functionality is not exported to userspace by now. Priorities and -+ * weights are updated lazily, first storing the new values into the -+ * new_* fields, then setting the @ioprio_changed flag. As soon as -+ * there is a transition in the entity state that allows the priority -+ * update to take place the effective and the requested priority -+ * values are synchronized. -+ * -+ * Unless cgroups are used, the weight value is calculated from the -+ * ioprio to export the same interface as CFQ. When dealing with -+ * ``well-behaved'' queues (i.e., queues that do not spend too much -+ * time to consume their budget and have true sequential behavior, and -+ * when there are no external factors breaking anticipation) the -+ * relative weights at each level of the cgroups hierarchy should be -+ * guaranteed. All the fields are protected by the queue lock of the -+ * containing bfqd. -+ */ -+struct bfq_entity { -+ struct rb_node rb_node; -+ struct bfq_weight_counter *weight_counter; -+ -+ int on_st; -+ -+ u64 finish; -+ u64 start; -+ -+ struct rb_root *tree; -+ -+ u64 min_start; -+ -+ unsigned long service, budget; -+ unsigned short weight, new_weight; -+ unsigned short orig_weight; -+ -+ struct bfq_entity *parent; -+ -+ struct bfq_sched_data *my_sched_data; -+ struct bfq_sched_data *sched_data; -+ -+ unsigned short ioprio, new_ioprio; -+ unsigned short ioprio_class, new_ioprio_class; -+ -+ int ioprio_changed; -+}; -+ -+struct bfq_group; -+ -+/** -+ * struct bfq_queue - leaf schedulable entity. -+ * @ref: reference counter. -+ * @bfqd: parent bfq_data. -+ * @new_bfqq: shared bfq_queue if queue is cooperating with -+ * one or more other queues. -+ * @pos_node: request-position tree member (see bfq_data's @rq_pos_tree). -+ * @pos_root: request-position tree root (see bfq_data's @rq_pos_tree). -+ * @sort_list: sorted list of pending requests. -+ * @next_rq: if fifo isn't expired, next request to serve. -+ * @queued: nr of requests queued in @sort_list. -+ * @allocated: currently allocated requests. -+ * @meta_pending: pending metadata requests. -+ * @fifo: fifo list of requests in sort_list. -+ * @entity: entity representing this queue in the scheduler. -+ * @max_budget: maximum budget allowed from the feedback mechanism. -+ * @budget_timeout: budget expiration (in jiffies). -+ * @dispatched: number of requests on the dispatch list or inside driver. -+ * @flags: status flags. -+ * @bfqq_list: node for active/idle bfqq list inside our bfqd. -+ * @burst_list_node: node for the device's burst list. -+ * @seek_samples: number of seeks sampled -+ * @seek_total: sum of the distances of the seeks sampled -+ * @seek_mean: mean seek distance -+ * @last_request_pos: position of the last request enqueued -+ * @requests_within_timer: number of consecutive pairs of request completion -+ * and arrival, such that the queue becomes idle -+ * after the completion, but the next request arrives -+ * within an idle time slice; used only if the queue's -+ * IO_bound has been cleared. -+ * @pid: pid of the process owning the queue, used for logging purposes. -+ * @last_wr_start_finish: start time of the current weight-raising period if -+ * the @bfq-queue is being weight-raised, otherwise -+ * finish time of the last weight-raising period -+ * @wr_cur_max_time: current max raising time for this queue -+ * @soft_rt_next_start: minimum time instant such that, only if a new -+ * request is enqueued after this time instant in an -+ * idle @bfq_queue with no outstanding requests, then -+ * the task associated with the queue it is deemed as -+ * soft real-time (see the comments to the function -+ * bfq_bfqq_softrt_next_start()). -+ * @last_idle_bklogged: time of the last transition of the @bfq_queue from -+ * idle to backlogged -+ * @service_from_backlogged: cumulative service received from the @bfq_queue -+ * since the last transition from idle to -+ * backlogged -+ * -+ * A bfq_queue is a leaf request queue; it can be associated with an io_context -+ * or more, if it is async or shared between cooperating processes. @cgroup -+ * holds a reference to the cgroup, to be sure that it does not disappear while -+ * a bfqq still references it (mostly to avoid races between request issuing and -+ * task migration followed by cgroup destruction). -+ * All the fields are protected by the queue lock of the containing bfqd. -+ */ -+struct bfq_queue { -+ atomic_t ref; -+ struct bfq_data *bfqd; -+ -+ /* fields for cooperating queues handling */ -+ struct bfq_queue *new_bfqq; -+ struct rb_node pos_node; -+ struct rb_root *pos_root; -+ -+ struct rb_root sort_list; -+ struct request *next_rq; -+ int queued[2]; -+ int allocated[2]; -+ int meta_pending; -+ struct list_head fifo; -+ -+ struct bfq_entity entity; -+ -+ unsigned long max_budget; -+ unsigned long budget_timeout; -+ -+ int dispatched; -+ -+ unsigned int flags; -+ -+ struct list_head bfqq_list; -+ -+ struct hlist_node burst_list_node; -+ -+ unsigned int seek_samples; -+ u64 seek_total; -+ sector_t seek_mean; -+ sector_t last_request_pos; -+ -+ unsigned int requests_within_timer; -+ -+ pid_t pid; -+ -+ /* weight-raising fields */ -+ unsigned long wr_cur_max_time; -+ unsigned long soft_rt_next_start; -+ unsigned long last_wr_start_finish; -+ unsigned int wr_coeff; -+ unsigned long last_idle_bklogged; -+ unsigned long service_from_backlogged; -+}; -+ -+/** -+ * struct bfq_ttime - per process thinktime stats. -+ * @ttime_total: total process thinktime -+ * @ttime_samples: number of thinktime samples -+ * @ttime_mean: average process thinktime -+ */ -+struct bfq_ttime { -+ unsigned long last_end_request; -+ -+ unsigned long ttime_total; -+ unsigned long ttime_samples; -+ unsigned long ttime_mean; -+}; -+ -+/** -+ * struct bfq_io_cq - per (request_queue, io_context) structure. -+ * @icq: associated io_cq structure -+ * @bfqq: array of two process queues, the sync and the async -+ * @ttime: associated @bfq_ttime struct -+ */ -+struct bfq_io_cq { -+ struct io_cq icq; /* must be the first member */ -+ struct bfq_queue *bfqq[2]; -+ struct bfq_ttime ttime; -+ int ioprio; -+}; -+ -+enum bfq_device_speed { -+ BFQ_BFQD_FAST, -+ BFQ_BFQD_SLOW, -+}; -+ -+/** -+ * struct bfq_data - per device data structure. -+ * @queue: request queue for the managed device. -+ * @root_group: root bfq_group for the device. -+ * @rq_pos_tree: rbtree sorted by next_request position, used when -+ * determining if two or more queues have interleaving -+ * requests (see bfq_close_cooperator()). -+ * @active_numerous_groups: number of bfq_groups containing more than one -+ * active @bfq_entity. -+ * @queue_weights_tree: rbtree of weight counters of @bfq_queues, sorted by -+ * weight. Used to keep track of whether all @bfq_queues -+ * have the same weight. The tree contains one counter -+ * for each distinct weight associated to some active -+ * and not weight-raised @bfq_queue (see the comments to -+ * the functions bfq_weights_tree_[add|remove] for -+ * further details). -+ * @group_weights_tree: rbtree of non-queue @bfq_entity weight counters, sorted -+ * by weight. Used to keep track of whether all -+ * @bfq_groups have the same weight. The tree contains -+ * one counter for each distinct weight associated to -+ * some active @bfq_group (see the comments to the -+ * functions bfq_weights_tree_[add|remove] for further -+ * details). -+ * @busy_queues: number of bfq_queues containing requests (including the -+ * queue in service, even if it is idling). -+ * @busy_in_flight_queues: number of @bfq_queues containing pending or -+ * in-flight requests, plus the @bfq_queue in -+ * service, even if idle but waiting for the -+ * possible arrival of its next sync request. This -+ * field is updated only if the device is rotational, -+ * but used only if the device is also NCQ-capable. -+ * The reason why the field is updated also for non- -+ * NCQ-capable rotational devices is related to the -+ * fact that the value of @hw_tag may be set also -+ * later than when busy_in_flight_queues may need to -+ * be incremented for the first time(s). Taking also -+ * this possibility into account, to avoid unbalanced -+ * increments/decrements, would imply more overhead -+ * than just updating busy_in_flight_queues -+ * regardless of the value of @hw_tag. -+ * @const_seeky_busy_in_flight_queues: number of constantly-seeky @bfq_queues -+ * (that is, seeky queues that expired -+ * for budget timeout at least once) -+ * containing pending or in-flight -+ * requests, including the in-service -+ * @bfq_queue if constantly seeky. This -+ * field is updated only if the device -+ * is rotational, but used only if the -+ * device is also NCQ-capable (see the -+ * comments to @busy_in_flight_queues). -+ * @wr_busy_queues: number of weight-raised busy @bfq_queues. -+ * @queued: number of queued requests. -+ * @rq_in_driver: number of requests dispatched and waiting for completion. -+ * @sync_flight: number of sync requests in the driver. -+ * @max_rq_in_driver: max number of reqs in driver in the last -+ * @hw_tag_samples completed requests. -+ * @hw_tag_samples: nr of samples used to calculate hw_tag. -+ * @hw_tag: flag set to one if the driver is showing a queueing behavior. -+ * @budgets_assigned: number of budgets assigned. -+ * @idle_slice_timer: timer set when idling for the next sequential request -+ * from the queue in service. -+ * @unplug_work: delayed work to restart dispatching on the request queue. -+ * @in_service_queue: bfq_queue in service. -+ * @in_service_bic: bfq_io_cq (bic) associated with the @in_service_queue. -+ * @last_position: on-disk position of the last served request. -+ * @last_budget_start: beginning of the last budget. -+ * @last_idling_start: beginning of the last idle slice. -+ * @peak_rate: peak transfer rate observed for a budget. -+ * @peak_rate_samples: number of samples used to calculate @peak_rate. -+ * @bfq_max_budget: maximum budget allotted to a bfq_queue before -+ * rescheduling. -+ * @group_list: list of all the bfq_groups active on the device. -+ * @active_list: list of all the bfq_queues active on the device. -+ * @idle_list: list of all the bfq_queues idle on the device. -+ * @bfq_quantum: max number of requests dispatched per dispatch round. -+ * @bfq_fifo_expire: timeout for async/sync requests; when it expires -+ * requests are served in fifo order. -+ * @bfq_back_penalty: weight of backward seeks wrt forward ones. -+ * @bfq_back_max: maximum allowed backward seek. -+ * @bfq_slice_idle: maximum idling time. -+ * @bfq_user_max_budget: user-configured max budget value -+ * (0 for auto-tuning). -+ * @bfq_max_budget_async_rq: maximum budget (in nr of requests) allotted to -+ * async queues. -+ * @bfq_timeout: timeout for bfq_queues to consume their budget; used to -+ * to prevent seeky queues to impose long latencies to well -+ * behaved ones (this also implies that seeky queues cannot -+ * receive guarantees in the service domain; after a timeout -+ * they are charged for the whole allocated budget, to try -+ * to preserve a behavior reasonably fair among them, but -+ * without service-domain guarantees). -+ * @bfq_coop_thresh: number of queue merges after which a @bfq_queue is -+ * no more granted any weight-raising. -+ * @bfq_failed_cooperations: number of consecutive failed cooperation -+ * chances after which weight-raising is restored -+ * to a queue subject to more than bfq_coop_thresh -+ * queue merges. -+ * @bfq_requests_within_timer: number of consecutive requests that must be -+ * issued within the idle time slice to set -+ * again idling to a queue which was marked as -+ * non-I/O-bound (see the definition of the -+ * IO_bound flag for further details). -+ * @last_ins_in_burst: last time at which a queue entered the current -+ * burst of queues being activated shortly after -+ * each other; for more details about this and the -+ * following parameters related to a burst of -+ * activations, see the comments to the function -+ * @bfq_handle_burst. -+ * @bfq_burst_interval: reference time interval used to decide whether a -+ * queue has been activated shortly after -+ * @last_ins_in_burst. -+ * @burst_size: number of queues in the current burst of queue activations. -+ * @bfq_large_burst_thresh: maximum burst size above which the current -+ * queue-activation burst is deemed as 'large'. -+ * @large_burst: true if a large queue-activation burst is in progress. -+ * @burst_list: head of the burst list (as for the above fields, more details -+ * in the comments to the function bfq_handle_burst). -+ * @low_latency: if set to true, low-latency heuristics are enabled. -+ * @bfq_wr_coeff: maximum factor by which the weight of a weight-raised -+ * queue is multiplied. -+ * @bfq_wr_max_time: maximum duration of a weight-raising period (jiffies). -+ * @bfq_wr_rt_max_time: maximum duration for soft real-time processes. -+ * @bfq_wr_min_idle_time: minimum idle period after which weight-raising -+ * may be reactivated for a queue (in jiffies). -+ * @bfq_wr_min_inter_arr_async: minimum period between request arrivals -+ * after which weight-raising may be -+ * reactivated for an already busy queue -+ * (in jiffies). -+ * @bfq_wr_max_softrt_rate: max service-rate for a soft real-time queue, -+ * sectors per seconds. -+ * @RT_prod: cached value of the product R*T used for computing the maximum -+ * duration of the weight raising automatically. -+ * @device_speed: device-speed class for the low-latency heuristic. -+ * @oom_bfqq: fallback dummy bfqq for extreme OOM conditions. -+ * -+ * All the fields are protected by the @queue lock. -+ */ -+struct bfq_data { -+ struct request_queue *queue; -+ -+ struct bfq_group *root_group; -+ struct rb_root rq_pos_tree; -+ -+#ifdef CONFIG_CGROUP_BFQIO -+ int active_numerous_groups; -+#endif -+ -+ struct rb_root queue_weights_tree; -+ struct rb_root group_weights_tree; -+ -+ int busy_queues; -+ int busy_in_flight_queues; -+ int const_seeky_busy_in_flight_queues; -+ int wr_busy_queues; -+ int queued; -+ int rq_in_driver; -+ int sync_flight; -+ -+ int max_rq_in_driver; -+ int hw_tag_samples; -+ int hw_tag; -+ -+ int budgets_assigned; -+ -+ struct timer_list idle_slice_timer; -+ struct work_struct unplug_work; -+ -+ struct bfq_queue *in_service_queue; -+ struct bfq_io_cq *in_service_bic; -+ -+ sector_t last_position; -+ -+ ktime_t last_budget_start; -+ ktime_t last_idling_start; -+ int peak_rate_samples; -+ u64 peak_rate; -+ unsigned long bfq_max_budget; -+ -+ struct hlist_head group_list; -+ struct list_head active_list; -+ struct list_head idle_list; -+ -+ unsigned int bfq_quantum; -+ unsigned int bfq_fifo_expire[2]; -+ unsigned int bfq_back_penalty; -+ unsigned int bfq_back_max; -+ unsigned int bfq_slice_idle; -+ u64 bfq_class_idle_last_service; -+ -+ unsigned int bfq_user_max_budget; -+ unsigned int bfq_max_budget_async_rq; -+ unsigned int bfq_timeout[2]; -+ -+ unsigned int bfq_coop_thresh; -+ unsigned int bfq_failed_cooperations; -+ unsigned int bfq_requests_within_timer; -+ -+ unsigned long last_ins_in_burst; -+ unsigned long bfq_burst_interval; -+ int burst_size; -+ unsigned long bfq_large_burst_thresh; -+ bool large_burst; -+ struct hlist_head burst_list; -+ -+ bool low_latency; -+ -+ /* parameters of the low_latency heuristics */ -+ unsigned int bfq_wr_coeff; -+ unsigned int bfq_wr_max_time; -+ unsigned int bfq_wr_rt_max_time; -+ unsigned int bfq_wr_min_idle_time; -+ unsigned long bfq_wr_min_inter_arr_async; -+ unsigned int bfq_wr_max_softrt_rate; -+ u64 RT_prod; -+ enum bfq_device_speed device_speed; -+ -+ struct bfq_queue oom_bfqq; -+}; -+ -+enum bfqq_state_flags { -+ BFQ_BFQQ_FLAG_busy = 0, /* has requests or is in service */ -+ BFQ_BFQQ_FLAG_wait_request, /* waiting for a request */ -+ BFQ_BFQQ_FLAG_must_alloc, /* must be allowed rq alloc */ -+ BFQ_BFQQ_FLAG_fifo_expire, /* FIFO checked in this slice */ -+ BFQ_BFQQ_FLAG_idle_window, /* slice idling enabled */ -+ BFQ_BFQQ_FLAG_prio_changed, /* task priority has changed */ -+ BFQ_BFQQ_FLAG_sync, /* synchronous queue */ -+ BFQ_BFQQ_FLAG_budget_new, /* no completion with this budget */ -+ BFQ_BFQQ_FLAG_IO_bound, /* -+ * bfqq has timed-out at least once -+ * having consumed at most 2/10 of -+ * its budget -+ */ -+ BFQ_BFQQ_FLAG_in_large_burst, /* -+ * bfqq activated in a large burst, -+ * see comments to bfq_handle_burst. -+ */ -+ BFQ_BFQQ_FLAG_constantly_seeky, /* -+ * bfqq has proved to be slow and -+ * seeky until budget timeout -+ */ -+ BFQ_BFQQ_FLAG_softrt_update, /* -+ * may need softrt-next-start -+ * update -+ */ -+ BFQ_BFQQ_FLAG_coop, /* bfqq is shared */ -+ BFQ_BFQQ_FLAG_split_coop, /* shared bfqq will be splitted */ -+}; -+ -+#define BFQ_BFQQ_FNS(name) \ -+static inline void bfq_mark_bfqq_##name(struct bfq_queue *bfqq) \ -+{ \ -+ (bfqq)->flags |= (1 << BFQ_BFQQ_FLAG_##name); \ -+} \ -+static inline void bfq_clear_bfqq_##name(struct bfq_queue *bfqq) \ -+{ \ -+ (bfqq)->flags &= ~(1 << BFQ_BFQQ_FLAG_##name); \ -+} \ -+static inline int bfq_bfqq_##name(const struct bfq_queue *bfqq) \ -+{ \ -+ return ((bfqq)->flags & (1 << BFQ_BFQQ_FLAG_##name)) != 0; \ -+} -+ -+BFQ_BFQQ_FNS(busy); -+BFQ_BFQQ_FNS(wait_request); -+BFQ_BFQQ_FNS(must_alloc); -+BFQ_BFQQ_FNS(fifo_expire); -+BFQ_BFQQ_FNS(idle_window); -+BFQ_BFQQ_FNS(prio_changed); -+BFQ_BFQQ_FNS(sync); -+BFQ_BFQQ_FNS(budget_new); -+BFQ_BFQQ_FNS(IO_bound); -+BFQ_BFQQ_FNS(in_large_burst); -+BFQ_BFQQ_FNS(constantly_seeky); -+BFQ_BFQQ_FNS(coop); -+BFQ_BFQQ_FNS(split_coop); -+BFQ_BFQQ_FNS(softrt_update); -+#undef BFQ_BFQQ_FNS -+ -+/* Logging facilities. */ -+#define bfq_log_bfqq(bfqd, bfqq, fmt, args...) \ -+ blk_add_trace_msg((bfqd)->queue, "bfq%d " fmt, (bfqq)->pid, ##args) -+ -+#define bfq_log(bfqd, fmt, args...) \ -+ blk_add_trace_msg((bfqd)->queue, "bfq " fmt, ##args) -+ -+/* Expiration reasons. */ -+enum bfqq_expiration { -+ BFQ_BFQQ_TOO_IDLE = 0, /* -+ * queue has been idling for -+ * too long -+ */ -+ BFQ_BFQQ_BUDGET_TIMEOUT, /* budget took too long to be used */ -+ BFQ_BFQQ_BUDGET_EXHAUSTED, /* budget consumed */ -+ BFQ_BFQQ_NO_MORE_REQUESTS, /* the queue has no more requests */ -+}; -+ -+#ifdef CONFIG_CGROUP_BFQIO -+/** -+ * struct bfq_group - per (device, cgroup) data structure. -+ * @entity: schedulable entity to insert into the parent group sched_data. -+ * @sched_data: own sched_data, to contain child entities (they may be -+ * both bfq_queues and bfq_groups). -+ * @group_node: node to be inserted into the bfqio_cgroup->group_data -+ * list of the containing cgroup's bfqio_cgroup. -+ * @bfqd_node: node to be inserted into the @bfqd->group_list list -+ * of the groups active on the same device; used for cleanup. -+ * @bfqd: the bfq_data for the device this group acts upon. -+ * @async_bfqq: array of async queues for all the tasks belonging to -+ * the group, one queue per ioprio value per ioprio_class, -+ * except for the idle class that has only one queue. -+ * @async_idle_bfqq: async queue for the idle class (ioprio is ignored). -+ * @my_entity: pointer to @entity, %NULL for the toplevel group; used -+ * to avoid too many special cases during group creation/ -+ * migration. -+ * @active_entities: number of active entities belonging to the group; -+ * unused for the root group. Used to know whether there -+ * are groups with more than one active @bfq_entity -+ * (see the comments to the function -+ * bfq_bfqq_must_not_expire()). -+ * -+ * Each (device, cgroup) pair has its own bfq_group, i.e., for each cgroup -+ * there is a set of bfq_groups, each one collecting the lower-level -+ * entities belonging to the group that are acting on the same device. -+ * -+ * Locking works as follows: -+ * o @group_node is protected by the bfqio_cgroup lock, and is accessed -+ * via RCU from its readers. -+ * o @bfqd is protected by the queue lock, RCU is used to access it -+ * from the readers. -+ * o All the other fields are protected by the @bfqd queue lock. -+ */ -+struct bfq_group { -+ struct bfq_entity entity; -+ struct bfq_sched_data sched_data; -+ -+ struct hlist_node group_node; -+ struct hlist_node bfqd_node; -+ -+ void *bfqd; -+ -+ struct bfq_queue *async_bfqq[2][IOPRIO_BE_NR]; -+ struct bfq_queue *async_idle_bfqq; -+ -+ struct bfq_entity *my_entity; -+ -+ int active_entities; -+}; -+ -+/** -+ * struct bfqio_cgroup - bfq cgroup data structure. -+ * @css: subsystem state for bfq in the containing cgroup. -+ * @online: flag marked when the subsystem is inserted. -+ * @weight: cgroup weight. -+ * @ioprio: cgroup ioprio. -+ * @ioprio_class: cgroup ioprio_class. -+ * @lock: spinlock that protects @ioprio, @ioprio_class and @group_data. -+ * @group_data: list containing the bfq_group belonging to this cgroup. -+ * -+ * @group_data is accessed using RCU, with @lock protecting the updates, -+ * @ioprio and @ioprio_class are protected by @lock. -+ */ -+struct bfqio_cgroup { -+ struct cgroup_subsys_state css; -+ bool online; -+ -+ unsigned short weight, ioprio, ioprio_class; -+ -+ spinlock_t lock; -+ struct hlist_head group_data; -+}; -+#else -+struct bfq_group { -+ struct bfq_sched_data sched_data; -+ -+ struct bfq_queue *async_bfqq[2][IOPRIO_BE_NR]; -+ struct bfq_queue *async_idle_bfqq; -+}; -+#endif -+ -+static inline struct bfq_service_tree * -+bfq_entity_service_tree(struct bfq_entity *entity) -+{ -+ struct bfq_sched_data *sched_data = entity->sched_data; -+ unsigned int idx = entity->ioprio_class - 1; -+ -+ BUG_ON(idx >= BFQ_IOPRIO_CLASSES); -+ BUG_ON(sched_data == NULL); -+ -+ return sched_data->service_tree + idx; -+} -+ -+static inline struct bfq_queue *bic_to_bfqq(struct bfq_io_cq *bic, -+ bool is_sync) -+{ -+ return bic->bfqq[is_sync]; -+} -+ -+static inline void bic_set_bfqq(struct bfq_io_cq *bic, -+ struct bfq_queue *bfqq, bool is_sync) -+{ -+ bic->bfqq[is_sync] = bfqq; -+} -+ -+static inline struct bfq_data *bic_to_bfqd(struct bfq_io_cq *bic) -+{ -+ return bic->icq.q->elevator->elevator_data; -+} -+ -+/** -+ * bfq_get_bfqd_locked - get a lock to a bfqd using a RCU protected pointer. -+ * @ptr: a pointer to a bfqd. -+ * @flags: storage for the flags to be saved. -+ * -+ * This function allows bfqg->bfqd to be protected by the -+ * queue lock of the bfqd they reference; the pointer is dereferenced -+ * under RCU, so the storage for bfqd is assured to be safe as long -+ * as the RCU read side critical section does not end. After the -+ * bfqd->queue->queue_lock is taken the pointer is rechecked, to be -+ * sure that no other writer accessed it. If we raced with a writer, -+ * the function returns NULL, with the queue unlocked, otherwise it -+ * returns the dereferenced pointer, with the queue locked. -+ */ -+static inline struct bfq_data *bfq_get_bfqd_locked(void **ptr, -+ unsigned long *flags) -+{ -+ struct bfq_data *bfqd; -+ -+ rcu_read_lock(); -+ bfqd = rcu_dereference(*(struct bfq_data **)ptr); -+ -+ if (bfqd != NULL) { -+ spin_lock_irqsave(bfqd->queue->queue_lock, *flags); -+ if (*ptr == bfqd) -+ goto out; -+ spin_unlock_irqrestore(bfqd->queue->queue_lock, *flags); -+ } -+ -+ bfqd = NULL; -+out: -+ rcu_read_unlock(); -+ return bfqd; -+} -+ -+static inline void bfq_put_bfqd_unlock(struct bfq_data *bfqd, -+ unsigned long *flags) -+{ -+ spin_unlock_irqrestore(bfqd->queue->queue_lock, *flags); -+} -+ -+static void bfq_changed_ioprio(struct bfq_io_cq *bic); -+static void bfq_put_queue(struct bfq_queue *bfqq); -+static void bfq_dispatch_insert(struct request_queue *q, struct request *rq); -+static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd, -+ struct bfq_group *bfqg, int is_sync, -+ struct bfq_io_cq *bic, gfp_t gfp_mask); -+static void bfq_end_wr_async_queues(struct bfq_data *bfqd, -+ struct bfq_group *bfqg); -+static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg); -+static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq); -+ -+#endif /* _BFQ_H */ --- -2.3.0 - diff --git a/kernel/tools/perf/files/patches/gentoo/5002_block-introduce-the-BFQ-v7r7-I-O-sched-for-3.19.patch1.txt b/kernel/tools/perf/files/patches/gentoo/5002_block-introduce-the-BFQ-v7r7-I-O-sched-for-3.19.patch1.txt deleted file mode 100644 index fb96ff28b3..0000000000 --- a/kernel/tools/perf/files/patches/gentoo/5002_block-introduce-the-BFQ-v7r7-I-O-sched-for-3.19.patch1.txt +++ /dev/null @@ -1,6966 +0,0 @@ -From 5bfaaa91a51940efaccb66bc5cd562ba3b9d4053 Mon Sep 17 00:00:00 2001 -From: Paolo Valente -Date: Thu, 9 May 2013 19:10:02 +0200 -Subject: [PATCH 2/3] block: introduce the BFQ-v7r7 I/O sched for 3.19 - -Add the BFQ-v7r7 I/O scheduler to 3.19. -The general structure is borrowed from CFQ, as much of the code for -handling I/O contexts. Over time, several useful features have been -ported from CFQ as well (details in the changelog in README.BFQ). A -(bfq_)queue is associated to each task doing I/O on a device, and each -time a scheduling decision has to be made a queue is selected and served -until it expires. - - - Slices are given in the service domain: tasks are assigned - budgets, measured in number of sectors. Once got the disk, a task - must however consume its assigned budget within a configurable - maximum time (by default, the maximum possible value of the - budgets is automatically computed to comply with this timeout). - This allows the desired latency vs "throughput boosting" tradeoff - to be set. - - - Budgets are scheduled according to a variant of WF2Q+, implemented - using an augmented rb-tree to take eligibility into account while - preserving an O(log N) overall complexity. - - - A low-latency tunable is provided; if enabled, both interactive - and soft real-time applications are guaranteed a very low latency. - - - Latency guarantees are preserved also in the presence of NCQ. - - - Also with flash-based devices, a high throughput is achieved - while still preserving latency guarantees. - - - BFQ features Early Queue Merge (EQM), a sort of fusion of the - cooperating-queue-merging and the preemption mechanisms present - in CFQ. EQM is in fact a unified mechanism that tries to get a - sequential read pattern, and hence a high throughput, with any - set of processes performing interleaved I/O over a contiguous - sequence of sectors. - - - BFQ supports full hierarchical scheduling, exporting a cgroups - interface. Since each node has a full scheduler, each group can - be assigned its own weight. - - - If the cgroups interface is not used, only I/O priorities can be - assigned to processes, with ioprio values mapped to weights - with the relation weight = IOPRIO_BE_NR - ioprio. - - - ioprio classes are served in strict priority order, i.e., lower - priority queues are not served as long as there are higher - priority queues. Among queues in the same class the bandwidth is - distributed in proportion to the weight of each queue. A very - thin extra bandwidth is however guaranteed to the Idle class, to - prevent it from starving. - -Signed-off-by: Paolo Valente -Signed-off-by: Arianna Avanzini ---- - block/bfq-cgroup.c | 936 ++++++++++++ - block/bfq-ioc.c | 36 + - block/bfq-iosched.c | 3902 +++++++++++++++++++++++++++++++++++++++++++++++++++ - block/bfq-sched.c | 1214 ++++++++++++++++ - block/bfq.h | 775 ++++++++++ - 5 files changed, 6863 insertions(+) - create mode 100644 block/bfq-cgroup.c - create mode 100644 block/bfq-ioc.c - create mode 100644 block/bfq-iosched.c - create mode 100644 block/bfq-sched.c - create mode 100644 block/bfq.h - -diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c -new file mode 100644 -index 0000000..11e2f1d ---- /dev/null -+++ b/block/bfq-cgroup.c -@@ -0,0 +1,936 @@ -+/* -+ * BFQ: CGROUPS support. -+ * -+ * Based on ideas and code from CFQ: -+ * Copyright (C) 2003 Jens Axboe -+ * -+ * Copyright (C) 2008 Fabio Checconi -+ * Paolo Valente -+ * -+ * Copyright (C) 2010 Paolo Valente -+ * -+ * Licensed under the GPL-2 as detailed in the accompanying COPYING.BFQ -+ * file. -+ */ -+ -+#ifdef CONFIG_CGROUP_BFQIO -+ -+static DEFINE_MUTEX(bfqio_mutex); -+ -+static bool bfqio_is_removed(struct bfqio_cgroup *bgrp) -+{ -+ return bgrp ? !bgrp->online : false; -+} -+ -+static struct bfqio_cgroup bfqio_root_cgroup = { -+ .weight = BFQ_DEFAULT_GRP_WEIGHT, -+ .ioprio = BFQ_DEFAULT_GRP_IOPRIO, -+ .ioprio_class = BFQ_DEFAULT_GRP_CLASS, -+}; -+ -+static inline void bfq_init_entity(struct bfq_entity *entity, -+ struct bfq_group *bfqg) -+{ -+ entity->weight = entity->new_weight; -+ entity->orig_weight = entity->new_weight; -+ entity->ioprio = entity->new_ioprio; -+ entity->ioprio_class = entity->new_ioprio_class; -+ entity->parent = bfqg->my_entity; -+ entity->sched_data = &bfqg->sched_data; -+} -+ -+static struct bfqio_cgroup *css_to_bfqio(struct cgroup_subsys_state *css) -+{ -+ return css ? container_of(css, struct bfqio_cgroup, css) : NULL; -+} -+ -+/* -+ * Search the bfq_group for bfqd into the hash table (by now only a list) -+ * of bgrp. Must be called under rcu_read_lock(). -+ */ -+static struct bfq_group *bfqio_lookup_group(struct bfqio_cgroup *bgrp, -+ struct bfq_data *bfqd) -+{ -+ struct bfq_group *bfqg; -+ void *key; -+ -+ hlist_for_each_entry_rcu(bfqg, &bgrp->group_data, group_node) { -+ key = rcu_dereference(bfqg->bfqd); -+ if (key == bfqd) -+ return bfqg; -+ } -+ -+ return NULL; -+} -+ -+static inline void bfq_group_init_entity(struct bfqio_cgroup *bgrp, -+ struct bfq_group *bfqg) -+{ -+ struct bfq_entity *entity = &bfqg->entity; -+ -+ /* -+ * If the weight of the entity has never been set via the sysfs -+ * interface, then bgrp->weight == 0. In this case we initialize -+ * the weight from the current ioprio value. Otherwise, the group -+ * weight, if set, has priority over the ioprio value. -+ */ -+ if (bgrp->weight == 0) { -+ entity->new_weight = bfq_ioprio_to_weight(bgrp->ioprio); -+ entity->new_ioprio = bgrp->ioprio; -+ } else { -+ if (bgrp->weight < BFQ_MIN_WEIGHT || -+ bgrp->weight > BFQ_MAX_WEIGHT) { -+ printk(KERN_CRIT "bfq_group_init_entity: " -+ "bgrp->weight %d\n", bgrp->weight); -+ BUG(); -+ } -+ entity->new_weight = bgrp->weight; -+ entity->new_ioprio = bfq_weight_to_ioprio(bgrp->weight); -+ } -+ entity->orig_weight = entity->weight = entity->new_weight; -+ entity->ioprio = entity->new_ioprio; -+ entity->ioprio_class = entity->new_ioprio_class = bgrp->ioprio_class; -+ entity->my_sched_data = &bfqg->sched_data; -+ bfqg->active_entities = 0; -+} -+ -+static inline void bfq_group_set_parent(struct bfq_group *bfqg, -+ struct bfq_group *parent) -+{ -+ struct bfq_entity *entity; -+ -+ BUG_ON(parent == NULL); -+ BUG_ON(bfqg == NULL); -+ -+ entity = &bfqg->entity; -+ entity->parent = parent->my_entity; -+ entity->sched_data = &parent->sched_data; -+} -+ -+/** -+ * bfq_group_chain_alloc - allocate a chain of groups. -+ * @bfqd: queue descriptor. -+ * @css: the leaf cgroup_subsys_state this chain starts from. -+ * -+ * Allocate a chain of groups starting from the one belonging to -+ * @cgroup up to the root cgroup. Stop if a cgroup on the chain -+ * to the root has already an allocated group on @bfqd. -+ */ -+static struct bfq_group *bfq_group_chain_alloc(struct bfq_data *bfqd, -+ struct cgroup_subsys_state *css) -+{ -+ struct bfqio_cgroup *bgrp; -+ struct bfq_group *bfqg, *prev = NULL, *leaf = NULL; -+ -+ for (; css != NULL; css = css->parent) { -+ bgrp = css_to_bfqio(css); -+ -+ bfqg = bfqio_lookup_group(bgrp, bfqd); -+ if (bfqg != NULL) { -+ /* -+ * All the cgroups in the path from there to the -+ * root must have a bfq_group for bfqd, so we don't -+ * need any more allocations. -+ */ -+ break; -+ } -+ -+ bfqg = kzalloc(sizeof(*bfqg), GFP_ATOMIC); -+ if (bfqg == NULL) -+ goto cleanup; -+ -+ bfq_group_init_entity(bgrp, bfqg); -+ bfqg->my_entity = &bfqg->entity; -+ -+ if (leaf == NULL) { -+ leaf = bfqg; -+ prev = leaf; -+ } else { -+ bfq_group_set_parent(prev, bfqg); -+ /* -+ * Build a list of allocated nodes using the bfqd -+ * filed, that is still unused and will be -+ * initialized only after the node will be -+ * connected. -+ */ -+ prev->bfqd = bfqg; -+ prev = bfqg; -+ } -+ } -+ -+ return leaf; -+ -+cleanup: -+ while (leaf != NULL) { -+ prev = leaf; -+ leaf = leaf->bfqd; -+ kfree(prev); -+ } -+ -+ return NULL; -+} -+ -+/** -+ * bfq_group_chain_link - link an allocated group chain to a cgroup -+ * hierarchy. -+ * @bfqd: the queue descriptor. -+ * @css: the leaf cgroup_subsys_state to start from. -+ * @leaf: the leaf group (to be associated to @cgroup). -+ * -+ * Try to link a chain of groups to a cgroup hierarchy, connecting the -+ * nodes bottom-up, so we can be sure that when we find a cgroup in the -+ * hierarchy that already as a group associated to @bfqd all the nodes -+ * in the path to the root cgroup have one too. -+ * -+ * On locking: the queue lock protects the hierarchy (there is a hierarchy -+ * per device) while the bfqio_cgroup lock protects the list of groups -+ * belonging to the same cgroup. -+ */ -+static void bfq_group_chain_link(struct bfq_data *bfqd, -+ struct cgroup_subsys_state *css, -+ struct bfq_group *leaf) -+{ -+ struct bfqio_cgroup *bgrp; -+ struct bfq_group *bfqg, *next, *prev = NULL; -+ unsigned long flags; -+ -+ assert_spin_locked(bfqd->queue->queue_lock); -+ -+ for (; css != NULL && leaf != NULL; css = css->parent) { -+ bgrp = css_to_bfqio(css); -+ next = leaf->bfqd; -+ -+ bfqg = bfqio_lookup_group(bgrp, bfqd); -+ BUG_ON(bfqg != NULL); -+ -+ spin_lock_irqsave(&bgrp->lock, flags); -+ -+ rcu_assign_pointer(leaf->bfqd, bfqd); -+ hlist_add_head_rcu(&leaf->group_node, &bgrp->group_data); -+ hlist_add_head(&leaf->bfqd_node, &bfqd->group_list); -+ -+ spin_unlock_irqrestore(&bgrp->lock, flags); -+ -+ prev = leaf; -+ leaf = next; -+ } -+ -+ BUG_ON(css == NULL && leaf != NULL); -+ if (css != NULL && prev != NULL) { -+ bgrp = css_to_bfqio(css); -+ bfqg = bfqio_lookup_group(bgrp, bfqd); -+ bfq_group_set_parent(prev, bfqg); -+ } -+} -+ -+/** -+ * bfq_find_alloc_group - return the group associated to @bfqd in @cgroup. -+ * @bfqd: queue descriptor. -+ * @cgroup: cgroup being searched for. -+ * -+ * Return a group associated to @bfqd in @cgroup, allocating one if -+ * necessary. When a group is returned all the cgroups in the path -+ * to the root have a group associated to @bfqd. -+ * -+ * If the allocation fails, return the root group: this breaks guarantees -+ * but is a safe fallback. If this loss becomes a problem it can be -+ * mitigated using the equivalent weight (given by the product of the -+ * weights of the groups in the path from @group to the root) in the -+ * root scheduler. -+ * -+ * We allocate all the missing nodes in the path from the leaf cgroup -+ * to the root and we connect the nodes only after all the allocations -+ * have been successful. -+ */ -+static struct bfq_group *bfq_find_alloc_group(struct bfq_data *bfqd, -+ struct cgroup_subsys_state *css) -+{ -+ struct bfqio_cgroup *bgrp = css_to_bfqio(css); -+ struct bfq_group *bfqg; -+ -+ bfqg = bfqio_lookup_group(bgrp, bfqd); -+ if (bfqg != NULL) -+ return bfqg; -+ -+ bfqg = bfq_group_chain_alloc(bfqd, css); -+ if (bfqg != NULL) -+ bfq_group_chain_link(bfqd, css, bfqg); -+ else -+ bfqg = bfqd->root_group; -+ -+ return bfqg; -+} -+ -+/** -+ * bfq_bfqq_move - migrate @bfqq to @bfqg. -+ * @bfqd: queue descriptor. -+ * @bfqq: the queue to move. -+ * @entity: @bfqq's entity. -+ * @bfqg: the group to move to. -+ * -+ * Move @bfqq to @bfqg, deactivating it from its old group and reactivating -+ * it on the new one. Avoid putting the entity on the old group idle tree. -+ * -+ * Must be called under the queue lock; the cgroup owning @bfqg must -+ * not disappear (by now this just means that we are called under -+ * rcu_read_lock()). -+ */ -+static void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq, -+ struct bfq_entity *entity, struct bfq_group *bfqg) -+{ -+ int busy, resume; -+ -+ busy = bfq_bfqq_busy(bfqq); -+ resume = !RB_EMPTY_ROOT(&bfqq->sort_list); -+ -+ BUG_ON(resume && !entity->on_st); -+ BUG_ON(busy && !resume && entity->on_st && -+ bfqq != bfqd->in_service_queue); -+ -+ if (busy) { -+ BUG_ON(atomic_read(&bfqq->ref) < 2); -+ -+ if (!resume) -+ bfq_del_bfqq_busy(bfqd, bfqq, 0); -+ else -+ bfq_deactivate_bfqq(bfqd, bfqq, 0); -+ } else if (entity->on_st) -+ bfq_put_idle_entity(bfq_entity_service_tree(entity), entity); -+ -+ /* -+ * Here we use a reference to bfqg. We don't need a refcounter -+ * as the cgroup reference will not be dropped, so that its -+ * destroy() callback will not be invoked. -+ */ -+ entity->parent = bfqg->my_entity; -+ entity->sched_data = &bfqg->sched_data; -+ -+ if (busy && resume) -+ bfq_activate_bfqq(bfqd, bfqq); -+ -+ if (bfqd->in_service_queue == NULL && !bfqd->rq_in_driver) -+ bfq_schedule_dispatch(bfqd); -+} -+ -+/** -+ * __bfq_bic_change_cgroup - move @bic to @cgroup. -+ * @bfqd: the queue descriptor. -+ * @bic: the bic to move. -+ * @cgroup: the cgroup to move to. -+ * -+ * Move bic to cgroup, assuming that bfqd->queue is locked; the caller -+ * has to make sure that the reference to cgroup is valid across the call. -+ * -+ * NOTE: an alternative approach might have been to store the current -+ * cgroup in bfqq and getting a reference to it, reducing the lookup -+ * time here, at the price of slightly more complex code. -+ */ -+static struct bfq_group *__bfq_bic_change_cgroup(struct bfq_data *bfqd, -+ struct bfq_io_cq *bic, -+ struct cgroup_subsys_state *css) -+{ -+ struct bfq_queue *async_bfqq = bic_to_bfqq(bic, 0); -+ struct bfq_queue *sync_bfqq = bic_to_bfqq(bic, 1); -+ struct bfq_entity *entity; -+ struct bfq_group *bfqg; -+ struct bfqio_cgroup *bgrp; -+ -+ bgrp = css_to_bfqio(css); -+ -+ bfqg = bfq_find_alloc_group(bfqd, css); -+ if (async_bfqq != NULL) { -+ entity = &async_bfqq->entity; -+ -+ if (entity->sched_data != &bfqg->sched_data) { -+ bic_set_bfqq(bic, NULL, 0); -+ bfq_log_bfqq(bfqd, async_bfqq, -+ "bic_change_group: %p %d", -+ async_bfqq, atomic_read(&async_bfqq->ref)); -+ bfq_put_queue(async_bfqq); -+ } -+ } -+ -+ if (sync_bfqq != NULL) { -+ entity = &sync_bfqq->entity; -+ if (entity->sched_data != &bfqg->sched_data) -+ bfq_bfqq_move(bfqd, sync_bfqq, entity, bfqg); -+ } -+ -+ return bfqg; -+} -+ -+/** -+ * bfq_bic_change_cgroup - move @bic to @cgroup. -+ * @bic: the bic being migrated. -+ * @cgroup: the destination cgroup. -+ * -+ * When the task owning @bic is moved to @cgroup, @bic is immediately -+ * moved into its new parent group. -+ */ -+static void bfq_bic_change_cgroup(struct bfq_io_cq *bic, -+ struct cgroup_subsys_state *css) -+{ -+ struct bfq_data *bfqd; -+ unsigned long uninitialized_var(flags); -+ -+ bfqd = bfq_get_bfqd_locked(&(bic->icq.q->elevator->elevator_data), -+ &flags); -+ if (bfqd != NULL) { -+ __bfq_bic_change_cgroup(bfqd, bic, css); -+ bfq_put_bfqd_unlock(bfqd, &flags); -+ } -+} -+ -+/** -+ * bfq_bic_update_cgroup - update the cgroup of @bic. -+ * @bic: the @bic to update. -+ * -+ * Make sure that @bic is enqueued in the cgroup of the current task. -+ * We need this in addition to moving bics during the cgroup attach -+ * phase because the task owning @bic could be at its first disk -+ * access or we may end up in the root cgroup as the result of a -+ * memory allocation failure and here we try to move to the right -+ * group. -+ * -+ * Must be called under the queue lock. It is safe to use the returned -+ * value even after the rcu_read_unlock() as the migration/destruction -+ * paths act under the queue lock too. IOW it is impossible to race with -+ * group migration/destruction and end up with an invalid group as: -+ * a) here cgroup has not yet been destroyed, nor its destroy callback -+ * has started execution, as current holds a reference to it, -+ * b) if it is destroyed after rcu_read_unlock() [after current is -+ * migrated to a different cgroup] its attach() callback will have -+ * taken care of remove all the references to the old cgroup data. -+ */ -+static struct bfq_group *bfq_bic_update_cgroup(struct bfq_io_cq *bic) -+{ -+ struct bfq_data *bfqd = bic_to_bfqd(bic); -+ struct bfq_group *bfqg; -+ struct cgroup_subsys_state *css; -+ -+ BUG_ON(bfqd == NULL); -+ -+ rcu_read_lock(); -+ css = task_css(current, bfqio_cgrp_id); -+ bfqg = __bfq_bic_change_cgroup(bfqd, bic, css); -+ rcu_read_unlock(); -+ -+ return bfqg; -+} -+ -+/** -+ * bfq_flush_idle_tree - deactivate any entity on the idle tree of @st. -+ * @st: the service tree being flushed. -+ */ -+static inline void bfq_flush_idle_tree(struct bfq_service_tree *st) -+{ -+ struct bfq_entity *entity = st->first_idle; -+ -+ for (; entity != NULL; entity = st->first_idle) -+ __bfq_deactivate_entity(entity, 0); -+} -+ -+/** -+ * bfq_reparent_leaf_entity - move leaf entity to the root_group. -+ * @bfqd: the device data structure with the root group. -+ * @entity: the entity to move. -+ */ -+static inline void bfq_reparent_leaf_entity(struct bfq_data *bfqd, -+ struct bfq_entity *entity) -+{ -+ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); -+ -+ BUG_ON(bfqq == NULL); -+ bfq_bfqq_move(bfqd, bfqq, entity, bfqd->root_group); -+ return; -+} -+ -+/** -+ * bfq_reparent_active_entities - move to the root group all active -+ * entities. -+ * @bfqd: the device data structure with the root group. -+ * @bfqg: the group to move from. -+ * @st: the service tree with the entities. -+ * -+ * Needs queue_lock to be taken and reference to be valid over the call. -+ */ -+static inline void bfq_reparent_active_entities(struct bfq_data *bfqd, -+ struct bfq_group *bfqg, -+ struct bfq_service_tree *st) -+{ -+ struct rb_root *active = &st->active; -+ struct bfq_entity *entity = NULL; -+ -+ if (!RB_EMPTY_ROOT(&st->active)) -+ entity = bfq_entity_of(rb_first(active)); -+ -+ for (; entity != NULL; entity = bfq_entity_of(rb_first(active))) -+ bfq_reparent_leaf_entity(bfqd, entity); -+ -+ if (bfqg->sched_data.in_service_entity != NULL) -+ bfq_reparent_leaf_entity(bfqd, -+ bfqg->sched_data.in_service_entity); -+ -+ return; -+} -+ -+/** -+ * bfq_destroy_group - destroy @bfqg. -+ * @bgrp: the bfqio_cgroup containing @bfqg. -+ * @bfqg: the group being destroyed. -+ * -+ * Destroy @bfqg, making sure that it is not referenced from its parent. -+ */ -+static void bfq_destroy_group(struct bfqio_cgroup *bgrp, struct bfq_group *bfqg) -+{ -+ struct bfq_data *bfqd; -+ struct bfq_service_tree *st; -+ struct bfq_entity *entity = bfqg->my_entity; -+ unsigned long uninitialized_var(flags); -+ int i; -+ -+ hlist_del(&bfqg->group_node); -+ -+ /* -+ * Empty all service_trees belonging to this group before -+ * deactivating the group itself. -+ */ -+ for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) { -+ st = bfqg->sched_data.service_tree + i; -+ -+ /* -+ * The idle tree may still contain bfq_queues belonging -+ * to exited task because they never migrated to a different -+ * cgroup from the one being destroyed now. No one else -+ * can access them so it's safe to act without any lock. -+ */ -+ bfq_flush_idle_tree(st); -+ -+ /* -+ * It may happen that some queues are still active -+ * (busy) upon group destruction (if the corresponding -+ * processes have been forced to terminate). We move -+ * all the leaf entities corresponding to these queues -+ * to the root_group. -+ * Also, it may happen that the group has an entity -+ * in service, which is disconnected from the active -+ * tree: it must be moved, too. -+ * There is no need to put the sync queues, as the -+ * scheduler has taken no reference. -+ */ -+ bfqd = bfq_get_bfqd_locked(&bfqg->bfqd, &flags); -+ if (bfqd != NULL) { -+ bfq_reparent_active_entities(bfqd, bfqg, st); -+ bfq_put_bfqd_unlock(bfqd, &flags); -+ } -+ BUG_ON(!RB_EMPTY_ROOT(&st->active)); -+ BUG_ON(!RB_EMPTY_ROOT(&st->idle)); -+ } -+ BUG_ON(bfqg->sched_data.next_in_service != NULL); -+ BUG_ON(bfqg->sched_data.in_service_entity != NULL); -+ -+ /* -+ * We may race with device destruction, take extra care when -+ * dereferencing bfqg->bfqd. -+ */ -+ bfqd = bfq_get_bfqd_locked(&bfqg->bfqd, &flags); -+ if (bfqd != NULL) { -+ hlist_del(&bfqg->bfqd_node); -+ __bfq_deactivate_entity(entity, 0); -+ bfq_put_async_queues(bfqd, bfqg); -+ bfq_put_bfqd_unlock(bfqd, &flags); -+ } -+ BUG_ON(entity->tree != NULL); -+ -+ /* -+ * No need to defer the kfree() to the end of the RCU grace -+ * period: we are called from the destroy() callback of our -+ * cgroup, so we can be sure that no one is a) still using -+ * this cgroup or b) doing lookups in it. -+ */ -+ kfree(bfqg); -+} -+ -+static void bfq_end_wr_async(struct bfq_data *bfqd) -+{ -+ struct hlist_node *tmp; -+ struct bfq_group *bfqg; -+ -+ hlist_for_each_entry_safe(bfqg, tmp, &bfqd->group_list, bfqd_node) -+ bfq_end_wr_async_queues(bfqd, bfqg); -+ bfq_end_wr_async_queues(bfqd, bfqd->root_group); -+} -+ -+/** -+ * bfq_disconnect_groups - disconnect @bfqd from all its groups. -+ * @bfqd: the device descriptor being exited. -+ * -+ * When the device exits we just make sure that no lookup can return -+ * the now unused group structures. They will be deallocated on cgroup -+ * destruction. -+ */ -+static void bfq_disconnect_groups(struct bfq_data *bfqd) -+{ -+ struct hlist_node *tmp; -+ struct bfq_group *bfqg; -+ -+ bfq_log(bfqd, "disconnect_groups beginning"); -+ hlist_for_each_entry_safe(bfqg, tmp, &bfqd->group_list, bfqd_node) { -+ hlist_del(&bfqg->bfqd_node); -+ -+ __bfq_deactivate_entity(bfqg->my_entity, 0); -+ -+ /* -+ * Don't remove from the group hash, just set an -+ * invalid key. No lookups can race with the -+ * assignment as bfqd is being destroyed; this -+ * implies also that new elements cannot be added -+ * to the list. -+ */ -+ rcu_assign_pointer(bfqg->bfqd, NULL); -+ -+ bfq_log(bfqd, "disconnect_groups: put async for group %p", -+ bfqg); -+ bfq_put_async_queues(bfqd, bfqg); -+ } -+} -+ -+static inline void bfq_free_root_group(struct bfq_data *bfqd) -+{ -+ struct bfqio_cgroup *bgrp = &bfqio_root_cgroup; -+ struct bfq_group *bfqg = bfqd->root_group; -+ -+ bfq_put_async_queues(bfqd, bfqg); -+ -+ spin_lock_irq(&bgrp->lock); -+ hlist_del_rcu(&bfqg->group_node); -+ spin_unlock_irq(&bgrp->lock); -+ -+ /* -+ * No need to synchronize_rcu() here: since the device is gone -+ * there cannot be any read-side access to its root_group. -+ */ -+ kfree(bfqg); -+} -+ -+static struct bfq_group *bfq_alloc_root_group(struct bfq_data *bfqd, int node) -+{ -+ struct bfq_group *bfqg; -+ struct bfqio_cgroup *bgrp; -+ int i; -+ -+ bfqg = kzalloc_node(sizeof(*bfqg), GFP_KERNEL, node); -+ if (bfqg == NULL) -+ return NULL; -+ -+ bfqg->entity.parent = NULL; -+ for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) -+ bfqg->sched_data.service_tree[i] = BFQ_SERVICE_TREE_INIT; -+ -+ bgrp = &bfqio_root_cgroup; -+ spin_lock_irq(&bgrp->lock); -+ rcu_assign_pointer(bfqg->bfqd, bfqd); -+ hlist_add_head_rcu(&bfqg->group_node, &bgrp->group_data); -+ spin_unlock_irq(&bgrp->lock); -+ -+ return bfqg; -+} -+ -+#define SHOW_FUNCTION(__VAR) \ -+static u64 bfqio_cgroup_##__VAR##_read(struct cgroup_subsys_state *css, \ -+ struct cftype *cftype) \ -+{ \ -+ struct bfqio_cgroup *bgrp = css_to_bfqio(css); \ -+ u64 ret = -ENODEV; \ -+ \ -+ mutex_lock(&bfqio_mutex); \ -+ if (bfqio_is_removed(bgrp)) \ -+ goto out_unlock; \ -+ \ -+ spin_lock_irq(&bgrp->lock); \ -+ ret = bgrp->__VAR; \ -+ spin_unlock_irq(&bgrp->lock); \ -+ \ -+out_unlock: \ -+ mutex_unlock(&bfqio_mutex); \ -+ return ret; \ -+} -+ -+SHOW_FUNCTION(weight); -+SHOW_FUNCTION(ioprio); -+SHOW_FUNCTION(ioprio_class); -+#undef SHOW_FUNCTION -+ -+#define STORE_FUNCTION(__VAR, __MIN, __MAX) \ -+static int bfqio_cgroup_##__VAR##_write(struct cgroup_subsys_state *css,\ -+ struct cftype *cftype, \ -+ u64 val) \ -+{ \ -+ struct bfqio_cgroup *bgrp = css_to_bfqio(css); \ -+ struct bfq_group *bfqg; \ -+ int ret = -EINVAL; \ -+ \ -+ if (val < (__MIN) || val > (__MAX)) \ -+ return ret; \ -+ \ -+ ret = -ENODEV; \ -+ mutex_lock(&bfqio_mutex); \ -+ if (bfqio_is_removed(bgrp)) \ -+ goto out_unlock; \ -+ ret = 0; \ -+ \ -+ spin_lock_irq(&bgrp->lock); \ -+ bgrp->__VAR = (unsigned short)val; \ -+ hlist_for_each_entry(bfqg, &bgrp->group_data, group_node) { \ -+ /* \ -+ * Setting the ioprio_changed flag of the entity \ -+ * to 1 with new_##__VAR == ##__VAR would re-set \ -+ * the value of the weight to its ioprio mapping. \ -+ * Set the flag only if necessary. \ -+ */ \ -+ if ((unsigned short)val != bfqg->entity.new_##__VAR) { \ -+ bfqg->entity.new_##__VAR = (unsigned short)val; \ -+ /* \ -+ * Make sure that the above new value has been \ -+ * stored in bfqg->entity.new_##__VAR before \ -+ * setting the ioprio_changed flag. In fact, \ -+ * this flag may be read asynchronously (in \ -+ * critical sections protected by a different \ -+ * lock than that held here), and finding this \ -+ * flag set may cause the execution of the code \ -+ * for updating parameters whose value may \ -+ * depend also on bfqg->entity.new_##__VAR (in \ -+ * __bfq_entity_update_weight_prio). \ -+ * This barrier makes sure that the new value \ -+ * of bfqg->entity.new_##__VAR is correctly \ -+ * seen in that code. \ -+ */ \ -+ smp_wmb(); \ -+ bfqg->entity.ioprio_changed = 1; \ -+ } \ -+ } \ -+ spin_unlock_irq(&bgrp->lock); \ -+ \ -+out_unlock: \ -+ mutex_unlock(&bfqio_mutex); \ -+ return ret; \ -+} -+ -+STORE_FUNCTION(weight, BFQ_MIN_WEIGHT, BFQ_MAX_WEIGHT); -+STORE_FUNCTION(ioprio, 0, IOPRIO_BE_NR - 1); -+STORE_FUNCTION(ioprio_class, IOPRIO_CLASS_RT, IOPRIO_CLASS_IDLE); -+#undef STORE_FUNCTION -+ -+static struct cftype bfqio_files[] = { -+ { -+ .name = "weight", -+ .read_u64 = bfqio_cgroup_weight_read, -+ .write_u64 = bfqio_cgroup_weight_write, -+ }, -+ { -+ .name = "ioprio", -+ .read_u64 = bfqio_cgroup_ioprio_read, -+ .write_u64 = bfqio_cgroup_ioprio_write, -+ }, -+ { -+ .name = "ioprio_class", -+ .read_u64 = bfqio_cgroup_ioprio_class_read, -+ .write_u64 = bfqio_cgroup_ioprio_class_write, -+ }, -+ { }, /* terminate */ -+}; -+ -+static struct cgroup_subsys_state *bfqio_create(struct cgroup_subsys_state -+ *parent_css) -+{ -+ struct bfqio_cgroup *bgrp; -+ -+ if (parent_css != NULL) { -+ bgrp = kzalloc(sizeof(*bgrp), GFP_KERNEL); -+ if (bgrp == NULL) -+ return ERR_PTR(-ENOMEM); -+ } else -+ bgrp = &bfqio_root_cgroup; -+ -+ spin_lock_init(&bgrp->lock); -+ INIT_HLIST_HEAD(&bgrp->group_data); -+ bgrp->ioprio = BFQ_DEFAULT_GRP_IOPRIO; -+ bgrp->ioprio_class = BFQ_DEFAULT_GRP_CLASS; -+ -+ return &bgrp->css; -+} -+ -+/* -+ * We cannot support shared io contexts, as we have no means to support -+ * two tasks with the same ioc in two different groups without major rework -+ * of the main bic/bfqq data structures. By now we allow a task to change -+ * its cgroup only if it's the only owner of its ioc; the drawback of this -+ * behavior is that a group containing a task that forked using CLONE_IO -+ * will not be destroyed until the tasks sharing the ioc die. -+ */ -+static int bfqio_can_attach(struct cgroup_subsys_state *css, -+ struct cgroup_taskset *tset) -+{ -+ struct task_struct *task; -+ struct io_context *ioc; -+ int ret = 0; -+ -+ cgroup_taskset_for_each(task, tset) { -+ /* -+ * task_lock() is needed to avoid races with -+ * exit_io_context() -+ */ -+ task_lock(task); -+ ioc = task->io_context; -+ if (ioc != NULL && atomic_read(&ioc->nr_tasks) > 1) -+ /* -+ * ioc == NULL means that the task is either too -+ * young or exiting: if it has still no ioc the -+ * ioc can't be shared, if the task is exiting the -+ * attach will fail anyway, no matter what we -+ * return here. -+ */ -+ ret = -EINVAL; -+ task_unlock(task); -+ if (ret) -+ break; -+ } -+ -+ return ret; -+} -+ -+static void bfqio_attach(struct cgroup_subsys_state *css, -+ struct cgroup_taskset *tset) -+{ -+ struct task_struct *task; -+ struct io_context *ioc; -+ struct io_cq *icq; -+ -+ /* -+ * IMPORTANT NOTE: The move of more than one process at a time to a -+ * new group has not yet been tested. -+ */ -+ cgroup_taskset_for_each(task, tset) { -+ ioc = get_task_io_context(task, GFP_ATOMIC, NUMA_NO_NODE); -+ if (ioc) { -+ /* -+ * Handle cgroup change here. -+ */ -+ rcu_read_lock(); -+ hlist_for_each_entry_rcu(icq, &ioc->icq_list, ioc_node) -+ if (!strncmp( -+ icq->q->elevator->type->elevator_name, -+ "bfq", ELV_NAME_MAX)) -+ bfq_bic_change_cgroup(icq_to_bic(icq), -+ css); -+ rcu_read_unlock(); -+ put_io_context(ioc); -+ } -+ } -+} -+ -+static void bfqio_destroy(struct cgroup_subsys_state *css) -+{ -+ struct bfqio_cgroup *bgrp = css_to_bfqio(css); -+ struct hlist_node *tmp; -+ struct bfq_group *bfqg; -+ -+ /* -+ * Since we are destroying the cgroup, there are no more tasks -+ * referencing it, and all the RCU grace periods that may have -+ * referenced it are ended (as the destruction of the parent -+ * cgroup is RCU-safe); bgrp->group_data will not be accessed by -+ * anything else and we don't need any synchronization. -+ */ -+ hlist_for_each_entry_safe(bfqg, tmp, &bgrp->group_data, group_node) -+ bfq_destroy_group(bgrp, bfqg); -+ -+ BUG_ON(!hlist_empty(&bgrp->group_data)); -+ -+ kfree(bgrp); -+} -+ -+static int bfqio_css_online(struct cgroup_subsys_state *css) -+{ -+ struct bfqio_cgroup *bgrp = css_to_bfqio(css); -+ -+ mutex_lock(&bfqio_mutex); -+ bgrp->online = true; -+ mutex_unlock(&bfqio_mutex); -+ -+ return 0; -+} -+ -+static void bfqio_css_offline(struct cgroup_subsys_state *css) -+{ -+ struct bfqio_cgroup *bgrp = css_to_bfqio(css); -+ -+ mutex_lock(&bfqio_mutex); -+ bgrp->online = false; -+ mutex_unlock(&bfqio_mutex); -+} -+ -+struct cgroup_subsys bfqio_cgrp_subsys = { -+ .css_alloc = bfqio_create, -+ .css_online = bfqio_css_online, -+ .css_offline = bfqio_css_offline, -+ .can_attach = bfqio_can_attach, -+ .attach = bfqio_attach, -+ .css_free = bfqio_destroy, -+ .legacy_cftypes = bfqio_files, -+}; -+#else -+static inline void bfq_init_entity(struct bfq_entity *entity, -+ struct bfq_group *bfqg) -+{ -+ entity->weight = entity->new_weight; -+ entity->orig_weight = entity->new_weight; -+ entity->ioprio = entity->new_ioprio; -+ entity->ioprio_class = entity->new_ioprio_class; -+ entity->sched_data = &bfqg->sched_data; -+} -+ -+static inline struct bfq_group * -+bfq_bic_update_cgroup(struct bfq_io_cq *bic) -+{ -+ struct bfq_data *bfqd = bic_to_bfqd(bic); -+ return bfqd->root_group; -+} -+ -+static inline void bfq_bfqq_move(struct bfq_data *bfqd, -+ struct bfq_queue *bfqq, -+ struct bfq_entity *entity, -+ struct bfq_group *bfqg) -+{ -+} -+ -+static void bfq_end_wr_async(struct bfq_data *bfqd) -+{ -+ bfq_end_wr_async_queues(bfqd, bfqd->root_group); -+} -+ -+static inline void bfq_disconnect_groups(struct bfq_data *bfqd) -+{ -+ bfq_put_async_queues(bfqd, bfqd->root_group); -+} -+ -+static inline void bfq_free_root_group(struct bfq_data *bfqd) -+{ -+ kfree(bfqd->root_group); -+} -+ -+static struct bfq_group *bfq_alloc_root_group(struct bfq_data *bfqd, int node) -+{ -+ struct bfq_group *bfqg; -+ int i; -+ -+ bfqg = kmalloc_node(sizeof(*bfqg), GFP_KERNEL | __GFP_ZERO, node); -+ if (bfqg == NULL) -+ return NULL; -+ -+ for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) -+ bfqg->sched_data.service_tree[i] = BFQ_SERVICE_TREE_INIT; -+ -+ return bfqg; -+} -+#endif -diff --git a/block/bfq-ioc.c b/block/bfq-ioc.c -new file mode 100644 -index 0000000..7f6b000 ---- /dev/null -+++ b/block/bfq-ioc.c -@@ -0,0 +1,36 @@ -+/* -+ * BFQ: I/O context handling. -+ * -+ * Based on ideas and code from CFQ: -+ * Copyright (C) 2003 Jens Axboe -+ * -+ * Copyright (C) 2008 Fabio Checconi -+ * Paolo Valente -+ * -+ * Copyright (C) 2010 Paolo Valente -+ */ -+ -+/** -+ * icq_to_bic - convert iocontext queue structure to bfq_io_cq. -+ * @icq: the iocontext queue. -+ */ -+static inline struct bfq_io_cq *icq_to_bic(struct io_cq *icq) -+{ -+ /* bic->icq is the first member, %NULL will convert to %NULL */ -+ return container_of(icq, struct bfq_io_cq, icq); -+} -+ -+/** -+ * bfq_bic_lookup - search into @ioc a bic associated to @bfqd. -+ * @bfqd: the lookup key. -+ * @ioc: the io_context of the process doing I/O. -+ * -+ * Queue lock must be held. -+ */ -+static inline struct bfq_io_cq *bfq_bic_lookup(struct bfq_data *bfqd, -+ struct io_context *ioc) -+{ -+ if (ioc) -+ return icq_to_bic(ioc_lookup_icq(ioc, bfqd->queue)); -+ return NULL; -+} -diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c -new file mode 100644 -index 0000000..97ee934 ---- /dev/null -+++ b/block/bfq-iosched.c -@@ -0,0 +1,3902 @@ -+/* -+ * Budget Fair Queueing (BFQ) disk scheduler. -+ * -+ * Based on ideas and code from CFQ: -+ * Copyright (C) 2003 Jens Axboe -+ * -+ * Copyright (C) 2008 Fabio Checconi -+ * Paolo Valente -+ * -+ * Copyright (C) 2010 Paolo Valente -+ * -+ * Licensed under the GPL-2 as detailed in the accompanying COPYING.BFQ -+ * file. -+ * -+ * BFQ is a proportional-share storage-I/O scheduling algorithm based on -+ * the slice-by-slice service scheme of CFQ. But BFQ assigns budgets, -+ * measured in number of sectors, to processes instead of time slices. The -+ * device is not granted to the in-service process for a given time slice, -+ * but until it has exhausted its assigned budget. This change from the time -+ * to the service domain allows BFQ to distribute the device throughput -+ * among processes as desired, without any distortion due to ZBR, workload -+ * fluctuations or other factors. BFQ uses an ad hoc internal scheduler, -+ * called B-WF2Q+, to schedule processes according to their budgets. More -+ * precisely, BFQ schedules queues associated to processes. Thanks to the -+ * accurate policy of B-WF2Q+, BFQ can afford to assign high budgets to -+ * I/O-bound processes issuing sequential requests (to boost the -+ * throughput), and yet guarantee a low latency to interactive and soft -+ * real-time applications. -+ * -+ * BFQ is described in [1], where also a reference to the initial, more -+ * theoretical paper on BFQ can be found. The interested reader can find -+ * in the latter paper full details on the main algorithm, as well as -+ * formulas of the guarantees and formal proofs of all the properties. -+ * With respect to the version of BFQ presented in these papers, this -+ * implementation adds a few more heuristics, such as the one that -+ * guarantees a low latency to soft real-time applications, and a -+ * hierarchical extension based on H-WF2Q+. -+ * -+ * B-WF2Q+ is based on WF2Q+, that is described in [2], together with -+ * H-WF2Q+, while the augmented tree used to implement B-WF2Q+ with O(log N) -+ * complexity derives from the one introduced with EEVDF in [3]. -+ * -+ * [1] P. Valente and M. Andreolini, ``Improving Application Responsiveness -+ * with the BFQ Disk I/O Scheduler'', -+ * Proceedings of the 5th Annual International Systems and Storage -+ * Conference (SYSTOR '12), June 2012. -+ * -+ * http://algogroup.unimo.it/people/paolo/disk_sched/bf1-v1-suite-results.pdf -+ * -+ * [2] Jon C.R. Bennett and H. Zhang, ``Hierarchical Packet Fair Queueing -+ * Algorithms,'' IEEE/ACM Transactions on Networking, 5(5):675-689, -+ * Oct 1997. -+ * -+ * http://www.cs.cmu.edu/~hzhang/papers/TON-97-Oct.ps.gz -+ * -+ * [3] I. Stoica and H. Abdel-Wahab, ``Earliest Eligible Virtual Deadline -+ * First: A Flexible and Accurate Mechanism for Proportional Share -+ * Resource Allocation,'' technical report. -+ * -+ * http://www.cs.berkeley.edu/~istoica/papers/eevdf-tr-95.pdf -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "bfq.h" -+#include "blk.h" -+ -+/* Max number of dispatches in one round of service. */ -+static const int bfq_quantum = 4; -+ -+/* Expiration time of sync (0) and async (1) requests, in jiffies. */ -+static const int bfq_fifo_expire[2] = { HZ / 4, HZ / 8 }; -+ -+/* Maximum backwards seek, in KiB. */ -+static const int bfq_back_max = 16 * 1024; -+ -+/* Penalty of a backwards seek, in number of sectors. */ -+static const int bfq_back_penalty = 2; -+ -+/* Idling period duration, in jiffies. */ -+static int bfq_slice_idle = HZ / 125; -+ -+/* Default maximum budget values, in sectors and number of requests. */ -+static const int bfq_default_max_budget = 16 * 1024; -+static const int bfq_max_budget_async_rq = 4; -+ -+/* -+ * Async to sync throughput distribution is controlled as follows: -+ * when an async request is served, the entity is charged the number -+ * of sectors of the request, multiplied by the factor below -+ */ -+static const int bfq_async_charge_factor = 10; -+ -+/* Default timeout values, in jiffies, approximating CFQ defaults. */ -+static const int bfq_timeout_sync = HZ / 8; -+static int bfq_timeout_async = HZ / 25; -+ -+struct kmem_cache *bfq_pool; -+ -+/* Below this threshold (in ms), we consider thinktime immediate. */ -+#define BFQ_MIN_TT 2 -+ -+/* hw_tag detection: parallel requests threshold and min samples needed. */ -+#define BFQ_HW_QUEUE_THRESHOLD 4 -+#define BFQ_HW_QUEUE_SAMPLES 32 -+ -+#define BFQQ_SEEK_THR (sector_t)(8 * 1024) -+#define BFQQ_SEEKY(bfqq) ((bfqq)->seek_mean > BFQQ_SEEK_THR) -+ -+/* Min samples used for peak rate estimation (for autotuning). */ -+#define BFQ_PEAK_RATE_SAMPLES 32 -+ -+/* Shift used for peak rate fixed precision calculations. */ -+#define BFQ_RATE_SHIFT 16 -+ -+/* -+ * By default, BFQ computes the duration of the weight raising for -+ * interactive applications automatically, using the following formula: -+ * duration = (R / r) * T, where r is the peak rate of the device, and -+ * R and T are two reference parameters. -+ * In particular, R is the peak rate of the reference device (see below), -+ * and T is a reference time: given the systems that are likely to be -+ * installed on the reference device according to its speed class, T is -+ * about the maximum time needed, under BFQ and while reading two files in -+ * parallel, to load typical large applications on these systems. -+ * In practice, the slower/faster the device at hand is, the more/less it -+ * takes to load applications with respect to the reference device. -+ * Accordingly, the longer/shorter BFQ grants weight raising to interactive -+ * applications. -+ * -+ * BFQ uses four different reference pairs (R, T), depending on: -+ * . whether the device is rotational or non-rotational; -+ * . whether the device is slow, such as old or portable HDDs, as well as -+ * SD cards, or fast, such as newer HDDs and SSDs. -+ * -+ * The device's speed class is dynamically (re)detected in -+ * bfq_update_peak_rate() every time the estimated peak rate is updated. -+ * -+ * In the following definitions, R_slow[0]/R_fast[0] and T_slow[0]/T_fast[0] -+ * are the reference values for a slow/fast rotational device, whereas -+ * R_slow[1]/R_fast[1] and T_slow[1]/T_fast[1] are the reference values for -+ * a slow/fast non-rotational device. Finally, device_speed_thresh are the -+ * thresholds used to switch between speed classes. -+ * Both the reference peak rates and the thresholds are measured in -+ * sectors/usec, left-shifted by BFQ_RATE_SHIFT. -+ */ -+static int R_slow[2] = {1536, 10752}; -+static int R_fast[2] = {17415, 34791}; -+/* -+ * To improve readability, a conversion function is used to initialize the -+ * following arrays, which entails that they can be initialized only in a -+ * function. -+ */ -+static int T_slow[2]; -+static int T_fast[2]; -+static int device_speed_thresh[2]; -+ -+#define BFQ_SERVICE_TREE_INIT ((struct bfq_service_tree) \ -+ { RB_ROOT, RB_ROOT, NULL, NULL, 0, 0 }) -+ -+#define RQ_BIC(rq) ((struct bfq_io_cq *) (rq)->elv.priv[0]) -+#define RQ_BFQQ(rq) ((rq)->elv.priv[1]) -+ -+static inline void bfq_schedule_dispatch(struct bfq_data *bfqd); -+ -+#include "bfq-ioc.c" -+#include "bfq-sched.c" -+#include "bfq-cgroup.c" -+ -+#define bfq_class_idle(bfqq) ((bfqq)->entity.ioprio_class ==\ -+ IOPRIO_CLASS_IDLE) -+#define bfq_class_rt(bfqq) ((bfqq)->entity.ioprio_class ==\ -+ IOPRIO_CLASS_RT) -+ -+#define bfq_sample_valid(samples) ((samples) > 80) -+ -+/* -+ * We regard a request as SYNC, if either it's a read or has the SYNC bit -+ * set (in which case it could also be a direct WRITE). -+ */ -+static inline int bfq_bio_sync(struct bio *bio) -+{ -+ if (bio_data_dir(bio) == READ || (bio->bi_rw & REQ_SYNC)) -+ return 1; -+ -+ return 0; -+} -+ -+/* -+ * Scheduler run of queue, if there are requests pending and no one in the -+ * driver that will restart queueing. -+ */ -+static inline void bfq_schedule_dispatch(struct bfq_data *bfqd) -+{ -+ if (bfqd->queued != 0) { -+ bfq_log(bfqd, "schedule dispatch"); -+ kblockd_schedule_work(&bfqd->unplug_work); -+ } -+} -+ -+/* -+ * Lifted from AS - choose which of rq1 and rq2 that is best served now. -+ * We choose the request that is closesr to the head right now. Distance -+ * behind the head is penalized and only allowed to a certain extent. -+ */ -+static struct request *bfq_choose_req(struct bfq_data *bfqd, -+ struct request *rq1, -+ struct request *rq2, -+ sector_t last) -+{ -+ sector_t s1, s2, d1 = 0, d2 = 0; -+ unsigned long back_max; -+#define BFQ_RQ1_WRAP 0x01 /* request 1 wraps */ -+#define BFQ_RQ2_WRAP 0x02 /* request 2 wraps */ -+ unsigned wrap = 0; /* bit mask: requests behind the disk head? */ -+ -+ if (rq1 == NULL || rq1 == rq2) -+ return rq2; -+ if (rq2 == NULL) -+ return rq1; -+ -+ if (rq_is_sync(rq1) && !rq_is_sync(rq2)) -+ return rq1; -+ else if (rq_is_sync(rq2) && !rq_is_sync(rq1)) -+ return rq2; -+ if ((rq1->cmd_flags & REQ_META) && !(rq2->cmd_flags & REQ_META)) -+ return rq1; -+ else if ((rq2->cmd_flags & REQ_META) && !(rq1->cmd_flags & REQ_META)) -+ return rq2; -+ -+ s1 = blk_rq_pos(rq1); -+ s2 = blk_rq_pos(rq2); -+ -+ /* -+ * By definition, 1KiB is 2 sectors. -+ */ -+ back_max = bfqd->bfq_back_max * 2; -+ -+ /* -+ * Strict one way elevator _except_ in the case where we allow -+ * short backward seeks which are biased as twice the cost of a -+ * similar forward seek. -+ */ -+ if (s1 >= last) -+ d1 = s1 - last; -+ else if (s1 + back_max >= last) -+ d1 = (last - s1) * bfqd->bfq_back_penalty; -+ else -+ wrap |= BFQ_RQ1_WRAP; -+ -+ if (s2 >= last) -+ d2 = s2 - last; -+ else if (s2 + back_max >= last) -+ d2 = (last - s2) * bfqd->bfq_back_penalty; -+ else -+ wrap |= BFQ_RQ2_WRAP; -+ -+ /* Found required data */ -+ -+ /* -+ * By doing switch() on the bit mask "wrap" we avoid having to -+ * check two variables for all permutations: --> faster! -+ */ -+ switch (wrap) { -+ case 0: /* common case for CFQ: rq1 and rq2 not wrapped */ -+ if (d1 < d2) -+ return rq1; -+ else if (d2 < d1) -+ return rq2; -+ else { -+ if (s1 >= s2) -+ return rq1; -+ else -+ return rq2; -+ } -+ -+ case BFQ_RQ2_WRAP: -+ return rq1; -+ case BFQ_RQ1_WRAP: -+ return rq2; -+ case (BFQ_RQ1_WRAP|BFQ_RQ2_WRAP): /* both rqs wrapped */ -+ default: -+ /* -+ * Since both rqs are wrapped, -+ * start with the one that's further behind head -+ * (--> only *one* back seek required), -+ * since back seek takes more time than forward. -+ */ -+ if (s1 <= s2) -+ return rq1; -+ else -+ return rq2; -+ } -+} -+ -+static struct bfq_queue * -+bfq_rq_pos_tree_lookup(struct bfq_data *bfqd, struct rb_root *root, -+ sector_t sector, struct rb_node **ret_parent, -+ struct rb_node ***rb_link) -+{ -+ struct rb_node **p, *parent; -+ struct bfq_queue *bfqq = NULL; -+ -+ parent = NULL; -+ p = &root->rb_node; -+ while (*p) { -+ struct rb_node **n; -+ -+ parent = *p; -+ bfqq = rb_entry(parent, struct bfq_queue, pos_node); -+ -+ /* -+ * Sort strictly based on sector. Smallest to the left, -+ * largest to the right. -+ */ -+ if (sector > blk_rq_pos(bfqq->next_rq)) -+ n = &(*p)->rb_right; -+ else if (sector < blk_rq_pos(bfqq->next_rq)) -+ n = &(*p)->rb_left; -+ else -+ break; -+ p = n; -+ bfqq = NULL; -+ } -+ -+ *ret_parent = parent; -+ if (rb_link) -+ *rb_link = p; -+ -+ bfq_log(bfqd, "rq_pos_tree_lookup %llu: returning %d", -+ (long long unsigned)sector, -+ bfqq != NULL ? bfqq->pid : 0); -+ -+ return bfqq; -+} -+ -+static void bfq_rq_pos_tree_add(struct bfq_data *bfqd, struct bfq_queue *bfqq) -+{ -+ struct rb_node **p, *parent; -+ struct bfq_queue *__bfqq; -+ -+ if (bfqq->pos_root != NULL) { -+ rb_erase(&bfqq->pos_node, bfqq->pos_root); -+ bfqq->pos_root = NULL; -+ } -+ -+ if (bfq_class_idle(bfqq)) -+ return; -+ if (!bfqq->next_rq) -+ return; -+ -+ bfqq->pos_root = &bfqd->rq_pos_tree; -+ __bfqq = bfq_rq_pos_tree_lookup(bfqd, bfqq->pos_root, -+ blk_rq_pos(bfqq->next_rq), &parent, &p); -+ if (__bfqq == NULL) { -+ rb_link_node(&bfqq->pos_node, parent, p); -+ rb_insert_color(&bfqq->pos_node, bfqq->pos_root); -+ } else -+ bfqq->pos_root = NULL; -+} -+ -+/* -+ * Tell whether there are active queues or groups with differentiated weights. -+ */ -+static inline bool bfq_differentiated_weights(struct bfq_data *bfqd) -+{ -+ BUG_ON(!bfqd->hw_tag); -+ /* -+ * For weights to differ, at least one of the trees must contain -+ * at least two nodes. -+ */ -+ return (!RB_EMPTY_ROOT(&bfqd->queue_weights_tree) && -+ (bfqd->queue_weights_tree.rb_node->rb_left || -+ bfqd->queue_weights_tree.rb_node->rb_right) -+#ifdef CONFIG_CGROUP_BFQIO -+ ) || -+ (!RB_EMPTY_ROOT(&bfqd->group_weights_tree) && -+ (bfqd->group_weights_tree.rb_node->rb_left || -+ bfqd->group_weights_tree.rb_node->rb_right) -+#endif -+ ); -+} -+ -+/* -+ * If the weight-counter tree passed as input contains no counter for -+ * the weight of the input entity, then add that counter; otherwise just -+ * increment the existing counter. -+ * -+ * Note that weight-counter trees contain few nodes in mostly symmetric -+ * scenarios. For example, if all queues have the same weight, then the -+ * weight-counter tree for the queues may contain at most one node. -+ * This holds even if low_latency is on, because weight-raised queues -+ * are not inserted in the tree. -+ * In most scenarios, the rate at which nodes are created/destroyed -+ * should be low too. -+ */ -+static void bfq_weights_tree_add(struct bfq_data *bfqd, -+ struct bfq_entity *entity, -+ struct rb_root *root) -+{ -+ struct rb_node **new = &(root->rb_node), *parent = NULL; -+ -+ /* -+ * Do not insert if: -+ * - the device does not support queueing; -+ * - the entity is already associated with a counter, which happens if: -+ * 1) the entity is associated with a queue, 2) a request arrival -+ * has caused the queue to become both non-weight-raised, and hence -+ * change its weight, and backlogged; in this respect, each -+ * of the two events causes an invocation of this function, -+ * 3) this is the invocation of this function caused by the second -+ * event. This second invocation is actually useless, and we handle -+ * this fact by exiting immediately. More efficient or clearer -+ * solutions might possibly be adopted. -+ */ -+ if (!bfqd->hw_tag || entity->weight_counter) -+ return; -+ -+ while (*new) { -+ struct bfq_weight_counter *__counter = container_of(*new, -+ struct bfq_weight_counter, -+ weights_node); -+ parent = *new; -+ -+ if (entity->weight == __counter->weight) { -+ entity->weight_counter = __counter; -+ goto inc_counter; -+ } -+ if (entity->weight < __counter->weight) -+ new = &((*new)->rb_left); -+ else -+ new = &((*new)->rb_right); -+ } -+ -+ entity->weight_counter = kzalloc(sizeof(struct bfq_weight_counter), -+ GFP_ATOMIC); -+ entity->weight_counter->weight = entity->weight; -+ rb_link_node(&entity->weight_counter->weights_node, parent, new); -+ rb_insert_color(&entity->weight_counter->weights_node, root); -+ -+inc_counter: -+ entity->weight_counter->num_active++; -+} -+ -+/* -+ * Decrement the weight counter associated with the entity, and, if the -+ * counter reaches 0, remove the counter from the tree. -+ * See the comments to the function bfq_weights_tree_add() for considerations -+ * about overhead. -+ */ -+static void bfq_weights_tree_remove(struct bfq_data *bfqd, -+ struct bfq_entity *entity, -+ struct rb_root *root) -+{ -+ /* -+ * Check whether the entity is actually associated with a counter. -+ * In fact, the device may not be considered NCQ-capable for a while, -+ * which implies that no insertion in the weight trees is performed, -+ * after which the device may start to be deemed NCQ-capable, and hence -+ * this function may start to be invoked. This may cause the function -+ * to be invoked for entities that are not associated with any counter. -+ */ -+ if (!entity->weight_counter) -+ return; -+ -+ BUG_ON(RB_EMPTY_ROOT(root)); -+ BUG_ON(entity->weight_counter->weight != entity->weight); -+ -+ BUG_ON(!entity->weight_counter->num_active); -+ entity->weight_counter->num_active--; -+ if (entity->weight_counter->num_active > 0) -+ goto reset_entity_pointer; -+ -+ rb_erase(&entity->weight_counter->weights_node, root); -+ kfree(entity->weight_counter); -+ -+reset_entity_pointer: -+ entity->weight_counter = NULL; -+} -+ -+static struct request *bfq_find_next_rq(struct bfq_data *bfqd, -+ struct bfq_queue *bfqq, -+ struct request *last) -+{ -+ struct rb_node *rbnext = rb_next(&last->rb_node); -+ struct rb_node *rbprev = rb_prev(&last->rb_node); -+ struct request *next = NULL, *prev = NULL; -+ -+ BUG_ON(RB_EMPTY_NODE(&last->rb_node)); -+ -+ if (rbprev != NULL) -+ prev = rb_entry_rq(rbprev); -+ -+ if (rbnext != NULL) -+ next = rb_entry_rq(rbnext); -+ else { -+ rbnext = rb_first(&bfqq->sort_list); -+ if (rbnext && rbnext != &last->rb_node) -+ next = rb_entry_rq(rbnext); -+ } -+ -+ return bfq_choose_req(bfqd, next, prev, blk_rq_pos(last)); -+} -+ -+/* see the definition of bfq_async_charge_factor for details */ -+static inline unsigned long bfq_serv_to_charge(struct request *rq, -+ struct bfq_queue *bfqq) -+{ -+ return blk_rq_sectors(rq) * -+ (1 + ((!bfq_bfqq_sync(bfqq)) * (bfqq->wr_coeff == 1) * -+ bfq_async_charge_factor)); -+} -+ -+/** -+ * bfq_updated_next_req - update the queue after a new next_rq selection. -+ * @bfqd: the device data the queue belongs to. -+ * @bfqq: the queue to update. -+ * -+ * If the first request of a queue changes we make sure that the queue -+ * has enough budget to serve at least its first request (if the -+ * request has grown). We do this because if the queue has not enough -+ * budget for its first request, it has to go through two dispatch -+ * rounds to actually get it dispatched. -+ */ -+static void bfq_updated_next_req(struct bfq_data *bfqd, -+ struct bfq_queue *bfqq) -+{ -+ struct bfq_entity *entity = &bfqq->entity; -+ struct bfq_service_tree *st = bfq_entity_service_tree(entity); -+ struct request *next_rq = bfqq->next_rq; -+ unsigned long new_budget; -+ -+ if (next_rq == NULL) -+ return; -+ -+ if (bfqq == bfqd->in_service_queue) -+ /* -+ * In order not to break guarantees, budgets cannot be -+ * changed after an entity has been selected. -+ */ -+ return; -+ -+ BUG_ON(entity->tree != &st->active); -+ BUG_ON(entity == entity->sched_data->in_service_entity); -+ -+ new_budget = max_t(unsigned long, bfqq->max_budget, -+ bfq_serv_to_charge(next_rq, bfqq)); -+ if (entity->budget != new_budget) { -+ entity->budget = new_budget; -+ bfq_log_bfqq(bfqd, bfqq, "updated next rq: new budget %lu", -+ new_budget); -+ bfq_activate_bfqq(bfqd, bfqq); -+ } -+} -+ -+static inline unsigned int bfq_wr_duration(struct bfq_data *bfqd) -+{ -+ u64 dur; -+ -+ if (bfqd->bfq_wr_max_time > 0) -+ return bfqd->bfq_wr_max_time; -+ -+ dur = bfqd->RT_prod; -+ do_div(dur, bfqd->peak_rate); -+ -+ return dur; -+} -+ -+/* Empty burst list and add just bfqq (see comments to bfq_handle_burst) */ -+static inline void bfq_reset_burst_list(struct bfq_data *bfqd, -+ struct bfq_queue *bfqq) -+{ -+ struct bfq_queue *item; -+ struct hlist_node *n; -+ -+ hlist_for_each_entry_safe(item, n, &bfqd->burst_list, burst_list_node) -+ hlist_del_init(&item->burst_list_node); -+ hlist_add_head(&bfqq->burst_list_node, &bfqd->burst_list); -+ bfqd->burst_size = 1; -+} -+ -+/* Add bfqq to the list of queues in current burst (see bfq_handle_burst) */ -+static void bfq_add_to_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq) -+{ -+ /* Increment burst size to take into account also bfqq */ -+ bfqd->burst_size++; -+ -+ if (bfqd->burst_size == bfqd->bfq_large_burst_thresh) { -+ struct bfq_queue *pos, *bfqq_item; -+ struct hlist_node *n; -+ -+ /* -+ * Enough queues have been activated shortly after each -+ * other to consider this burst as large. -+ */ -+ bfqd->large_burst = true; -+ -+ /* -+ * We can now mark all queues in the burst list as -+ * belonging to a large burst. -+ */ -+ hlist_for_each_entry(bfqq_item, &bfqd->burst_list, -+ burst_list_node) -+ bfq_mark_bfqq_in_large_burst(bfqq_item); -+ bfq_mark_bfqq_in_large_burst(bfqq); -+ -+ /* -+ * From now on, and until the current burst finishes, any -+ * new queue being activated shortly after the last queue -+ * was inserted in the burst can be immediately marked as -+ * belonging to a large burst. So the burst list is not -+ * needed any more. Remove it. -+ */ -+ hlist_for_each_entry_safe(pos, n, &bfqd->burst_list, -+ burst_list_node) -+ hlist_del_init(&pos->burst_list_node); -+ } else /* burst not yet large: add bfqq to the burst list */ -+ hlist_add_head(&bfqq->burst_list_node, &bfqd->burst_list); -+} -+ -+/* -+ * If many queues happen to become active shortly after each other, then, -+ * to help the processes associated to these queues get their job done as -+ * soon as possible, it is usually better to not grant either weight-raising -+ * or device idling to these queues. In this comment we describe, firstly, -+ * the reasons why this fact holds, and, secondly, the next function, which -+ * implements the main steps needed to properly mark these queues so that -+ * they can then be treated in a different way. -+ * -+ * As for the terminology, we say that a queue becomes active, i.e., -+ * switches from idle to backlogged, either when it is created (as a -+ * consequence of the arrival of an I/O request), or, if already existing, -+ * when a new request for the queue arrives while the queue is idle. -+ * Bursts of activations, i.e., activations of different queues occurring -+ * shortly after each other, are typically caused by services or applications -+ * that spawn or reactivate many parallel threads/processes. Examples are -+ * systemd during boot or git grep. -+ * -+ * These services or applications benefit mostly from a high throughput: -+ * the quicker the requests of the activated queues are cumulatively served, -+ * the sooner the target job of these queues gets completed. As a consequence, -+ * weight-raising any of these queues, which also implies idling the device -+ * for it, is almost always counterproductive: in most cases it just lowers -+ * throughput. -+ * -+ * On the other hand, a burst of activations may be also caused by the start -+ * of an application that does not consist in a lot of parallel I/O-bound -+ * threads. In fact, with a complex application, the burst may be just a -+ * consequence of the fact that several processes need to be executed to -+ * start-up the application. To start an application as quickly as possible, -+ * the best thing to do is to privilege the I/O related to the application -+ * with respect to all other I/O. Therefore, the best strategy to start as -+ * quickly as possible an application that causes a burst of activations is -+ * to weight-raise all the queues activated during the burst. This is the -+ * exact opposite of the best strategy for the other type of bursts. -+ * -+ * In the end, to take the best action for each of the two cases, the two -+ * types of bursts need to be distinguished. Fortunately, this seems -+ * relatively easy to do, by looking at the sizes of the bursts. In -+ * particular, we found a threshold such that bursts with a larger size -+ * than that threshold are apparently caused only by services or commands -+ * such as systemd or git grep. For brevity, hereafter we call just 'large' -+ * these bursts. BFQ *does not* weight-raise queues whose activations occur -+ * in a large burst. In addition, for each of these queues BFQ performs or -+ * does not perform idling depending on which choice boosts the throughput -+ * most. The exact choice depends on the device and request pattern at -+ * hand. -+ * -+ * Turning back to the next function, it implements all the steps needed -+ * to detect the occurrence of a large burst and to properly mark all the -+ * queues belonging to it (so that they can then be treated in a different -+ * way). This goal is achieved by maintaining a special "burst list" that -+ * holds, temporarily, the queues that belong to the burst in progress. The -+ * list is then used to mark these queues as belonging to a large burst if -+ * the burst does become large. The main steps are the following. -+ * -+ * . when the very first queue is activated, the queue is inserted into the -+ * list (as it could be the first queue in a possible burst) -+ * -+ * . if the current burst has not yet become large, and a queue Q that does -+ * not yet belong to the burst is activated shortly after the last time -+ * at which a new queue entered the burst list, then the function appends -+ * Q to the burst list -+ * -+ * . if, as a consequence of the previous step, the burst size reaches -+ * the large-burst threshold, then -+ * -+ * . all the queues in the burst list are marked as belonging to a -+ * large burst -+ * -+ * . the burst list is deleted; in fact, the burst list already served -+ * its purpose (keeping temporarily track of the queues in a burst, -+ * so as to be able to mark them as belonging to a large burst in the -+ * previous sub-step), and now is not needed any more -+ * -+ * . the device enters a large-burst mode -+ * -+ * . if a queue Q that does not belong to the burst is activated while -+ * the device is in large-burst mode and shortly after the last time -+ * at which a queue either entered the burst list or was marked as -+ * belonging to the current large burst, then Q is immediately marked -+ * as belonging to a large burst. -+ * -+ * . if a queue Q that does not belong to the burst is activated a while -+ * later, i.e., not shortly after, than the last time at which a queue -+ * either entered the burst list or was marked as belonging to the -+ * current large burst, then the current burst is deemed as finished and: -+ * -+ * . the large-burst mode is reset if set -+ * -+ * . the burst list is emptied -+ * -+ * . Q is inserted in the burst list, as Q may be the first queue -+ * in a possible new burst (then the burst list contains just Q -+ * after this step). -+ */ -+static void bfq_handle_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq, -+ bool idle_for_long_time) -+{ -+ /* -+ * If bfqq happened to be activated in a burst, but has been idle -+ * for at least as long as an interactive queue, then we assume -+ * that, in the overall I/O initiated in the burst, the I/O -+ * associated to bfqq is finished. So bfqq does not need to be -+ * treated as a queue belonging to a burst anymore. Accordingly, -+ * we reset bfqq's in_large_burst flag if set, and remove bfqq -+ * from the burst list if it's there. We do not decrement instead -+ * burst_size, because the fact that bfqq does not need to belong -+ * to the burst list any more does not invalidate the fact that -+ * bfqq may have been activated during the current burst. -+ */ -+ if (idle_for_long_time) { -+ hlist_del_init(&bfqq->burst_list_node); -+ bfq_clear_bfqq_in_large_burst(bfqq); -+ } -+ -+ /* -+ * If bfqq is already in the burst list or is part of a large -+ * burst, then there is nothing else to do. -+ */ -+ if (!hlist_unhashed(&bfqq->burst_list_node) || -+ bfq_bfqq_in_large_burst(bfqq)) -+ return; -+ -+ /* -+ * If bfqq's activation happens late enough, then the current -+ * burst is finished, and related data structures must be reset. -+ * -+ * In this respect, consider the special case where bfqq is the very -+ * first queue being activated. In this case, last_ins_in_burst is -+ * not yet significant when we get here. But it is easy to verify -+ * that, whether or not the following condition is true, bfqq will -+ * end up being inserted into the burst list. In particular the -+ * list will happen to contain only bfqq. And this is exactly what -+ * has to happen, as bfqq may be the first queue in a possible -+ * burst. -+ */ -+ if (time_is_before_jiffies(bfqd->last_ins_in_burst + -+ bfqd->bfq_burst_interval)) { -+ bfqd->large_burst = false; -+ bfq_reset_burst_list(bfqd, bfqq); -+ return; -+ } -+ -+ /* -+ * If we get here, then bfqq is being activated shortly after the -+ * last queue. So, if the current burst is also large, we can mark -+ * bfqq as belonging to this large burst immediately. -+ */ -+ if (bfqd->large_burst) { -+ bfq_mark_bfqq_in_large_burst(bfqq); -+ return; -+ } -+ -+ /* -+ * If we get here, then a large-burst state has not yet been -+ * reached, but bfqq is being activated shortly after the last -+ * queue. Then we add bfqq to the burst. -+ */ -+ bfq_add_to_burst(bfqd, bfqq); -+} -+ -+static void bfq_add_request(struct request *rq) -+{ -+ struct bfq_queue *bfqq = RQ_BFQQ(rq); -+ struct bfq_entity *entity = &bfqq->entity; -+ struct bfq_data *bfqd = bfqq->bfqd; -+ struct request *next_rq, *prev; -+ unsigned long old_wr_coeff = bfqq->wr_coeff; -+ bool interactive = false; -+ -+ bfq_log_bfqq(bfqd, bfqq, "add_request %d", rq_is_sync(rq)); -+ bfqq->queued[rq_is_sync(rq)]++; -+ bfqd->queued++; -+ -+ elv_rb_add(&bfqq->sort_list, rq); -+ -+ /* -+ * Check if this request is a better next-serve candidate. -+ */ -+ prev = bfqq->next_rq; -+ next_rq = bfq_choose_req(bfqd, bfqq->next_rq, rq, bfqd->last_position); -+ BUG_ON(next_rq == NULL); -+ bfqq->next_rq = next_rq; -+ -+ /* -+ * Adjust priority tree position, if next_rq changes. -+ */ -+ if (prev != bfqq->next_rq) -+ bfq_rq_pos_tree_add(bfqd, bfqq); -+ -+ if (!bfq_bfqq_busy(bfqq)) { -+ bool soft_rt, -+ idle_for_long_time = time_is_before_jiffies( -+ bfqq->budget_timeout + -+ bfqd->bfq_wr_min_idle_time); -+ -+ if (bfq_bfqq_sync(bfqq)) { -+ bool already_in_burst = -+ !hlist_unhashed(&bfqq->burst_list_node) || -+ bfq_bfqq_in_large_burst(bfqq); -+ bfq_handle_burst(bfqd, bfqq, idle_for_long_time); -+ /* -+ * If bfqq was not already in the current burst, -+ * then, at this point, bfqq either has been -+ * added to the current burst or has caused the -+ * current burst to terminate. In particular, in -+ * the second case, bfqq has become the first -+ * queue in a possible new burst. -+ * In both cases last_ins_in_burst needs to be -+ * moved forward. -+ */ -+ if (!already_in_burst) -+ bfqd->last_ins_in_burst = jiffies; -+ } -+ -+ soft_rt = bfqd->bfq_wr_max_softrt_rate > 0 && -+ !bfq_bfqq_in_large_burst(bfqq) && -+ time_is_before_jiffies(bfqq->soft_rt_next_start); -+ interactive = !bfq_bfqq_in_large_burst(bfqq) && -+ idle_for_long_time; -+ entity->budget = max_t(unsigned long, bfqq->max_budget, -+ bfq_serv_to_charge(next_rq, bfqq)); -+ -+ if (!bfq_bfqq_IO_bound(bfqq)) { -+ if (time_before(jiffies, -+ RQ_BIC(rq)->ttime.last_end_request + -+ bfqd->bfq_slice_idle)) { -+ bfqq->requests_within_timer++; -+ if (bfqq->requests_within_timer >= -+ bfqd->bfq_requests_within_timer) -+ bfq_mark_bfqq_IO_bound(bfqq); -+ } else -+ bfqq->requests_within_timer = 0; -+ } -+ -+ if (!bfqd->low_latency) -+ goto add_bfqq_busy; -+ -+ /* -+ * If the queue is not being boosted and has been idle -+ * for enough time, start a weight-raising period -+ */ -+ if (old_wr_coeff == 1 && (interactive || soft_rt)) { -+ bfqq->wr_coeff = bfqd->bfq_wr_coeff; -+ if (interactive) -+ bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); -+ else -+ bfqq->wr_cur_max_time = -+ bfqd->bfq_wr_rt_max_time; -+ bfq_log_bfqq(bfqd, bfqq, -+ "wrais starting at %lu, rais_max_time %u", -+ jiffies, -+ jiffies_to_msecs(bfqq->wr_cur_max_time)); -+ } else if (old_wr_coeff > 1) { -+ if (interactive) -+ bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); -+ else if (bfq_bfqq_in_large_burst(bfqq) || -+ (bfqq->wr_cur_max_time == -+ bfqd->bfq_wr_rt_max_time && -+ !soft_rt)) { -+ bfqq->wr_coeff = 1; -+ bfq_log_bfqq(bfqd, bfqq, -+ "wrais ending at %lu, rais_max_time %u", -+ jiffies, -+ jiffies_to_msecs(bfqq-> -+ wr_cur_max_time)); -+ } else if (time_before( -+ bfqq->last_wr_start_finish + -+ bfqq->wr_cur_max_time, -+ jiffies + -+ bfqd->bfq_wr_rt_max_time) && -+ soft_rt) { -+ /* -+ * -+ * The remaining weight-raising time is lower -+ * than bfqd->bfq_wr_rt_max_time, which -+ * means that the application is enjoying -+ * weight raising either because deemed soft- -+ * rt in the near past, or because deemed -+ * interactive a long ago. In both cases, -+ * resetting now the current remaining weight- -+ * raising time for the application to the -+ * weight-raising duration for soft rt -+ * applications would not cause any latency -+ * increase for the application (as the new -+ * duration would be higher than the remaining -+ * time). -+ * -+ * In addition, the application is now meeting -+ * the requirements for being deemed soft rt. -+ * In the end we can correctly and safely -+ * (re)charge the weight-raising duration for -+ * the application with the weight-raising -+ * duration for soft rt applications. -+ * -+ * In particular, doing this recharge now, i.e., -+ * before the weight-raising period for the -+ * application finishes, reduces the probability -+ * of the following negative scenario: -+ * 1) the weight of a soft rt application is -+ * raised at startup (as for any newly -+ * created application), -+ * 2) since the application is not interactive, -+ * at a certain time weight-raising is -+ * stopped for the application, -+ * 3) at that time the application happens to -+ * still have pending requests, and hence -+ * is destined to not have a chance to be -+ * deemed soft rt before these requests are -+ * completed (see the comments to the -+ * function bfq_bfqq_softrt_next_start() -+ * for details on soft rt detection), -+ * 4) these pending requests experience a high -+ * latency because the application is not -+ * weight-raised while they are pending. -+ */ -+ bfqq->last_wr_start_finish = jiffies; -+ bfqq->wr_cur_max_time = -+ bfqd->bfq_wr_rt_max_time; -+ } -+ } -+ if (old_wr_coeff != bfqq->wr_coeff) -+ entity->ioprio_changed = 1; -+add_bfqq_busy: -+ bfqq->last_idle_bklogged = jiffies; -+ bfqq->service_from_backlogged = 0; -+ bfq_clear_bfqq_softrt_update(bfqq); -+ bfq_add_bfqq_busy(bfqd, bfqq); -+ } else { -+ if (bfqd->low_latency && old_wr_coeff == 1 && !rq_is_sync(rq) && -+ time_is_before_jiffies( -+ bfqq->last_wr_start_finish + -+ bfqd->bfq_wr_min_inter_arr_async)) { -+ bfqq->wr_coeff = bfqd->bfq_wr_coeff; -+ bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); -+ -+ bfqd->wr_busy_queues++; -+ entity->ioprio_changed = 1; -+ bfq_log_bfqq(bfqd, bfqq, -+ "non-idle wrais starting at %lu, rais_max_time %u", -+ jiffies, -+ jiffies_to_msecs(bfqq->wr_cur_max_time)); -+ } -+ if (prev != bfqq->next_rq) -+ bfq_updated_next_req(bfqd, bfqq); -+ } -+ -+ if (bfqd->low_latency && -+ (old_wr_coeff == 1 || bfqq->wr_coeff == 1 || interactive)) -+ bfqq->last_wr_start_finish = jiffies; -+} -+ -+static struct request *bfq_find_rq_fmerge(struct bfq_data *bfqd, -+ struct bio *bio) -+{ -+ struct task_struct *tsk = current; -+ struct bfq_io_cq *bic; -+ struct bfq_queue *bfqq; -+ -+ bic = bfq_bic_lookup(bfqd, tsk->io_context); -+ if (bic == NULL) -+ return NULL; -+ -+ bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio)); -+ if (bfqq != NULL) -+ return elv_rb_find(&bfqq->sort_list, bio_end_sector(bio)); -+ -+ return NULL; -+} -+ -+static void bfq_activate_request(struct request_queue *q, struct request *rq) -+{ -+ struct bfq_data *bfqd = q->elevator->elevator_data; -+ -+ bfqd->rq_in_driver++; -+ bfqd->last_position = blk_rq_pos(rq) + blk_rq_sectors(rq); -+ bfq_log(bfqd, "activate_request: new bfqd->last_position %llu", -+ (long long unsigned)bfqd->last_position); -+} -+ -+static inline void bfq_deactivate_request(struct request_queue *q, -+ struct request *rq) -+{ -+ struct bfq_data *bfqd = q->elevator->elevator_data; -+ -+ BUG_ON(bfqd->rq_in_driver == 0); -+ bfqd->rq_in_driver--; -+} -+ -+static void bfq_remove_request(struct request *rq) -+{ -+ struct bfq_queue *bfqq = RQ_BFQQ(rq); -+ struct bfq_data *bfqd = bfqq->bfqd; -+ const int sync = rq_is_sync(rq); -+ -+ if (bfqq->next_rq == rq) { -+ bfqq->next_rq = bfq_find_next_rq(bfqd, bfqq, rq); -+ bfq_updated_next_req(bfqd, bfqq); -+ } -+ -+ list_del_init(&rq->queuelist); -+ BUG_ON(bfqq->queued[sync] == 0); -+ bfqq->queued[sync]--; -+ bfqd->queued--; -+ elv_rb_del(&bfqq->sort_list, rq); -+ -+ if (RB_EMPTY_ROOT(&bfqq->sort_list)) { -+ if (bfq_bfqq_busy(bfqq) && bfqq != bfqd->in_service_queue) -+ bfq_del_bfqq_busy(bfqd, bfqq, 1); -+ /* -+ * Remove queue from request-position tree as it is empty. -+ */ -+ if (bfqq->pos_root != NULL) { -+ rb_erase(&bfqq->pos_node, bfqq->pos_root); -+ bfqq->pos_root = NULL; -+ } -+ } -+ -+ if (rq->cmd_flags & REQ_META) { -+ BUG_ON(bfqq->meta_pending == 0); -+ bfqq->meta_pending--; -+ } -+} -+ -+static int bfq_merge(struct request_queue *q, struct request **req, -+ struct bio *bio) -+{ -+ struct bfq_data *bfqd = q->elevator->elevator_data; -+ struct request *__rq; -+ -+ __rq = bfq_find_rq_fmerge(bfqd, bio); -+ if (__rq != NULL && elv_rq_merge_ok(__rq, bio)) { -+ *req = __rq; -+ return ELEVATOR_FRONT_MERGE; -+ } -+ -+ return ELEVATOR_NO_MERGE; -+} -+ -+static void bfq_merged_request(struct request_queue *q, struct request *req, -+ int type) -+{ -+ if (type == ELEVATOR_FRONT_MERGE && -+ rb_prev(&req->rb_node) && -+ blk_rq_pos(req) < -+ blk_rq_pos(container_of(rb_prev(&req->rb_node), -+ struct request, rb_node))) { -+ struct bfq_queue *bfqq = RQ_BFQQ(req); -+ struct bfq_data *bfqd = bfqq->bfqd; -+ struct request *prev, *next_rq; -+ -+ /* Reposition request in its sort_list */ -+ elv_rb_del(&bfqq->sort_list, req); -+ elv_rb_add(&bfqq->sort_list, req); -+ /* Choose next request to be served for bfqq */ -+ prev = bfqq->next_rq; -+ next_rq = bfq_choose_req(bfqd, bfqq->next_rq, req, -+ bfqd->last_position); -+ BUG_ON(next_rq == NULL); -+ bfqq->next_rq = next_rq; -+ /* -+ * If next_rq changes, update both the queue's budget to -+ * fit the new request and the queue's position in its -+ * rq_pos_tree. -+ */ -+ if (prev != bfqq->next_rq) { -+ bfq_updated_next_req(bfqd, bfqq); -+ bfq_rq_pos_tree_add(bfqd, bfqq); -+ } -+ } -+} -+ -+static void bfq_merged_requests(struct request_queue *q, struct request *rq, -+ struct request *next) -+{ -+ struct bfq_queue *bfqq = RQ_BFQQ(rq); -+ -+ /* -+ * Reposition in fifo if next is older than rq. -+ */ -+ if (!list_empty(&rq->queuelist) && !list_empty(&next->queuelist) && -+ time_before(next->fifo_time, rq->fifo_time)) { -+ list_move(&rq->queuelist, &next->queuelist); -+ rq->fifo_time = next->fifo_time; -+ } -+ -+ if (bfqq->next_rq == next) -+ bfqq->next_rq = rq; -+ -+ bfq_remove_request(next); -+} -+ -+/* Must be called with bfqq != NULL */ -+static inline void bfq_bfqq_end_wr(struct bfq_queue *bfqq) -+{ -+ BUG_ON(bfqq == NULL); -+ if (bfq_bfqq_busy(bfqq)) -+ bfqq->bfqd->wr_busy_queues--; -+ bfqq->wr_coeff = 1; -+ bfqq->wr_cur_max_time = 0; -+ /* Trigger a weight change on the next activation of the queue */ -+ bfqq->entity.ioprio_changed = 1; -+} -+ -+static void bfq_end_wr_async_queues(struct bfq_data *bfqd, -+ struct bfq_group *bfqg) -+{ -+ int i, j; -+ -+ for (i = 0; i < 2; i++) -+ for (j = 0; j < IOPRIO_BE_NR; j++) -+ if (bfqg->async_bfqq[i][j] != NULL) -+ bfq_bfqq_end_wr(bfqg->async_bfqq[i][j]); -+ if (bfqg->async_idle_bfqq != NULL) -+ bfq_bfqq_end_wr(bfqg->async_idle_bfqq); -+} -+ -+static void bfq_end_wr(struct bfq_data *bfqd) -+{ -+ struct bfq_queue *bfqq; -+ -+ spin_lock_irq(bfqd->queue->queue_lock); -+ -+ list_for_each_entry(bfqq, &bfqd->active_list, bfqq_list) -+ bfq_bfqq_end_wr(bfqq); -+ list_for_each_entry(bfqq, &bfqd->idle_list, bfqq_list) -+ bfq_bfqq_end_wr(bfqq); -+ bfq_end_wr_async(bfqd); -+ -+ spin_unlock_irq(bfqd->queue->queue_lock); -+} -+ -+static int bfq_allow_merge(struct request_queue *q, struct request *rq, -+ struct bio *bio) -+{ -+ struct bfq_data *bfqd = q->elevator->elevator_data; -+ struct bfq_io_cq *bic; -+ struct bfq_queue *bfqq; -+ -+ /* -+ * Disallow merge of a sync bio into an async request. -+ */ -+ if (bfq_bio_sync(bio) && !rq_is_sync(rq)) -+ return 0; -+ -+ /* -+ * Lookup the bfqq that this bio will be queued with. Allow -+ * merge only if rq is queued there. -+ * Queue lock is held here. -+ */ -+ bic = bfq_bic_lookup(bfqd, current->io_context); -+ if (bic == NULL) -+ return 0; -+ -+ bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio)); -+ return bfqq == RQ_BFQQ(rq); -+} -+ -+static void __bfq_set_in_service_queue(struct bfq_data *bfqd, -+ struct bfq_queue *bfqq) -+{ -+ if (bfqq != NULL) { -+ bfq_mark_bfqq_must_alloc(bfqq); -+ bfq_mark_bfqq_budget_new(bfqq); -+ bfq_clear_bfqq_fifo_expire(bfqq); -+ -+ bfqd->budgets_assigned = (bfqd->budgets_assigned*7 + 256) / 8; -+ -+ bfq_log_bfqq(bfqd, bfqq, -+ "set_in_service_queue, cur-budget = %lu", -+ bfqq->entity.budget); -+ } -+ -+ bfqd->in_service_queue = bfqq; -+} -+ -+/* -+ * Get and set a new queue for service. -+ */ -+static struct bfq_queue *bfq_set_in_service_queue(struct bfq_data *bfqd, -+ struct bfq_queue *bfqq) -+{ -+ if (!bfqq) -+ bfqq = bfq_get_next_queue(bfqd); -+ else -+ bfq_get_next_queue_forced(bfqd, bfqq); -+ -+ __bfq_set_in_service_queue(bfqd, bfqq); -+ return bfqq; -+} -+ -+static inline sector_t bfq_dist_from_last(struct bfq_data *bfqd, -+ struct request *rq) -+{ -+ if (blk_rq_pos(rq) >= bfqd->last_position) -+ return blk_rq_pos(rq) - bfqd->last_position; -+ else -+ return bfqd->last_position - blk_rq_pos(rq); -+} -+ -+/* -+ * Return true if bfqq has no request pending and rq is close enough to -+ * bfqd->last_position, or if rq is closer to bfqd->last_position than -+ * bfqq->next_rq -+ */ -+static inline int bfq_rq_close(struct bfq_data *bfqd, struct request *rq) -+{ -+ return bfq_dist_from_last(bfqd, rq) <= BFQQ_SEEK_THR; -+} -+ -+static struct bfq_queue *bfqq_close(struct bfq_data *bfqd) -+{ -+ struct rb_root *root = &bfqd->rq_pos_tree; -+ struct rb_node *parent, *node; -+ struct bfq_queue *__bfqq; -+ sector_t sector = bfqd->last_position; -+ -+ if (RB_EMPTY_ROOT(root)) -+ return NULL; -+ -+ /* -+ * First, if we find a request starting at the end of the last -+ * request, choose it. -+ */ -+ __bfqq = bfq_rq_pos_tree_lookup(bfqd, root, sector, &parent, NULL); -+ if (__bfqq != NULL) -+ return __bfqq; -+ -+ /* -+ * If the exact sector wasn't found, the parent of the NULL leaf -+ * will contain the closest sector (rq_pos_tree sorted by -+ * next_request position). -+ */ -+ __bfqq = rb_entry(parent, struct bfq_queue, pos_node); -+ if (bfq_rq_close(bfqd, __bfqq->next_rq)) -+ return __bfqq; -+ -+ if (blk_rq_pos(__bfqq->next_rq) < sector) -+ node = rb_next(&__bfqq->pos_node); -+ else -+ node = rb_prev(&__bfqq->pos_node); -+ if (node == NULL) -+ return NULL; -+ -+ __bfqq = rb_entry(node, struct bfq_queue, pos_node); -+ if (bfq_rq_close(bfqd, __bfqq->next_rq)) -+ return __bfqq; -+ -+ return NULL; -+} -+ -+/* -+ * bfqd - obvious -+ * cur_bfqq - passed in so that we don't decide that the current queue -+ * is closely cooperating with itself. -+ * -+ * We are assuming that cur_bfqq has dispatched at least one request, -+ * and that bfqd->last_position reflects a position on the disk associated -+ * with the I/O issued by cur_bfqq. -+ */ -+static struct bfq_queue *bfq_close_cooperator(struct bfq_data *bfqd, -+ struct bfq_queue *cur_bfqq) -+{ -+ struct bfq_queue *bfqq; -+ -+ if (bfq_class_idle(cur_bfqq)) -+ return NULL; -+ if (!bfq_bfqq_sync(cur_bfqq)) -+ return NULL; -+ if (BFQQ_SEEKY(cur_bfqq)) -+ return NULL; -+ -+ /* If device has only one backlogged bfq_queue, don't search. */ -+ if (bfqd->busy_queues == 1) -+ return NULL; -+ -+ /* -+ * We should notice if some of the queues are cooperating, e.g. -+ * working closely on the same area of the disk. In that case, -+ * we can group them together and don't waste time idling. -+ */ -+ bfqq = bfqq_close(bfqd); -+ if (bfqq == NULL || bfqq == cur_bfqq) -+ return NULL; -+ -+ /* -+ * Do not merge queues from different bfq_groups. -+ */ -+ if (bfqq->entity.parent != cur_bfqq->entity.parent) -+ return NULL; -+ -+ /* -+ * It only makes sense to merge sync queues. -+ */ -+ if (!bfq_bfqq_sync(bfqq)) -+ return NULL; -+ if (BFQQ_SEEKY(bfqq)) -+ return NULL; -+ -+ /* -+ * Do not merge queues of different priority classes. -+ */ -+ if (bfq_class_rt(bfqq) != bfq_class_rt(cur_bfqq)) -+ return NULL; -+ -+ return bfqq; -+} -+ -+/* -+ * If enough samples have been computed, return the current max budget -+ * stored in bfqd, which is dynamically updated according to the -+ * estimated disk peak rate; otherwise return the default max budget -+ */ -+static inline unsigned long bfq_max_budget(struct bfq_data *bfqd) -+{ -+ if (bfqd->budgets_assigned < 194) -+ return bfq_default_max_budget; -+ else -+ return bfqd->bfq_max_budget; -+} -+ -+/* -+ * Return min budget, which is a fraction of the current or default -+ * max budget (trying with 1/32) -+ */ -+static inline unsigned long bfq_min_budget(struct bfq_data *bfqd) -+{ -+ if (bfqd->budgets_assigned < 194) -+ return bfq_default_max_budget / 32; -+ else -+ return bfqd->bfq_max_budget / 32; -+} -+ -+static void bfq_arm_slice_timer(struct bfq_data *bfqd) -+{ -+ struct bfq_queue *bfqq = bfqd->in_service_queue; -+ struct bfq_io_cq *bic; -+ unsigned long sl; -+ -+ BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list)); -+ -+ /* Processes have exited, don't wait. */ -+ bic = bfqd->in_service_bic; -+ if (bic == NULL || atomic_read(&bic->icq.ioc->active_ref) == 0) -+ return; -+ -+ bfq_mark_bfqq_wait_request(bfqq); -+ -+ /* -+ * We don't want to idle for seeks, but we do want to allow -+ * fair distribution of slice time for a process doing back-to-back -+ * seeks. So allow a little bit of time for him to submit a new rq. -+ * -+ * To prevent processes with (partly) seeky workloads from -+ * being too ill-treated, grant them a small fraction of the -+ * assigned budget before reducing the waiting time to -+ * BFQ_MIN_TT. This happened to help reduce latency. -+ */ -+ sl = bfqd->bfq_slice_idle; -+ /* -+ * Unless the queue is being weight-raised, grant only minimum idle -+ * time if the queue either has been seeky for long enough or has -+ * already proved to be constantly seeky. -+ */ -+ if (bfq_sample_valid(bfqq->seek_samples) && -+ ((BFQQ_SEEKY(bfqq) && bfqq->entity.service > -+ bfq_max_budget(bfqq->bfqd) / 8) || -+ bfq_bfqq_constantly_seeky(bfqq)) && bfqq->wr_coeff == 1) -+ sl = min(sl, msecs_to_jiffies(BFQ_MIN_TT)); -+ else if (bfqq->wr_coeff > 1) -+ sl = sl * 3; -+ bfqd->last_idling_start = ktime_get(); -+ mod_timer(&bfqd->idle_slice_timer, jiffies + sl); -+ bfq_log(bfqd, "arm idle: %u/%u ms", -+ jiffies_to_msecs(sl), jiffies_to_msecs(bfqd->bfq_slice_idle)); -+} -+ -+/* -+ * Set the maximum time for the in-service queue to consume its -+ * budget. This prevents seeky processes from lowering the disk -+ * throughput (always guaranteed with a time slice scheme as in CFQ). -+ */ -+static void bfq_set_budget_timeout(struct bfq_data *bfqd) -+{ -+ struct bfq_queue *bfqq = bfqd->in_service_queue; -+ unsigned int timeout_coeff; -+ if (bfqq->wr_cur_max_time == bfqd->bfq_wr_rt_max_time) -+ timeout_coeff = 1; -+ else -+ timeout_coeff = bfqq->entity.weight / bfqq->entity.orig_weight; -+ -+ bfqd->last_budget_start = ktime_get(); -+ -+ bfq_clear_bfqq_budget_new(bfqq); -+ bfqq->budget_timeout = jiffies + -+ bfqd->bfq_timeout[bfq_bfqq_sync(bfqq)] * timeout_coeff; -+ -+ bfq_log_bfqq(bfqd, bfqq, "set budget_timeout %u", -+ jiffies_to_msecs(bfqd->bfq_timeout[bfq_bfqq_sync(bfqq)] * -+ timeout_coeff)); -+} -+ -+/* -+ * Move request from internal lists to the request queue dispatch list. -+ */ -+static void bfq_dispatch_insert(struct request_queue *q, struct request *rq) -+{ -+ struct bfq_data *bfqd = q->elevator->elevator_data; -+ struct bfq_queue *bfqq = RQ_BFQQ(rq); -+ -+ /* -+ * For consistency, the next instruction should have been executed -+ * after removing the request from the queue and dispatching it. -+ * We execute instead this instruction before bfq_remove_request() -+ * (and hence introduce a temporary inconsistency), for efficiency. -+ * In fact, in a forced_dispatch, this prevents two counters related -+ * to bfqq->dispatched to risk to be uselessly decremented if bfqq -+ * is not in service, and then to be incremented again after -+ * incrementing bfqq->dispatched. -+ */ -+ bfqq->dispatched++; -+ bfq_remove_request(rq); -+ elv_dispatch_sort(q, rq); -+ -+ if (bfq_bfqq_sync(bfqq)) -+ bfqd->sync_flight++; -+} -+ -+/* -+ * Return expired entry, or NULL to just start from scratch in rbtree. -+ */ -+static struct request *bfq_check_fifo(struct bfq_queue *bfqq) -+{ -+ struct request *rq = NULL; -+ -+ if (bfq_bfqq_fifo_expire(bfqq)) -+ return NULL; -+ -+ bfq_mark_bfqq_fifo_expire(bfqq); -+ -+ if (list_empty(&bfqq->fifo)) -+ return NULL; -+ -+ rq = rq_entry_fifo(bfqq->fifo.next); -+ -+ if (time_before(jiffies, rq->fifo_time)) -+ return NULL; -+ -+ return rq; -+} -+ -+/* Must be called with the queue_lock held. */ -+static int bfqq_process_refs(struct bfq_queue *bfqq) -+{ -+ int process_refs, io_refs; -+ -+ io_refs = bfqq->allocated[READ] + bfqq->allocated[WRITE]; -+ process_refs = atomic_read(&bfqq->ref) - io_refs - bfqq->entity.on_st; -+ BUG_ON(process_refs < 0); -+ return process_refs; -+} -+ -+static void bfq_setup_merge(struct bfq_queue *bfqq, struct bfq_queue *new_bfqq) -+{ -+ int process_refs, new_process_refs; -+ struct bfq_queue *__bfqq; -+ -+ /* -+ * If there are no process references on the new_bfqq, then it is -+ * unsafe to follow the ->new_bfqq chain as other bfqq's in the chain -+ * may have dropped their last reference (not just their last process -+ * reference). -+ */ -+ if (!bfqq_process_refs(new_bfqq)) -+ return; -+ -+ /* Avoid a circular list and skip interim queue merges. */ -+ while ((__bfqq = new_bfqq->new_bfqq)) { -+ if (__bfqq == bfqq) -+ return; -+ new_bfqq = __bfqq; -+ } -+ -+ process_refs = bfqq_process_refs(bfqq); -+ new_process_refs = bfqq_process_refs(new_bfqq); -+ /* -+ * If the process for the bfqq has gone away, there is no -+ * sense in merging the queues. -+ */ -+ if (process_refs == 0 || new_process_refs == 0) -+ return; -+ -+ /* -+ * Merge in the direction of the lesser amount of work. -+ */ -+ if (new_process_refs >= process_refs) { -+ bfqq->new_bfqq = new_bfqq; -+ atomic_add(process_refs, &new_bfqq->ref); -+ } else { -+ new_bfqq->new_bfqq = bfqq; -+ atomic_add(new_process_refs, &bfqq->ref); -+ } -+ bfq_log_bfqq(bfqq->bfqd, bfqq, "scheduling merge with queue %d", -+ new_bfqq->pid); -+} -+ -+static inline unsigned long bfq_bfqq_budget_left(struct bfq_queue *bfqq) -+{ -+ struct bfq_entity *entity = &bfqq->entity; -+ return entity->budget - entity->service; -+} -+ -+static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq) -+{ -+ BUG_ON(bfqq != bfqd->in_service_queue); -+ -+ __bfq_bfqd_reset_in_service(bfqd); -+ -+ /* -+ * If this bfqq is shared between multiple processes, check -+ * to make sure that those processes are still issuing I/Os -+ * within the mean seek distance. If not, it may be time to -+ * break the queues apart again. -+ */ -+ if (bfq_bfqq_coop(bfqq) && BFQQ_SEEKY(bfqq)) -+ bfq_mark_bfqq_split_coop(bfqq); -+ -+ if (RB_EMPTY_ROOT(&bfqq->sort_list)) { -+ /* -+ * Overloading budget_timeout field to store the time -+ * at which the queue remains with no backlog; used by -+ * the weight-raising mechanism. -+ */ -+ bfqq->budget_timeout = jiffies; -+ bfq_del_bfqq_busy(bfqd, bfqq, 1); -+ } else { -+ bfq_activate_bfqq(bfqd, bfqq); -+ /* -+ * Resort priority tree of potential close cooperators. -+ */ -+ bfq_rq_pos_tree_add(bfqd, bfqq); -+ } -+} -+ -+/** -+ * __bfq_bfqq_recalc_budget - try to adapt the budget to the @bfqq behavior. -+ * @bfqd: device data. -+ * @bfqq: queue to update. -+ * @reason: reason for expiration. -+ * -+ * Handle the feedback on @bfqq budget. See the body for detailed -+ * comments. -+ */ -+static void __bfq_bfqq_recalc_budget(struct bfq_data *bfqd, -+ struct bfq_queue *bfqq, -+ enum bfqq_expiration reason) -+{ -+ struct request *next_rq; -+ unsigned long budget, min_budget; -+ -+ budget = bfqq->max_budget; -+ min_budget = bfq_min_budget(bfqd); -+ -+ BUG_ON(bfqq != bfqd->in_service_queue); -+ -+ bfq_log_bfqq(bfqd, bfqq, "recalc_budg: last budg %lu, budg left %lu", -+ bfqq->entity.budget, bfq_bfqq_budget_left(bfqq)); -+ bfq_log_bfqq(bfqd, bfqq, "recalc_budg: last max_budg %lu, min budg %lu", -+ budget, bfq_min_budget(bfqd)); -+ bfq_log_bfqq(bfqd, bfqq, "recalc_budg: sync %d, seeky %d", -+ bfq_bfqq_sync(bfqq), BFQQ_SEEKY(bfqd->in_service_queue)); -+ -+ if (bfq_bfqq_sync(bfqq)) { -+ switch (reason) { -+ /* -+ * Caveat: in all the following cases we trade latency -+ * for throughput. -+ */ -+ case BFQ_BFQQ_TOO_IDLE: -+ /* -+ * This is the only case where we may reduce -+ * the budget: if there is no request of the -+ * process still waiting for completion, then -+ * we assume (tentatively) that the timer has -+ * expired because the batch of requests of -+ * the process could have been served with a -+ * smaller budget. Hence, betting that -+ * process will behave in the same way when it -+ * becomes backlogged again, we reduce its -+ * next budget. As long as we guess right, -+ * this budget cut reduces the latency -+ * experienced by the process. -+ * -+ * However, if there are still outstanding -+ * requests, then the process may have not yet -+ * issued its next request just because it is -+ * still waiting for the completion of some of -+ * the still outstanding ones. So in this -+ * subcase we do not reduce its budget, on the -+ * contrary we increase it to possibly boost -+ * the throughput, as discussed in the -+ * comments to the BUDGET_TIMEOUT case. -+ */ -+ if (bfqq->dispatched > 0) /* still outstanding reqs */ -+ budget = min(budget * 2, bfqd->bfq_max_budget); -+ else { -+ if (budget > 5 * min_budget) -+ budget -= 4 * min_budget; -+ else -+ budget = min_budget; -+ } -+ break; -+ case BFQ_BFQQ_BUDGET_TIMEOUT: -+ /* -+ * We double the budget here because: 1) it -+ * gives the chance to boost the throughput if -+ * this is not a seeky process (which may have -+ * bumped into this timeout because of, e.g., -+ * ZBR), 2) together with charge_full_budget -+ * it helps give seeky processes higher -+ * timestamps, and hence be served less -+ * frequently. -+ */ -+ budget = min(budget * 2, bfqd->bfq_max_budget); -+ break; -+ case BFQ_BFQQ_BUDGET_EXHAUSTED: -+ /* -+ * The process still has backlog, and did not -+ * let either the budget timeout or the disk -+ * idling timeout expire. Hence it is not -+ * seeky, has a short thinktime and may be -+ * happy with a higher budget too. So -+ * definitely increase the budget of this good -+ * candidate to boost the disk throughput. -+ */ -+ budget = min(budget * 4, bfqd->bfq_max_budget); -+ break; -+ case BFQ_BFQQ_NO_MORE_REQUESTS: -+ /* -+ * Leave the budget unchanged. -+ */ -+ default: -+ return; -+ } -+ } else /* async queue */ -+ /* async queues get always the maximum possible budget -+ * (their ability to dispatch is limited by -+ * @bfqd->bfq_max_budget_async_rq). -+ */ -+ budget = bfqd->bfq_max_budget; -+ -+ bfqq->max_budget = budget; -+ -+ if (bfqd->budgets_assigned >= 194 && bfqd->bfq_user_max_budget == 0 && -+ bfqq->max_budget > bfqd->bfq_max_budget) -+ bfqq->max_budget = bfqd->bfq_max_budget; -+ -+ /* -+ * Make sure that we have enough budget for the next request. -+ * Since the finish time of the bfqq must be kept in sync with -+ * the budget, be sure to call __bfq_bfqq_expire() after the -+ * update. -+ */ -+ next_rq = bfqq->next_rq; -+ if (next_rq != NULL) -+ bfqq->entity.budget = max_t(unsigned long, bfqq->max_budget, -+ bfq_serv_to_charge(next_rq, bfqq)); -+ else -+ bfqq->entity.budget = bfqq->max_budget; -+ -+ bfq_log_bfqq(bfqd, bfqq, "head sect: %u, new budget %lu", -+ next_rq != NULL ? blk_rq_sectors(next_rq) : 0, -+ bfqq->entity.budget); -+} -+ -+static unsigned long bfq_calc_max_budget(u64 peak_rate, u64 timeout) -+{ -+ unsigned long max_budget; -+ -+ /* -+ * The max_budget calculated when autotuning is equal to the -+ * amount of sectors transfered in timeout_sync at the -+ * estimated peak rate. -+ */ -+ max_budget = (unsigned long)(peak_rate * 1000 * -+ timeout >> BFQ_RATE_SHIFT); -+ -+ return max_budget; -+} -+ -+/* -+ * In addition to updating the peak rate, checks whether the process -+ * is "slow", and returns 1 if so. This slow flag is used, in addition -+ * to the budget timeout, to reduce the amount of service provided to -+ * seeky processes, and hence reduce their chances to lower the -+ * throughput. See the code for more details. -+ */ -+static int bfq_update_peak_rate(struct bfq_data *bfqd, struct bfq_queue *bfqq, -+ int compensate, enum bfqq_expiration reason) -+{ -+ u64 bw, usecs, expected, timeout; -+ ktime_t delta; -+ int update = 0; -+ -+ if (!bfq_bfqq_sync(bfqq) || bfq_bfqq_budget_new(bfqq)) -+ return 0; -+ -+ if (compensate) -+ delta = bfqd->last_idling_start; -+ else -+ delta = ktime_get(); -+ delta = ktime_sub(delta, bfqd->last_budget_start); -+ usecs = ktime_to_us(delta); -+ -+ /* Don't trust short/unrealistic values. */ -+ if (usecs < 100 || usecs >= LONG_MAX) -+ return 0; -+ -+ /* -+ * Calculate the bandwidth for the last slice. We use a 64 bit -+ * value to store the peak rate, in sectors per usec in fixed -+ * point math. We do so to have enough precision in the estimate -+ * and to avoid overflows. -+ */ -+ bw = (u64)bfqq->entity.service << BFQ_RATE_SHIFT; -+ do_div(bw, (unsigned long)usecs); -+ -+ timeout = jiffies_to_msecs(bfqd->bfq_timeout[BLK_RW_SYNC]); -+ -+ /* -+ * Use only long (> 20ms) intervals to filter out spikes for -+ * the peak rate estimation. -+ */ -+ if (usecs > 20000) { -+ if (bw > bfqd->peak_rate || -+ (!BFQQ_SEEKY(bfqq) && -+ reason == BFQ_BFQQ_BUDGET_TIMEOUT)) { -+ bfq_log(bfqd, "measured bw =%llu", bw); -+ /* -+ * To smooth oscillations use a low-pass filter with -+ * alpha=7/8, i.e., -+ * new_rate = (7/8) * old_rate + (1/8) * bw -+ */ -+ do_div(bw, 8); -+ if (bw == 0) -+ return 0; -+ bfqd->peak_rate *= 7; -+ do_div(bfqd->peak_rate, 8); -+ bfqd->peak_rate += bw; -+ update = 1; -+ bfq_log(bfqd, "new peak_rate=%llu", bfqd->peak_rate); -+ } -+ -+ update |= bfqd->peak_rate_samples == BFQ_PEAK_RATE_SAMPLES - 1; -+ -+ if (bfqd->peak_rate_samples < BFQ_PEAK_RATE_SAMPLES) -+ bfqd->peak_rate_samples++; -+ -+ if (bfqd->peak_rate_samples == BFQ_PEAK_RATE_SAMPLES && -+ update) { -+ int dev_type = blk_queue_nonrot(bfqd->queue); -+ if (bfqd->bfq_user_max_budget == 0) { -+ bfqd->bfq_max_budget = -+ bfq_calc_max_budget(bfqd->peak_rate, -+ timeout); -+ bfq_log(bfqd, "new max_budget=%lu", -+ bfqd->bfq_max_budget); -+ } -+ if (bfqd->device_speed == BFQ_BFQD_FAST && -+ bfqd->peak_rate < device_speed_thresh[dev_type]) { -+ bfqd->device_speed = BFQ_BFQD_SLOW; -+ bfqd->RT_prod = R_slow[dev_type] * -+ T_slow[dev_type]; -+ } else if (bfqd->device_speed == BFQ_BFQD_SLOW && -+ bfqd->peak_rate > device_speed_thresh[dev_type]) { -+ bfqd->device_speed = BFQ_BFQD_FAST; -+ bfqd->RT_prod = R_fast[dev_type] * -+ T_fast[dev_type]; -+ } -+ } -+ } -+ -+ /* -+ * If the process has been served for a too short time -+ * interval to let its possible sequential accesses prevail on -+ * the initial seek time needed to move the disk head on the -+ * first sector it requested, then give the process a chance -+ * and for the moment return false. -+ */ -+ if (bfqq->entity.budget <= bfq_max_budget(bfqd) / 8) -+ return 0; -+ -+ /* -+ * A process is considered ``slow'' (i.e., seeky, so that we -+ * cannot treat it fairly in the service domain, as it would -+ * slow down too much the other processes) if, when a slice -+ * ends for whatever reason, it has received service at a -+ * rate that would not be high enough to complete the budget -+ * before the budget timeout expiration. -+ */ -+ expected = bw * 1000 * timeout >> BFQ_RATE_SHIFT; -+ -+ /* -+ * Caveat: processes doing IO in the slower disk zones will -+ * tend to be slow(er) even if not seeky. And the estimated -+ * peak rate will actually be an average over the disk -+ * surface. Hence, to not be too harsh with unlucky processes, -+ * we keep a budget/3 margin of safety before declaring a -+ * process slow. -+ */ -+ return expected > (4 * bfqq->entity.budget) / 3; -+} -+ -+/* -+ * To be deemed as soft real-time, an application must meet two -+ * requirements. First, the application must not require an average -+ * bandwidth higher than the approximate bandwidth required to playback or -+ * record a compressed high-definition video. -+ * The next function is invoked on the completion of the last request of a -+ * batch, to compute the next-start time instant, soft_rt_next_start, such -+ * that, if the next request of the application does not arrive before -+ * soft_rt_next_start, then the above requirement on the bandwidth is met. -+ * -+ * The second requirement is that the request pattern of the application is -+ * isochronous, i.e., that, after issuing a request or a batch of requests, -+ * the application stops issuing new requests until all its pending requests -+ * have been completed. After that, the application may issue a new batch, -+ * and so on. -+ * For this reason the next function is invoked to compute -+ * soft_rt_next_start only for applications that meet this requirement, -+ * whereas soft_rt_next_start is set to infinity for applications that do -+ * not. -+ * -+ * Unfortunately, even a greedy application may happen to behave in an -+ * isochronous way if the CPU load is high. In fact, the application may -+ * stop issuing requests while the CPUs are busy serving other processes, -+ * then restart, then stop again for a while, and so on. In addition, if -+ * the disk achieves a low enough throughput with the request pattern -+ * issued by the application (e.g., because the request pattern is random -+ * and/or the device is slow), then the application may meet the above -+ * bandwidth requirement too. To prevent such a greedy application to be -+ * deemed as soft real-time, a further rule is used in the computation of -+ * soft_rt_next_start: soft_rt_next_start must be higher than the current -+ * time plus the maximum time for which the arrival of a request is waited -+ * for when a sync queue becomes idle, namely bfqd->bfq_slice_idle. -+ * This filters out greedy applications, as the latter issue instead their -+ * next request as soon as possible after the last one has been completed -+ * (in contrast, when a batch of requests is completed, a soft real-time -+ * application spends some time processing data). -+ * -+ * Unfortunately, the last filter may easily generate false positives if -+ * only bfqd->bfq_slice_idle is used as a reference time interval and one -+ * or both the following cases occur: -+ * 1) HZ is so low that the duration of a jiffy is comparable to or higher -+ * than bfqd->bfq_slice_idle. This happens, e.g., on slow devices with -+ * HZ=100. -+ * 2) jiffies, instead of increasing at a constant rate, may stop increasing -+ * for a while, then suddenly 'jump' by several units to recover the lost -+ * increments. This seems to happen, e.g., inside virtual machines. -+ * To address this issue, we do not use as a reference time interval just -+ * bfqd->bfq_slice_idle, but bfqd->bfq_slice_idle plus a few jiffies. In -+ * particular we add the minimum number of jiffies for which the filter -+ * seems to be quite precise also in embedded systems and KVM/QEMU virtual -+ * machines. -+ */ -+static inline unsigned long bfq_bfqq_softrt_next_start(struct bfq_data *bfqd, -+ struct bfq_queue *bfqq) -+{ -+ return max(bfqq->last_idle_bklogged + -+ HZ * bfqq->service_from_backlogged / -+ bfqd->bfq_wr_max_softrt_rate, -+ jiffies + bfqq->bfqd->bfq_slice_idle + 4); -+} -+ -+/* -+ * Return the largest-possible time instant such that, for as long as possible, -+ * the current time will be lower than this time instant according to the macro -+ * time_is_before_jiffies(). -+ */ -+static inline unsigned long bfq_infinity_from_now(unsigned long now) -+{ -+ return now + ULONG_MAX / 2; -+} -+ -+/** -+ * bfq_bfqq_expire - expire a queue. -+ * @bfqd: device owning the queue. -+ * @bfqq: the queue to expire. -+ * @compensate: if true, compensate for the time spent idling. -+ * @reason: the reason causing the expiration. -+ * -+ * -+ * If the process associated to the queue is slow (i.e., seeky), or in -+ * case of budget timeout, or, finally, if it is async, we -+ * artificially charge it an entire budget (independently of the -+ * actual service it received). As a consequence, the queue will get -+ * higher timestamps than the correct ones upon reactivation, and -+ * hence it will be rescheduled as if it had received more service -+ * than what it actually received. In the end, this class of processes -+ * will receive less service in proportion to how slowly they consume -+ * their budgets (and hence how seriously they tend to lower the -+ * throughput). -+ * -+ * In contrast, when a queue expires because it has been idling for -+ * too much or because it exhausted its budget, we do not touch the -+ * amount of service it has received. Hence when the queue will be -+ * reactivated and its timestamps updated, the latter will be in sync -+ * with the actual service received by the queue until expiration. -+ * -+ * Charging a full budget to the first type of queues and the exact -+ * service to the others has the effect of using the WF2Q+ policy to -+ * schedule the former on a timeslice basis, without violating the -+ * service domain guarantees of the latter. -+ */ -+static void bfq_bfqq_expire(struct bfq_data *bfqd, -+ struct bfq_queue *bfqq, -+ int compensate, -+ enum bfqq_expiration reason) -+{ -+ int slow; -+ BUG_ON(bfqq != bfqd->in_service_queue); -+ -+ /* Update disk peak rate for autotuning and check whether the -+ * process is slow (see bfq_update_peak_rate). -+ */ -+ slow = bfq_update_peak_rate(bfqd, bfqq, compensate, reason); -+ -+ /* -+ * As above explained, 'punish' slow (i.e., seeky), timed-out -+ * and async queues, to favor sequential sync workloads. -+ * -+ * Processes doing I/O in the slower disk zones will tend to be -+ * slow(er) even if not seeky. Hence, since the estimated peak -+ * rate is actually an average over the disk surface, these -+ * processes may timeout just for bad luck. To avoid punishing -+ * them we do not charge a full budget to a process that -+ * succeeded in consuming at least 2/3 of its budget. -+ */ -+ if (slow || (reason == BFQ_BFQQ_BUDGET_TIMEOUT && -+ bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3)) -+ bfq_bfqq_charge_full_budget(bfqq); -+ -+ bfqq->service_from_backlogged += bfqq->entity.service; -+ -+ if (BFQQ_SEEKY(bfqq) && reason == BFQ_BFQQ_BUDGET_TIMEOUT && -+ !bfq_bfqq_constantly_seeky(bfqq)) { -+ bfq_mark_bfqq_constantly_seeky(bfqq); -+ if (!blk_queue_nonrot(bfqd->queue)) -+ bfqd->const_seeky_busy_in_flight_queues++; -+ } -+ -+ if (reason == BFQ_BFQQ_TOO_IDLE && -+ bfqq->entity.service <= 2 * bfqq->entity.budget / 10 ) -+ bfq_clear_bfqq_IO_bound(bfqq); -+ -+ if (bfqd->low_latency && bfqq->wr_coeff == 1) -+ bfqq->last_wr_start_finish = jiffies; -+ -+ if (bfqd->low_latency && bfqd->bfq_wr_max_softrt_rate > 0 && -+ RB_EMPTY_ROOT(&bfqq->sort_list)) { -+ /* -+ * If we get here, and there are no outstanding requests, -+ * then the request pattern is isochronous (see the comments -+ * to the function bfq_bfqq_softrt_next_start()). Hence we -+ * can compute soft_rt_next_start. If, instead, the queue -+ * still has outstanding requests, then we have to wait -+ * for the completion of all the outstanding requests to -+ * discover whether the request pattern is actually -+ * isochronous. -+ */ -+ if (bfqq->dispatched == 0) -+ bfqq->soft_rt_next_start = -+ bfq_bfqq_softrt_next_start(bfqd, bfqq); -+ else { -+ /* -+ * The application is still waiting for the -+ * completion of one or more requests: -+ * prevent it from possibly being incorrectly -+ * deemed as soft real-time by setting its -+ * soft_rt_next_start to infinity. In fact, -+ * without this assignment, the application -+ * would be incorrectly deemed as soft -+ * real-time if: -+ * 1) it issued a new request before the -+ * completion of all its in-flight -+ * requests, and -+ * 2) at that time, its soft_rt_next_start -+ * happened to be in the past. -+ */ -+ bfqq->soft_rt_next_start = -+ bfq_infinity_from_now(jiffies); -+ /* -+ * Schedule an update of soft_rt_next_start to when -+ * the task may be discovered to be isochronous. -+ */ -+ bfq_mark_bfqq_softrt_update(bfqq); -+ } -+ } -+ -+ bfq_log_bfqq(bfqd, bfqq, -+ "expire (%d, slow %d, num_disp %d, idle_win %d)", reason, -+ slow, bfqq->dispatched, bfq_bfqq_idle_window(bfqq)); -+ -+ /* -+ * Increase, decrease or leave budget unchanged according to -+ * reason. -+ */ -+ __bfq_bfqq_recalc_budget(bfqd, bfqq, reason); -+ __bfq_bfqq_expire(bfqd, bfqq); -+} -+ -+/* -+ * Budget timeout is not implemented through a dedicated timer, but -+ * just checked on request arrivals and completions, as well as on -+ * idle timer expirations. -+ */ -+static int bfq_bfqq_budget_timeout(struct bfq_queue *bfqq) -+{ -+ if (bfq_bfqq_budget_new(bfqq) || -+ time_before(jiffies, bfqq->budget_timeout)) -+ return 0; -+ return 1; -+} -+ -+/* -+ * If we expire a queue that is waiting for the arrival of a new -+ * request, we may prevent the fictitious timestamp back-shifting that -+ * allows the guarantees of the queue to be preserved (see [1] for -+ * this tricky aspect). Hence we return true only if this condition -+ * does not hold, or if the queue is slow enough to deserve only to be -+ * kicked off for preserving a high throughput. -+*/ -+static inline int bfq_may_expire_for_budg_timeout(struct bfq_queue *bfqq) -+{ -+ bfq_log_bfqq(bfqq->bfqd, bfqq, -+ "may_budget_timeout: wait_request %d left %d timeout %d", -+ bfq_bfqq_wait_request(bfqq), -+ bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3, -+ bfq_bfqq_budget_timeout(bfqq)); -+ -+ return (!bfq_bfqq_wait_request(bfqq) || -+ bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3) -+ && -+ bfq_bfqq_budget_timeout(bfqq); -+} -+ -+/* -+ * Device idling is allowed only for the queues for which this function -+ * returns true. For this reason, the return value of this function plays a -+ * critical role for both throughput boosting and service guarantees. The -+ * return value is computed through a logical expression. In this rather -+ * long comment, we try to briefly describe all the details and motivations -+ * behind the components of this logical expression. -+ * -+ * First, the expression is false if bfqq is not sync, or if: bfqq happened -+ * to become active during a large burst of queue activations, and the -+ * pattern of requests bfqq contains boosts the throughput if bfqq is -+ * expired. In fact, queues that became active during a large burst benefit -+ * only from throughput, as discussed in the comments to bfq_handle_burst. -+ * In this respect, expiring bfqq certainly boosts the throughput on NCQ- -+ * capable flash-based devices, whereas, on rotational devices, it boosts -+ * the throughput only if bfqq contains random requests. -+ * -+ * On the opposite end, if (a) bfqq is sync, (b) the above burst-related -+ * condition does not hold, and (c) bfqq is being weight-raised, then the -+ * expression always evaluates to true, as device idling is instrumental -+ * for preserving low-latency guarantees (see [1]). If, instead, conditions -+ * (a) and (b) do hold, but (c) does not, then the expression evaluates to -+ * true only if: (1) bfqq is I/O-bound and has a non-null idle window, and -+ * (2) at least one of the following two conditions holds. -+ * The first condition is that the device is not performing NCQ, because -+ * idling the device most certainly boosts the throughput if this condition -+ * holds and bfqq is I/O-bound and has been granted a non-null idle window. -+ * The second compound condition is made of the logical AND of two components. -+ * -+ * The first component is true only if there is no weight-raised busy -+ * queue. This guarantees that the device is not idled for a sync non- -+ * weight-raised queue when there are busy weight-raised queues. The former -+ * is then expired immediately if empty. Combined with the timestamping -+ * rules of BFQ (see [1] for details), this causes sync non-weight-raised -+ * queues to get a lower number of requests served, and hence to ask for a -+ * lower number of requests from the request pool, before the busy weight- -+ * raised queues get served again. -+ * -+ * This is beneficial for the processes associated with weight-raised -+ * queues, when the request pool is saturated (e.g., in the presence of -+ * write hogs). In fact, if the processes associated with the other queues -+ * ask for requests at a lower rate, then weight-raised processes have a -+ * higher probability to get a request from the pool immediately (or at -+ * least soon) when they need one. Hence they have a higher probability to -+ * actually get a fraction of the disk throughput proportional to their -+ * high weight. This is especially true with NCQ-capable drives, which -+ * enqueue several requests in advance and further reorder internally- -+ * queued requests. -+ * -+ * In the end, mistreating non-weight-raised queues when there are busy -+ * weight-raised queues seems to mitigate starvation problems in the -+ * presence of heavy write workloads and NCQ, and hence to guarantee a -+ * higher application and system responsiveness in these hostile scenarios. -+ * -+ * If the first component of the compound condition is instead true, i.e., -+ * there is no weight-raised busy queue, then the second component of the -+ * compound condition takes into account service-guarantee and throughput -+ * issues related to NCQ (recall that the compound condition is evaluated -+ * only if the device is detected as supporting NCQ). -+ * -+ * As for service guarantees, allowing the drive to enqueue more than one -+ * request at a time, and hence delegating de facto final scheduling -+ * decisions to the drive's internal scheduler, causes loss of control on -+ * the actual request service order. In this respect, when the drive is -+ * allowed to enqueue more than one request at a time, the service -+ * distribution enforced by the drive's internal scheduler is likely to -+ * coincide with the desired device-throughput distribution only in the -+ * following, perfectly symmetric, scenario: -+ * 1) all active queues have the same weight, -+ * 2) all active groups at the same level in the groups tree have the same -+ * weight, -+ * 3) all active groups at the same level in the groups tree have the same -+ * number of children. -+ * -+ * Even in such a scenario, sequential I/O may still receive a preferential -+ * treatment, but this is not likely to be a big issue with flash-based -+ * devices, because of their non-dramatic loss of throughput with random -+ * I/O. Things do differ with HDDs, for which additional care is taken, as -+ * explained after completing the discussion for flash-based devices. -+ * -+ * Unfortunately, keeping the necessary state for evaluating exactly the -+ * above symmetry conditions would be quite complex and time-consuming. -+ * Therefore BFQ evaluates instead the following stronger sub-conditions, -+ * for which it is much easier to maintain the needed state: -+ * 1) all active queues have the same weight, -+ * 2) all active groups have the same weight, -+ * 3) all active groups have at most one active child each. -+ * In particular, the last two conditions are always true if hierarchical -+ * support and the cgroups interface are not enabled, hence no state needs -+ * to be maintained in this case. -+ * -+ * According to the above considerations, the second component of the -+ * compound condition evaluates to true if any of the above symmetry -+ * sub-condition does not hold, or the device is not flash-based. Therefore, -+ * if also the first component is true, then idling is allowed for a sync -+ * queue. These are the only sub-conditions considered if the device is -+ * flash-based, as, for such a device, it is sensible to force idling only -+ * for service-guarantee issues. In fact, as for throughput, idling -+ * NCQ-capable flash-based devices would not boost the throughput even -+ * with sequential I/O; rather it would lower the throughput in proportion -+ * to how fast the device is. In the end, (only) if all the three -+ * sub-conditions hold and the device is flash-based, the compound -+ * condition evaluates to false and therefore no idling is performed. -+ * -+ * As already said, things change with a rotational device, where idling -+ * boosts the throughput with sequential I/O (even with NCQ). Hence, for -+ * such a device the second component of the compound condition evaluates -+ * to true also if the following additional sub-condition does not hold: -+ * the queue is constantly seeky. Unfortunately, this different behavior -+ * with respect to flash-based devices causes an additional asymmetry: if -+ * some sync queues enjoy idling and some other sync queues do not, then -+ * the latter get a low share of the device throughput, simply because the -+ * former get many requests served after being set as in service, whereas -+ * the latter do not. As a consequence, to guarantee the desired throughput -+ * distribution, on HDDs the compound expression evaluates to true (and -+ * hence device idling is performed) also if the following last symmetry -+ * condition does not hold: no other queue is benefiting from idling. Also -+ * this last condition is actually replaced with a simpler-to-maintain and -+ * stronger condition: there is no busy queue which is not constantly seeky -+ * (and hence may also benefit from idling). -+ * -+ * To sum up, when all the required symmetry and throughput-boosting -+ * sub-conditions hold, the second component of the compound condition -+ * evaluates to false, and hence no idling is performed. This helps to -+ * keep the drives' internal queues full on NCQ-capable devices, and hence -+ * to boost the throughput, without causing 'almost' any loss of service -+ * guarantees. The 'almost' follows from the fact that, if the internal -+ * queue of one such device is filled while all the sub-conditions hold, -+ * but at some point in time some sub-condition stops to hold, then it may -+ * become impossible to let requests be served in the new desired order -+ * until all the requests already queued in the device have been served. -+ */ -+static inline bool bfq_bfqq_must_not_expire(struct bfq_queue *bfqq) -+{ -+ struct bfq_data *bfqd = bfqq->bfqd; -+#ifdef CONFIG_CGROUP_BFQIO -+#define symmetric_scenario (!bfqd->active_numerous_groups && \ -+ !bfq_differentiated_weights(bfqd)) -+#else -+#define symmetric_scenario (!bfq_differentiated_weights(bfqd)) -+#endif -+#define cond_for_seeky_on_ncq_hdd (bfq_bfqq_constantly_seeky(bfqq) && \ -+ bfqd->busy_in_flight_queues == \ -+ bfqd->const_seeky_busy_in_flight_queues) -+ -+#define cond_for_expiring_in_burst (bfq_bfqq_in_large_burst(bfqq) && \ -+ bfqd->hw_tag && \ -+ (blk_queue_nonrot(bfqd->queue) || \ -+ bfq_bfqq_constantly_seeky(bfqq))) -+ -+/* -+ * Condition for expiring a non-weight-raised queue (and hence not idling -+ * the device). -+ */ -+#define cond_for_expiring_non_wr (bfqd->hw_tag && \ -+ (bfqd->wr_busy_queues > 0 || \ -+ (symmetric_scenario && \ -+ (blk_queue_nonrot(bfqd->queue) || \ -+ cond_for_seeky_on_ncq_hdd)))) -+ -+ return bfq_bfqq_sync(bfqq) && -+ !cond_for_expiring_in_burst && -+ (bfqq->wr_coeff > 1 || -+ (bfq_bfqq_IO_bound(bfqq) && bfq_bfqq_idle_window(bfqq) && -+ !cond_for_expiring_non_wr) -+ ); -+} -+ -+/* -+ * If the in-service queue is empty but sync, and the function -+ * bfq_bfqq_must_not_expire returns true, then: -+ * 1) the queue must remain in service and cannot be expired, and -+ * 2) the disk must be idled to wait for the possible arrival of a new -+ * request for the queue. -+ * See the comments to the function bfq_bfqq_must_not_expire for the reasons -+ * why performing device idling is the best choice to boost the throughput -+ * and preserve service guarantees when bfq_bfqq_must_not_expire itself -+ * returns true. -+ */ -+static inline bool bfq_bfqq_must_idle(struct bfq_queue *bfqq) -+{ -+ struct bfq_data *bfqd = bfqq->bfqd; -+ -+ return RB_EMPTY_ROOT(&bfqq->sort_list) && bfqd->bfq_slice_idle != 0 && -+ bfq_bfqq_must_not_expire(bfqq); -+} -+ -+/* -+ * Select a queue for service. If we have a current queue in service, -+ * check whether to continue servicing it, or retrieve and set a new one. -+ */ -+static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd) -+{ -+ struct bfq_queue *bfqq, *new_bfqq = NULL; -+ struct request *next_rq; -+ enum bfqq_expiration reason = BFQ_BFQQ_BUDGET_TIMEOUT; -+ -+ bfqq = bfqd->in_service_queue; -+ if (bfqq == NULL) -+ goto new_queue; -+ -+ bfq_log_bfqq(bfqd, bfqq, "select_queue: already in-service queue"); -+ -+ /* -+ * If another queue has a request waiting within our mean seek -+ * distance, let it run. The expire code will check for close -+ * cooperators and put the close queue at the front of the -+ * service tree. If possible, merge the expiring queue with the -+ * new bfqq. -+ */ -+ new_bfqq = bfq_close_cooperator(bfqd, bfqq); -+ if (new_bfqq != NULL && bfqq->new_bfqq == NULL) -+ bfq_setup_merge(bfqq, new_bfqq); -+ -+ if (bfq_may_expire_for_budg_timeout(bfqq) && -+ !timer_pending(&bfqd->idle_slice_timer) && -+ !bfq_bfqq_must_idle(bfqq)) -+ goto expire; -+ -+ next_rq = bfqq->next_rq; -+ /* -+ * If bfqq has requests queued and it has enough budget left to -+ * serve them, keep the queue, otherwise expire it. -+ */ -+ if (next_rq != NULL) { -+ if (bfq_serv_to_charge(next_rq, bfqq) > -+ bfq_bfqq_budget_left(bfqq)) { -+ reason = BFQ_BFQQ_BUDGET_EXHAUSTED; -+ goto expire; -+ } else { -+ /* -+ * The idle timer may be pending because we may -+ * not disable disk idling even when a new request -+ * arrives. -+ */ -+ if (timer_pending(&bfqd->idle_slice_timer)) { -+ /* -+ * If we get here: 1) at least a new request -+ * has arrived but we have not disabled the -+ * timer because the request was too small, -+ * 2) then the block layer has unplugged -+ * the device, causing the dispatch to be -+ * invoked. -+ * -+ * Since the device is unplugged, now the -+ * requests are probably large enough to -+ * provide a reasonable throughput. -+ * So we disable idling. -+ */ -+ bfq_clear_bfqq_wait_request(bfqq); -+ del_timer(&bfqd->idle_slice_timer); -+ } -+ if (new_bfqq == NULL) -+ goto keep_queue; -+ else -+ goto expire; -+ } -+ } -+ -+ /* -+ * No requests pending. If the in-service queue still has requests -+ * in flight (possibly waiting for a completion) or is idling for a -+ * new request, then keep it. -+ */ -+ if (new_bfqq == NULL && (timer_pending(&bfqd->idle_slice_timer) || -+ (bfqq->dispatched != 0 && bfq_bfqq_must_not_expire(bfqq)))) { -+ bfqq = NULL; -+ goto keep_queue; -+ } else if (new_bfqq != NULL && timer_pending(&bfqd->idle_slice_timer)) { -+ /* -+ * Expiring the queue because there is a close cooperator, -+ * cancel timer. -+ */ -+ bfq_clear_bfqq_wait_request(bfqq); -+ del_timer(&bfqd->idle_slice_timer); -+ } -+ -+ reason = BFQ_BFQQ_NO_MORE_REQUESTS; -+expire: -+ bfq_bfqq_expire(bfqd, bfqq, 0, reason); -+new_queue: -+ bfqq = bfq_set_in_service_queue(bfqd, new_bfqq); -+ bfq_log(bfqd, "select_queue: new queue %d returned", -+ bfqq != NULL ? bfqq->pid : 0); -+keep_queue: -+ return bfqq; -+} -+ -+static void bfq_update_wr_data(struct bfq_data *bfqd, -+ struct bfq_queue *bfqq) -+{ -+ if (bfqq->wr_coeff > 1) { /* queue is being boosted */ -+ struct bfq_entity *entity = &bfqq->entity; -+ -+ bfq_log_bfqq(bfqd, bfqq, -+ "raising period dur %u/%u msec, old coeff %u, w %d(%d)", -+ jiffies_to_msecs(jiffies - -+ bfqq->last_wr_start_finish), -+ jiffies_to_msecs(bfqq->wr_cur_max_time), -+ bfqq->wr_coeff, -+ bfqq->entity.weight, bfqq->entity.orig_weight); -+ -+ BUG_ON(bfqq != bfqd->in_service_queue && entity->weight != -+ entity->orig_weight * bfqq->wr_coeff); -+ if (entity->ioprio_changed) -+ bfq_log_bfqq(bfqd, bfqq, "WARN: pending prio change"); -+ /* -+ * If the queue was activated in a burst, or -+ * too much time has elapsed from the beginning -+ * of this weight-raising, then end weight raising. -+ */ -+ if (bfq_bfqq_in_large_burst(bfqq) || -+ time_is_before_jiffies(bfqq->last_wr_start_finish + -+ bfqq->wr_cur_max_time)) { -+ bfqq->last_wr_start_finish = jiffies; -+ bfq_log_bfqq(bfqd, bfqq, -+ "wrais ending at %lu, rais_max_time %u", -+ bfqq->last_wr_start_finish, -+ jiffies_to_msecs(bfqq->wr_cur_max_time)); -+ bfq_bfqq_end_wr(bfqq); -+ __bfq_entity_update_weight_prio( -+ bfq_entity_service_tree(entity), -+ entity); -+ } -+ } -+} -+ -+/* -+ * Dispatch one request from bfqq, moving it to the request queue -+ * dispatch list. -+ */ -+static int bfq_dispatch_request(struct bfq_data *bfqd, -+ struct bfq_queue *bfqq) -+{ -+ int dispatched = 0; -+ struct request *rq; -+ unsigned long service_to_charge; -+ -+ BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list)); -+ -+ /* Follow expired path, else get first next available. */ -+ rq = bfq_check_fifo(bfqq); -+ if (rq == NULL) -+ rq = bfqq->next_rq; -+ service_to_charge = bfq_serv_to_charge(rq, bfqq); -+ -+ if (service_to_charge > bfq_bfqq_budget_left(bfqq)) { -+ /* -+ * This may happen if the next rq is chosen in fifo order -+ * instead of sector order. The budget is properly -+ * dimensioned to be always sufficient to serve the next -+ * request only if it is chosen in sector order. The reason -+ * is that it would be quite inefficient and little useful -+ * to always make sure that the budget is large enough to -+ * serve even the possible next rq in fifo order. -+ * In fact, requests are seldom served in fifo order. -+ * -+ * Expire the queue for budget exhaustion, and make sure -+ * that the next act_budget is enough to serve the next -+ * request, even if it comes from the fifo expired path. -+ */ -+ bfqq->next_rq = rq; -+ /* -+ * Since this dispatch is failed, make sure that -+ * a new one will be performed -+ */ -+ if (!bfqd->rq_in_driver) -+ bfq_schedule_dispatch(bfqd); -+ goto expire; -+ } -+ -+ /* Finally, insert request into driver dispatch list. */ -+ bfq_bfqq_served(bfqq, service_to_charge); -+ bfq_dispatch_insert(bfqd->queue, rq); -+ -+ bfq_update_wr_data(bfqd, bfqq); -+ -+ bfq_log_bfqq(bfqd, bfqq, -+ "dispatched %u sec req (%llu), budg left %lu", -+ blk_rq_sectors(rq), -+ (long long unsigned)blk_rq_pos(rq), -+ bfq_bfqq_budget_left(bfqq)); -+ -+ dispatched++; -+ -+ if (bfqd->in_service_bic == NULL) { -+ atomic_long_inc(&RQ_BIC(rq)->icq.ioc->refcount); -+ bfqd->in_service_bic = RQ_BIC(rq); -+ } -+ -+ if (bfqd->busy_queues > 1 && ((!bfq_bfqq_sync(bfqq) && -+ dispatched >= bfqd->bfq_max_budget_async_rq) || -+ bfq_class_idle(bfqq))) -+ goto expire; -+ -+ return dispatched; -+ -+expire: -+ bfq_bfqq_expire(bfqd, bfqq, 0, BFQ_BFQQ_BUDGET_EXHAUSTED); -+ return dispatched; -+} -+ -+static int __bfq_forced_dispatch_bfqq(struct bfq_queue *bfqq) -+{ -+ int dispatched = 0; -+ -+ while (bfqq->next_rq != NULL) { -+ bfq_dispatch_insert(bfqq->bfqd->queue, bfqq->next_rq); -+ dispatched++; -+ } -+ -+ BUG_ON(!list_empty(&bfqq->fifo)); -+ return dispatched; -+} -+ -+/* -+ * Drain our current requests. -+ * Used for barriers and when switching io schedulers on-the-fly. -+ */ -+static int bfq_forced_dispatch(struct bfq_data *bfqd) -+{ -+ struct bfq_queue *bfqq, *n; -+ struct bfq_service_tree *st; -+ int dispatched = 0; -+ -+ bfqq = bfqd->in_service_queue; -+ if (bfqq != NULL) -+ __bfq_bfqq_expire(bfqd, bfqq); -+ -+ /* -+ * Loop through classes, and be careful to leave the scheduler -+ * in a consistent state, as feedback mechanisms and vtime -+ * updates cannot be disabled during the process. -+ */ -+ list_for_each_entry_safe(bfqq, n, &bfqd->active_list, bfqq_list) { -+ st = bfq_entity_service_tree(&bfqq->entity); -+ -+ dispatched += __bfq_forced_dispatch_bfqq(bfqq); -+ bfqq->max_budget = bfq_max_budget(bfqd); -+ -+ bfq_forget_idle(st); -+ } -+ -+ BUG_ON(bfqd->busy_queues != 0); -+ -+ return dispatched; -+} -+ -+static int bfq_dispatch_requests(struct request_queue *q, int force) -+{ -+ struct bfq_data *bfqd = q->elevator->elevator_data; -+ struct bfq_queue *bfqq; -+ int max_dispatch; -+ -+ bfq_log(bfqd, "dispatch requests: %d busy queues", bfqd->busy_queues); -+ if (bfqd->busy_queues == 0) -+ return 0; -+ -+ if (unlikely(force)) -+ return bfq_forced_dispatch(bfqd); -+ -+ bfqq = bfq_select_queue(bfqd); -+ if (bfqq == NULL) -+ return 0; -+ -+ max_dispatch = bfqd->bfq_quantum; -+ if (bfq_class_idle(bfqq)) -+ max_dispatch = 1; -+ -+ if (!bfq_bfqq_sync(bfqq)) -+ max_dispatch = bfqd->bfq_max_budget_async_rq; -+ -+ if (bfqq->dispatched >= max_dispatch) { -+ if (bfqd->busy_queues > 1) -+ return 0; -+ if (bfqq->dispatched >= 4 * max_dispatch) -+ return 0; -+ } -+ -+ if (bfqd->sync_flight != 0 && !bfq_bfqq_sync(bfqq)) -+ return 0; -+ -+ bfq_clear_bfqq_wait_request(bfqq); -+ BUG_ON(timer_pending(&bfqd->idle_slice_timer)); -+ -+ if (!bfq_dispatch_request(bfqd, bfqq)) -+ return 0; -+ -+ bfq_log_bfqq(bfqd, bfqq, "dispatched one request of %d (max_disp %d)", -+ bfqq->pid, max_dispatch); -+ -+ return 1; -+} -+ -+/* -+ * Task holds one reference to the queue, dropped when task exits. Each rq -+ * in-flight on this queue also holds a reference, dropped when rq is freed. -+ * -+ * Queue lock must be held here. -+ */ -+static void bfq_put_queue(struct bfq_queue *bfqq) -+{ -+ struct bfq_data *bfqd = bfqq->bfqd; -+ -+ BUG_ON(atomic_read(&bfqq->ref) <= 0); -+ -+ bfq_log_bfqq(bfqd, bfqq, "put_queue: %p %d", bfqq, -+ atomic_read(&bfqq->ref)); -+ if (!atomic_dec_and_test(&bfqq->ref)) -+ return; -+ -+ BUG_ON(rb_first(&bfqq->sort_list) != NULL); -+ BUG_ON(bfqq->allocated[READ] + bfqq->allocated[WRITE] != 0); -+ BUG_ON(bfqq->entity.tree != NULL); -+ BUG_ON(bfq_bfqq_busy(bfqq)); -+ BUG_ON(bfqd->in_service_queue == bfqq); -+ -+ if (bfq_bfqq_sync(bfqq)) -+ /* -+ * The fact that this queue is being destroyed does not -+ * invalidate the fact that this queue may have been -+ * activated during the current burst. As a consequence, -+ * although the queue does not exist anymore, and hence -+ * needs to be removed from the burst list if there, -+ * the burst size has not to be decremented. -+ */ -+ hlist_del_init(&bfqq->burst_list_node); -+ -+ bfq_log_bfqq(bfqd, bfqq, "put_queue: %p freed", bfqq); -+ -+ kmem_cache_free(bfq_pool, bfqq); -+} -+ -+static void bfq_put_cooperator(struct bfq_queue *bfqq) -+{ -+ struct bfq_queue *__bfqq, *next; -+ -+ /* -+ * If this queue was scheduled to merge with another queue, be -+ * sure to drop the reference taken on that queue (and others in -+ * the merge chain). See bfq_setup_merge and bfq_merge_bfqqs. -+ */ -+ __bfqq = bfqq->new_bfqq; -+ while (__bfqq) { -+ if (__bfqq == bfqq) -+ break; -+ next = __bfqq->new_bfqq; -+ bfq_put_queue(__bfqq); -+ __bfqq = next; -+ } -+} -+ -+static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq) -+{ -+ if (bfqq == bfqd->in_service_queue) { -+ __bfq_bfqq_expire(bfqd, bfqq); -+ bfq_schedule_dispatch(bfqd); -+ } -+ -+ bfq_log_bfqq(bfqd, bfqq, "exit_bfqq: %p, %d", bfqq, -+ atomic_read(&bfqq->ref)); -+ -+ bfq_put_cooperator(bfqq); -+ -+ bfq_put_queue(bfqq); -+} -+ -+static inline void bfq_init_icq(struct io_cq *icq) -+{ -+ struct bfq_io_cq *bic = icq_to_bic(icq); -+ -+ bic->ttime.last_end_request = jiffies; -+} -+ -+static void bfq_exit_icq(struct io_cq *icq) -+{ -+ struct bfq_io_cq *bic = icq_to_bic(icq); -+ struct bfq_data *bfqd = bic_to_bfqd(bic); -+ -+ if (bic->bfqq[BLK_RW_ASYNC]) { -+ bfq_exit_bfqq(bfqd, bic->bfqq[BLK_RW_ASYNC]); -+ bic->bfqq[BLK_RW_ASYNC] = NULL; -+ } -+ -+ if (bic->bfqq[BLK_RW_SYNC]) { -+ bfq_exit_bfqq(bfqd, bic->bfqq[BLK_RW_SYNC]); -+ bic->bfqq[BLK_RW_SYNC] = NULL; -+ } -+} -+ -+/* -+ * Update the entity prio values; note that the new values will not -+ * be used until the next (re)activation. -+ */ -+static void bfq_init_prio_data(struct bfq_queue *bfqq, struct bfq_io_cq *bic) -+{ -+ struct task_struct *tsk = current; -+ int ioprio_class; -+ -+ if (!bfq_bfqq_prio_changed(bfqq)) -+ return; -+ -+ ioprio_class = IOPRIO_PRIO_CLASS(bic->ioprio); -+ switch (ioprio_class) { -+ default: -+ dev_err(bfqq->bfqd->queue->backing_dev_info.dev, -+ "bfq: bad prio class %d\n", ioprio_class); -+ case IOPRIO_CLASS_NONE: -+ /* -+ * No prio set, inherit CPU scheduling settings. -+ */ -+ bfqq->entity.new_ioprio = task_nice_ioprio(tsk); -+ bfqq->entity.new_ioprio_class = task_nice_ioclass(tsk); -+ break; -+ case IOPRIO_CLASS_RT: -+ bfqq->entity.new_ioprio = IOPRIO_PRIO_DATA(bic->ioprio); -+ bfqq->entity.new_ioprio_class = IOPRIO_CLASS_RT; -+ break; -+ case IOPRIO_CLASS_BE: -+ bfqq->entity.new_ioprio = IOPRIO_PRIO_DATA(bic->ioprio); -+ bfqq->entity.new_ioprio_class = IOPRIO_CLASS_BE; -+ break; -+ case IOPRIO_CLASS_IDLE: -+ bfqq->entity.new_ioprio_class = IOPRIO_CLASS_IDLE; -+ bfqq->entity.new_ioprio = 7; -+ bfq_clear_bfqq_idle_window(bfqq); -+ break; -+ } -+ -+ if (bfqq->entity.new_ioprio < 0 || -+ bfqq->entity.new_ioprio >= IOPRIO_BE_NR) { -+ printk(KERN_CRIT "bfq_init_prio_data: new_ioprio %d\n", -+ bfqq->entity.new_ioprio); -+ BUG(); -+ } -+ -+ bfqq->entity.ioprio_changed = 1; -+ -+ bfq_clear_bfqq_prio_changed(bfqq); -+} -+ -+static void bfq_changed_ioprio(struct bfq_io_cq *bic) -+{ -+ struct bfq_data *bfqd; -+ struct bfq_queue *bfqq, *new_bfqq; -+ struct bfq_group *bfqg; -+ unsigned long uninitialized_var(flags); -+ int ioprio = bic->icq.ioc->ioprio; -+ -+ bfqd = bfq_get_bfqd_locked(&(bic->icq.q->elevator->elevator_data), -+ &flags); -+ /* -+ * This condition may trigger on a newly created bic, be sure to -+ * drop the lock before returning. -+ */ -+ if (unlikely(bfqd == NULL) || likely(bic->ioprio == ioprio)) -+ goto out; -+ -+ bfqq = bic->bfqq[BLK_RW_ASYNC]; -+ if (bfqq != NULL) { -+ bfqg = container_of(bfqq->entity.sched_data, struct bfq_group, -+ sched_data); -+ new_bfqq = bfq_get_queue(bfqd, bfqg, BLK_RW_ASYNC, bic, -+ GFP_ATOMIC); -+ if (new_bfqq != NULL) { -+ bic->bfqq[BLK_RW_ASYNC] = new_bfqq; -+ bfq_log_bfqq(bfqd, bfqq, -+ "changed_ioprio: bfqq %p %d", -+ bfqq, atomic_read(&bfqq->ref)); -+ bfq_put_queue(bfqq); -+ } -+ } -+ -+ bfqq = bic->bfqq[BLK_RW_SYNC]; -+ if (bfqq != NULL) -+ bfq_mark_bfqq_prio_changed(bfqq); -+ -+ bic->ioprio = ioprio; -+ -+out: -+ bfq_put_bfqd_unlock(bfqd, &flags); -+} -+ -+static void bfq_init_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, -+ pid_t pid, int is_sync) -+{ -+ RB_CLEAR_NODE(&bfqq->entity.rb_node); -+ INIT_LIST_HEAD(&bfqq->fifo); -+ INIT_HLIST_NODE(&bfqq->burst_list_node); -+ -+ atomic_set(&bfqq->ref, 0); -+ bfqq->bfqd = bfqd; -+ -+ bfq_mark_bfqq_prio_changed(bfqq); -+ -+ if (is_sync) { -+ if (!bfq_class_idle(bfqq)) -+ bfq_mark_bfqq_idle_window(bfqq); -+ bfq_mark_bfqq_sync(bfqq); -+ } -+ bfq_mark_bfqq_IO_bound(bfqq); -+ -+ /* Tentative initial value to trade off between thr and lat */ -+ bfqq->max_budget = (2 * bfq_max_budget(bfqd)) / 3; -+ bfqq->pid = pid; -+ -+ bfqq->wr_coeff = 1; -+ bfqq->last_wr_start_finish = 0; -+ /* -+ * Set to the value for which bfqq will not be deemed as -+ * soft rt when it becomes backlogged. -+ */ -+ bfqq->soft_rt_next_start = bfq_infinity_from_now(jiffies); -+} -+ -+static struct bfq_queue *bfq_find_alloc_queue(struct bfq_data *bfqd, -+ struct bfq_group *bfqg, -+ int is_sync, -+ struct bfq_io_cq *bic, -+ gfp_t gfp_mask) -+{ -+ struct bfq_queue *bfqq, *new_bfqq = NULL; -+ -+retry: -+ /* bic always exists here */ -+ bfqq = bic_to_bfqq(bic, is_sync); -+ -+ /* -+ * Always try a new alloc if we fall back to the OOM bfqq -+ * originally, since it should just be a temporary situation. -+ */ -+ if (bfqq == NULL || bfqq == &bfqd->oom_bfqq) { -+ bfqq = NULL; -+ if (new_bfqq != NULL) { -+ bfqq = new_bfqq; -+ new_bfqq = NULL; -+ } else if (gfp_mask & __GFP_WAIT) { -+ spin_unlock_irq(bfqd->queue->queue_lock); -+ new_bfqq = kmem_cache_alloc_node(bfq_pool, -+ gfp_mask | __GFP_ZERO, -+ bfqd->queue->node); -+ spin_lock_irq(bfqd->queue->queue_lock); -+ if (new_bfqq != NULL) -+ goto retry; -+ } else { -+ bfqq = kmem_cache_alloc_node(bfq_pool, -+ gfp_mask | __GFP_ZERO, -+ bfqd->queue->node); -+ } -+ -+ if (bfqq != NULL) { -+ bfq_init_bfqq(bfqd, bfqq, current->pid, is_sync); -+ bfq_init_prio_data(bfqq, bic); -+ bfq_init_entity(&bfqq->entity, bfqg); -+ bfq_log_bfqq(bfqd, bfqq, "allocated"); -+ } else { -+ bfqq = &bfqd->oom_bfqq; -+ bfq_log_bfqq(bfqd, bfqq, "using oom bfqq"); -+ } -+ } -+ -+ if (new_bfqq != NULL) -+ kmem_cache_free(bfq_pool, new_bfqq); -+ -+ return bfqq; -+} -+ -+static struct bfq_queue **bfq_async_queue_prio(struct bfq_data *bfqd, -+ struct bfq_group *bfqg, -+ int ioprio_class, int ioprio) -+{ -+ switch (ioprio_class) { -+ case IOPRIO_CLASS_RT: -+ return &bfqg->async_bfqq[0][ioprio]; -+ case IOPRIO_CLASS_NONE: -+ ioprio = IOPRIO_NORM; -+ /* fall through */ -+ case IOPRIO_CLASS_BE: -+ return &bfqg->async_bfqq[1][ioprio]; -+ case IOPRIO_CLASS_IDLE: -+ return &bfqg->async_idle_bfqq; -+ default: -+ BUG(); -+ } -+} -+ -+static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd, -+ struct bfq_group *bfqg, int is_sync, -+ struct bfq_io_cq *bic, gfp_t gfp_mask) -+{ -+ const int ioprio = IOPRIO_PRIO_DATA(bic->ioprio); -+ const int ioprio_class = IOPRIO_PRIO_CLASS(bic->ioprio); -+ struct bfq_queue **async_bfqq = NULL; -+ struct bfq_queue *bfqq = NULL; -+ -+ if (!is_sync) { -+ async_bfqq = bfq_async_queue_prio(bfqd, bfqg, ioprio_class, -+ ioprio); -+ bfqq = *async_bfqq; -+ } -+ -+ if (bfqq == NULL) -+ bfqq = bfq_find_alloc_queue(bfqd, bfqg, is_sync, bic, gfp_mask); -+ -+ /* -+ * Pin the queue now that it's allocated, scheduler exit will -+ * prune it. -+ */ -+ if (!is_sync && *async_bfqq == NULL) { -+ atomic_inc(&bfqq->ref); -+ bfq_log_bfqq(bfqd, bfqq, "get_queue, bfqq not in async: %p, %d", -+ bfqq, atomic_read(&bfqq->ref)); -+ *async_bfqq = bfqq; -+ } -+ -+ atomic_inc(&bfqq->ref); -+ bfq_log_bfqq(bfqd, bfqq, "get_queue, at end: %p, %d", bfqq, -+ atomic_read(&bfqq->ref)); -+ return bfqq; -+} -+ -+static void bfq_update_io_thinktime(struct bfq_data *bfqd, -+ struct bfq_io_cq *bic) -+{ -+ unsigned long elapsed = jiffies - bic->ttime.last_end_request; -+ unsigned long ttime = min(elapsed, 2UL * bfqd->bfq_slice_idle); -+ -+ bic->ttime.ttime_samples = (7*bic->ttime.ttime_samples + 256) / 8; -+ bic->ttime.ttime_total = (7*bic->ttime.ttime_total + 256*ttime) / 8; -+ bic->ttime.ttime_mean = (bic->ttime.ttime_total + 128) / -+ bic->ttime.ttime_samples; -+} -+ -+static void bfq_update_io_seektime(struct bfq_data *bfqd, -+ struct bfq_queue *bfqq, -+ struct request *rq) -+{ -+ sector_t sdist; -+ u64 total; -+ -+ if (bfqq->last_request_pos < blk_rq_pos(rq)) -+ sdist = blk_rq_pos(rq) - bfqq->last_request_pos; -+ else -+ sdist = bfqq->last_request_pos - blk_rq_pos(rq); -+ -+ /* -+ * Don't allow the seek distance to get too large from the -+ * odd fragment, pagein, etc. -+ */ -+ if (bfqq->seek_samples == 0) /* first request, not really a seek */ -+ sdist = 0; -+ else if (bfqq->seek_samples <= 60) /* second & third seek */ -+ sdist = min(sdist, (bfqq->seek_mean * 4) + 2*1024*1024); -+ else -+ sdist = min(sdist, (bfqq->seek_mean * 4) + 2*1024*64); -+ -+ bfqq->seek_samples = (7*bfqq->seek_samples + 256) / 8; -+ bfqq->seek_total = (7*bfqq->seek_total + (u64)256*sdist) / 8; -+ total = bfqq->seek_total + (bfqq->seek_samples/2); -+ do_div(total, bfqq->seek_samples); -+ bfqq->seek_mean = (sector_t)total; -+ -+ bfq_log_bfqq(bfqd, bfqq, "dist=%llu mean=%llu", (u64)sdist, -+ (u64)bfqq->seek_mean); -+} -+ -+/* -+ * Disable idle window if the process thinks too long or seeks so much that -+ * it doesn't matter. -+ */ -+static void bfq_update_idle_window(struct bfq_data *bfqd, -+ struct bfq_queue *bfqq, -+ struct bfq_io_cq *bic) -+{ -+ int enable_idle; -+ -+ /* Don't idle for async or idle io prio class. */ -+ if (!bfq_bfqq_sync(bfqq) || bfq_class_idle(bfqq)) -+ return; -+ -+ enable_idle = bfq_bfqq_idle_window(bfqq); -+ -+ if (atomic_read(&bic->icq.ioc->active_ref) == 0 || -+ bfqd->bfq_slice_idle == 0 || -+ (bfqd->hw_tag && BFQQ_SEEKY(bfqq) && -+ bfqq->wr_coeff == 1)) -+ enable_idle = 0; -+ else if (bfq_sample_valid(bic->ttime.ttime_samples)) { -+ if (bic->ttime.ttime_mean > bfqd->bfq_slice_idle && -+ bfqq->wr_coeff == 1) -+ enable_idle = 0; -+ else -+ enable_idle = 1; -+ } -+ bfq_log_bfqq(bfqd, bfqq, "update_idle_window: enable_idle %d", -+ enable_idle); -+ -+ if (enable_idle) -+ bfq_mark_bfqq_idle_window(bfqq); -+ else -+ bfq_clear_bfqq_idle_window(bfqq); -+} -+ -+/* -+ * Called when a new fs request (rq) is added to bfqq. Check if there's -+ * something we should do about it. -+ */ -+static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq, -+ struct request *rq) -+{ -+ struct bfq_io_cq *bic = RQ_BIC(rq); -+ -+ if (rq->cmd_flags & REQ_META) -+ bfqq->meta_pending++; -+ -+ bfq_update_io_thinktime(bfqd, bic); -+ bfq_update_io_seektime(bfqd, bfqq, rq); -+ if (!BFQQ_SEEKY(bfqq) && bfq_bfqq_constantly_seeky(bfqq)) { -+ bfq_clear_bfqq_constantly_seeky(bfqq); -+ if (!blk_queue_nonrot(bfqd->queue)) { -+ BUG_ON(!bfqd->const_seeky_busy_in_flight_queues); -+ bfqd->const_seeky_busy_in_flight_queues--; -+ } -+ } -+ if (bfqq->entity.service > bfq_max_budget(bfqd) / 8 || -+ !BFQQ_SEEKY(bfqq)) -+ bfq_update_idle_window(bfqd, bfqq, bic); -+ -+ bfq_log_bfqq(bfqd, bfqq, -+ "rq_enqueued: idle_window=%d (seeky %d, mean %llu)", -+ bfq_bfqq_idle_window(bfqq), BFQQ_SEEKY(bfqq), -+ (long long unsigned)bfqq->seek_mean); -+ -+ bfqq->last_request_pos = blk_rq_pos(rq) + blk_rq_sectors(rq); -+ -+ if (bfqq == bfqd->in_service_queue && bfq_bfqq_wait_request(bfqq)) { -+ int small_req = bfqq->queued[rq_is_sync(rq)] == 1 && -+ blk_rq_sectors(rq) < 32; -+ int budget_timeout = bfq_bfqq_budget_timeout(bfqq); -+ -+ /* -+ * There is just this request queued: if the request -+ * is small and the queue is not to be expired, then -+ * just exit. -+ * -+ * In this way, if the disk is being idled to wait for -+ * a new request from the in-service queue, we avoid -+ * unplugging the device and committing the disk to serve -+ * just a small request. On the contrary, we wait for -+ * the block layer to decide when to unplug the device: -+ * hopefully, new requests will be merged to this one -+ * quickly, then the device will be unplugged and -+ * larger requests will be dispatched. -+ */ -+ if (small_req && !budget_timeout) -+ return; -+ -+ /* -+ * A large enough request arrived, or the queue is to -+ * be expired: in both cases disk idling is to be -+ * stopped, so clear wait_request flag and reset -+ * timer. -+ */ -+ bfq_clear_bfqq_wait_request(bfqq); -+ del_timer(&bfqd->idle_slice_timer); -+ -+ /* -+ * The queue is not empty, because a new request just -+ * arrived. Hence we can safely expire the queue, in -+ * case of budget timeout, without risking that the -+ * timestamps of the queue are not updated correctly. -+ * See [1] for more details. -+ */ -+ if (budget_timeout) -+ bfq_bfqq_expire(bfqd, bfqq, 0, BFQ_BFQQ_BUDGET_TIMEOUT); -+ -+ /* -+ * Let the request rip immediately, or let a new queue be -+ * selected if bfqq has just been expired. -+ */ -+ __blk_run_queue(bfqd->queue); -+ } -+} -+ -+static void bfq_insert_request(struct request_queue *q, struct request *rq) -+{ -+ struct bfq_data *bfqd = q->elevator->elevator_data; -+ struct bfq_queue *bfqq = RQ_BFQQ(rq); -+ -+ assert_spin_locked(bfqd->queue->queue_lock); -+ bfq_init_prio_data(bfqq, RQ_BIC(rq)); -+ -+ bfq_add_request(rq); -+ -+ rq->fifo_time = jiffies + bfqd->bfq_fifo_expire[rq_is_sync(rq)]; -+ list_add_tail(&rq->queuelist, &bfqq->fifo); -+ -+ bfq_rq_enqueued(bfqd, bfqq, rq); -+} -+ -+static void bfq_update_hw_tag(struct bfq_data *bfqd) -+{ -+ bfqd->max_rq_in_driver = max(bfqd->max_rq_in_driver, -+ bfqd->rq_in_driver); -+ -+ if (bfqd->hw_tag == 1) -+ return; -+ -+ /* -+ * This sample is valid if the number of outstanding requests -+ * is large enough to allow a queueing behavior. Note that the -+ * sum is not exact, as it's not taking into account deactivated -+ * requests. -+ */ -+ if (bfqd->rq_in_driver + bfqd->queued < BFQ_HW_QUEUE_THRESHOLD) -+ return; -+ -+ if (bfqd->hw_tag_samples++ < BFQ_HW_QUEUE_SAMPLES) -+ return; -+ -+ bfqd->hw_tag = bfqd->max_rq_in_driver > BFQ_HW_QUEUE_THRESHOLD; -+ bfqd->max_rq_in_driver = 0; -+ bfqd->hw_tag_samples = 0; -+} -+ -+static void bfq_completed_request(struct request_queue *q, struct request *rq) -+{ -+ struct bfq_queue *bfqq = RQ_BFQQ(rq); -+ struct bfq_data *bfqd = bfqq->bfqd; -+ bool sync = bfq_bfqq_sync(bfqq); -+ -+ bfq_log_bfqq(bfqd, bfqq, "completed one req with %u sects left (%d)", -+ blk_rq_sectors(rq), sync); -+ -+ bfq_update_hw_tag(bfqd); -+ -+ BUG_ON(!bfqd->rq_in_driver); -+ BUG_ON(!bfqq->dispatched); -+ bfqd->rq_in_driver--; -+ bfqq->dispatched--; -+ -+ if (!bfqq->dispatched && !bfq_bfqq_busy(bfqq)) { -+ bfq_weights_tree_remove(bfqd, &bfqq->entity, -+ &bfqd->queue_weights_tree); -+ if (!blk_queue_nonrot(bfqd->queue)) { -+ BUG_ON(!bfqd->busy_in_flight_queues); -+ bfqd->busy_in_flight_queues--; -+ if (bfq_bfqq_constantly_seeky(bfqq)) { -+ BUG_ON(!bfqd-> -+ const_seeky_busy_in_flight_queues); -+ bfqd->const_seeky_busy_in_flight_queues--; -+ } -+ } -+ } -+ -+ if (sync) { -+ bfqd->sync_flight--; -+ RQ_BIC(rq)->ttime.last_end_request = jiffies; -+ } -+ -+ /* -+ * If we are waiting to discover whether the request pattern of the -+ * task associated with the queue is actually isochronous, and -+ * both requisites for this condition to hold are satisfied, then -+ * compute soft_rt_next_start (see the comments to the function -+ * bfq_bfqq_softrt_next_start()). -+ */ -+ if (bfq_bfqq_softrt_update(bfqq) && bfqq->dispatched == 0 && -+ RB_EMPTY_ROOT(&bfqq->sort_list)) -+ bfqq->soft_rt_next_start = -+ bfq_bfqq_softrt_next_start(bfqd, bfqq); -+ -+ /* -+ * If this is the in-service queue, check if it needs to be expired, -+ * or if we want to idle in case it has no pending requests. -+ */ -+ if (bfqd->in_service_queue == bfqq) { -+ if (bfq_bfqq_budget_new(bfqq)) -+ bfq_set_budget_timeout(bfqd); -+ -+ if (bfq_bfqq_must_idle(bfqq)) { -+ bfq_arm_slice_timer(bfqd); -+ goto out; -+ } else if (bfq_may_expire_for_budg_timeout(bfqq)) -+ bfq_bfqq_expire(bfqd, bfqq, 0, BFQ_BFQQ_BUDGET_TIMEOUT); -+ else if (RB_EMPTY_ROOT(&bfqq->sort_list) && -+ (bfqq->dispatched == 0 || -+ !bfq_bfqq_must_not_expire(bfqq))) -+ bfq_bfqq_expire(bfqd, bfqq, 0, -+ BFQ_BFQQ_NO_MORE_REQUESTS); -+ } -+ -+ if (!bfqd->rq_in_driver) -+ bfq_schedule_dispatch(bfqd); -+ -+out: -+ return; -+} -+ -+static inline int __bfq_may_queue(struct bfq_queue *bfqq) -+{ -+ if (bfq_bfqq_wait_request(bfqq) && bfq_bfqq_must_alloc(bfqq)) { -+ bfq_clear_bfqq_must_alloc(bfqq); -+ return ELV_MQUEUE_MUST; -+ } -+ -+ return ELV_MQUEUE_MAY; -+} -+ -+static int bfq_may_queue(struct request_queue *q, int rw) -+{ -+ struct bfq_data *bfqd = q->elevator->elevator_data; -+ struct task_struct *tsk = current; -+ struct bfq_io_cq *bic; -+ struct bfq_queue *bfqq; -+ -+ /* -+ * Don't force setup of a queue from here, as a call to may_queue -+ * does not necessarily imply that a request actually will be -+ * queued. So just lookup a possibly existing queue, or return -+ * 'may queue' if that fails. -+ */ -+ bic = bfq_bic_lookup(bfqd, tsk->io_context); -+ if (bic == NULL) -+ return ELV_MQUEUE_MAY; -+ -+ bfqq = bic_to_bfqq(bic, rw_is_sync(rw)); -+ if (bfqq != NULL) { -+ bfq_init_prio_data(bfqq, bic); -+ -+ return __bfq_may_queue(bfqq); -+ } -+ -+ return ELV_MQUEUE_MAY; -+} -+ -+/* -+ * Queue lock held here. -+ */ -+static void bfq_put_request(struct request *rq) -+{ -+ struct bfq_queue *bfqq = RQ_BFQQ(rq); -+ -+ if (bfqq != NULL) { -+ const int rw = rq_data_dir(rq); -+ -+ BUG_ON(!bfqq->allocated[rw]); -+ bfqq->allocated[rw]--; -+ -+ rq->elv.priv[0] = NULL; -+ rq->elv.priv[1] = NULL; -+ -+ bfq_log_bfqq(bfqq->bfqd, bfqq, "put_request %p, %d", -+ bfqq, atomic_read(&bfqq->ref)); -+ bfq_put_queue(bfqq); -+ } -+} -+ -+static struct bfq_queue * -+bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic, -+ struct bfq_queue *bfqq) -+{ -+ bfq_log_bfqq(bfqd, bfqq, "merging with queue %lu", -+ (long unsigned)bfqq->new_bfqq->pid); -+ bic_set_bfqq(bic, bfqq->new_bfqq, 1); -+ bfq_mark_bfqq_coop(bfqq->new_bfqq); -+ bfq_put_queue(bfqq); -+ return bic_to_bfqq(bic, 1); -+} -+ -+/* -+ * Returns NULL if a new bfqq should be allocated, or the old bfqq if this -+ * was the last process referring to said bfqq. -+ */ -+static struct bfq_queue * -+bfq_split_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq) -+{ -+ bfq_log_bfqq(bfqq->bfqd, bfqq, "splitting queue"); -+ if (bfqq_process_refs(bfqq) == 1) { -+ bfqq->pid = current->pid; -+ bfq_clear_bfqq_coop(bfqq); -+ bfq_clear_bfqq_split_coop(bfqq); -+ return bfqq; -+ } -+ -+ bic_set_bfqq(bic, NULL, 1); -+ -+ bfq_put_cooperator(bfqq); -+ -+ bfq_put_queue(bfqq); -+ return NULL; -+} -+ -+/* -+ * Allocate bfq data structures associated with this request. -+ */ -+static int bfq_set_request(struct request_queue *q, struct request *rq, -+ struct bio *bio, gfp_t gfp_mask) -+{ -+ struct bfq_data *bfqd = q->elevator->elevator_data; -+ struct bfq_io_cq *bic = icq_to_bic(rq->elv.icq); -+ const int rw = rq_data_dir(rq); -+ const int is_sync = rq_is_sync(rq); -+ struct bfq_queue *bfqq; -+ struct bfq_group *bfqg; -+ unsigned long flags; -+ -+ might_sleep_if(gfp_mask & __GFP_WAIT); -+ -+ bfq_changed_ioprio(bic); -+ -+ spin_lock_irqsave(q->queue_lock, flags); -+ -+ if (bic == NULL) -+ goto queue_fail; -+ -+ bfqg = bfq_bic_update_cgroup(bic); -+ -+new_queue: -+ bfqq = bic_to_bfqq(bic, is_sync); -+ if (bfqq == NULL || bfqq == &bfqd->oom_bfqq) { -+ bfqq = bfq_get_queue(bfqd, bfqg, is_sync, bic, gfp_mask); -+ bic_set_bfqq(bic, bfqq, is_sync); -+ } else { -+ /* -+ * If the queue was seeky for too long, break it apart. -+ */ -+ if (bfq_bfqq_coop(bfqq) && bfq_bfqq_split_coop(bfqq)) { -+ bfq_log_bfqq(bfqd, bfqq, "breaking apart bfqq"); -+ bfqq = bfq_split_bfqq(bic, bfqq); -+ if (!bfqq) -+ goto new_queue; -+ } -+ -+ /* -+ * Check to see if this queue is scheduled to merge with -+ * another closely cooperating queue. The merging of queues -+ * happens here as it must be done in process context. -+ * The reference on new_bfqq was taken in merge_bfqqs. -+ */ -+ if (bfqq->new_bfqq != NULL) -+ bfqq = bfq_merge_bfqqs(bfqd, bic, bfqq); -+ } -+ -+ bfqq->allocated[rw]++; -+ atomic_inc(&bfqq->ref); -+ bfq_log_bfqq(bfqd, bfqq, "set_request: bfqq %p, %d", bfqq, -+ atomic_read(&bfqq->ref)); -+ -+ rq->elv.priv[0] = bic; -+ rq->elv.priv[1] = bfqq; -+ -+ spin_unlock_irqrestore(q->queue_lock, flags); -+ -+ return 0; -+ -+queue_fail: -+ bfq_schedule_dispatch(bfqd); -+ spin_unlock_irqrestore(q->queue_lock, flags); -+ -+ return 1; -+} -+ -+static void bfq_kick_queue(struct work_struct *work) -+{ -+ struct bfq_data *bfqd = -+ container_of(work, struct bfq_data, unplug_work); -+ struct request_queue *q = bfqd->queue; -+ -+ spin_lock_irq(q->queue_lock); -+ __blk_run_queue(q); -+ spin_unlock_irq(q->queue_lock); -+} -+ -+/* -+ * Handler of the expiration of the timer running if the in-service queue -+ * is idling inside its time slice. -+ */ -+static void bfq_idle_slice_timer(unsigned long data) -+{ -+ struct bfq_data *bfqd = (struct bfq_data *)data; -+ struct bfq_queue *bfqq; -+ unsigned long flags; -+ enum bfqq_expiration reason; -+ -+ spin_lock_irqsave(bfqd->queue->queue_lock, flags); -+ -+ bfqq = bfqd->in_service_queue; -+ /* -+ * Theoretical race here: the in-service queue can be NULL or -+ * different from the queue that was idling if the timer handler -+ * spins on the queue_lock and a new request arrives for the -+ * current queue and there is a full dispatch cycle that changes -+ * the in-service queue. This can hardly happen, but in the worst -+ * case we just expire a queue too early. -+ */ -+ if (bfqq != NULL) { -+ bfq_log_bfqq(bfqd, bfqq, "slice_timer expired"); -+ if (bfq_bfqq_budget_timeout(bfqq)) -+ /* -+ * Also here the queue can be safely expired -+ * for budget timeout without wasting -+ * guarantees -+ */ -+ reason = BFQ_BFQQ_BUDGET_TIMEOUT; -+ else if (bfqq->queued[0] == 0 && bfqq->queued[1] == 0) -+ /* -+ * The queue may not be empty upon timer expiration, -+ * because we may not disable the timer when the -+ * first request of the in-service queue arrives -+ * during disk idling. -+ */ -+ reason = BFQ_BFQQ_TOO_IDLE; -+ else -+ goto schedule_dispatch; -+ -+ bfq_bfqq_expire(bfqd, bfqq, 1, reason); -+ } -+ -+schedule_dispatch: -+ bfq_schedule_dispatch(bfqd); -+ -+ spin_unlock_irqrestore(bfqd->queue->queue_lock, flags); -+} -+ -+static void bfq_shutdown_timer_wq(struct bfq_data *bfqd) -+{ -+ del_timer_sync(&bfqd->idle_slice_timer); -+ cancel_work_sync(&bfqd->unplug_work); -+} -+ -+static inline void __bfq_put_async_bfqq(struct bfq_data *bfqd, -+ struct bfq_queue **bfqq_ptr) -+{ -+ struct bfq_group *root_group = bfqd->root_group; -+ struct bfq_queue *bfqq = *bfqq_ptr; -+ -+ bfq_log(bfqd, "put_async_bfqq: %p", bfqq); -+ if (bfqq != NULL) { -+ bfq_bfqq_move(bfqd, bfqq, &bfqq->entity, root_group); -+ bfq_log_bfqq(bfqd, bfqq, "put_async_bfqq: putting %p, %d", -+ bfqq, atomic_read(&bfqq->ref)); -+ bfq_put_queue(bfqq); -+ *bfqq_ptr = NULL; -+ } -+} -+ -+/* -+ * Release all the bfqg references to its async queues. If we are -+ * deallocating the group these queues may still contain requests, so -+ * we reparent them to the root cgroup (i.e., the only one that will -+ * exist for sure until all the requests on a device are gone). -+ */ -+static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg) -+{ -+ int i, j; -+ -+ for (i = 0; i < 2; i++) -+ for (j = 0; j < IOPRIO_BE_NR; j++) -+ __bfq_put_async_bfqq(bfqd, &bfqg->async_bfqq[i][j]); -+ -+ __bfq_put_async_bfqq(bfqd, &bfqg->async_idle_bfqq); -+} -+ -+static void bfq_exit_queue(struct elevator_queue *e) -+{ -+ struct bfq_data *bfqd = e->elevator_data; -+ struct request_queue *q = bfqd->queue; -+ struct bfq_queue *bfqq, *n; -+ -+ bfq_shutdown_timer_wq(bfqd); -+ -+ spin_lock_irq(q->queue_lock); -+ -+ BUG_ON(bfqd->in_service_queue != NULL); -+ list_for_each_entry_safe(bfqq, n, &bfqd->idle_list, bfqq_list) -+ bfq_deactivate_bfqq(bfqd, bfqq, 0); -+ -+ bfq_disconnect_groups(bfqd); -+ spin_unlock_irq(q->queue_lock); -+ -+ bfq_shutdown_timer_wq(bfqd); -+ -+ synchronize_rcu(); -+ -+ BUG_ON(timer_pending(&bfqd->idle_slice_timer)); -+ -+ bfq_free_root_group(bfqd); -+ kfree(bfqd); -+} -+ -+static int bfq_init_queue(struct request_queue *q, struct elevator_type *e) -+{ -+ struct bfq_group *bfqg; -+ struct bfq_data *bfqd; -+ struct elevator_queue *eq; -+ -+ eq = elevator_alloc(q, e); -+ if (eq == NULL) -+ return -ENOMEM; -+ -+ bfqd = kzalloc_node(sizeof(*bfqd), GFP_KERNEL, q->node); -+ if (bfqd == NULL) { -+ kobject_put(&eq->kobj); -+ return -ENOMEM; -+ } -+ eq->elevator_data = bfqd; -+ -+ /* -+ * Our fallback bfqq if bfq_find_alloc_queue() runs into OOM issues. -+ * Grab a permanent reference to it, so that the normal code flow -+ * will not attempt to free it. -+ */ -+ bfq_init_bfqq(bfqd, &bfqd->oom_bfqq, 1, 0); -+ atomic_inc(&bfqd->oom_bfqq.ref); -+ bfqd->oom_bfqq.entity.new_ioprio = BFQ_DEFAULT_QUEUE_IOPRIO; -+ bfqd->oom_bfqq.entity.new_ioprio_class = IOPRIO_CLASS_BE; -+ /* -+ * Trigger weight initialization, according to ioprio, at the -+ * oom_bfqq's first activation. The oom_bfqq's ioprio and ioprio -+ * class won't be changed any more. -+ */ -+ bfqd->oom_bfqq.entity.ioprio_changed = 1; -+ -+ bfqd->queue = q; -+ -+ spin_lock_irq(q->queue_lock); -+ q->elevator = eq; -+ spin_unlock_irq(q->queue_lock); -+ -+ bfqg = bfq_alloc_root_group(bfqd, q->node); -+ if (bfqg == NULL) { -+ kfree(bfqd); -+ kobject_put(&eq->kobj); -+ return -ENOMEM; -+ } -+ -+ bfqd->root_group = bfqg; -+ bfq_init_entity(&bfqd->oom_bfqq.entity, bfqd->root_group); -+#ifdef CONFIG_CGROUP_BFQIO -+ bfqd->active_numerous_groups = 0; -+#endif -+ -+ init_timer(&bfqd->idle_slice_timer); -+ bfqd->idle_slice_timer.function = bfq_idle_slice_timer; -+ bfqd->idle_slice_timer.data = (unsigned long)bfqd; -+ -+ bfqd->rq_pos_tree = RB_ROOT; -+ bfqd->queue_weights_tree = RB_ROOT; -+ bfqd->group_weights_tree = RB_ROOT; -+ -+ INIT_WORK(&bfqd->unplug_work, bfq_kick_queue); -+ -+ INIT_LIST_HEAD(&bfqd->active_list); -+ INIT_LIST_HEAD(&bfqd->idle_list); -+ INIT_HLIST_HEAD(&bfqd->burst_list); -+ -+ bfqd->hw_tag = -1; -+ -+ bfqd->bfq_max_budget = bfq_default_max_budget; -+ -+ bfqd->bfq_quantum = bfq_quantum; -+ bfqd->bfq_fifo_expire[0] = bfq_fifo_expire[0]; -+ bfqd->bfq_fifo_expire[1] = bfq_fifo_expire[1]; -+ bfqd->bfq_back_max = bfq_back_max; -+ bfqd->bfq_back_penalty = bfq_back_penalty; -+ bfqd->bfq_slice_idle = bfq_slice_idle; -+ bfqd->bfq_class_idle_last_service = 0; -+ bfqd->bfq_max_budget_async_rq = bfq_max_budget_async_rq; -+ bfqd->bfq_timeout[BLK_RW_ASYNC] = bfq_timeout_async; -+ bfqd->bfq_timeout[BLK_RW_SYNC] = bfq_timeout_sync; -+ -+ bfqd->bfq_coop_thresh = 2; -+ bfqd->bfq_failed_cooperations = 7000; -+ bfqd->bfq_requests_within_timer = 120; -+ -+ bfqd->bfq_large_burst_thresh = 11; -+ bfqd->bfq_burst_interval = msecs_to_jiffies(500); -+ -+ bfqd->low_latency = true; -+ -+ bfqd->bfq_wr_coeff = 20; -+ bfqd->bfq_wr_rt_max_time = msecs_to_jiffies(300); -+ bfqd->bfq_wr_max_time = 0; -+ bfqd->bfq_wr_min_idle_time = msecs_to_jiffies(2000); -+ bfqd->bfq_wr_min_inter_arr_async = msecs_to_jiffies(500); -+ bfqd->bfq_wr_max_softrt_rate = 7000; /* -+ * Approximate rate required -+ * to playback or record a -+ * high-definition compressed -+ * video. -+ */ -+ bfqd->wr_busy_queues = 0; -+ bfqd->busy_in_flight_queues = 0; -+ bfqd->const_seeky_busy_in_flight_queues = 0; -+ -+ /* -+ * Begin by assuming, optimistically, that the device peak rate is -+ * equal to the highest reference rate. -+ */ -+ bfqd->RT_prod = R_fast[blk_queue_nonrot(bfqd->queue)] * -+ T_fast[blk_queue_nonrot(bfqd->queue)]; -+ bfqd->peak_rate = R_fast[blk_queue_nonrot(bfqd->queue)]; -+ bfqd->device_speed = BFQ_BFQD_FAST; -+ -+ return 0; -+} -+ -+static void bfq_slab_kill(void) -+{ -+ if (bfq_pool != NULL) -+ kmem_cache_destroy(bfq_pool); -+} -+ -+static int __init bfq_slab_setup(void) -+{ -+ bfq_pool = KMEM_CACHE(bfq_queue, 0); -+ if (bfq_pool == NULL) -+ return -ENOMEM; -+ return 0; -+} -+ -+static ssize_t bfq_var_show(unsigned int var, char *page) -+{ -+ return sprintf(page, "%d\n", var); -+} -+ -+static ssize_t bfq_var_store(unsigned long *var, const char *page, -+ size_t count) -+{ -+ unsigned long new_val; -+ int ret = kstrtoul(page, 10, &new_val); -+ -+ if (ret == 0) -+ *var = new_val; -+ -+ return count; -+} -+ -+static ssize_t bfq_wr_max_time_show(struct elevator_queue *e, char *page) -+{ -+ struct bfq_data *bfqd = e->elevator_data; -+ return sprintf(page, "%d\n", bfqd->bfq_wr_max_time > 0 ? -+ jiffies_to_msecs(bfqd->bfq_wr_max_time) : -+ jiffies_to_msecs(bfq_wr_duration(bfqd))); -+} -+ -+static ssize_t bfq_weights_show(struct elevator_queue *e, char *page) -+{ -+ struct bfq_queue *bfqq; -+ struct bfq_data *bfqd = e->elevator_data; -+ ssize_t num_char = 0; -+ -+ num_char += sprintf(page + num_char, "Tot reqs queued %d\n\n", -+ bfqd->queued); -+ -+ spin_lock_irq(bfqd->queue->queue_lock); -+ -+ num_char += sprintf(page + num_char, "Active:\n"); -+ list_for_each_entry(bfqq, &bfqd->active_list, bfqq_list) { -+ num_char += sprintf(page + num_char, -+ "pid%d: weight %hu, nr_queued %d %d, dur %d/%u\n", -+ bfqq->pid, -+ bfqq->entity.weight, -+ bfqq->queued[0], -+ bfqq->queued[1], -+ jiffies_to_msecs(jiffies - bfqq->last_wr_start_finish), -+ jiffies_to_msecs(bfqq->wr_cur_max_time)); -+ } -+ -+ num_char += sprintf(page + num_char, "Idle:\n"); -+ list_for_each_entry(bfqq, &bfqd->idle_list, bfqq_list) { -+ num_char += sprintf(page + num_char, -+ "pid%d: weight %hu, dur %d/%u\n", -+ bfqq->pid, -+ bfqq->entity.weight, -+ jiffies_to_msecs(jiffies - -+ bfqq->last_wr_start_finish), -+ jiffies_to_msecs(bfqq->wr_cur_max_time)); -+ } -+ -+ spin_unlock_irq(bfqd->queue->queue_lock); -+ -+ return num_char; -+} -+ -+#define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \ -+static ssize_t __FUNC(struct elevator_queue *e, char *page) \ -+{ \ -+ struct bfq_data *bfqd = e->elevator_data; \ -+ unsigned int __data = __VAR; \ -+ if (__CONV) \ -+ __data = jiffies_to_msecs(__data); \ -+ return bfq_var_show(__data, (page)); \ -+} -+SHOW_FUNCTION(bfq_quantum_show, bfqd->bfq_quantum, 0); -+SHOW_FUNCTION(bfq_fifo_expire_sync_show, bfqd->bfq_fifo_expire[1], 1); -+SHOW_FUNCTION(bfq_fifo_expire_async_show, bfqd->bfq_fifo_expire[0], 1); -+SHOW_FUNCTION(bfq_back_seek_max_show, bfqd->bfq_back_max, 0); -+SHOW_FUNCTION(bfq_back_seek_penalty_show, bfqd->bfq_back_penalty, 0); -+SHOW_FUNCTION(bfq_slice_idle_show, bfqd->bfq_slice_idle, 1); -+SHOW_FUNCTION(bfq_max_budget_show, bfqd->bfq_user_max_budget, 0); -+SHOW_FUNCTION(bfq_max_budget_async_rq_show, -+ bfqd->bfq_max_budget_async_rq, 0); -+SHOW_FUNCTION(bfq_timeout_sync_show, bfqd->bfq_timeout[BLK_RW_SYNC], 1); -+SHOW_FUNCTION(bfq_timeout_async_show, bfqd->bfq_timeout[BLK_RW_ASYNC], 1); -+SHOW_FUNCTION(bfq_low_latency_show, bfqd->low_latency, 0); -+SHOW_FUNCTION(bfq_wr_coeff_show, bfqd->bfq_wr_coeff, 0); -+SHOW_FUNCTION(bfq_wr_rt_max_time_show, bfqd->bfq_wr_rt_max_time, 1); -+SHOW_FUNCTION(bfq_wr_min_idle_time_show, bfqd->bfq_wr_min_idle_time, 1); -+SHOW_FUNCTION(bfq_wr_min_inter_arr_async_show, bfqd->bfq_wr_min_inter_arr_async, -+ 1); -+SHOW_FUNCTION(bfq_wr_max_softrt_rate_show, bfqd->bfq_wr_max_softrt_rate, 0); -+#undef SHOW_FUNCTION -+ -+#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \ -+static ssize_t \ -+__FUNC(struct elevator_queue *e, const char *page, size_t count) \ -+{ \ -+ struct bfq_data *bfqd = e->elevator_data; \ -+ unsigned long uninitialized_var(__data); \ -+ int ret = bfq_var_store(&__data, (page), count); \ -+ if (__data < (MIN)) \ -+ __data = (MIN); \ -+ else if (__data > (MAX)) \ -+ __data = (MAX); \ -+ if (__CONV) \ -+ *(__PTR) = msecs_to_jiffies(__data); \ -+ else \ -+ *(__PTR) = __data; \ -+ return ret; \ -+} -+STORE_FUNCTION(bfq_quantum_store, &bfqd->bfq_quantum, 1, INT_MAX, 0); -+STORE_FUNCTION(bfq_fifo_expire_sync_store, &bfqd->bfq_fifo_expire[1], 1, -+ INT_MAX, 1); -+STORE_FUNCTION(bfq_fifo_expire_async_store, &bfqd->bfq_fifo_expire[0], 1, -+ INT_MAX, 1); -+STORE_FUNCTION(bfq_back_seek_max_store, &bfqd->bfq_back_max, 0, INT_MAX, 0); -+STORE_FUNCTION(bfq_back_seek_penalty_store, &bfqd->bfq_back_penalty, 1, -+ INT_MAX, 0); -+STORE_FUNCTION(bfq_slice_idle_store, &bfqd->bfq_slice_idle, 0, INT_MAX, 1); -+STORE_FUNCTION(bfq_max_budget_async_rq_store, &bfqd->bfq_max_budget_async_rq, -+ 1, INT_MAX, 0); -+STORE_FUNCTION(bfq_timeout_async_store, &bfqd->bfq_timeout[BLK_RW_ASYNC], 0, -+ INT_MAX, 1); -+STORE_FUNCTION(bfq_wr_coeff_store, &bfqd->bfq_wr_coeff, 1, INT_MAX, 0); -+STORE_FUNCTION(bfq_wr_max_time_store, &bfqd->bfq_wr_max_time, 0, INT_MAX, 1); -+STORE_FUNCTION(bfq_wr_rt_max_time_store, &bfqd->bfq_wr_rt_max_time, 0, INT_MAX, -+ 1); -+STORE_FUNCTION(bfq_wr_min_idle_time_store, &bfqd->bfq_wr_min_idle_time, 0, -+ INT_MAX, 1); -+STORE_FUNCTION(bfq_wr_min_inter_arr_async_store, -+ &bfqd->bfq_wr_min_inter_arr_async, 0, INT_MAX, 1); -+STORE_FUNCTION(bfq_wr_max_softrt_rate_store, &bfqd->bfq_wr_max_softrt_rate, 0, -+ INT_MAX, 0); -+#undef STORE_FUNCTION -+ -+/* do nothing for the moment */ -+static ssize_t bfq_weights_store(struct elevator_queue *e, -+ const char *page, size_t count) -+{ -+ return count; -+} -+ -+static inline unsigned long bfq_estimated_max_budget(struct bfq_data *bfqd) -+{ -+ u64 timeout = jiffies_to_msecs(bfqd->bfq_timeout[BLK_RW_SYNC]); -+ -+ if (bfqd->peak_rate_samples >= BFQ_PEAK_RATE_SAMPLES) -+ return bfq_calc_max_budget(bfqd->peak_rate, timeout); -+ else -+ return bfq_default_max_budget; -+} -+ -+static ssize_t bfq_max_budget_store(struct elevator_queue *e, -+ const char *page, size_t count) -+{ -+ struct bfq_data *bfqd = e->elevator_data; -+ unsigned long uninitialized_var(__data); -+ int ret = bfq_var_store(&__data, (page), count); -+ -+ if (__data == 0) -+ bfqd->bfq_max_budget = bfq_estimated_max_budget(bfqd); -+ else { -+ if (__data > INT_MAX) -+ __data = INT_MAX; -+ bfqd->bfq_max_budget = __data; -+ } -+ -+ bfqd->bfq_user_max_budget = __data; -+ -+ return ret; -+} -+ -+static ssize_t bfq_timeout_sync_store(struct elevator_queue *e, -+ const char *page, size_t count) -+{ -+ struct bfq_data *bfqd = e->elevator_data; -+ unsigned long uninitialized_var(__data); -+ int ret = bfq_var_store(&__data, (page), count); -+ -+ if (__data < 1) -+ __data = 1; -+ else if (__data > INT_MAX) -+ __data = INT_MAX; -+ -+ bfqd->bfq_timeout[BLK_RW_SYNC] = msecs_to_jiffies(__data); -+ if (bfqd->bfq_user_max_budget == 0) -+ bfqd->bfq_max_budget = bfq_estimated_max_budget(bfqd); -+ -+ return ret; -+} -+ -+static ssize_t bfq_low_latency_store(struct elevator_queue *e, -+ const char *page, size_t count) -+{ -+ struct bfq_data *bfqd = e->elevator_data; -+ unsigned long uninitialized_var(__data); -+ int ret = bfq_var_store(&__data, (page), count); -+ -+ if (__data > 1) -+ __data = 1; -+ if (__data == 0 && bfqd->low_latency != 0) -+ bfq_end_wr(bfqd); -+ bfqd->low_latency = __data; -+ -+ return ret; -+} -+ -+#define BFQ_ATTR(name) \ -+ __ATTR(name, S_IRUGO|S_IWUSR, bfq_##name##_show, bfq_##name##_store) -+ -+static struct elv_fs_entry bfq_attrs[] = { -+ BFQ_ATTR(quantum), -+ BFQ_ATTR(fifo_expire_sync), -+ BFQ_ATTR(fifo_expire_async), -+ BFQ_ATTR(back_seek_max), -+ BFQ_ATTR(back_seek_penalty), -+ BFQ_ATTR(slice_idle), -+ BFQ_ATTR(max_budget), -+ BFQ_ATTR(max_budget_async_rq), -+ BFQ_ATTR(timeout_sync), -+ BFQ_ATTR(timeout_async), -+ BFQ_ATTR(low_latency), -+ BFQ_ATTR(wr_coeff), -+ BFQ_ATTR(wr_max_time), -+ BFQ_ATTR(wr_rt_max_time), -+ BFQ_ATTR(wr_min_idle_time), -+ BFQ_ATTR(wr_min_inter_arr_async), -+ BFQ_ATTR(wr_max_softrt_rate), -+ BFQ_ATTR(weights), -+ __ATTR_NULL -+}; -+ -+static struct elevator_type iosched_bfq = { -+ .ops = { -+ .elevator_merge_fn = bfq_merge, -+ .elevator_merged_fn = bfq_merged_request, -+ .elevator_merge_req_fn = bfq_merged_requests, -+ .elevator_allow_merge_fn = bfq_allow_merge, -+ .elevator_dispatch_fn = bfq_dispatch_requests, -+ .elevator_add_req_fn = bfq_insert_request, -+ .elevator_activate_req_fn = bfq_activate_request, -+ .elevator_deactivate_req_fn = bfq_deactivate_request, -+ .elevator_completed_req_fn = bfq_completed_request, -+ .elevator_former_req_fn = elv_rb_former_request, -+ .elevator_latter_req_fn = elv_rb_latter_request, -+ .elevator_init_icq_fn = bfq_init_icq, -+ .elevator_exit_icq_fn = bfq_exit_icq, -+ .elevator_set_req_fn = bfq_set_request, -+ .elevator_put_req_fn = bfq_put_request, -+ .elevator_may_queue_fn = bfq_may_queue, -+ .elevator_init_fn = bfq_init_queue, -+ .elevator_exit_fn = bfq_exit_queue, -+ }, -+ .icq_size = sizeof(struct bfq_io_cq), -+ .icq_align = __alignof__(struct bfq_io_cq), -+ .elevator_attrs = bfq_attrs, -+ .elevator_name = "bfq", -+ .elevator_owner = THIS_MODULE, -+}; -+ -+static int __init bfq_init(void) -+{ -+ /* -+ * Can be 0 on HZ < 1000 setups. -+ */ -+ if (bfq_slice_idle == 0) -+ bfq_slice_idle = 1; -+ -+ if (bfq_timeout_async == 0) -+ bfq_timeout_async = 1; -+ -+ if (bfq_slab_setup()) -+ return -ENOMEM; -+ -+ /* -+ * Times to load large popular applications for the typical systems -+ * installed on the reference devices (see the comments before the -+ * definitions of the two arrays). -+ */ -+ T_slow[0] = msecs_to_jiffies(2600); -+ T_slow[1] = msecs_to_jiffies(1000); -+ T_fast[0] = msecs_to_jiffies(5500); -+ T_fast[1] = msecs_to_jiffies(2000); -+ -+ /* -+ * Thresholds that determine the switch between speed classes (see -+ * the comments before the definition of the array). -+ */ -+ device_speed_thresh[0] = (R_fast[0] + R_slow[0]) / 2; -+ device_speed_thresh[1] = (R_fast[1] + R_slow[1]) / 2; -+ -+ elv_register(&iosched_bfq); -+ pr_info("BFQ I/O-scheduler version: v7r7"); -+ -+ return 0; -+} -+ -+static void __exit bfq_exit(void) -+{ -+ elv_unregister(&iosched_bfq); -+ bfq_slab_kill(); -+} -+ -+module_init(bfq_init); -+module_exit(bfq_exit); -+ -+MODULE_AUTHOR("Fabio Checconi, Paolo Valente"); -+MODULE_LICENSE("GPL"); -diff --git a/block/bfq-sched.c b/block/bfq-sched.c -new file mode 100644 -index 0000000..2931563 ---- /dev/null -+++ b/block/bfq-sched.c -@@ -0,0 +1,1214 @@ -+/* -+ * BFQ: Hierarchical B-WF2Q+ scheduler. -+ * -+ * Based on ideas and code from CFQ: -+ * Copyright (C) 2003 Jens Axboe -+ * -+ * Copyright (C) 2008 Fabio Checconi -+ * Paolo Valente -+ * -+ * Copyright (C) 2010 Paolo Valente -+ */ -+ -+#ifdef CONFIG_CGROUP_BFQIO -+#define for_each_entity(entity) \ -+ for (; entity != NULL; entity = entity->parent) -+ -+#define for_each_entity_safe(entity, parent) \ -+ for (; entity && ({ parent = entity->parent; 1; }); entity = parent) -+ -+static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd, -+ int extract, -+ struct bfq_data *bfqd); -+ -+static inline void bfq_update_budget(struct bfq_entity *next_in_service) -+{ -+ struct bfq_entity *bfqg_entity; -+ struct bfq_group *bfqg; -+ struct bfq_sched_data *group_sd; -+ -+ BUG_ON(next_in_service == NULL); -+ -+ group_sd = next_in_service->sched_data; -+ -+ bfqg = container_of(group_sd, struct bfq_group, sched_data); -+ /* -+ * bfq_group's my_entity field is not NULL only if the group -+ * is not the root group. We must not touch the root entity -+ * as it must never become an in-service entity. -+ */ -+ bfqg_entity = bfqg->my_entity; -+ if (bfqg_entity != NULL) -+ bfqg_entity->budget = next_in_service->budget; -+} -+ -+static int bfq_update_next_in_service(struct bfq_sched_data *sd) -+{ -+ struct bfq_entity *next_in_service; -+ -+ if (sd->in_service_entity != NULL) -+ /* will update/requeue at the end of service */ -+ return 0; -+ -+ /* -+ * NOTE: this can be improved in many ways, such as returning -+ * 1 (and thus propagating upwards the update) only when the -+ * budget changes, or caching the bfqq that will be scheduled -+ * next from this subtree. By now we worry more about -+ * correctness than about performance... -+ */ -+ next_in_service = bfq_lookup_next_entity(sd, 0, NULL); -+ sd->next_in_service = next_in_service; -+ -+ if (next_in_service != NULL) -+ bfq_update_budget(next_in_service); -+ -+ return 1; -+} -+ -+static inline void bfq_check_next_in_service(struct bfq_sched_data *sd, -+ struct bfq_entity *entity) -+{ -+ BUG_ON(sd->next_in_service != entity); -+} -+#else -+#define for_each_entity(entity) \ -+ for (; entity != NULL; entity = NULL) -+ -+#define for_each_entity_safe(entity, parent) \ -+ for (parent = NULL; entity != NULL; entity = parent) -+ -+static inline int bfq_update_next_in_service(struct bfq_sched_data *sd) -+{ -+ return 0; -+} -+ -+static inline void bfq_check_next_in_service(struct bfq_sched_data *sd, -+ struct bfq_entity *entity) -+{ -+} -+ -+static inline void bfq_update_budget(struct bfq_entity *next_in_service) -+{ -+} -+#endif -+ -+/* -+ * Shift for timestamp calculations. This actually limits the maximum -+ * service allowed in one timestamp delta (small shift values increase it), -+ * the maximum total weight that can be used for the queues in the system -+ * (big shift values increase it), and the period of virtual time -+ * wraparounds. -+ */ -+#define WFQ_SERVICE_SHIFT 22 -+ -+/** -+ * bfq_gt - compare two timestamps. -+ * @a: first ts. -+ * @b: second ts. -+ * -+ * Return @a > @b, dealing with wrapping correctly. -+ */ -+static inline int bfq_gt(u64 a, u64 b) -+{ -+ return (s64)(a - b) > 0; -+} -+ -+static inline struct bfq_queue *bfq_entity_to_bfqq(struct bfq_entity *entity) -+{ -+ struct bfq_queue *bfqq = NULL; -+ -+ BUG_ON(entity == NULL); -+ -+ if (entity->my_sched_data == NULL) -+ bfqq = container_of(entity, struct bfq_queue, entity); -+ -+ return bfqq; -+} -+ -+ -+/** -+ * bfq_delta - map service into the virtual time domain. -+ * @service: amount of service. -+ * @weight: scale factor (weight of an entity or weight sum). -+ */ -+static inline u64 bfq_delta(unsigned long service, -+ unsigned long weight) -+{ -+ u64 d = (u64)service << WFQ_SERVICE_SHIFT; -+ -+ do_div(d, weight); -+ return d; -+} -+ -+/** -+ * bfq_calc_finish - assign the finish time to an entity. -+ * @entity: the entity to act upon. -+ * @service: the service to be charged to the entity. -+ */ -+static inline void bfq_calc_finish(struct bfq_entity *entity, -+ unsigned long service) -+{ -+ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); -+ -+ BUG_ON(entity->weight == 0); -+ -+ entity->finish = entity->start + -+ bfq_delta(service, entity->weight); -+ -+ if (bfqq != NULL) { -+ bfq_log_bfqq(bfqq->bfqd, bfqq, -+ "calc_finish: serv %lu, w %d", -+ service, entity->weight); -+ bfq_log_bfqq(bfqq->bfqd, bfqq, -+ "calc_finish: start %llu, finish %llu, delta %llu", -+ entity->start, entity->finish, -+ bfq_delta(service, entity->weight)); -+ } -+} -+ -+/** -+ * bfq_entity_of - get an entity from a node. -+ * @node: the node field of the entity. -+ * -+ * Convert a node pointer to the relative entity. This is used only -+ * to simplify the logic of some functions and not as the generic -+ * conversion mechanism because, e.g., in the tree walking functions, -+ * the check for a %NULL value would be redundant. -+ */ -+static inline struct bfq_entity *bfq_entity_of(struct rb_node *node) -+{ -+ struct bfq_entity *entity = NULL; -+ -+ if (node != NULL) -+ entity = rb_entry(node, struct bfq_entity, rb_node); -+ -+ return entity; -+} -+ -+/** -+ * bfq_extract - remove an entity from a tree. -+ * @root: the tree root. -+ * @entity: the entity to remove. -+ */ -+static inline void bfq_extract(struct rb_root *root, -+ struct bfq_entity *entity) -+{ -+ BUG_ON(entity->tree != root); -+ -+ entity->tree = NULL; -+ rb_erase(&entity->rb_node, root); -+} -+ -+/** -+ * bfq_idle_extract - extract an entity from the idle tree. -+ * @st: the service tree of the owning @entity. -+ * @entity: the entity being removed. -+ */ -+static void bfq_idle_extract(struct bfq_service_tree *st, -+ struct bfq_entity *entity) -+{ -+ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); -+ struct rb_node *next; -+ -+ BUG_ON(entity->tree != &st->idle); -+ -+ if (entity == st->first_idle) { -+ next = rb_next(&entity->rb_node); -+ st->first_idle = bfq_entity_of(next); -+ } -+ -+ if (entity == st->last_idle) { -+ next = rb_prev(&entity->rb_node); -+ st->last_idle = bfq_entity_of(next); -+ } -+ -+ bfq_extract(&st->idle, entity); -+ -+ if (bfqq != NULL) -+ list_del(&bfqq->bfqq_list); -+} -+ -+/** -+ * bfq_insert - generic tree insertion. -+ * @root: tree root. -+ * @entity: entity to insert. -+ * -+ * This is used for the idle and the active tree, since they are both -+ * ordered by finish time. -+ */ -+static void bfq_insert(struct rb_root *root, struct bfq_entity *entity) -+{ -+ struct bfq_entity *entry; -+ struct rb_node **node = &root->rb_node; -+ struct rb_node *parent = NULL; -+ -+ BUG_ON(entity->tree != NULL); -+ -+ while (*node != NULL) { -+ parent = *node; -+ entry = rb_entry(parent, struct bfq_entity, rb_node); -+ -+ if (bfq_gt(entry->finish, entity->finish)) -+ node = &parent->rb_left; -+ else -+ node = &parent->rb_right; -+ } -+ -+ rb_link_node(&entity->rb_node, parent, node); -+ rb_insert_color(&entity->rb_node, root); -+ -+ entity->tree = root; -+} -+ -+/** -+ * bfq_update_min - update the min_start field of a entity. -+ * @entity: the entity to update. -+ * @node: one of its children. -+ * -+ * This function is called when @entity may store an invalid value for -+ * min_start due to updates to the active tree. The function assumes -+ * that the subtree rooted at @node (which may be its left or its right -+ * child) has a valid min_start value. -+ */ -+static inline void bfq_update_min(struct bfq_entity *entity, -+ struct rb_node *node) -+{ -+ struct bfq_entity *child; -+ -+ if (node != NULL) { -+ child = rb_entry(node, struct bfq_entity, rb_node); -+ if (bfq_gt(entity->min_start, child->min_start)) -+ entity->min_start = child->min_start; -+ } -+} -+ -+/** -+ * bfq_update_active_node - recalculate min_start. -+ * @node: the node to update. -+ * -+ * @node may have changed position or one of its children may have moved, -+ * this function updates its min_start value. The left and right subtrees -+ * are assumed to hold a correct min_start value. -+ */ -+static inline void bfq_update_active_node(struct rb_node *node) -+{ -+ struct bfq_entity *entity = rb_entry(node, struct bfq_entity, rb_node); -+ -+ entity->min_start = entity->start; -+ bfq_update_min(entity, node->rb_right); -+ bfq_update_min(entity, node->rb_left); -+} -+ -+/** -+ * bfq_update_active_tree - update min_start for the whole active tree. -+ * @node: the starting node. -+ * -+ * @node must be the deepest modified node after an update. This function -+ * updates its min_start using the values held by its children, assuming -+ * that they did not change, and then updates all the nodes that may have -+ * changed in the path to the root. The only nodes that may have changed -+ * are the ones in the path or their siblings. -+ */ -+static void bfq_update_active_tree(struct rb_node *node) -+{ -+ struct rb_node *parent; -+ -+up: -+ bfq_update_active_node(node); -+ -+ parent = rb_parent(node); -+ if (parent == NULL) -+ return; -+ -+ if (node == parent->rb_left && parent->rb_right != NULL) -+ bfq_update_active_node(parent->rb_right); -+ else if (parent->rb_left != NULL) -+ bfq_update_active_node(parent->rb_left); -+ -+ node = parent; -+ goto up; -+} -+ -+static void bfq_weights_tree_add(struct bfq_data *bfqd, -+ struct bfq_entity *entity, -+ struct rb_root *root); -+ -+static void bfq_weights_tree_remove(struct bfq_data *bfqd, -+ struct bfq_entity *entity, -+ struct rb_root *root); -+ -+ -+/** -+ * bfq_active_insert - insert an entity in the active tree of its -+ * group/device. -+ * @st: the service tree of the entity. -+ * @entity: the entity being inserted. -+ * -+ * The active tree is ordered by finish time, but an extra key is kept -+ * per each node, containing the minimum value for the start times of -+ * its children (and the node itself), so it's possible to search for -+ * the eligible node with the lowest finish time in logarithmic time. -+ */ -+static void bfq_active_insert(struct bfq_service_tree *st, -+ struct bfq_entity *entity) -+{ -+ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); -+ struct rb_node *node = &entity->rb_node; -+#ifdef CONFIG_CGROUP_BFQIO -+ struct bfq_sched_data *sd = NULL; -+ struct bfq_group *bfqg = NULL; -+ struct bfq_data *bfqd = NULL; -+#endif -+ -+ bfq_insert(&st->active, entity); -+ -+ if (node->rb_left != NULL) -+ node = node->rb_left; -+ else if (node->rb_right != NULL) -+ node = node->rb_right; -+ -+ bfq_update_active_tree(node); -+ -+#ifdef CONFIG_CGROUP_BFQIO -+ sd = entity->sched_data; -+ bfqg = container_of(sd, struct bfq_group, sched_data); -+ BUG_ON(!bfqg); -+ bfqd = (struct bfq_data *)bfqg->bfqd; -+#endif -+ if (bfqq != NULL) -+ list_add(&bfqq->bfqq_list, &bfqq->bfqd->active_list); -+#ifdef CONFIG_CGROUP_BFQIO -+ else { /* bfq_group */ -+ BUG_ON(!bfqd); -+ bfq_weights_tree_add(bfqd, entity, &bfqd->group_weights_tree); -+ } -+ if (bfqg != bfqd->root_group) { -+ BUG_ON(!bfqg); -+ BUG_ON(!bfqd); -+ bfqg->active_entities++; -+ if (bfqg->active_entities == 2) -+ bfqd->active_numerous_groups++; -+ } -+#endif -+} -+ -+/** -+ * bfq_ioprio_to_weight - calc a weight from an ioprio. -+ * @ioprio: the ioprio value to convert. -+ */ -+static inline unsigned short bfq_ioprio_to_weight(int ioprio) -+{ -+ BUG_ON(ioprio < 0 || ioprio >= IOPRIO_BE_NR); -+ return IOPRIO_BE_NR - ioprio; -+} -+ -+/** -+ * bfq_weight_to_ioprio - calc an ioprio from a weight. -+ * @weight: the weight value to convert. -+ * -+ * To preserve as mush as possible the old only-ioprio user interface, -+ * 0 is used as an escape ioprio value for weights (numerically) equal or -+ * larger than IOPRIO_BE_NR -+ */ -+static inline unsigned short bfq_weight_to_ioprio(int weight) -+{ -+ BUG_ON(weight < BFQ_MIN_WEIGHT || weight > BFQ_MAX_WEIGHT); -+ return IOPRIO_BE_NR - weight < 0 ? 0 : IOPRIO_BE_NR - weight; -+} -+ -+static inline void bfq_get_entity(struct bfq_entity *entity) -+{ -+ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); -+ -+ if (bfqq != NULL) { -+ atomic_inc(&bfqq->ref); -+ bfq_log_bfqq(bfqq->bfqd, bfqq, "get_entity: %p %d", -+ bfqq, atomic_read(&bfqq->ref)); -+ } -+} -+ -+/** -+ * bfq_find_deepest - find the deepest node that an extraction can modify. -+ * @node: the node being removed. -+ * -+ * Do the first step of an extraction in an rb tree, looking for the -+ * node that will replace @node, and returning the deepest node that -+ * the following modifications to the tree can touch. If @node is the -+ * last node in the tree return %NULL. -+ */ -+static struct rb_node *bfq_find_deepest(struct rb_node *node) -+{ -+ struct rb_node *deepest; -+ -+ if (node->rb_right == NULL && node->rb_left == NULL) -+ deepest = rb_parent(node); -+ else if (node->rb_right == NULL) -+ deepest = node->rb_left; -+ else if (node->rb_left == NULL) -+ deepest = node->rb_right; -+ else { -+ deepest = rb_next(node); -+ if (deepest->rb_right != NULL) -+ deepest = deepest->rb_right; -+ else if (rb_parent(deepest) != node) -+ deepest = rb_parent(deepest); -+ } -+ -+ return deepest; -+} -+ -+/** -+ * bfq_active_extract - remove an entity from the active tree. -+ * @st: the service_tree containing the tree. -+ * @entity: the entity being removed. -+ */ -+static void bfq_active_extract(struct bfq_service_tree *st, -+ struct bfq_entity *entity) -+{ -+ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); -+ struct rb_node *node; -+#ifdef CONFIG_CGROUP_BFQIO -+ struct bfq_sched_data *sd = NULL; -+ struct bfq_group *bfqg = NULL; -+ struct bfq_data *bfqd = NULL; -+#endif -+ -+ node = bfq_find_deepest(&entity->rb_node); -+ bfq_extract(&st->active, entity); -+ -+ if (node != NULL) -+ bfq_update_active_tree(node); -+ -+#ifdef CONFIG_CGROUP_BFQIO -+ sd = entity->sched_data; -+ bfqg = container_of(sd, struct bfq_group, sched_data); -+ BUG_ON(!bfqg); -+ bfqd = (struct bfq_data *)bfqg->bfqd; -+#endif -+ if (bfqq != NULL) -+ list_del(&bfqq->bfqq_list); -+#ifdef CONFIG_CGROUP_BFQIO -+ else { /* bfq_group */ -+ BUG_ON(!bfqd); -+ bfq_weights_tree_remove(bfqd, entity, -+ &bfqd->group_weights_tree); -+ } -+ if (bfqg != bfqd->root_group) { -+ BUG_ON(!bfqg); -+ BUG_ON(!bfqd); -+ BUG_ON(!bfqg->active_entities); -+ bfqg->active_entities--; -+ if (bfqg->active_entities == 1) { -+ BUG_ON(!bfqd->active_numerous_groups); -+ bfqd->active_numerous_groups--; -+ } -+ } -+#endif -+} -+ -+/** -+ * bfq_idle_insert - insert an entity into the idle tree. -+ * @st: the service tree containing the tree. -+ * @entity: the entity to insert. -+ */ -+static void bfq_idle_insert(struct bfq_service_tree *st, -+ struct bfq_entity *entity) -+{ -+ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); -+ struct bfq_entity *first_idle = st->first_idle; -+ struct bfq_entity *last_idle = st->last_idle; -+ -+ if (first_idle == NULL || bfq_gt(first_idle->finish, entity->finish)) -+ st->first_idle = entity; -+ if (last_idle == NULL || bfq_gt(entity->finish, last_idle->finish)) -+ st->last_idle = entity; -+ -+ bfq_insert(&st->idle, entity); -+ -+ if (bfqq != NULL) -+ list_add(&bfqq->bfqq_list, &bfqq->bfqd->idle_list); -+} -+ -+/** -+ * bfq_forget_entity - remove an entity from the wfq trees. -+ * @st: the service tree. -+ * @entity: the entity being removed. -+ * -+ * Update the device status and forget everything about @entity, putting -+ * the device reference to it, if it is a queue. Entities belonging to -+ * groups are not refcounted. -+ */ -+static void bfq_forget_entity(struct bfq_service_tree *st, -+ struct bfq_entity *entity) -+{ -+ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); -+ struct bfq_sched_data *sd; -+ -+ BUG_ON(!entity->on_st); -+ -+ entity->on_st = 0; -+ st->wsum -= entity->weight; -+ if (bfqq != NULL) { -+ sd = entity->sched_data; -+ bfq_log_bfqq(bfqq->bfqd, bfqq, "forget_entity: %p %d", -+ bfqq, atomic_read(&bfqq->ref)); -+ bfq_put_queue(bfqq); -+ } -+} -+ -+/** -+ * bfq_put_idle_entity - release the idle tree ref of an entity. -+ * @st: service tree for the entity. -+ * @entity: the entity being released. -+ */ -+static void bfq_put_idle_entity(struct bfq_service_tree *st, -+ struct bfq_entity *entity) -+{ -+ bfq_idle_extract(st, entity); -+ bfq_forget_entity(st, entity); -+} -+ -+/** -+ * bfq_forget_idle - update the idle tree if necessary. -+ * @st: the service tree to act upon. -+ * -+ * To preserve the global O(log N) complexity we only remove one entry here; -+ * as the idle tree will not grow indefinitely this can be done safely. -+ */ -+static void bfq_forget_idle(struct bfq_service_tree *st) -+{ -+ struct bfq_entity *first_idle = st->first_idle; -+ struct bfq_entity *last_idle = st->last_idle; -+ -+ if (RB_EMPTY_ROOT(&st->active) && last_idle != NULL && -+ !bfq_gt(last_idle->finish, st->vtime)) { -+ /* -+ * Forget the whole idle tree, increasing the vtime past -+ * the last finish time of idle entities. -+ */ -+ st->vtime = last_idle->finish; -+ } -+ -+ if (first_idle != NULL && !bfq_gt(first_idle->finish, st->vtime)) -+ bfq_put_idle_entity(st, first_idle); -+} -+ -+static struct bfq_service_tree * -+__bfq_entity_update_weight_prio(struct bfq_service_tree *old_st, -+ struct bfq_entity *entity) -+{ -+ struct bfq_service_tree *new_st = old_st; -+ -+ if (entity->ioprio_changed) { -+ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); -+ unsigned short prev_weight, new_weight; -+ struct bfq_data *bfqd = NULL; -+ struct rb_root *root; -+#ifdef CONFIG_CGROUP_BFQIO -+ struct bfq_sched_data *sd; -+ struct bfq_group *bfqg; -+#endif -+ -+ if (bfqq != NULL) -+ bfqd = bfqq->bfqd; -+#ifdef CONFIG_CGROUP_BFQIO -+ else { -+ sd = entity->my_sched_data; -+ bfqg = container_of(sd, struct bfq_group, sched_data); -+ BUG_ON(!bfqg); -+ bfqd = (struct bfq_data *)bfqg->bfqd; -+ BUG_ON(!bfqd); -+ } -+#endif -+ -+ BUG_ON(old_st->wsum < entity->weight); -+ old_st->wsum -= entity->weight; -+ -+ if (entity->new_weight != entity->orig_weight) { -+ if (entity->new_weight < BFQ_MIN_WEIGHT || -+ entity->new_weight > BFQ_MAX_WEIGHT) { -+ printk(KERN_CRIT "update_weight_prio: " -+ "new_weight %d\n", -+ entity->new_weight); -+ BUG(); -+ } -+ entity->orig_weight = entity->new_weight; -+ entity->ioprio = -+ bfq_weight_to_ioprio(entity->orig_weight); -+ } else if (entity->new_ioprio != entity->ioprio) { -+ entity->ioprio = entity->new_ioprio; -+ entity->orig_weight = -+ bfq_ioprio_to_weight(entity->ioprio); -+ } else -+ entity->new_weight = entity->orig_weight = -+ bfq_ioprio_to_weight(entity->ioprio); -+ -+ entity->ioprio_class = entity->new_ioprio_class; -+ entity->ioprio_changed = 0; -+ -+ /* -+ * NOTE: here we may be changing the weight too early, -+ * this will cause unfairness. The correct approach -+ * would have required additional complexity to defer -+ * weight changes to the proper time instants (i.e., -+ * when entity->finish <= old_st->vtime). -+ */ -+ new_st = bfq_entity_service_tree(entity); -+ -+ prev_weight = entity->weight; -+ new_weight = entity->orig_weight * -+ (bfqq != NULL ? bfqq->wr_coeff : 1); -+ /* -+ * If the weight of the entity changes, remove the entity -+ * from its old weight counter (if there is a counter -+ * associated with the entity), and add it to the counter -+ * associated with its new weight. -+ */ -+ if (prev_weight != new_weight) { -+ root = bfqq ? &bfqd->queue_weights_tree : -+ &bfqd->group_weights_tree; -+ bfq_weights_tree_remove(bfqd, entity, root); -+ } -+ entity->weight = new_weight; -+ /* -+ * Add the entity to its weights tree only if it is -+ * not associated with a weight-raised queue. -+ */ -+ if (prev_weight != new_weight && -+ (bfqq ? bfqq->wr_coeff == 1 : 1)) -+ /* If we get here, root has been initialized. */ -+ bfq_weights_tree_add(bfqd, entity, root); -+ -+ new_st->wsum += entity->weight; -+ -+ if (new_st != old_st) -+ entity->start = new_st->vtime; -+ } -+ -+ return new_st; -+} -+ -+/** -+ * bfq_bfqq_served - update the scheduler status after selection for -+ * service. -+ * @bfqq: the queue being served. -+ * @served: bytes to transfer. -+ * -+ * NOTE: this can be optimized, as the timestamps of upper level entities -+ * are synchronized every time a new bfqq is selected for service. By now, -+ * we keep it to better check consistency. -+ */ -+static void bfq_bfqq_served(struct bfq_queue *bfqq, unsigned long served) -+{ -+ struct bfq_entity *entity = &bfqq->entity; -+ struct bfq_service_tree *st; -+ -+ for_each_entity(entity) { -+ st = bfq_entity_service_tree(entity); -+ -+ entity->service += served; -+ BUG_ON(entity->service > entity->budget); -+ BUG_ON(st->wsum == 0); -+ -+ st->vtime += bfq_delta(served, st->wsum); -+ bfq_forget_idle(st); -+ } -+ bfq_log_bfqq(bfqq->bfqd, bfqq, "bfqq_served %lu secs", served); -+} -+ -+/** -+ * bfq_bfqq_charge_full_budget - set the service to the entity budget. -+ * @bfqq: the queue that needs a service update. -+ * -+ * When it's not possible to be fair in the service domain, because -+ * a queue is not consuming its budget fast enough (the meaning of -+ * fast depends on the timeout parameter), we charge it a full -+ * budget. In this way we should obtain a sort of time-domain -+ * fairness among all the seeky/slow queues. -+ */ -+static inline void bfq_bfqq_charge_full_budget(struct bfq_queue *bfqq) -+{ -+ struct bfq_entity *entity = &bfqq->entity; -+ -+ bfq_log_bfqq(bfqq->bfqd, bfqq, "charge_full_budget"); -+ -+ bfq_bfqq_served(bfqq, entity->budget - entity->service); -+} -+ -+/** -+ * __bfq_activate_entity - activate an entity. -+ * @entity: the entity being activated. -+ * -+ * Called whenever an entity is activated, i.e., it is not active and one -+ * of its children receives a new request, or has to be reactivated due to -+ * budget exhaustion. It uses the current budget of the entity (and the -+ * service received if @entity is active) of the queue to calculate its -+ * timestamps. -+ */ -+static void __bfq_activate_entity(struct bfq_entity *entity) -+{ -+ struct bfq_sched_data *sd = entity->sched_data; -+ struct bfq_service_tree *st = bfq_entity_service_tree(entity); -+ -+ if (entity == sd->in_service_entity) { -+ BUG_ON(entity->tree != NULL); -+ /* -+ * If we are requeueing the current entity we have -+ * to take care of not charging to it service it has -+ * not received. -+ */ -+ bfq_calc_finish(entity, entity->service); -+ entity->start = entity->finish; -+ sd->in_service_entity = NULL; -+ } else if (entity->tree == &st->active) { -+ /* -+ * Requeueing an entity due to a change of some -+ * next_in_service entity below it. We reuse the -+ * old start time. -+ */ -+ bfq_active_extract(st, entity); -+ } else if (entity->tree == &st->idle) { -+ /* -+ * Must be on the idle tree, bfq_idle_extract() will -+ * check for that. -+ */ -+ bfq_idle_extract(st, entity); -+ entity->start = bfq_gt(st->vtime, entity->finish) ? -+ st->vtime : entity->finish; -+ } else { -+ /* -+ * The finish time of the entity may be invalid, and -+ * it is in the past for sure, otherwise the queue -+ * would have been on the idle tree. -+ */ -+ entity->start = st->vtime; -+ st->wsum += entity->weight; -+ bfq_get_entity(entity); -+ -+ BUG_ON(entity->on_st); -+ entity->on_st = 1; -+ } -+ -+ st = __bfq_entity_update_weight_prio(st, entity); -+ bfq_calc_finish(entity, entity->budget); -+ bfq_active_insert(st, entity); -+} -+ -+/** -+ * bfq_activate_entity - activate an entity and its ancestors if necessary. -+ * @entity: the entity to activate. -+ * -+ * Activate @entity and all the entities on the path from it to the root. -+ */ -+static void bfq_activate_entity(struct bfq_entity *entity) -+{ -+ struct bfq_sched_data *sd; -+ -+ for_each_entity(entity) { -+ __bfq_activate_entity(entity); -+ -+ sd = entity->sched_data; -+ if (!bfq_update_next_in_service(sd)) -+ /* -+ * No need to propagate the activation to the -+ * upper entities, as they will be updated when -+ * the in-service entity is rescheduled. -+ */ -+ break; -+ } -+} -+ -+/** -+ * __bfq_deactivate_entity - deactivate an entity from its service tree. -+ * @entity: the entity to deactivate. -+ * @requeue: if false, the entity will not be put into the idle tree. -+ * -+ * Deactivate an entity, independently from its previous state. If the -+ * entity was not on a service tree just return, otherwise if it is on -+ * any scheduler tree, extract it from that tree, and if necessary -+ * and if the caller did not specify @requeue, put it on the idle tree. -+ * -+ * Return %1 if the caller should update the entity hierarchy, i.e., -+ * if the entity was in service or if it was the next_in_service for -+ * its sched_data; return %0 otherwise. -+ */ -+static int __bfq_deactivate_entity(struct bfq_entity *entity, int requeue) -+{ -+ struct bfq_sched_data *sd = entity->sched_data; -+ struct bfq_service_tree *st = bfq_entity_service_tree(entity); -+ int was_in_service = entity == sd->in_service_entity; -+ int ret = 0; -+ -+ if (!entity->on_st) -+ return 0; -+ -+ BUG_ON(was_in_service && entity->tree != NULL); -+ -+ if (was_in_service) { -+ bfq_calc_finish(entity, entity->service); -+ sd->in_service_entity = NULL; -+ } else if (entity->tree == &st->active) -+ bfq_active_extract(st, entity); -+ else if (entity->tree == &st->idle) -+ bfq_idle_extract(st, entity); -+ else if (entity->tree != NULL) -+ BUG(); -+ -+ if (was_in_service || sd->next_in_service == entity) -+ ret = bfq_update_next_in_service(sd); -+ -+ if (!requeue || !bfq_gt(entity->finish, st->vtime)) -+ bfq_forget_entity(st, entity); -+ else -+ bfq_idle_insert(st, entity); -+ -+ BUG_ON(sd->in_service_entity == entity); -+ BUG_ON(sd->next_in_service == entity); -+ -+ return ret; -+} -+ -+/** -+ * bfq_deactivate_entity - deactivate an entity. -+ * @entity: the entity to deactivate. -+ * @requeue: true if the entity can be put on the idle tree -+ */ -+static void bfq_deactivate_entity(struct bfq_entity *entity, int requeue) -+{ -+ struct bfq_sched_data *sd; -+ struct bfq_entity *parent; -+ -+ for_each_entity_safe(entity, parent) { -+ sd = entity->sched_data; -+ -+ if (!__bfq_deactivate_entity(entity, requeue)) -+ /* -+ * The parent entity is still backlogged, and -+ * we don't need to update it as it is still -+ * in service. -+ */ -+ break; -+ -+ if (sd->next_in_service != NULL) -+ /* -+ * The parent entity is still backlogged and -+ * the budgets on the path towards the root -+ * need to be updated. -+ */ -+ goto update; -+ -+ /* -+ * If we reach there the parent is no more backlogged and -+ * we want to propagate the dequeue upwards. -+ */ -+ requeue = 1; -+ } -+ -+ return; -+ -+update: -+ entity = parent; -+ for_each_entity(entity) { -+ __bfq_activate_entity(entity); -+ -+ sd = entity->sched_data; -+ if (!bfq_update_next_in_service(sd)) -+ break; -+ } -+} -+ -+/** -+ * bfq_update_vtime - update vtime if necessary. -+ * @st: the service tree to act upon. -+ * -+ * If necessary update the service tree vtime to have at least one -+ * eligible entity, skipping to its start time. Assumes that the -+ * active tree of the device is not empty. -+ * -+ * NOTE: this hierarchical implementation updates vtimes quite often, -+ * we may end up with reactivated processes getting timestamps after a -+ * vtime skip done because we needed a ->first_active entity on some -+ * intermediate node. -+ */ -+static void bfq_update_vtime(struct bfq_service_tree *st) -+{ -+ struct bfq_entity *entry; -+ struct rb_node *node = st->active.rb_node; -+ -+ entry = rb_entry(node, struct bfq_entity, rb_node); -+ if (bfq_gt(entry->min_start, st->vtime)) { -+ st->vtime = entry->min_start; -+ bfq_forget_idle(st); -+ } -+} -+ -+/** -+ * bfq_first_active_entity - find the eligible entity with -+ * the smallest finish time -+ * @st: the service tree to select from. -+ * -+ * This function searches the first schedulable entity, starting from the -+ * root of the tree and going on the left every time on this side there is -+ * a subtree with at least one eligible (start >= vtime) entity. The path on -+ * the right is followed only if a) the left subtree contains no eligible -+ * entities and b) no eligible entity has been found yet. -+ */ -+static struct bfq_entity *bfq_first_active_entity(struct bfq_service_tree *st) -+{ -+ struct bfq_entity *entry, *first = NULL; -+ struct rb_node *node = st->active.rb_node; -+ -+ while (node != NULL) { -+ entry = rb_entry(node, struct bfq_entity, rb_node); -+left: -+ if (!bfq_gt(entry->start, st->vtime)) -+ first = entry; -+ -+ BUG_ON(bfq_gt(entry->min_start, st->vtime)); -+ -+ if (node->rb_left != NULL) { -+ entry = rb_entry(node->rb_left, -+ struct bfq_entity, rb_node); -+ if (!bfq_gt(entry->min_start, st->vtime)) { -+ node = node->rb_left; -+ goto left; -+ } -+ } -+ if (first != NULL) -+ break; -+ node = node->rb_right; -+ } -+ -+ BUG_ON(first == NULL && !RB_EMPTY_ROOT(&st->active)); -+ return first; -+} -+ -+/** -+ * __bfq_lookup_next_entity - return the first eligible entity in @st. -+ * @st: the service tree. -+ * -+ * Update the virtual time in @st and return the first eligible entity -+ * it contains. -+ */ -+static struct bfq_entity *__bfq_lookup_next_entity(struct bfq_service_tree *st, -+ bool force) -+{ -+ struct bfq_entity *entity, *new_next_in_service = NULL; -+ -+ if (RB_EMPTY_ROOT(&st->active)) -+ return NULL; -+ -+ bfq_update_vtime(st); -+ entity = bfq_first_active_entity(st); -+ BUG_ON(bfq_gt(entity->start, st->vtime)); -+ -+ /* -+ * If the chosen entity does not match with the sched_data's -+ * next_in_service and we are forcedly serving the IDLE priority -+ * class tree, bubble up budget update. -+ */ -+ if (unlikely(force && entity != entity->sched_data->next_in_service)) { -+ new_next_in_service = entity; -+ for_each_entity(new_next_in_service) -+ bfq_update_budget(new_next_in_service); -+ } -+ -+ return entity; -+} -+ -+/** -+ * bfq_lookup_next_entity - return the first eligible entity in @sd. -+ * @sd: the sched_data. -+ * @extract: if true the returned entity will be also extracted from @sd. -+ * -+ * NOTE: since we cache the next_in_service entity at each level of the -+ * hierarchy, the complexity of the lookup can be decreased with -+ * absolutely no effort just returning the cached next_in_service value; -+ * we prefer to do full lookups to test the consistency of * the data -+ * structures. -+ */ -+static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd, -+ int extract, -+ struct bfq_data *bfqd) -+{ -+ struct bfq_service_tree *st = sd->service_tree; -+ struct bfq_entity *entity; -+ int i = 0; -+ -+ BUG_ON(sd->in_service_entity != NULL); -+ -+ if (bfqd != NULL && -+ jiffies - bfqd->bfq_class_idle_last_service > BFQ_CL_IDLE_TIMEOUT) { -+ entity = __bfq_lookup_next_entity(st + BFQ_IOPRIO_CLASSES - 1, -+ true); -+ if (entity != NULL) { -+ i = BFQ_IOPRIO_CLASSES - 1; -+ bfqd->bfq_class_idle_last_service = jiffies; -+ sd->next_in_service = entity; -+ } -+ } -+ for (; i < BFQ_IOPRIO_CLASSES; i++) { -+ entity = __bfq_lookup_next_entity(st + i, false); -+ if (entity != NULL) { -+ if (extract) { -+ bfq_check_next_in_service(sd, entity); -+ bfq_active_extract(st + i, entity); -+ sd->in_service_entity = entity; -+ sd->next_in_service = NULL; -+ } -+ break; -+ } -+ } -+ -+ return entity; -+} -+ -+/* -+ * Get next queue for service. -+ */ -+static struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd) -+{ -+ struct bfq_entity *entity = NULL; -+ struct bfq_sched_data *sd; -+ struct bfq_queue *bfqq; -+ -+ BUG_ON(bfqd->in_service_queue != NULL); -+ -+ if (bfqd->busy_queues == 0) -+ return NULL; -+ -+ sd = &bfqd->root_group->sched_data; -+ for (; sd != NULL; sd = entity->my_sched_data) { -+ entity = bfq_lookup_next_entity(sd, 1, bfqd); -+ BUG_ON(entity == NULL); -+ entity->service = 0; -+ } -+ -+ bfqq = bfq_entity_to_bfqq(entity); -+ BUG_ON(bfqq == NULL); -+ -+ return bfqq; -+} -+ -+/* -+ * Forced extraction of the given queue. -+ */ -+static void bfq_get_next_queue_forced(struct bfq_data *bfqd, -+ struct bfq_queue *bfqq) -+{ -+ struct bfq_entity *entity; -+ struct bfq_sched_data *sd; -+ -+ BUG_ON(bfqd->in_service_queue != NULL); -+ -+ entity = &bfqq->entity; -+ /* -+ * Bubble up extraction/update from the leaf to the root. -+ */ -+ for_each_entity(entity) { -+ sd = entity->sched_data; -+ bfq_update_budget(entity); -+ bfq_update_vtime(bfq_entity_service_tree(entity)); -+ bfq_active_extract(bfq_entity_service_tree(entity), entity); -+ sd->in_service_entity = entity; -+ sd->next_in_service = NULL; -+ entity->service = 0; -+ } -+ -+ return; -+} -+ -+static void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd) -+{ -+ if (bfqd->in_service_bic != NULL) { -+ put_io_context(bfqd->in_service_bic->icq.ioc); -+ bfqd->in_service_bic = NULL; -+ } -+ -+ bfqd->in_service_queue = NULL; -+ del_timer(&bfqd->idle_slice_timer); -+} -+ -+static void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, -+ int requeue) -+{ -+ struct bfq_entity *entity = &bfqq->entity; -+ -+ if (bfqq == bfqd->in_service_queue) -+ __bfq_bfqd_reset_in_service(bfqd); -+ -+ bfq_deactivate_entity(entity, requeue); -+} -+ -+static void bfq_activate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq) -+{ -+ struct bfq_entity *entity = &bfqq->entity; -+ -+ bfq_activate_entity(entity); -+} -+ -+/* -+ * Called when the bfqq no longer has requests pending, remove it from -+ * the service tree. -+ */ -+static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq, -+ int requeue) -+{ -+ BUG_ON(!bfq_bfqq_busy(bfqq)); -+ BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list)); -+ -+ bfq_log_bfqq(bfqd, bfqq, "del from busy"); -+ -+ bfq_clear_bfqq_busy(bfqq); -+ -+ BUG_ON(bfqd->busy_queues == 0); -+ bfqd->busy_queues--; -+ -+ if (!bfqq->dispatched) { -+ bfq_weights_tree_remove(bfqd, &bfqq->entity, -+ &bfqd->queue_weights_tree); -+ if (!blk_queue_nonrot(bfqd->queue)) { -+ BUG_ON(!bfqd->busy_in_flight_queues); -+ bfqd->busy_in_flight_queues--; -+ if (bfq_bfqq_constantly_seeky(bfqq)) { -+ BUG_ON(!bfqd-> -+ const_seeky_busy_in_flight_queues); -+ bfqd->const_seeky_busy_in_flight_queues--; -+ } -+ } -+ } -+ if (bfqq->wr_coeff > 1) -+ bfqd->wr_busy_queues--; -+ -+ bfq_deactivate_bfqq(bfqd, bfqq, requeue); -+} -+ -+/* -+ * Called when an inactive queue receives a new request. -+ */ -+static void bfq_add_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq) -+{ -+ BUG_ON(bfq_bfqq_busy(bfqq)); -+ BUG_ON(bfqq == bfqd->in_service_queue); -+ -+ bfq_log_bfqq(bfqd, bfqq, "add to busy"); -+ -+ bfq_activate_bfqq(bfqd, bfqq); -+ -+ bfq_mark_bfqq_busy(bfqq); -+ bfqd->busy_queues++; -+ -+ if (!bfqq->dispatched) { -+ if (bfqq->wr_coeff == 1) -+ bfq_weights_tree_add(bfqd, &bfqq->entity, -+ &bfqd->queue_weights_tree); -+ if (!blk_queue_nonrot(bfqd->queue)) { -+ bfqd->busy_in_flight_queues++; -+ if (bfq_bfqq_constantly_seeky(bfqq)) -+ bfqd->const_seeky_busy_in_flight_queues++; -+ } -+ } -+ if (bfqq->wr_coeff > 1) -+ bfqd->wr_busy_queues++; -+} -diff --git a/block/bfq.h b/block/bfq.h -new file mode 100644 -index 0000000..3c5d85e ---- /dev/null -+++ b/block/bfq.h -@@ -0,0 +1,775 @@ -+/* -+ * BFQ-v7r7 for 3.19.0: data structures and common functions prototypes. -+ * -+ * Based on ideas and code from CFQ: -+ * Copyright (C) 2003 Jens Axboe -+ * -+ * Copyright (C) 2008 Fabio Checconi -+ * Paolo Valente -+ * -+ * Copyright (C) 2010 Paolo Valente -+ */ -+ -+#ifndef _BFQ_H -+#define _BFQ_H -+ -+#include -+#include -+#include -+#include -+ -+#define BFQ_IOPRIO_CLASSES 3 -+#define BFQ_CL_IDLE_TIMEOUT (HZ/5) -+ -+#define BFQ_MIN_WEIGHT 1 -+#define BFQ_MAX_WEIGHT 1000 -+ -+#define BFQ_DEFAULT_QUEUE_IOPRIO 4 -+ -+#define BFQ_DEFAULT_GRP_WEIGHT 10 -+#define BFQ_DEFAULT_GRP_IOPRIO 0 -+#define BFQ_DEFAULT_GRP_CLASS IOPRIO_CLASS_BE -+ -+struct bfq_entity; -+ -+/** -+ * struct bfq_service_tree - per ioprio_class service tree. -+ * @active: tree for active entities (i.e., those backlogged). -+ * @idle: tree for idle entities (i.e., those not backlogged, with V <= F_i). -+ * @first_idle: idle entity with minimum F_i. -+ * @last_idle: idle entity with maximum F_i. -+ * @vtime: scheduler virtual time. -+ * @wsum: scheduler weight sum; active and idle entities contribute to it. -+ * -+ * Each service tree represents a B-WF2Q+ scheduler on its own. Each -+ * ioprio_class has its own independent scheduler, and so its own -+ * bfq_service_tree. All the fields are protected by the queue lock -+ * of the containing bfqd. -+ */ -+struct bfq_service_tree { -+ struct rb_root active; -+ struct rb_root idle; -+ -+ struct bfq_entity *first_idle; -+ struct bfq_entity *last_idle; -+ -+ u64 vtime; -+ unsigned long wsum; -+}; -+ -+/** -+ * struct bfq_sched_data - multi-class scheduler. -+ * @in_service_entity: entity in service. -+ * @next_in_service: head-of-the-line entity in the scheduler. -+ * @service_tree: array of service trees, one per ioprio_class. -+ * -+ * bfq_sched_data is the basic scheduler queue. It supports three -+ * ioprio_classes, and can be used either as a toplevel queue or as -+ * an intermediate queue on a hierarchical setup. -+ * @next_in_service points to the active entity of the sched_data -+ * service trees that will be scheduled next. -+ * -+ * The supported ioprio_classes are the same as in CFQ, in descending -+ * priority order, IOPRIO_CLASS_RT, IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE. -+ * Requests from higher priority queues are served before all the -+ * requests from lower priority queues; among requests of the same -+ * queue requests are served according to B-WF2Q+. -+ * All the fields are protected by the queue lock of the containing bfqd. -+ */ -+struct bfq_sched_data { -+ struct bfq_entity *in_service_entity; -+ struct bfq_entity *next_in_service; -+ struct bfq_service_tree service_tree[BFQ_IOPRIO_CLASSES]; -+}; -+ -+/** -+ * struct bfq_weight_counter - counter of the number of all active entities -+ * with a given weight. -+ * @weight: weight of the entities that this counter refers to. -+ * @num_active: number of active entities with this weight. -+ * @weights_node: weights tree member (see bfq_data's @queue_weights_tree -+ * and @group_weights_tree). -+ */ -+struct bfq_weight_counter { -+ short int weight; -+ unsigned int num_active; -+ struct rb_node weights_node; -+}; -+ -+/** -+ * struct bfq_entity - schedulable entity. -+ * @rb_node: service_tree member. -+ * @weight_counter: pointer to the weight counter associated with this entity. -+ * @on_st: flag, true if the entity is on a tree (either the active or -+ * the idle one of its service_tree). -+ * @finish: B-WF2Q+ finish timestamp (aka F_i). -+ * @start: B-WF2Q+ start timestamp (aka S_i). -+ * @tree: tree the entity is enqueued into; %NULL if not on a tree. -+ * @min_start: minimum start time of the (active) subtree rooted at -+ * this entity; used for O(log N) lookups into active trees. -+ * @service: service received during the last round of service. -+ * @budget: budget used to calculate F_i; F_i = S_i + @budget / @weight. -+ * @weight: weight of the queue -+ * @parent: parent entity, for hierarchical scheduling. -+ * @my_sched_data: for non-leaf nodes in the cgroup hierarchy, the -+ * associated scheduler queue, %NULL on leaf nodes. -+ * @sched_data: the scheduler queue this entity belongs to. -+ * @ioprio: the ioprio in use. -+ * @new_weight: when a weight change is requested, the new weight value. -+ * @orig_weight: original weight, used to implement weight boosting -+ * @new_ioprio: when an ioprio change is requested, the new ioprio value. -+ * @ioprio_class: the ioprio_class in use. -+ * @new_ioprio_class: when an ioprio_class change is requested, the new -+ * ioprio_class value. -+ * @ioprio_changed: flag, true when the user requested a weight, ioprio or -+ * ioprio_class change. -+ * -+ * A bfq_entity is used to represent either a bfq_queue (leaf node in the -+ * cgroup hierarchy) or a bfq_group into the upper level scheduler. Each -+ * entity belongs to the sched_data of the parent group in the cgroup -+ * hierarchy. Non-leaf entities have also their own sched_data, stored -+ * in @my_sched_data. -+ * -+ * Each entity stores independently its priority values; this would -+ * allow different weights on different devices, but this -+ * functionality is not exported to userspace by now. Priorities and -+ * weights are updated lazily, first storing the new values into the -+ * new_* fields, then setting the @ioprio_changed flag. As soon as -+ * there is a transition in the entity state that allows the priority -+ * update to take place the effective and the requested priority -+ * values are synchronized. -+ * -+ * Unless cgroups are used, the weight value is calculated from the -+ * ioprio to export the same interface as CFQ. When dealing with -+ * ``well-behaved'' queues (i.e., queues that do not spend too much -+ * time to consume their budget and have true sequential behavior, and -+ * when there are no external factors breaking anticipation) the -+ * relative weights at each level of the cgroups hierarchy should be -+ * guaranteed. All the fields are protected by the queue lock of the -+ * containing bfqd. -+ */ -+struct bfq_entity { -+ struct rb_node rb_node; -+ struct bfq_weight_counter *weight_counter; -+ -+ int on_st; -+ -+ u64 finish; -+ u64 start; -+ -+ struct rb_root *tree; -+ -+ u64 min_start; -+ -+ unsigned long service, budget; -+ unsigned short weight, new_weight; -+ unsigned short orig_weight; -+ -+ struct bfq_entity *parent; -+ -+ struct bfq_sched_data *my_sched_data; -+ struct bfq_sched_data *sched_data; -+ -+ unsigned short ioprio, new_ioprio; -+ unsigned short ioprio_class, new_ioprio_class; -+ -+ int ioprio_changed; -+}; -+ -+struct bfq_group; -+ -+/** -+ * struct bfq_queue - leaf schedulable entity. -+ * @ref: reference counter. -+ * @bfqd: parent bfq_data. -+ * @new_bfqq: shared bfq_queue if queue is cooperating with -+ * one or more other queues. -+ * @pos_node: request-position tree member (see bfq_data's @rq_pos_tree). -+ * @pos_root: request-position tree root (see bfq_data's @rq_pos_tree). -+ * @sort_list: sorted list of pending requests. -+ * @next_rq: if fifo isn't expired, next request to serve. -+ * @queued: nr of requests queued in @sort_list. -+ * @allocated: currently allocated requests. -+ * @meta_pending: pending metadata requests. -+ * @fifo: fifo list of requests in sort_list. -+ * @entity: entity representing this queue in the scheduler. -+ * @max_budget: maximum budget allowed from the feedback mechanism. -+ * @budget_timeout: budget expiration (in jiffies). -+ * @dispatched: number of requests on the dispatch list or inside driver. -+ * @flags: status flags. -+ * @bfqq_list: node for active/idle bfqq list inside our bfqd. -+ * @burst_list_node: node for the device's burst list. -+ * @seek_samples: number of seeks sampled -+ * @seek_total: sum of the distances of the seeks sampled -+ * @seek_mean: mean seek distance -+ * @last_request_pos: position of the last request enqueued -+ * @requests_within_timer: number of consecutive pairs of request completion -+ * and arrival, such that the queue becomes idle -+ * after the completion, but the next request arrives -+ * within an idle time slice; used only if the queue's -+ * IO_bound has been cleared. -+ * @pid: pid of the process owning the queue, used for logging purposes. -+ * @last_wr_start_finish: start time of the current weight-raising period if -+ * the @bfq-queue is being weight-raised, otherwise -+ * finish time of the last weight-raising period -+ * @wr_cur_max_time: current max raising time for this queue -+ * @soft_rt_next_start: minimum time instant such that, only if a new -+ * request is enqueued after this time instant in an -+ * idle @bfq_queue with no outstanding requests, then -+ * the task associated with the queue it is deemed as -+ * soft real-time (see the comments to the function -+ * bfq_bfqq_softrt_next_start()). -+ * @last_idle_bklogged: time of the last transition of the @bfq_queue from -+ * idle to backlogged -+ * @service_from_backlogged: cumulative service received from the @bfq_queue -+ * since the last transition from idle to -+ * backlogged -+ * -+ * A bfq_queue is a leaf request queue; it can be associated with an io_context -+ * or more, if it is async or shared between cooperating processes. @cgroup -+ * holds a reference to the cgroup, to be sure that it does not disappear while -+ * a bfqq still references it (mostly to avoid races between request issuing and -+ * task migration followed by cgroup destruction). -+ * All the fields are protected by the queue lock of the containing bfqd. -+ */ -+struct bfq_queue { -+ atomic_t ref; -+ struct bfq_data *bfqd; -+ -+ /* fields for cooperating queues handling */ -+ struct bfq_queue *new_bfqq; -+ struct rb_node pos_node; -+ struct rb_root *pos_root; -+ -+ struct rb_root sort_list; -+ struct request *next_rq; -+ int queued[2]; -+ int allocated[2]; -+ int meta_pending; -+ struct list_head fifo; -+ -+ struct bfq_entity entity; -+ -+ unsigned long max_budget; -+ unsigned long budget_timeout; -+ -+ int dispatched; -+ -+ unsigned int flags; -+ -+ struct list_head bfqq_list; -+ -+ struct hlist_node burst_list_node; -+ -+ unsigned int seek_samples; -+ u64 seek_total; -+ sector_t seek_mean; -+ sector_t last_request_pos; -+ -+ unsigned int requests_within_timer; -+ -+ pid_t pid; -+ -+ /* weight-raising fields */ -+ unsigned long wr_cur_max_time; -+ unsigned long soft_rt_next_start; -+ unsigned long last_wr_start_finish; -+ unsigned int wr_coeff; -+ unsigned long last_idle_bklogged; -+ unsigned long service_from_backlogged; -+}; -+ -+/** -+ * struct bfq_ttime - per process thinktime stats. -+ * @ttime_total: total process thinktime -+ * @ttime_samples: number of thinktime samples -+ * @ttime_mean: average process thinktime -+ */ -+struct bfq_ttime { -+ unsigned long last_end_request; -+ -+ unsigned long ttime_total; -+ unsigned long ttime_samples; -+ unsigned long ttime_mean; -+}; -+ -+/** -+ * struct bfq_io_cq - per (request_queue, io_context) structure. -+ * @icq: associated io_cq structure -+ * @bfqq: array of two process queues, the sync and the async -+ * @ttime: associated @bfq_ttime struct -+ */ -+struct bfq_io_cq { -+ struct io_cq icq; /* must be the first member */ -+ struct bfq_queue *bfqq[2]; -+ struct bfq_ttime ttime; -+ int ioprio; -+}; -+ -+enum bfq_device_speed { -+ BFQ_BFQD_FAST, -+ BFQ_BFQD_SLOW, -+}; -+ -+/** -+ * struct bfq_data - per device data structure. -+ * @queue: request queue for the managed device. -+ * @root_group: root bfq_group for the device. -+ * @rq_pos_tree: rbtree sorted by next_request position, used when -+ * determining if two or more queues have interleaving -+ * requests (see bfq_close_cooperator()). -+ * @active_numerous_groups: number of bfq_groups containing more than one -+ * active @bfq_entity. -+ * @queue_weights_tree: rbtree of weight counters of @bfq_queues, sorted by -+ * weight. Used to keep track of whether all @bfq_queues -+ * have the same weight. The tree contains one counter -+ * for each distinct weight associated to some active -+ * and not weight-raised @bfq_queue (see the comments to -+ * the functions bfq_weights_tree_[add|remove] for -+ * further details). -+ * @group_weights_tree: rbtree of non-queue @bfq_entity weight counters, sorted -+ * by weight. Used to keep track of whether all -+ * @bfq_groups have the same weight. The tree contains -+ * one counter for each distinct weight associated to -+ * some active @bfq_group (see the comments to the -+ * functions bfq_weights_tree_[add|remove] for further -+ * details). -+ * @busy_queues: number of bfq_queues containing requests (including the -+ * queue in service, even if it is idling). -+ * @busy_in_flight_queues: number of @bfq_queues containing pending or -+ * in-flight requests, plus the @bfq_queue in -+ * service, even if idle but waiting for the -+ * possible arrival of its next sync request. This -+ * field is updated only if the device is rotational, -+ * but used only if the device is also NCQ-capable. -+ * The reason why the field is updated also for non- -+ * NCQ-capable rotational devices is related to the -+ * fact that the value of @hw_tag may be set also -+ * later than when busy_in_flight_queues may need to -+ * be incremented for the first time(s). Taking also -+ * this possibility into account, to avoid unbalanced -+ * increments/decrements, would imply more overhead -+ * than just updating busy_in_flight_queues -+ * regardless of the value of @hw_tag. -+ * @const_seeky_busy_in_flight_queues: number of constantly-seeky @bfq_queues -+ * (that is, seeky queues that expired -+ * for budget timeout at least once) -+ * containing pending or in-flight -+ * requests, including the in-service -+ * @bfq_queue if constantly seeky. This -+ * field is updated only if the device -+ * is rotational, but used only if the -+ * device is also NCQ-capable (see the -+ * comments to @busy_in_flight_queues). -+ * @wr_busy_queues: number of weight-raised busy @bfq_queues. -+ * @queued: number of queued requests. -+ * @rq_in_driver: number of requests dispatched and waiting for completion. -+ * @sync_flight: number of sync requests in the driver. -+ * @max_rq_in_driver: max number of reqs in driver in the last -+ * @hw_tag_samples completed requests. -+ * @hw_tag_samples: nr of samples used to calculate hw_tag. -+ * @hw_tag: flag set to one if the driver is showing a queueing behavior. -+ * @budgets_assigned: number of budgets assigned. -+ * @idle_slice_timer: timer set when idling for the next sequential request -+ * from the queue in service. -+ * @unplug_work: delayed work to restart dispatching on the request queue. -+ * @in_service_queue: bfq_queue in service. -+ * @in_service_bic: bfq_io_cq (bic) associated with the @in_service_queue. -+ * @last_position: on-disk position of the last served request. -+ * @last_budget_start: beginning of the last budget. -+ * @last_idling_start: beginning of the last idle slice. -+ * @peak_rate: peak transfer rate observed for a budget. -+ * @peak_rate_samples: number of samples used to calculate @peak_rate. -+ * @bfq_max_budget: maximum budget allotted to a bfq_queue before -+ * rescheduling. -+ * @group_list: list of all the bfq_groups active on the device. -+ * @active_list: list of all the bfq_queues active on the device. -+ * @idle_list: list of all the bfq_queues idle on the device. -+ * @bfq_quantum: max number of requests dispatched per dispatch round. -+ * @bfq_fifo_expire: timeout for async/sync requests; when it expires -+ * requests are served in fifo order. -+ * @bfq_back_penalty: weight of backward seeks wrt forward ones. -+ * @bfq_back_max: maximum allowed backward seek. -+ * @bfq_slice_idle: maximum idling time. -+ * @bfq_user_max_budget: user-configured max budget value -+ * (0 for auto-tuning). -+ * @bfq_max_budget_async_rq: maximum budget (in nr of requests) allotted to -+ * async queues. -+ * @bfq_timeout: timeout for bfq_queues to consume their budget; used to -+ * to prevent seeky queues to impose long latencies to well -+ * behaved ones (this also implies that seeky queues cannot -+ * receive guarantees in the service domain; after a timeout -+ * they are charged for the whole allocated budget, to try -+ * to preserve a behavior reasonably fair among them, but -+ * without service-domain guarantees). -+ * @bfq_coop_thresh: number of queue merges after which a @bfq_queue is -+ * no more granted any weight-raising. -+ * @bfq_failed_cooperations: number of consecutive failed cooperation -+ * chances after which weight-raising is restored -+ * to a queue subject to more than bfq_coop_thresh -+ * queue merges. -+ * @bfq_requests_within_timer: number of consecutive requests that must be -+ * issued within the idle time slice to set -+ * again idling to a queue which was marked as -+ * non-I/O-bound (see the definition of the -+ * IO_bound flag for further details). -+ * @last_ins_in_burst: last time at which a queue entered the current -+ * burst of queues being activated shortly after -+ * each other; for more details about this and the -+ * following parameters related to a burst of -+ * activations, see the comments to the function -+ * @bfq_handle_burst. -+ * @bfq_burst_interval: reference time interval used to decide whether a -+ * queue has been activated shortly after -+ * @last_ins_in_burst. -+ * @burst_size: number of queues in the current burst of queue activations. -+ * @bfq_large_burst_thresh: maximum burst size above which the current -+ * queue-activation burst is deemed as 'large'. -+ * @large_burst: true if a large queue-activation burst is in progress. -+ * @burst_list: head of the burst list (as for the above fields, more details -+ * in the comments to the function bfq_handle_burst). -+ * @low_latency: if set to true, low-latency heuristics are enabled. -+ * @bfq_wr_coeff: maximum factor by which the weight of a weight-raised -+ * queue is multiplied. -+ * @bfq_wr_max_time: maximum duration of a weight-raising period (jiffies). -+ * @bfq_wr_rt_max_time: maximum duration for soft real-time processes. -+ * @bfq_wr_min_idle_time: minimum idle period after which weight-raising -+ * may be reactivated for a queue (in jiffies). -+ * @bfq_wr_min_inter_arr_async: minimum period between request arrivals -+ * after which weight-raising may be -+ * reactivated for an already busy queue -+ * (in jiffies). -+ * @bfq_wr_max_softrt_rate: max service-rate for a soft real-time queue, -+ * sectors per seconds. -+ * @RT_prod: cached value of the product R*T used for computing the maximum -+ * duration of the weight raising automatically. -+ * @device_speed: device-speed class for the low-latency heuristic. -+ * @oom_bfqq: fallback dummy bfqq for extreme OOM conditions. -+ * -+ * All the fields are protected by the @queue lock. -+ */ -+struct bfq_data { -+ struct request_queue *queue; -+ -+ struct bfq_group *root_group; -+ struct rb_root rq_pos_tree; -+ -+#ifdef CONFIG_CGROUP_BFQIO -+ int active_numerous_groups; -+#endif -+ -+ struct rb_root queue_weights_tree; -+ struct rb_root group_weights_tree; -+ -+ int busy_queues; -+ int busy_in_flight_queues; -+ int const_seeky_busy_in_flight_queues; -+ int wr_busy_queues; -+ int queued; -+ int rq_in_driver; -+ int sync_flight; -+ -+ int max_rq_in_driver; -+ int hw_tag_samples; -+ int hw_tag; -+ -+ int budgets_assigned; -+ -+ struct timer_list idle_slice_timer; -+ struct work_struct unplug_work; -+ -+ struct bfq_queue *in_service_queue; -+ struct bfq_io_cq *in_service_bic; -+ -+ sector_t last_position; -+ -+ ktime_t last_budget_start; -+ ktime_t last_idling_start; -+ int peak_rate_samples; -+ u64 peak_rate; -+ unsigned long bfq_max_budget; -+ -+ struct hlist_head group_list; -+ struct list_head active_list; -+ struct list_head idle_list; -+ -+ unsigned int bfq_quantum; -+ unsigned int bfq_fifo_expire[2]; -+ unsigned int bfq_back_penalty; -+ unsigned int bfq_back_max; -+ unsigned int bfq_slice_idle; -+ u64 bfq_class_idle_last_service; -+ -+ unsigned int bfq_user_max_budget; -+ unsigned int bfq_max_budget_async_rq; -+ unsigned int bfq_timeout[2]; -+ -+ unsigned int bfq_coop_thresh; -+ unsigned int bfq_failed_cooperations; -+ unsigned int bfq_requests_within_timer; -+ -+ unsigned long last_ins_in_burst; -+ unsigned long bfq_burst_interval; -+ int burst_size; -+ unsigned long bfq_large_burst_thresh; -+ bool large_burst; -+ struct hlist_head burst_list; -+ -+ bool low_latency; -+ -+ /* parameters of the low_latency heuristics */ -+ unsigned int bfq_wr_coeff; -+ unsigned int bfq_wr_max_time; -+ unsigned int bfq_wr_rt_max_time; -+ unsigned int bfq_wr_min_idle_time; -+ unsigned long bfq_wr_min_inter_arr_async; -+ unsigned int bfq_wr_max_softrt_rate; -+ u64 RT_prod; -+ enum bfq_device_speed device_speed; -+ -+ struct bfq_queue oom_bfqq; -+}; -+ -+enum bfqq_state_flags { -+ BFQ_BFQQ_FLAG_busy = 0, /* has requests or is in service */ -+ BFQ_BFQQ_FLAG_wait_request, /* waiting for a request */ -+ BFQ_BFQQ_FLAG_must_alloc, /* must be allowed rq alloc */ -+ BFQ_BFQQ_FLAG_fifo_expire, /* FIFO checked in this slice */ -+ BFQ_BFQQ_FLAG_idle_window, /* slice idling enabled */ -+ BFQ_BFQQ_FLAG_prio_changed, /* task priority has changed */ -+ BFQ_BFQQ_FLAG_sync, /* synchronous queue */ -+ BFQ_BFQQ_FLAG_budget_new, /* no completion with this budget */ -+ BFQ_BFQQ_FLAG_IO_bound, /* -+ * bfqq has timed-out at least once -+ * having consumed at most 2/10 of -+ * its budget -+ */ -+ BFQ_BFQQ_FLAG_in_large_burst, /* -+ * bfqq activated in a large burst, -+ * see comments to bfq_handle_burst. -+ */ -+ BFQ_BFQQ_FLAG_constantly_seeky, /* -+ * bfqq has proved to be slow and -+ * seeky until budget timeout -+ */ -+ BFQ_BFQQ_FLAG_softrt_update, /* -+ * may need softrt-next-start -+ * update -+ */ -+ BFQ_BFQQ_FLAG_coop, /* bfqq is shared */ -+ BFQ_BFQQ_FLAG_split_coop, /* shared bfqq will be splitted */ -+}; -+ -+#define BFQ_BFQQ_FNS(name) \ -+static inline void bfq_mark_bfqq_##name(struct bfq_queue *bfqq) \ -+{ \ -+ (bfqq)->flags |= (1 << BFQ_BFQQ_FLAG_##name); \ -+} \ -+static inline void bfq_clear_bfqq_##name(struct bfq_queue *bfqq) \ -+{ \ -+ (bfqq)->flags &= ~(1 << BFQ_BFQQ_FLAG_##name); \ -+} \ -+static inline int bfq_bfqq_##name(const struct bfq_queue *bfqq) \ -+{ \ -+ return ((bfqq)->flags & (1 << BFQ_BFQQ_FLAG_##name)) != 0; \ -+} -+ -+BFQ_BFQQ_FNS(busy); -+BFQ_BFQQ_FNS(wait_request); -+BFQ_BFQQ_FNS(must_alloc); -+BFQ_BFQQ_FNS(fifo_expire); -+BFQ_BFQQ_FNS(idle_window); -+BFQ_BFQQ_FNS(prio_changed); -+BFQ_BFQQ_FNS(sync); -+BFQ_BFQQ_FNS(budget_new); -+BFQ_BFQQ_FNS(IO_bound); -+BFQ_BFQQ_FNS(in_large_burst); -+BFQ_BFQQ_FNS(constantly_seeky); -+BFQ_BFQQ_FNS(coop); -+BFQ_BFQQ_FNS(split_coop); -+BFQ_BFQQ_FNS(softrt_update); -+#undef BFQ_BFQQ_FNS -+ -+/* Logging facilities. */ -+#define bfq_log_bfqq(bfqd, bfqq, fmt, args...) \ -+ blk_add_trace_msg((bfqd)->queue, "bfq%d " fmt, (bfqq)->pid, ##args) -+ -+#define bfq_log(bfqd, fmt, args...) \ -+ blk_add_trace_msg((bfqd)->queue, "bfq " fmt, ##args) -+ -+/* Expiration reasons. */ -+enum bfqq_expiration { -+ BFQ_BFQQ_TOO_IDLE = 0, /* -+ * queue has been idling for -+ * too long -+ */ -+ BFQ_BFQQ_BUDGET_TIMEOUT, /* budget took too long to be used */ -+ BFQ_BFQQ_BUDGET_EXHAUSTED, /* budget consumed */ -+ BFQ_BFQQ_NO_MORE_REQUESTS, /* the queue has no more requests */ -+}; -+ -+#ifdef CONFIG_CGROUP_BFQIO -+/** -+ * struct bfq_group - per (device, cgroup) data structure. -+ * @entity: schedulable entity to insert into the parent group sched_data. -+ * @sched_data: own sched_data, to contain child entities (they may be -+ * both bfq_queues and bfq_groups). -+ * @group_node: node to be inserted into the bfqio_cgroup->group_data -+ * list of the containing cgroup's bfqio_cgroup. -+ * @bfqd_node: node to be inserted into the @bfqd->group_list list -+ * of the groups active on the same device; used for cleanup. -+ * @bfqd: the bfq_data for the device this group acts upon. -+ * @async_bfqq: array of async queues for all the tasks belonging to -+ * the group, one queue per ioprio value per ioprio_class, -+ * except for the idle class that has only one queue. -+ * @async_idle_bfqq: async queue for the idle class (ioprio is ignored). -+ * @my_entity: pointer to @entity, %NULL for the toplevel group; used -+ * to avoid too many special cases during group creation/ -+ * migration. -+ * @active_entities: number of active entities belonging to the group; -+ * unused for the root group. Used to know whether there -+ * are groups with more than one active @bfq_entity -+ * (see the comments to the function -+ * bfq_bfqq_must_not_expire()). -+ * -+ * Each (device, cgroup) pair has its own bfq_group, i.e., for each cgroup -+ * there is a set of bfq_groups, each one collecting the lower-level -+ * entities belonging to the group that are acting on the same device. -+ * -+ * Locking works as follows: -+ * o @group_node is protected by the bfqio_cgroup lock, and is accessed -+ * via RCU from its readers. -+ * o @bfqd is protected by the queue lock, RCU is used to access it -+ * from the readers. -+ * o All the other fields are protected by the @bfqd queue lock. -+ */ -+struct bfq_group { -+ struct bfq_entity entity; -+ struct bfq_sched_data sched_data; -+ -+ struct hlist_node group_node; -+ struct hlist_node bfqd_node; -+ -+ void *bfqd; -+ -+ struct bfq_queue *async_bfqq[2][IOPRIO_BE_NR]; -+ struct bfq_queue *async_idle_bfqq; -+ -+ struct bfq_entity *my_entity; -+ -+ int active_entities; -+}; -+ -+/** -+ * struct bfqio_cgroup - bfq cgroup data structure. -+ * @css: subsystem state for bfq in the containing cgroup. -+ * @online: flag marked when the subsystem is inserted. -+ * @weight: cgroup weight. -+ * @ioprio: cgroup ioprio. -+ * @ioprio_class: cgroup ioprio_class. -+ * @lock: spinlock that protects @ioprio, @ioprio_class and @group_data. -+ * @group_data: list containing the bfq_group belonging to this cgroup. -+ * -+ * @group_data is accessed using RCU, with @lock protecting the updates, -+ * @ioprio and @ioprio_class are protected by @lock. -+ */ -+struct bfqio_cgroup { -+ struct cgroup_subsys_state css; -+ bool online; -+ -+ unsigned short weight, ioprio, ioprio_class; -+ -+ spinlock_t lock; -+ struct hlist_head group_data; -+}; -+#else -+struct bfq_group { -+ struct bfq_sched_data sched_data; -+ -+ struct bfq_queue *async_bfqq[2][IOPRIO_BE_NR]; -+ struct bfq_queue *async_idle_bfqq; -+}; -+#endif -+ -+static inline struct bfq_service_tree * -+bfq_entity_service_tree(struct bfq_entity *entity) -+{ -+ struct bfq_sched_data *sched_data = entity->sched_data; -+ unsigned int idx = entity->ioprio_class - 1; -+ -+ BUG_ON(idx >= BFQ_IOPRIO_CLASSES); -+ BUG_ON(sched_data == NULL); -+ -+ return sched_data->service_tree + idx; -+} -+ -+static inline struct bfq_queue *bic_to_bfqq(struct bfq_io_cq *bic, -+ bool is_sync) -+{ -+ return bic->bfqq[is_sync]; -+} -+ -+static inline void bic_set_bfqq(struct bfq_io_cq *bic, -+ struct bfq_queue *bfqq, bool is_sync) -+{ -+ bic->bfqq[is_sync] = bfqq; -+} -+ -+static inline struct bfq_data *bic_to_bfqd(struct bfq_io_cq *bic) -+{ -+ return bic->icq.q->elevator->elevator_data; -+} -+ -+/** -+ * bfq_get_bfqd_locked - get a lock to a bfqd using a RCU protected pointer. -+ * @ptr: a pointer to a bfqd. -+ * @flags: storage for the flags to be saved. -+ * -+ * This function allows bfqg->bfqd to be protected by the -+ * queue lock of the bfqd they reference; the pointer is dereferenced -+ * under RCU, so the storage for bfqd is assured to be safe as long -+ * as the RCU read side critical section does not end. After the -+ * bfqd->queue->queue_lock is taken the pointer is rechecked, to be -+ * sure that no other writer accessed it. If we raced with a writer, -+ * the function returns NULL, with the queue unlocked, otherwise it -+ * returns the dereferenced pointer, with the queue locked. -+ */ -+static inline struct bfq_data *bfq_get_bfqd_locked(void **ptr, -+ unsigned long *flags) -+{ -+ struct bfq_data *bfqd; -+ -+ rcu_read_lock(); -+ bfqd = rcu_dereference(*(struct bfq_data **)ptr); -+ -+ if (bfqd != NULL) { -+ spin_lock_irqsave(bfqd->queue->queue_lock, *flags); -+ if (*ptr == bfqd) -+ goto out; -+ spin_unlock_irqrestore(bfqd->queue->queue_lock, *flags); -+ } -+ -+ bfqd = NULL; -+out: -+ rcu_read_unlock(); -+ return bfqd; -+} -+ -+static inline void bfq_put_bfqd_unlock(struct bfq_data *bfqd, -+ unsigned long *flags) -+{ -+ spin_unlock_irqrestore(bfqd->queue->queue_lock, *flags); -+} -+ -+static void bfq_changed_ioprio(struct bfq_io_cq *bic); -+static void bfq_put_queue(struct bfq_queue *bfqq); -+static void bfq_dispatch_insert(struct request_queue *q, struct request *rq); -+static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd, -+ struct bfq_group *bfqg, int is_sync, -+ struct bfq_io_cq *bic, gfp_t gfp_mask); -+static void bfq_end_wr_async_queues(struct bfq_data *bfqd, -+ struct bfq_group *bfqg); -+static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg); -+static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq); -+ -+#endif /* _BFQ_H */ --- -2.3.0 - diff --git a/kernel/tools/perf/files/patches/gentoo/5003_block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r7-for-3.19.0.patch b/kernel/tools/perf/files/patches/gentoo/5003_block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r7-for-3.19.0.patch deleted file mode 100644 index b2e83e405f..0000000000 --- a/kernel/tools/perf/files/patches/gentoo/5003_block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r7-for-3.19.0.patch +++ /dev/null @@ -1,1222 +0,0 @@ -From 8308a96c0ba080015eb1c58a1bfbfbf1fee80fd6 Mon Sep 17 00:00:00 2001 -From: Mauro Andreolini -Date: Thu, 18 Dec 2014 21:32:08 +0100 -Subject: [PATCH 3/3] block, bfq: add Early Queue Merge (EQM) to BFQ-v7r7 for - 3.19.0 - -A set of processes may happen to perform interleaved reads, i.e.,requests -whose union would give rise to a sequential read pattern. There are two -typical cases: in the first case, processes read fixed-size chunks of -data at a fixed distance from each other, while in the second case processes -may read variable-size chunks at variable distances. The latter case occurs -for example with QEMU, which splits the I/O generated by the guest into -multiple chunks, and lets these chunks be served by a pool of cooperating -processes, iteratively assigning the next chunk of I/O to the first -available process. CFQ uses actual queue merging for the first type of -rocesses, whereas it uses preemption to get a sequential read pattern out -of the read requests performed by the second type of processes. In the end -it uses two different mechanisms to achieve the same goal: boosting the -throughput with interleaved I/O. - -This patch introduces Early Queue Merge (EQM), a unified mechanism to get a -sequential read pattern with both types of processes. The main idea is -checking newly arrived requests against the next request of the active queue -both in case of actual request insert and in case of request merge. By doing -so, both the types of processes can be handled by just merging their queues. -EQM is then simpler and more compact than the pair of mechanisms used in -CFQ. - -Finally, EQM also preserves the typical low-latency properties of BFQ, by -properly restoring the weight-raising state of a queue when it gets back to -a non-merged state. - -Signed-off-by: Mauro Andreolini -Signed-off-by: Arianna Avanzini -Signed-off-by: Paolo Valente ---- - block/bfq-iosched.c | 751 +++++++++++++++++++++++++++++++++++++--------------- - block/bfq-sched.c | 28 -- - block/bfq.h | 54 +++- - 3 files changed, 581 insertions(+), 252 deletions(-) - -diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c -index 97ee934..328f33c 100644 ---- a/block/bfq-iosched.c -+++ b/block/bfq-iosched.c -@@ -571,6 +571,57 @@ static inline unsigned int bfq_wr_duration(struct bfq_data *bfqd) - return dur; - } - -+static inline unsigned -+bfq_bfqq_cooperations(struct bfq_queue *bfqq) -+{ -+ return bfqq->bic ? bfqq->bic->cooperations : 0; -+} -+ -+static inline void -+bfq_bfqq_resume_state(struct bfq_queue *bfqq, struct bfq_io_cq *bic) -+{ -+ if (bic->saved_idle_window) -+ bfq_mark_bfqq_idle_window(bfqq); -+ else -+ bfq_clear_bfqq_idle_window(bfqq); -+ if (bic->saved_IO_bound) -+ bfq_mark_bfqq_IO_bound(bfqq); -+ else -+ bfq_clear_bfqq_IO_bound(bfqq); -+ /* Assuming that the flag in_large_burst is already correctly set */ -+ if (bic->wr_time_left && bfqq->bfqd->low_latency && -+ !bfq_bfqq_in_large_burst(bfqq) && -+ bic->cooperations < bfqq->bfqd->bfq_coop_thresh) { -+ /* -+ * Start a weight raising period with the duration given by -+ * the raising_time_left snapshot. -+ */ -+ if (bfq_bfqq_busy(bfqq)) -+ bfqq->bfqd->wr_busy_queues++; -+ bfqq->wr_coeff = bfqq->bfqd->bfq_wr_coeff; -+ bfqq->wr_cur_max_time = bic->wr_time_left; -+ bfqq->last_wr_start_finish = jiffies; -+ bfqq->entity.ioprio_changed = 1; -+ } -+ /* -+ * Clear wr_time_left to prevent bfq_bfqq_save_state() from -+ * getting confused about the queue's need of a weight-raising -+ * period. -+ */ -+ bic->wr_time_left = 0; -+} -+ -+/* Must be called with the queue_lock held. */ -+static int bfqq_process_refs(struct bfq_queue *bfqq) -+{ -+ int process_refs, io_refs; -+ -+ io_refs = bfqq->allocated[READ] + bfqq->allocated[WRITE]; -+ process_refs = atomic_read(&bfqq->ref) - io_refs - bfqq->entity.on_st; -+ BUG_ON(process_refs < 0); -+ return process_refs; -+} -+ - /* Empty burst list and add just bfqq (see comments to bfq_handle_burst) */ - static inline void bfq_reset_burst_list(struct bfq_data *bfqd, - struct bfq_queue *bfqq) -@@ -815,7 +866,7 @@ static void bfq_add_request(struct request *rq) - bfq_rq_pos_tree_add(bfqd, bfqq); - - if (!bfq_bfqq_busy(bfqq)) { -- bool soft_rt, -+ bool soft_rt, coop_or_in_burst, - idle_for_long_time = time_is_before_jiffies( - bfqq->budget_timeout + - bfqd->bfq_wr_min_idle_time); -@@ -839,11 +890,12 @@ static void bfq_add_request(struct request *rq) - bfqd->last_ins_in_burst = jiffies; - } - -+ coop_or_in_burst = bfq_bfqq_in_large_burst(bfqq) || -+ bfq_bfqq_cooperations(bfqq) >= bfqd->bfq_coop_thresh; - soft_rt = bfqd->bfq_wr_max_softrt_rate > 0 && -- !bfq_bfqq_in_large_burst(bfqq) && -+ !coop_or_in_burst && - time_is_before_jiffies(bfqq->soft_rt_next_start); -- interactive = !bfq_bfqq_in_large_burst(bfqq) && -- idle_for_long_time; -+ interactive = !coop_or_in_burst && idle_for_long_time; - entity->budget = max_t(unsigned long, bfqq->max_budget, - bfq_serv_to_charge(next_rq, bfqq)); - -@@ -862,11 +914,20 @@ static void bfq_add_request(struct request *rq) - if (!bfqd->low_latency) - goto add_bfqq_busy; - -+ if (bfq_bfqq_just_split(bfqq)) -+ goto set_ioprio_changed; -+ - /* -- * If the queue is not being boosted and has been idle -- * for enough time, start a weight-raising period -+ * If the queue: -+ * - is not being boosted, -+ * - has been idle for enough time, -+ * - is not a sync queue or is linked to a bfq_io_cq (it is -+ * shared "for its nature" or it is not shared and its -+ * requests have not been redirected to a shared queue) -+ * start a weight-raising period. - */ -- if (old_wr_coeff == 1 && (interactive || soft_rt)) { -+ if (old_wr_coeff == 1 && (interactive || soft_rt) && -+ (!bfq_bfqq_sync(bfqq) || bfqq->bic != NULL)) { - bfqq->wr_coeff = bfqd->bfq_wr_coeff; - if (interactive) - bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); -@@ -880,7 +941,7 @@ static void bfq_add_request(struct request *rq) - } else if (old_wr_coeff > 1) { - if (interactive) - bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); -- else if (bfq_bfqq_in_large_burst(bfqq) || -+ else if (coop_or_in_burst || - (bfqq->wr_cur_max_time == - bfqd->bfq_wr_rt_max_time && - !soft_rt)) { -@@ -899,18 +960,18 @@ static void bfq_add_request(struct request *rq) - /* - * - * The remaining weight-raising time is lower -- * than bfqd->bfq_wr_rt_max_time, which -- * means that the application is enjoying -- * weight raising either because deemed soft- -- * rt in the near past, or because deemed -- * interactive a long ago. In both cases, -- * resetting now the current remaining weight- -- * raising time for the application to the -- * weight-raising duration for soft rt -- * applications would not cause any latency -- * increase for the application (as the new -- * duration would be higher than the remaining -- * time). -+ * than bfqd->bfq_wr_rt_max_time, which means -+ * that the application is enjoying weight -+ * raising either because deemed soft-rt in -+ * the near past, or because deemed interactive -+ * a long ago. -+ * In both cases, resetting now the current -+ * remaining weight-raising time for the -+ * application to the weight-raising duration -+ * for soft rt applications would not cause any -+ * latency increase for the application (as the -+ * new duration would be higher than the -+ * remaining time). - * - * In addition, the application is now meeting - * the requirements for being deemed soft rt. -@@ -945,6 +1006,7 @@ static void bfq_add_request(struct request *rq) - bfqd->bfq_wr_rt_max_time; - } - } -+set_ioprio_changed: - if (old_wr_coeff != bfqq->wr_coeff) - entity->ioprio_changed = 1; - add_bfqq_busy: -@@ -1156,90 +1218,35 @@ static void bfq_end_wr(struct bfq_data *bfqd) - spin_unlock_irq(bfqd->queue->queue_lock); - } - --static int bfq_allow_merge(struct request_queue *q, struct request *rq, -- struct bio *bio) -+static inline sector_t bfq_io_struct_pos(void *io_struct, bool request) - { -- struct bfq_data *bfqd = q->elevator->elevator_data; -- struct bfq_io_cq *bic; -- struct bfq_queue *bfqq; -- -- /* -- * Disallow merge of a sync bio into an async request. -- */ -- if (bfq_bio_sync(bio) && !rq_is_sync(rq)) -- return 0; -- -- /* -- * Lookup the bfqq that this bio will be queued with. Allow -- * merge only if rq is queued there. -- * Queue lock is held here. -- */ -- bic = bfq_bic_lookup(bfqd, current->io_context); -- if (bic == NULL) -- return 0; -- -- bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio)); -- return bfqq == RQ_BFQQ(rq); --} -- --static void __bfq_set_in_service_queue(struct bfq_data *bfqd, -- struct bfq_queue *bfqq) --{ -- if (bfqq != NULL) { -- bfq_mark_bfqq_must_alloc(bfqq); -- bfq_mark_bfqq_budget_new(bfqq); -- bfq_clear_bfqq_fifo_expire(bfqq); -- -- bfqd->budgets_assigned = (bfqd->budgets_assigned*7 + 256) / 8; -- -- bfq_log_bfqq(bfqd, bfqq, -- "set_in_service_queue, cur-budget = %lu", -- bfqq->entity.budget); -- } -- -- bfqd->in_service_queue = bfqq; --} -- --/* -- * Get and set a new queue for service. -- */ --static struct bfq_queue *bfq_set_in_service_queue(struct bfq_data *bfqd, -- struct bfq_queue *bfqq) --{ -- if (!bfqq) -- bfqq = bfq_get_next_queue(bfqd); -+ if (request) -+ return blk_rq_pos(io_struct); - else -- bfq_get_next_queue_forced(bfqd, bfqq); -- -- __bfq_set_in_service_queue(bfqd, bfqq); -- return bfqq; -+ return ((struct bio *)io_struct)->bi_iter.bi_sector; - } - --static inline sector_t bfq_dist_from_last(struct bfq_data *bfqd, -- struct request *rq) -+static inline sector_t bfq_dist_from(sector_t pos1, -+ sector_t pos2) - { -- if (blk_rq_pos(rq) >= bfqd->last_position) -- return blk_rq_pos(rq) - bfqd->last_position; -+ if (pos1 >= pos2) -+ return pos1 - pos2; - else -- return bfqd->last_position - blk_rq_pos(rq); -+ return pos2 - pos1; - } - --/* -- * Return true if bfqq has no request pending and rq is close enough to -- * bfqd->last_position, or if rq is closer to bfqd->last_position than -- * bfqq->next_rq -- */ --static inline int bfq_rq_close(struct bfq_data *bfqd, struct request *rq) -+static inline int bfq_rq_close_to_sector(void *io_struct, bool request, -+ sector_t sector) - { -- return bfq_dist_from_last(bfqd, rq) <= BFQQ_SEEK_THR; -+ return bfq_dist_from(bfq_io_struct_pos(io_struct, request), sector) <= -+ BFQQ_SEEK_THR; - } - --static struct bfq_queue *bfqq_close(struct bfq_data *bfqd) -+static struct bfq_queue *bfqq_close(struct bfq_data *bfqd, sector_t sector) - { - struct rb_root *root = &bfqd->rq_pos_tree; - struct rb_node *parent, *node; - struct bfq_queue *__bfqq; -- sector_t sector = bfqd->last_position; - - if (RB_EMPTY_ROOT(root)) - return NULL; -@@ -1258,7 +1265,7 @@ static struct bfq_queue *bfqq_close(struct bfq_data *bfqd) - * next_request position). - */ - __bfqq = rb_entry(parent, struct bfq_queue, pos_node); -- if (bfq_rq_close(bfqd, __bfqq->next_rq)) -+ if (bfq_rq_close_to_sector(__bfqq->next_rq, true, sector)) - return __bfqq; - - if (blk_rq_pos(__bfqq->next_rq) < sector) -@@ -1269,7 +1276,7 @@ static struct bfq_queue *bfqq_close(struct bfq_data *bfqd) - return NULL; - - __bfqq = rb_entry(node, struct bfq_queue, pos_node); -- if (bfq_rq_close(bfqd, __bfqq->next_rq)) -+ if (bfq_rq_close_to_sector(__bfqq->next_rq, true, sector)) - return __bfqq; - - return NULL; -@@ -1278,14 +1285,12 @@ static struct bfq_queue *bfqq_close(struct bfq_data *bfqd) - /* - * bfqd - obvious - * cur_bfqq - passed in so that we don't decide that the current queue -- * is closely cooperating with itself. -- * -- * We are assuming that cur_bfqq has dispatched at least one request, -- * and that bfqd->last_position reflects a position on the disk associated -- * with the I/O issued by cur_bfqq. -+ * is closely cooperating with itself -+ * sector - used as a reference point to search for a close queue - */ - static struct bfq_queue *bfq_close_cooperator(struct bfq_data *bfqd, -- struct bfq_queue *cur_bfqq) -+ struct bfq_queue *cur_bfqq, -+ sector_t sector) - { - struct bfq_queue *bfqq; - -@@ -1305,7 +1310,7 @@ static struct bfq_queue *bfq_close_cooperator(struct bfq_data *bfqd, - * working closely on the same area of the disk. In that case, - * we can group them together and don't waste time idling. - */ -- bfqq = bfqq_close(bfqd); -+ bfqq = bfqq_close(bfqd, sector); - if (bfqq == NULL || bfqq == cur_bfqq) - return NULL; - -@@ -1332,6 +1337,315 @@ static struct bfq_queue *bfq_close_cooperator(struct bfq_data *bfqd, - return bfqq; - } - -+static struct bfq_queue * -+bfq_setup_merge(struct bfq_queue *bfqq, struct bfq_queue *new_bfqq) -+{ -+ int process_refs, new_process_refs; -+ struct bfq_queue *__bfqq; -+ -+ /* -+ * If there are no process references on the new_bfqq, then it is -+ * unsafe to follow the ->new_bfqq chain as other bfqq's in the chain -+ * may have dropped their last reference (not just their last process -+ * reference). -+ */ -+ if (!bfqq_process_refs(new_bfqq)) -+ return NULL; -+ -+ /* Avoid a circular list and skip interim queue merges. */ -+ while ((__bfqq = new_bfqq->new_bfqq)) { -+ if (__bfqq == bfqq) -+ return NULL; -+ new_bfqq = __bfqq; -+ } -+ -+ process_refs = bfqq_process_refs(bfqq); -+ new_process_refs = bfqq_process_refs(new_bfqq); -+ /* -+ * If the process for the bfqq has gone away, there is no -+ * sense in merging the queues. -+ */ -+ if (process_refs == 0 || new_process_refs == 0) -+ return NULL; -+ -+ bfq_log_bfqq(bfqq->bfqd, bfqq, "scheduling merge with queue %d", -+ new_bfqq->pid); -+ -+ /* -+ * Merging is just a redirection: the requests of the process -+ * owning one of the two queues are redirected to the other queue. -+ * The latter queue, in its turn, is set as shared if this is the -+ * first time that the requests of some process are redirected to -+ * it. -+ * -+ * We redirect bfqq to new_bfqq and not the opposite, because we -+ * are in the context of the process owning bfqq, hence we have -+ * the io_cq of this process. So we can immediately configure this -+ * io_cq to redirect the requests of the process to new_bfqq. -+ * -+ * NOTE, even if new_bfqq coincides with the in-service queue, the -+ * io_cq of new_bfqq is not available, because, if the in-service -+ * queue is shared, bfqd->in_service_bic may not point to the -+ * io_cq of the in-service queue. -+ * Redirecting the requests of the process owning bfqq to the -+ * currently in-service queue is in any case the best option, as -+ * we feed the in-service queue with new requests close to the -+ * last request served and, by doing so, hopefully increase the -+ * throughput. -+ */ -+ bfqq->new_bfqq = new_bfqq; -+ atomic_add(process_refs, &new_bfqq->ref); -+ return new_bfqq; -+} -+ -+/* -+ * Attempt to schedule a merge of bfqq with the currently in-service queue -+ * or with a close queue among the scheduled queues. -+ * Return NULL if no merge was scheduled, a pointer to the shared bfq_queue -+ * structure otherwise. -+ * -+ * The OOM queue is not allowed to participate to cooperation: in fact, since -+ * the requests temporarily redirected to the OOM queue could be redirected -+ * again to dedicated queues at any time, the state needed to correctly -+ * handle merging with the OOM queue would be quite complex and expensive -+ * to maintain. Besides, in such a critical condition as an out of memory, -+ * the benefits of queue merging may be little relevant, or even negligible. -+ */ -+static struct bfq_queue * -+bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq, -+ void *io_struct, bool request) -+{ -+ struct bfq_queue *in_service_bfqq, *new_bfqq; -+ -+ if (bfqq->new_bfqq) -+ return bfqq->new_bfqq; -+ -+ if (!io_struct || unlikely(bfqq == &bfqd->oom_bfqq)) -+ return NULL; -+ -+ in_service_bfqq = bfqd->in_service_queue; -+ -+ if (in_service_bfqq == NULL || in_service_bfqq == bfqq || -+ !bfqd->in_service_bic || -+ unlikely(in_service_bfqq == &bfqd->oom_bfqq)) -+ goto check_scheduled; -+ -+ if (bfq_class_idle(in_service_bfqq) || bfq_class_idle(bfqq)) -+ goto check_scheduled; -+ -+ if (bfq_class_rt(in_service_bfqq) != bfq_class_rt(bfqq)) -+ goto check_scheduled; -+ -+ if (in_service_bfqq->entity.parent != bfqq->entity.parent) -+ goto check_scheduled; -+ -+ if (bfq_rq_close_to_sector(io_struct, request, bfqd->last_position) && -+ bfq_bfqq_sync(in_service_bfqq) && bfq_bfqq_sync(bfqq)) { -+ new_bfqq = bfq_setup_merge(bfqq, in_service_bfqq); -+ if (new_bfqq != NULL) -+ return new_bfqq; /* Merge with in-service queue */ -+ } -+ -+ /* -+ * Check whether there is a cooperator among currently scheduled -+ * queues. The only thing we need is that the bio/request is not -+ * NULL, as we need it to establish whether a cooperator exists. -+ */ -+check_scheduled: -+ new_bfqq = bfq_close_cooperator(bfqd, bfqq, -+ bfq_io_struct_pos(io_struct, request)); -+ if (new_bfqq && likely(new_bfqq != &bfqd->oom_bfqq)) -+ return bfq_setup_merge(bfqq, new_bfqq); -+ -+ return NULL; -+} -+ -+static inline void -+bfq_bfqq_save_state(struct bfq_queue *bfqq) -+{ -+ /* -+ * If bfqq->bic == NULL, the queue is already shared or its requests -+ * have already been redirected to a shared queue; both idle window -+ * and weight raising state have already been saved. Do nothing. -+ */ -+ if (bfqq->bic == NULL) -+ return; -+ if (bfqq->bic->wr_time_left) -+ /* -+ * This is the queue of a just-started process, and would -+ * deserve weight raising: we set wr_time_left to the full -+ * weight-raising duration to trigger weight-raising when -+ * and if the queue is split and the first request of the -+ * queue is enqueued. -+ */ -+ bfqq->bic->wr_time_left = bfq_wr_duration(bfqq->bfqd); -+ else if (bfqq->wr_coeff > 1) { -+ unsigned long wr_duration = -+ jiffies - bfqq->last_wr_start_finish; -+ /* -+ * It may happen that a queue's weight raising period lasts -+ * longer than its wr_cur_max_time, as weight raising is -+ * handled only when a request is enqueued or dispatched (it -+ * does not use any timer). If the weight raising period is -+ * about to end, don't save it. -+ */ -+ if (bfqq->wr_cur_max_time <= wr_duration) -+ bfqq->bic->wr_time_left = 0; -+ else -+ bfqq->bic->wr_time_left = -+ bfqq->wr_cur_max_time - wr_duration; -+ /* -+ * The bfq_queue is becoming shared or the requests of the -+ * process owning the queue are being redirected to a shared -+ * queue. Stop the weight raising period of the queue, as in -+ * both cases it should not be owned by an interactive or -+ * soft real-time application. -+ */ -+ bfq_bfqq_end_wr(bfqq); -+ } else -+ bfqq->bic->wr_time_left = 0; -+ bfqq->bic->saved_idle_window = bfq_bfqq_idle_window(bfqq); -+ bfqq->bic->saved_IO_bound = bfq_bfqq_IO_bound(bfqq); -+ bfqq->bic->saved_in_large_burst = bfq_bfqq_in_large_burst(bfqq); -+ bfqq->bic->was_in_burst_list = !hlist_unhashed(&bfqq->burst_list_node); -+ bfqq->bic->cooperations++; -+ bfqq->bic->failed_cooperations = 0; -+} -+ -+static inline void -+bfq_get_bic_reference(struct bfq_queue *bfqq) -+{ -+ /* -+ * If bfqq->bic has a non-NULL value, the bic to which it belongs -+ * is about to begin using a shared bfq_queue. -+ */ -+ if (bfqq->bic) -+ atomic_long_inc(&bfqq->bic->icq.ioc->refcount); -+} -+ -+static void -+bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic, -+ struct bfq_queue *bfqq, struct bfq_queue *new_bfqq) -+{ -+ bfq_log_bfqq(bfqd, bfqq, "merging with queue %lu", -+ (long unsigned)new_bfqq->pid); -+ /* Save weight raising and idle window of the merged queues */ -+ bfq_bfqq_save_state(bfqq); -+ bfq_bfqq_save_state(new_bfqq); -+ if (bfq_bfqq_IO_bound(bfqq)) -+ bfq_mark_bfqq_IO_bound(new_bfqq); -+ bfq_clear_bfqq_IO_bound(bfqq); -+ /* -+ * Grab a reference to the bic, to prevent it from being destroyed -+ * before being possibly touched by a bfq_split_bfqq(). -+ */ -+ bfq_get_bic_reference(bfqq); -+ bfq_get_bic_reference(new_bfqq); -+ /* -+ * Merge queues (that is, let bic redirect its requests to new_bfqq) -+ */ -+ bic_set_bfqq(bic, new_bfqq, 1); -+ bfq_mark_bfqq_coop(new_bfqq); -+ /* -+ * new_bfqq now belongs to at least two bics (it is a shared queue): -+ * set new_bfqq->bic to NULL. bfqq either: -+ * - does not belong to any bic any more, and hence bfqq->bic must -+ * be set to NULL, or -+ * - is a queue whose owning bics have already been redirected to a -+ * different queue, hence the queue is destined to not belong to -+ * any bic soon and bfqq->bic is already NULL (therefore the next -+ * assignment causes no harm). -+ */ -+ new_bfqq->bic = NULL; -+ bfqq->bic = NULL; -+ bfq_put_queue(bfqq); -+} -+ -+static inline void bfq_bfqq_increase_failed_cooperations(struct bfq_queue *bfqq) -+{ -+ struct bfq_io_cq *bic = bfqq->bic; -+ struct bfq_data *bfqd = bfqq->bfqd; -+ -+ if (bic && bfq_bfqq_cooperations(bfqq) >= bfqd->bfq_coop_thresh) { -+ bic->failed_cooperations++; -+ if (bic->failed_cooperations >= bfqd->bfq_failed_cooperations) -+ bic->cooperations = 0; -+ } -+} -+ -+static int bfq_allow_merge(struct request_queue *q, struct request *rq, -+ struct bio *bio) -+{ -+ struct bfq_data *bfqd = q->elevator->elevator_data; -+ struct bfq_io_cq *bic; -+ struct bfq_queue *bfqq, *new_bfqq; -+ -+ /* -+ * Disallow merge of a sync bio into an async request. -+ */ -+ if (bfq_bio_sync(bio) && !rq_is_sync(rq)) -+ return 0; -+ -+ /* -+ * Lookup the bfqq that this bio will be queued with. Allow -+ * merge only if rq is queued there. -+ * Queue lock is held here. -+ */ -+ bic = bfq_bic_lookup(bfqd, current->io_context); -+ if (bic == NULL) -+ return 0; -+ -+ bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio)); -+ /* -+ * We take advantage of this function to perform an early merge -+ * of the queues of possible cooperating processes. -+ */ -+ if (bfqq != NULL) { -+ new_bfqq = bfq_setup_cooperator(bfqd, bfqq, bio, false); -+ if (new_bfqq != NULL) { -+ bfq_merge_bfqqs(bfqd, bic, bfqq, new_bfqq); -+ /* -+ * If we get here, the bio will be queued in the -+ * shared queue, i.e., new_bfqq, so use new_bfqq -+ * to decide whether bio and rq can be merged. -+ */ -+ bfqq = new_bfqq; -+ } else -+ bfq_bfqq_increase_failed_cooperations(bfqq); -+ } -+ -+ return bfqq == RQ_BFQQ(rq); -+} -+ -+static void __bfq_set_in_service_queue(struct bfq_data *bfqd, -+ struct bfq_queue *bfqq) -+{ -+ if (bfqq != NULL) { -+ bfq_mark_bfqq_must_alloc(bfqq); -+ bfq_mark_bfqq_budget_new(bfqq); -+ bfq_clear_bfqq_fifo_expire(bfqq); -+ -+ bfqd->budgets_assigned = (bfqd->budgets_assigned*7 + 256) / 8; -+ -+ bfq_log_bfqq(bfqd, bfqq, -+ "set_in_service_queue, cur-budget = %lu", -+ bfqq->entity.budget); -+ } -+ -+ bfqd->in_service_queue = bfqq; -+} -+ -+/* -+ * Get and set a new queue for service. -+ */ -+static struct bfq_queue *bfq_set_in_service_queue(struct bfq_data *bfqd) -+{ -+ struct bfq_queue *bfqq = bfq_get_next_queue(bfqd); -+ -+ __bfq_set_in_service_queue(bfqd, bfqq); -+ return bfqq; -+} -+ - /* - * If enough samples have been computed, return the current max budget - * stored in bfqd, which is dynamically updated according to the -@@ -1475,61 +1789,6 @@ static struct request *bfq_check_fifo(struct bfq_queue *bfqq) - return rq; - } - --/* Must be called with the queue_lock held. */ --static int bfqq_process_refs(struct bfq_queue *bfqq) --{ -- int process_refs, io_refs; -- -- io_refs = bfqq->allocated[READ] + bfqq->allocated[WRITE]; -- process_refs = atomic_read(&bfqq->ref) - io_refs - bfqq->entity.on_st; -- BUG_ON(process_refs < 0); -- return process_refs; --} -- --static void bfq_setup_merge(struct bfq_queue *bfqq, struct bfq_queue *new_bfqq) --{ -- int process_refs, new_process_refs; -- struct bfq_queue *__bfqq; -- -- /* -- * If there are no process references on the new_bfqq, then it is -- * unsafe to follow the ->new_bfqq chain as other bfqq's in the chain -- * may have dropped their last reference (not just their last process -- * reference). -- */ -- if (!bfqq_process_refs(new_bfqq)) -- return; -- -- /* Avoid a circular list and skip interim queue merges. */ -- while ((__bfqq = new_bfqq->new_bfqq)) { -- if (__bfqq == bfqq) -- return; -- new_bfqq = __bfqq; -- } -- -- process_refs = bfqq_process_refs(bfqq); -- new_process_refs = bfqq_process_refs(new_bfqq); -- /* -- * If the process for the bfqq has gone away, there is no -- * sense in merging the queues. -- */ -- if (process_refs == 0 || new_process_refs == 0) -- return; -- -- /* -- * Merge in the direction of the lesser amount of work. -- */ -- if (new_process_refs >= process_refs) { -- bfqq->new_bfqq = new_bfqq; -- atomic_add(process_refs, &new_bfqq->ref); -- } else { -- new_bfqq->new_bfqq = bfqq; -- atomic_add(new_process_refs, &bfqq->ref); -- } -- bfq_log_bfqq(bfqq->bfqd, bfqq, "scheduling merge with queue %d", -- new_bfqq->pid); --} -- - static inline unsigned long bfq_bfqq_budget_left(struct bfq_queue *bfqq) - { - struct bfq_entity *entity = &bfqq->entity; -@@ -2263,7 +2522,7 @@ static inline bool bfq_bfqq_must_idle(struct bfq_queue *bfqq) - */ - static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd) - { -- struct bfq_queue *bfqq, *new_bfqq = NULL; -+ struct bfq_queue *bfqq; - struct request *next_rq; - enum bfqq_expiration reason = BFQ_BFQQ_BUDGET_TIMEOUT; - -@@ -2273,17 +2532,6 @@ static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd) - - bfq_log_bfqq(bfqd, bfqq, "select_queue: already in-service queue"); - -- /* -- * If another queue has a request waiting within our mean seek -- * distance, let it run. The expire code will check for close -- * cooperators and put the close queue at the front of the -- * service tree. If possible, merge the expiring queue with the -- * new bfqq. -- */ -- new_bfqq = bfq_close_cooperator(bfqd, bfqq); -- if (new_bfqq != NULL && bfqq->new_bfqq == NULL) -- bfq_setup_merge(bfqq, new_bfqq); -- - if (bfq_may_expire_for_budg_timeout(bfqq) && - !timer_pending(&bfqd->idle_slice_timer) && - !bfq_bfqq_must_idle(bfqq)) -@@ -2322,10 +2570,7 @@ static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd) - bfq_clear_bfqq_wait_request(bfqq); - del_timer(&bfqd->idle_slice_timer); - } -- if (new_bfqq == NULL) -- goto keep_queue; -- else -- goto expire; -+ goto keep_queue; - } - } - -@@ -2334,40 +2579,30 @@ static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd) - * in flight (possibly waiting for a completion) or is idling for a - * new request, then keep it. - */ -- if (new_bfqq == NULL && (timer_pending(&bfqd->idle_slice_timer) || -- (bfqq->dispatched != 0 && bfq_bfqq_must_not_expire(bfqq)))) { -+ if (timer_pending(&bfqd->idle_slice_timer) || -+ (bfqq->dispatched != 0 && bfq_bfqq_must_not_expire(bfqq))) { - bfqq = NULL; - goto keep_queue; -- } else if (new_bfqq != NULL && timer_pending(&bfqd->idle_slice_timer)) { -- /* -- * Expiring the queue because there is a close cooperator, -- * cancel timer. -- */ -- bfq_clear_bfqq_wait_request(bfqq); -- del_timer(&bfqd->idle_slice_timer); - } - - reason = BFQ_BFQQ_NO_MORE_REQUESTS; - expire: - bfq_bfqq_expire(bfqd, bfqq, 0, reason); - new_queue: -- bfqq = bfq_set_in_service_queue(bfqd, new_bfqq); -+ bfqq = bfq_set_in_service_queue(bfqd); - bfq_log(bfqd, "select_queue: new queue %d returned", - bfqq != NULL ? bfqq->pid : 0); - keep_queue: - return bfqq; - } - --static void bfq_update_wr_data(struct bfq_data *bfqd, -- struct bfq_queue *bfqq) -+static void bfq_update_wr_data(struct bfq_data *bfqd, struct bfq_queue *bfqq) - { -- if (bfqq->wr_coeff > 1) { /* queue is being boosted */ -- struct bfq_entity *entity = &bfqq->entity; -- -+ struct bfq_entity *entity = &bfqq->entity; -+ if (bfqq->wr_coeff > 1) { /* queue is being weight-raised */ - bfq_log_bfqq(bfqd, bfqq, - "raising period dur %u/%u msec, old coeff %u, w %d(%d)", -- jiffies_to_msecs(jiffies - -- bfqq->last_wr_start_finish), -+ jiffies_to_msecs(jiffies - bfqq->last_wr_start_finish), - jiffies_to_msecs(bfqq->wr_cur_max_time), - bfqq->wr_coeff, - bfqq->entity.weight, bfqq->entity.orig_weight); -@@ -2376,12 +2611,16 @@ static void bfq_update_wr_data(struct bfq_data *bfqd, - entity->orig_weight * bfqq->wr_coeff); - if (entity->ioprio_changed) - bfq_log_bfqq(bfqd, bfqq, "WARN: pending prio change"); -+ - /* - * If the queue was activated in a burst, or - * too much time has elapsed from the beginning -- * of this weight-raising, then end weight raising. -+ * of this weight-raising period, or the queue has -+ * exceeded the acceptable number of cooperations, -+ * then end weight raising. - */ - if (bfq_bfqq_in_large_burst(bfqq) || -+ bfq_bfqq_cooperations(bfqq) >= bfqd->bfq_coop_thresh || - time_is_before_jiffies(bfqq->last_wr_start_finish + - bfqq->wr_cur_max_time)) { - bfqq->last_wr_start_finish = jiffies; -@@ -2390,11 +2629,13 @@ static void bfq_update_wr_data(struct bfq_data *bfqd, - bfqq->last_wr_start_finish, - jiffies_to_msecs(bfqq->wr_cur_max_time)); - bfq_bfqq_end_wr(bfqq); -- __bfq_entity_update_weight_prio( -- bfq_entity_service_tree(entity), -- entity); - } - } -+ /* Update weight both if it must be raised and if it must be lowered */ -+ if ((entity->weight > entity->orig_weight) != (bfqq->wr_coeff > 1)) -+ __bfq_entity_update_weight_prio( -+ bfq_entity_service_tree(entity), -+ entity); - } - - /* -@@ -2642,6 +2883,25 @@ static inline void bfq_init_icq(struct io_cq *icq) - struct bfq_io_cq *bic = icq_to_bic(icq); - - bic->ttime.last_end_request = jiffies; -+ /* -+ * A newly created bic indicates that the process has just -+ * started doing I/O, and is probably mapping into memory its -+ * executable and libraries: it definitely needs weight raising. -+ * There is however the possibility that the process performs, -+ * for a while, I/O close to some other process. EQM intercepts -+ * this behavior and may merge the queue corresponding to the -+ * process with some other queue, BEFORE the weight of the queue -+ * is raised. Merged queues are not weight-raised (they are assumed -+ * to belong to processes that benefit only from high throughput). -+ * If the merge is basically the consequence of an accident, then -+ * the queue will be split soon and will get back its old weight. -+ * It is then important to write down somewhere that this queue -+ * does need weight raising, even if it did not make it to get its -+ * weight raised before being merged. To this purpose, we overload -+ * the field raising_time_left and assign 1 to it, to mark the queue -+ * as needing weight raising. -+ */ -+ bic->wr_time_left = 1; - } - - static void bfq_exit_icq(struct io_cq *icq) -@@ -2655,6 +2915,13 @@ static void bfq_exit_icq(struct io_cq *icq) - } - - if (bic->bfqq[BLK_RW_SYNC]) { -+ /* -+ * If the bic is using a shared queue, put the reference -+ * taken on the io_context when the bic started using a -+ * shared bfq_queue. -+ */ -+ if (bfq_bfqq_coop(bic->bfqq[BLK_RW_SYNC])) -+ put_io_context(icq->ioc); - bfq_exit_bfqq(bfqd, bic->bfqq[BLK_RW_SYNC]); - bic->bfqq[BLK_RW_SYNC] = NULL; - } -@@ -2950,6 +3217,10 @@ static void bfq_update_idle_window(struct bfq_data *bfqd, - if (!bfq_bfqq_sync(bfqq) || bfq_class_idle(bfqq)) - return; - -+ /* Idle window just restored, statistics are meaningless. */ -+ if (bfq_bfqq_just_split(bfqq)) -+ return; -+ - enable_idle = bfq_bfqq_idle_window(bfqq); - - if (atomic_read(&bic->icq.ioc->active_ref) == 0 || -@@ -2997,6 +3268,7 @@ static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq, - if (bfqq->entity.service > bfq_max_budget(bfqd) / 8 || - !BFQQ_SEEKY(bfqq)) - bfq_update_idle_window(bfqd, bfqq, bic); -+ bfq_clear_bfqq_just_split(bfqq); - - bfq_log_bfqq(bfqd, bfqq, - "rq_enqueued: idle_window=%d (seeky %d, mean %llu)", -@@ -3057,13 +3329,49 @@ static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq, - static void bfq_insert_request(struct request_queue *q, struct request *rq) - { - struct bfq_data *bfqd = q->elevator->elevator_data; -- struct bfq_queue *bfqq = RQ_BFQQ(rq); -+ struct bfq_queue *bfqq = RQ_BFQQ(rq), *new_bfqq; - - assert_spin_locked(bfqd->queue->queue_lock); -+ -+ /* -+ * An unplug may trigger a requeue of a request from the device -+ * driver: make sure we are in process context while trying to -+ * merge two bfq_queues. -+ */ -+ if (!in_interrupt()) { -+ new_bfqq = bfq_setup_cooperator(bfqd, bfqq, rq, true); -+ if (new_bfqq != NULL) { -+ if (bic_to_bfqq(RQ_BIC(rq), 1) != bfqq) -+ new_bfqq = bic_to_bfqq(RQ_BIC(rq), 1); -+ /* -+ * Release the request's reference to the old bfqq -+ * and make sure one is taken to the shared queue. -+ */ -+ new_bfqq->allocated[rq_data_dir(rq)]++; -+ bfqq->allocated[rq_data_dir(rq)]--; -+ atomic_inc(&new_bfqq->ref); -+ bfq_put_queue(bfqq); -+ if (bic_to_bfqq(RQ_BIC(rq), 1) == bfqq) -+ bfq_merge_bfqqs(bfqd, RQ_BIC(rq), -+ bfqq, new_bfqq); -+ rq->elv.priv[1] = new_bfqq; -+ bfqq = new_bfqq; -+ } else -+ bfq_bfqq_increase_failed_cooperations(bfqq); -+ } -+ - bfq_init_prio_data(bfqq, RQ_BIC(rq)); - - bfq_add_request(rq); - -+ /* -+ * Here a newly-created bfq_queue has already started a weight-raising -+ * period: clear raising_time_left to prevent bfq_bfqq_save_state() -+ * from assigning it a full weight-raising period. See the detailed -+ * comments about this field in bfq_init_icq(). -+ */ -+ if (bfqq->bic != NULL) -+ bfqq->bic->wr_time_left = 0; - rq->fifo_time = jiffies + bfqd->bfq_fifo_expire[rq_is_sync(rq)]; - list_add_tail(&rq->queuelist, &bfqq->fifo); - -@@ -3228,18 +3536,6 @@ static void bfq_put_request(struct request *rq) - } - } - --static struct bfq_queue * --bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic, -- struct bfq_queue *bfqq) --{ -- bfq_log_bfqq(bfqd, bfqq, "merging with queue %lu", -- (long unsigned)bfqq->new_bfqq->pid); -- bic_set_bfqq(bic, bfqq->new_bfqq, 1); -- bfq_mark_bfqq_coop(bfqq->new_bfqq); -- bfq_put_queue(bfqq); -- return bic_to_bfqq(bic, 1); --} -- - /* - * Returns NULL if a new bfqq should be allocated, or the old bfqq if this - * was the last process referring to said bfqq. -@@ -3248,6 +3544,9 @@ static struct bfq_queue * - bfq_split_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq) - { - bfq_log_bfqq(bfqq->bfqd, bfqq, "splitting queue"); -+ -+ put_io_context(bic->icq.ioc); -+ - if (bfqq_process_refs(bfqq) == 1) { - bfqq->pid = current->pid; - bfq_clear_bfqq_coop(bfqq); -@@ -3276,6 +3575,7 @@ static int bfq_set_request(struct request_queue *q, struct request *rq, - struct bfq_queue *bfqq; - struct bfq_group *bfqg; - unsigned long flags; -+ bool split = false; - - might_sleep_if(gfp_mask & __GFP_WAIT); - -@@ -3293,25 +3593,26 @@ new_queue: - if (bfqq == NULL || bfqq == &bfqd->oom_bfqq) { - bfqq = bfq_get_queue(bfqd, bfqg, is_sync, bic, gfp_mask); - bic_set_bfqq(bic, bfqq, is_sync); -+ if (split && is_sync) { -+ if ((bic->was_in_burst_list && bfqd->large_burst) || -+ bic->saved_in_large_burst) -+ bfq_mark_bfqq_in_large_burst(bfqq); -+ else { -+ bfq_clear_bfqq_in_large_burst(bfqq); -+ if (bic->was_in_burst_list) -+ hlist_add_head(&bfqq->burst_list_node, -+ &bfqd->burst_list); -+ } -+ } - } else { -- /* -- * If the queue was seeky for too long, break it apart. -- */ -+ /* If the queue was seeky for too long, break it apart. */ - if (bfq_bfqq_coop(bfqq) && bfq_bfqq_split_coop(bfqq)) { - bfq_log_bfqq(bfqd, bfqq, "breaking apart bfqq"); - bfqq = bfq_split_bfqq(bic, bfqq); -+ split = true; - if (!bfqq) - goto new_queue; - } -- -- /* -- * Check to see if this queue is scheduled to merge with -- * another closely cooperating queue. The merging of queues -- * happens here as it must be done in process context. -- * The reference on new_bfqq was taken in merge_bfqqs. -- */ -- if (bfqq->new_bfqq != NULL) -- bfqq = bfq_merge_bfqqs(bfqd, bic, bfqq); - } - - bfqq->allocated[rw]++; -@@ -3322,6 +3623,26 @@ new_queue: - rq->elv.priv[0] = bic; - rq->elv.priv[1] = bfqq; - -+ /* -+ * If a bfq_queue has only one process reference, it is owned -+ * by only one bfq_io_cq: we can set the bic field of the -+ * bfq_queue to the address of that structure. Also, if the -+ * queue has just been split, mark a flag so that the -+ * information is available to the other scheduler hooks. -+ */ -+ if (likely(bfqq != &bfqd->oom_bfqq) && bfqq_process_refs(bfqq) == 1) { -+ bfqq->bic = bic; -+ if (split) { -+ bfq_mark_bfqq_just_split(bfqq); -+ /* -+ * If the queue has just been split from a shared -+ * queue, restore the idle window and the possible -+ * weight raising period. -+ */ -+ bfq_bfqq_resume_state(bfqq, bic); -+ } -+ } -+ - spin_unlock_irqrestore(q->queue_lock, flags); - - return 0; -diff --git a/block/bfq-sched.c b/block/bfq-sched.c -index 2931563..6764a7e 100644 ---- a/block/bfq-sched.c -+++ b/block/bfq-sched.c -@@ -1091,34 +1091,6 @@ static struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd) - return bfqq; - } - --/* -- * Forced extraction of the given queue. -- */ --static void bfq_get_next_queue_forced(struct bfq_data *bfqd, -- struct bfq_queue *bfqq) --{ -- struct bfq_entity *entity; -- struct bfq_sched_data *sd; -- -- BUG_ON(bfqd->in_service_queue != NULL); -- -- entity = &bfqq->entity; -- /* -- * Bubble up extraction/update from the leaf to the root. -- */ -- for_each_entity(entity) { -- sd = entity->sched_data; -- bfq_update_budget(entity); -- bfq_update_vtime(bfq_entity_service_tree(entity)); -- bfq_active_extract(bfq_entity_service_tree(entity), entity); -- sd->in_service_entity = entity; -- sd->next_in_service = NULL; -- entity->service = 0; -- } -- -- return; --} -- - static void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd) - { - if (bfqd->in_service_bic != NULL) { -diff --git a/block/bfq.h b/block/bfq.h -index 3c5d85e..5ced336 100644 ---- a/block/bfq.h -+++ b/block/bfq.h -@@ -218,18 +218,21 @@ struct bfq_group; - * idle @bfq_queue with no outstanding requests, then - * the task associated with the queue it is deemed as - * soft real-time (see the comments to the function -- * bfq_bfqq_softrt_next_start()). -+ * bfq_bfqq_softrt_next_start()) - * @last_idle_bklogged: time of the last transition of the @bfq_queue from - * idle to backlogged - * @service_from_backlogged: cumulative service received from the @bfq_queue - * since the last transition from idle to - * backlogged -+ * @bic: pointer to the bfq_io_cq owning the bfq_queue, set to %NULL if the -+ * queue is shared - * -- * A bfq_queue is a leaf request queue; it can be associated with an io_context -- * or more, if it is async or shared between cooperating processes. @cgroup -- * holds a reference to the cgroup, to be sure that it does not disappear while -- * a bfqq still references it (mostly to avoid races between request issuing and -- * task migration followed by cgroup destruction). -+ * A bfq_queue is a leaf request queue; it can be associated with an -+ * io_context or more, if it is async or shared between cooperating -+ * processes. @cgroup holds a reference to the cgroup, to be sure that it -+ * does not disappear while a bfqq still references it (mostly to avoid -+ * races between request issuing and task migration followed by cgroup -+ * destruction). - * All the fields are protected by the queue lock of the containing bfqd. - */ - struct bfq_queue { -@@ -269,6 +272,7 @@ struct bfq_queue { - unsigned int requests_within_timer; - - pid_t pid; -+ struct bfq_io_cq *bic; - - /* weight-raising fields */ - unsigned long wr_cur_max_time; -@@ -298,12 +302,42 @@ struct bfq_ttime { - * @icq: associated io_cq structure - * @bfqq: array of two process queues, the sync and the async - * @ttime: associated @bfq_ttime struct -+ * @wr_time_left: snapshot of the time left before weight raising ends -+ * for the sync queue associated to this process; this -+ * snapshot is taken to remember this value while the weight -+ * raising is suspended because the queue is merged with a -+ * shared queue, and is used to set @raising_cur_max_time -+ * when the queue is split from the shared queue and its -+ * weight is raised again -+ * @saved_idle_window: same purpose as the previous field for the idle -+ * window -+ * @saved_IO_bound: same purpose as the previous two fields for the I/O -+ * bound classification of a queue -+ * @saved_in_large_burst: same purpose as the previous fields for the -+ * value of the field keeping the queue's belonging -+ * to a large burst -+ * @was_in_burst_list: true if the queue belonged to a burst list -+ * before its merge with another cooperating queue -+ * @cooperations: counter of consecutive successful queue merges underwent -+ * by any of the process' @bfq_queues -+ * @failed_cooperations: counter of consecutive failed queue merges of any -+ * of the process' @bfq_queues - */ - struct bfq_io_cq { - struct io_cq icq; /* must be the first member */ - struct bfq_queue *bfqq[2]; - struct bfq_ttime ttime; - int ioprio; -+ -+ unsigned int wr_time_left; -+ bool saved_idle_window; -+ bool saved_IO_bound; -+ -+ bool saved_in_large_burst; -+ bool was_in_burst_list; -+ -+ unsigned int cooperations; -+ unsigned int failed_cooperations; - }; - - enum bfq_device_speed { -@@ -539,7 +573,7 @@ enum bfqq_state_flags { - BFQ_BFQQ_FLAG_prio_changed, /* task priority has changed */ - BFQ_BFQQ_FLAG_sync, /* synchronous queue */ - BFQ_BFQQ_FLAG_budget_new, /* no completion with this budget */ -- BFQ_BFQQ_FLAG_IO_bound, /* -+ BFQ_BFQQ_FLAG_IO_bound, /* - * bfqq has timed-out at least once - * having consumed at most 2/10 of - * its budget -@@ -552,12 +586,13 @@ enum bfqq_state_flags { - * bfqq has proved to be slow and - * seeky until budget timeout - */ -- BFQ_BFQQ_FLAG_softrt_update, /* -+ BFQ_BFQQ_FLAG_softrt_update, /* - * may need softrt-next-start - * update - */ - BFQ_BFQQ_FLAG_coop, /* bfqq is shared */ -- BFQ_BFQQ_FLAG_split_coop, /* shared bfqq will be splitted */ -+ BFQ_BFQQ_FLAG_split_coop, /* shared bfqq will be split */ -+ BFQ_BFQQ_FLAG_just_split, /* queue has just been split */ - }; - - #define BFQ_BFQQ_FNS(name) \ -@@ -587,6 +622,7 @@ BFQ_BFQQ_FNS(in_large_burst); - BFQ_BFQQ_FNS(constantly_seeky); - BFQ_BFQQ_FNS(coop); - BFQ_BFQQ_FNS(split_coop); -+BFQ_BFQQ_FNS(just_split); - BFQ_BFQQ_FNS(softrt_update); - #undef BFQ_BFQQ_FNS - --- -2.3.0 - diff --git a/kernel/tools/perf/files/patches/gentoo/5010_enable-additional-cpu-optimizations-for-gcc-4.9.patch b/kernel/tools/perf/files/patches/gentoo/5010_enable-additional-cpu-optimizations-for-gcc-4.9.patch deleted file mode 100644 index f931f75f98..0000000000 --- a/kernel/tools/perf/files/patches/gentoo/5010_enable-additional-cpu-optimizations-for-gcc-4.9.patch +++ /dev/null @@ -1,387 +0,0 @@ -WARNING - this version of the patch works with version 4.9+ of gcc and with -kernel version 3.15.x+ and should NOT be applied when compiling on older -versions due to name changes of the flags with the 4.9 release of gcc. -Use the older version of this patch hosted on the same github for older -versions of gcc. For example: - -corei7 --> nehalem -corei7-avx --> sandybridge -core-avx-i --> ivybridge -core-avx2 --> haswell - -For more, see: https://gcc.gnu.org/gcc-4.9/changes.html - -It also changes 'atom' to 'bonnell' in accordance with the gcc v4.9 changes. -Note that upstream is using the deprecated 'match=atom' flags when I believe it -should use the newer 'march=bonnell' flag for atom processors. - -I have made that change to this patch set as well. See the following kernel -bug report to see if I'm right: https://bugzilla.kernel.org/show_bug.cgi?id=77461 - -This patch will expand the number of microarchitectures to include new -processors including: AMD K10-family, AMD Family 10h (Barcelona), AMD Family -14h (Bobcat), AMD Family 15h (Bulldozer), AMD Family 15h (Piledriver), AMD -Family 16h (Jaguar), Intel 1st Gen Core i3/i5/i7 (Nehalem), Intel 1.5 Gen Core -i3/i5/i7 (Westmere), Intel 2nd Gen Core i3/i5/i7 (Sandybridge), Intel 3rd Gen -Core i3/i5/i7 (Ivybridge), Intel 4th Gen Core i3/i5/i7 (Haswell), and Intel 5th -Gen Core i3/i5/i7 (Broadwell). It also offers the compiler the 'native' flag. - -Small but real speed increases are measurable using a make endpoint comparing -a generic kernel to one built with one of the respective microarchs. - -See the following experimental evidence supporting this statement: -https://github.com/graysky2/kernel_gcc_patch - -REQUIREMENTS -linux version >=3.15 -gcc version >=4.9 - ---- a/arch/x86/include/asm/module.h 2014-08-03 18:25:02.000000000 -0400 -+++ b/arch/x86/include/asm/module.h 2014-09-13 09:37:16.721385247 -0400 -@@ -15,6 +15,20 @@ - #define MODULE_PROC_FAMILY "586MMX " - #elif defined CONFIG_MCORE2 - #define MODULE_PROC_FAMILY "CORE2 " -+#elif defined CONFIG_MNATIVE -+#define MODULE_PROC_FAMILY "NATIVE " -+#elif defined CONFIG_MNEHALEM -+#define MODULE_PROC_FAMILY "NEHALEM " -+#elif defined CONFIG_MWESTMERE -+#define MODULE_PROC_FAMILY "WESTMERE " -+#elif defined CONFIG_MSANDYBRIDGE -+#define MODULE_PROC_FAMILY "SANDYBRIDGE " -+#elif defined CONFIG_MIVYBRIDGE -+#define MODULE_PROC_FAMILY "IVYBRIDGE " -+#elif defined CONFIG_MHASWELL -+#define MODULE_PROC_FAMILY "HASWELL " -+#elif defined CONFIG_MBROADWELL -+#define MODULE_PROC_FAMILY "BROADWELL " - #elif defined CONFIG_MATOM - #define MODULE_PROC_FAMILY "ATOM " - #elif defined CONFIG_M686 -@@ -33,6 +47,20 @@ - #define MODULE_PROC_FAMILY "K7 " - #elif defined CONFIG_MK8 - #define MODULE_PROC_FAMILY "K8 " -+#elif defined CONFIG_MK8SSE3 -+#define MODULE_PROC_FAMILY "K8SSE3 " -+#elif defined CONFIG_MK10 -+#define MODULE_PROC_FAMILY "K10 " -+#elif defined CONFIG_MBARCELONA -+#define MODULE_PROC_FAMILY "BARCELONA " -+#elif defined CONFIG_MBOBCAT -+#define MODULE_PROC_FAMILY "BOBCAT " -+#elif defined CONFIG_MBULLDOZER -+#define MODULE_PROC_FAMILY "BULLDOZER " -+#elif defined CONFIG_MPILEDRIVER -+#define MODULE_PROC_FAMILY "PILEDRIVER " -+#elif defined CONFIG_MJAGUAR -+#define MODULE_PROC_FAMILY "JAGUAR " - #elif defined CONFIG_MELAN - #define MODULE_PROC_FAMILY "ELAN " - #elif defined CONFIG_MCRUSOE ---- a/arch/x86/Kconfig.cpu 2014-08-03 18:25:02.000000000 -0400 -+++ b/arch/x86/Kconfig.cpu 2014-09-13 09:37:16.721385247 -0400 -@@ -137,9 +137,8 @@ config MPENTIUM4 - -Paxville - -Dempsey - -- - config MK6 -- bool "K6/K6-II/K6-III" -+ bool "AMD K6/K6-II/K6-III" - depends on X86_32 - ---help--- - Select this for an AMD K6-family processor. Enables use of -@@ -147,7 +146,7 @@ config MK6 - flags to GCC. - - config MK7 -- bool "Athlon/Duron/K7" -+ bool "AMD Athlon/Duron/K7" - depends on X86_32 - ---help--- - Select this for an AMD Athlon K7-family processor. Enables use of -@@ -155,12 +154,62 @@ config MK7 - flags to GCC. - - config MK8 -- bool "Opteron/Athlon64/Hammer/K8" -+ bool "AMD Opteron/Athlon64/Hammer/K8" - ---help--- - Select this for an AMD Opteron or Athlon64 Hammer-family processor. - Enables use of some extended instructions, and passes appropriate - optimization flags to GCC. - -+config MK8SSE3 -+ bool "AMD Opteron/Athlon64/Hammer/K8 with SSE3" -+ ---help--- -+ Select this for improved AMD Opteron or Athlon64 Hammer-family processors. -+ Enables use of some extended instructions, and passes appropriate -+ optimization flags to GCC. -+ -+config MK10 -+ bool "AMD 61xx/7x50/PhenomX3/X4/II/K10" -+ ---help--- -+ Select this for an AMD 61xx Eight-Core Magny-Cours, Athlon X2 7x50, -+ Phenom X3/X4/II, Athlon II X2/X3/X4, or Turion II-family processor. -+ Enables use of some extended instructions, and passes appropriate -+ optimization flags to GCC. -+ -+config MBARCELONA -+ bool "AMD Barcelona" -+ ---help--- -+ Select this for AMD Barcelona and newer processors. -+ -+ Enables -march=barcelona -+ -+config MBOBCAT -+ bool "AMD Bobcat" -+ ---help--- -+ Select this for AMD Bobcat processors. -+ -+ Enables -march=btver1 -+ -+config MBULLDOZER -+ bool "AMD Bulldozer" -+ ---help--- -+ Select this for AMD Bulldozer processors. -+ -+ Enables -march=bdver1 -+ -+config MPILEDRIVER -+ bool "AMD Piledriver" -+ ---help--- -+ Select this for AMD Piledriver processors. -+ -+ Enables -march=bdver2 -+ -+config MJAGUAR -+ bool "AMD Jaguar" -+ ---help--- -+ Select this for AMD Jaguar processors. -+ -+ Enables -march=btver2 -+ - config MCRUSOE - bool "Crusoe" - depends on X86_32 -@@ -251,8 +300,17 @@ config MPSC - using the cpu family field - in /proc/cpuinfo. Family 15 is an older Xeon, Family 6 a newer one. - -+config MATOM -+ bool "Intel Atom" -+ ---help--- -+ -+ Select this for the Intel Atom platform. Intel Atom CPUs have an -+ in-order pipelining architecture and thus can benefit from -+ accordingly optimized code. Use a recent GCC with specific Atom -+ support in order to fully benefit from selecting this option. -+ - config MCORE2 -- bool "Core 2/newer Xeon" -+ bool "Intel Core 2" - ---help--- - - Select this for Intel Core 2 and newer Core 2 Xeons (Xeon 51xx and -@@ -260,14 +318,55 @@ config MCORE2 - family in /proc/cpuinfo. Newer ones have 6 and older ones 15 - (not a typo) - --config MATOM -- bool "Intel Atom" -+ Enables -march=core2 -+ -+config MNEHALEM -+ bool "Intel Nehalem" - ---help--- - -- Select this for the Intel Atom platform. Intel Atom CPUs have an -- in-order pipelining architecture and thus can benefit from -- accordingly optimized code. Use a recent GCC with specific Atom -- support in order to fully benefit from selecting this option. -+ Select this for 1st Gen Core processors in the Nehalem family. -+ -+ Enables -march=nehalem -+ -+config MWESTMERE -+ bool "Intel Westmere" -+ ---help--- -+ -+ Select this for the Intel Westmere formerly Nehalem-C family. -+ -+ Enables -march=westmere -+ -+config MSANDYBRIDGE -+ bool "Intel Sandy Bridge" -+ ---help--- -+ -+ Select this for 2nd Gen Core processors in the Sandy Bridge family. -+ -+ Enables -march=sandybridge -+ -+config MIVYBRIDGE -+ bool "Intel Ivy Bridge" -+ ---help--- -+ -+ Select this for 3rd Gen Core processors in the Ivy Bridge family. -+ -+ Enables -march=ivybridge -+ -+config MHASWELL -+ bool "Intel Haswell" -+ ---help--- -+ -+ Select this for 4th Gen Core processors in the Haswell family. -+ -+ Enables -march=haswell -+ -+config MBROADWELL -+ bool "Intel Broadwell" -+ ---help--- -+ -+ Select this for 5th Gen Core processors in the Broadwell family. -+ -+ Enables -march=broadwell - - config GENERIC_CPU - bool "Generic-x86-64" -@@ -276,6 +375,19 @@ config GENERIC_CPU - Generic x86-64 CPU. - Run equally well on all x86-64 CPUs. - -+config MNATIVE -+ bool "Native optimizations autodetected by GCC" -+ ---help--- -+ -+ GCC 4.2 and above support -march=native, which automatically detects -+ the optimum settings to use based on your processor. -march=native -+ also detects and applies additional settings beyond -march specific -+ to your CPU, (eg. -msse4). Unless you have a specific reason not to -+ (e.g. distcc cross-compiling), you should probably be using -+ -march=native rather than anything listed below. -+ -+ Enables -march=native -+ - endchoice - - config X86_GENERIC -@@ -300,7 +412,7 @@ config X86_INTERNODE_CACHE_SHIFT - config X86_L1_CACHE_SHIFT - int - default "7" if MPENTIUM4 || MPSC -- default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || X86_GENERIC || GENERIC_CPU -+ default "6" if MK7 || MK8 || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MBULLDOZER || MPILEDRIVER || MJAGUAR || MPENTIUMM || MCORE2 || MNEHALEM || MWESTMERE || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || BROADWELL || MNATIVE || MATOM || MVIAC7 || X86_GENERIC || GENERIC_CPU - default "4" if MELAN || M486 || MGEODEGX1 - default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX - -@@ -331,11 +443,11 @@ config X86_ALIGNMENT_16 - - config X86_INTEL_USERCOPY - def_bool y -- depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON || MCORE2 -+ depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK8SSE3 || MK7 || MEFFICEON || MCORE2 || MK10 || MBARCELONA || MNEHALEM || MWESTMERE || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MNATIVE - - config X86_USE_PPRO_CHECKSUM - def_bool y -- depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MVIAC7 || MEFFICEON || MGEODE_LX || MCORE2 || MATOM -+ depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MK10 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MK8SSE3 || MVIAC3_2 || MVIAC7 || MEFFICEON || MGEODE_LX || MCORE2 || MNEHALEM || MWESTMERE || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MATOM || MNATIVE - - config X86_USE_3DNOW - def_bool y -@@ -359,17 +471,17 @@ config X86_P6_NOP - - config X86_TSC - def_bool y -- depends on (MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2 || MATOM) || X86_64 -+ depends on (MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MK8SSE3 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2 || MNEHALEM || MWESTMERE || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MNATIVE || MATOM) || X86_64 - - config X86_CMPXCHG64 - def_bool y -- depends on X86_PAE || X86_64 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MATOM -+ depends on X86_PAE || X86_64 || MCORE2 || MNEHALEM || MWESTMERE || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MATOM || MNATIVE - - # this should be set for all -march=.. options where the compiler - # generates cmov. - config X86_CMOV - def_bool y -- depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MATOM || MGEODE_LX) -+ depends on (MK8 || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MBULLDOZER || MPILEDRIVER || MJAGUAR || MK7 || MCORE2 || MNEHALEM || MWESTMERE || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MNATIVE || MATOM || MGEODE_LX) - - config X86_MINIMUM_CPU_FAMILY - int ---- a/arch/x86/Makefile 2014-08-03 18:25:02.000000000 -0400 -+++ b/arch/x86/Makefile 2014-09-13 09:37:16.721385247 -0400 -@@ -92,13 +92,33 @@ else - KBUILD_CFLAGS += $(call cc-option,-mpreferred-stack-boundary=3) - - # FIXME - should be integrated in Makefile.cpu (Makefile_32.cpu) -+ cflags-$(CONFIG_MNATIVE) += $(call cc-option,-march=native) - cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8) -+ cflags-$(CONFIG_MK8SSE3) += $(call cc-option,-march=k8-sse3,-mtune=k8) -+ cflags-$(CONFIG_MK10) += $(call cc-option,-march=amdfam10) -+ cflags-$(CONFIG_MBARCELONA) += $(call cc-option,-march=barcelona) -+ cflags-$(CONFIG_MBOBCAT) += $(call cc-option,-march=btver1) -+ cflags-$(CONFIG_MBULLDOZER) += $(call cc-option,-march=bdver1) -+ cflags-$(CONFIG_MPILEDRIVER) += $(call cc-option,-march=bdver2) -+ cflags-$(CONFIG_MJAGUAR) += $(call cc-option,-march=btver2) - cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona) - - cflags-$(CONFIG_MCORE2) += \ -- $(call cc-option,-march=core2,$(call cc-option,-mtune=generic)) -- cflags-$(CONFIG_MATOM) += $(call cc-option,-march=atom) \ -- $(call cc-option,-mtune=atom,$(call cc-option,-mtune=generic)) -+ $(call cc-option,-march=core2,$(call cc-option,-mtune=core2)) -+ cflags-$(CONFIG_MNEHALEM) += \ -+ $(call cc-option,-march=nehalem,$(call cc-option,-mtune=nehalem)) -+ cflags-$(CONFIG_MWESTMERE) += \ -+ $(call cc-option,-march=westmere,$(call cc-option,-mtune=westmere)) -+ cflags-$(CONFIG_MSANDYBRIDGE) += \ -+ $(call cc-option,-march=sandybridge,$(call cc-option,-mtune=sandybridge)) -+ cflags-$(CONFIG_MIVYBRIDGE) += \ -+ $(call cc-option,-march=ivybridge,$(call cc-option,-mtune=ivybridge)) -+ cflags-$(CONFIG_MHASWELL) += \ -+ $(call cc-option,-march=haswell,$(call cc-option,-mtune=haswell)) -+ cflags-$(CONFIG_MBROADWELL) += \ -+ $(call cc-option,-march=broadwell,$(call cc-option,-mtune=broadwell)) -+ cflags-$(CONFIG_MATOM) += $(call cc-option,-march=bonnell) \ -+ $(call cc-option,-mtune=bonnell,$(call cc-option,-mtune=generic)) - cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic) - KBUILD_CFLAGS += $(cflags-y) - ---- a/arch/x86/Makefile_32.cpu 2014-08-03 18:25:02.000000000 -0400 -+++ b/arch/x86/Makefile_32.cpu 2014-09-13 09:37:16.721385247 -0400 -@@ -23,7 +23,15 @@ cflags-$(CONFIG_MK6) += -march=k6 - # Please note, that patches that add -march=athlon-xp and friends are pointless. - # They make zero difference whatsosever to performance at this time. - cflags-$(CONFIG_MK7) += -march=athlon -+cflags-$(CONFIG_MNATIVE) += $(call cc-option,-march=native) - cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8,-march=athlon) -+cflags-$(CONFIG_MK8SSE3) += $(call cc-option,-march=k8-sse3,-march=athlon) -+cflags-$(CONFIG_MK10) += $(call cc-option,-march=amdfam10,-march=athlon) -+cflags-$(CONFIG_MBARCELONA) += $(call cc-option,-march=barcelona,-march=athlon) -+cflags-$(CONFIG_MBOBCAT) += $(call cc-option,-march=btver1,-march=athlon) -+cflags-$(CONFIG_MBULLDOZER) += $(call cc-option,-march=bdver1,-march=athlon) -+cflags-$(CONFIG_MPILEDRIVER) += $(call cc-option,-march=bdver2,-march=athlon) -+cflags-$(CONFIG_MJAGUAR) += $(call cc-option,-march=btver2,-march=athlon) - cflags-$(CONFIG_MCRUSOE) += -march=i686 $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0 - cflags-$(CONFIG_MEFFICEON) += -march=i686 $(call tune,pentium3) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0 - cflags-$(CONFIG_MWINCHIPC6) += $(call cc-option,-march=winchip-c6,-march=i586) -@@ -32,8 +40,14 @@ cflags-$(CONFIG_MCYRIXIII) += $(call cc- - cflags-$(CONFIG_MVIAC3_2) += $(call cc-option,-march=c3-2,-march=i686) - cflags-$(CONFIG_MVIAC7) += -march=i686 - cflags-$(CONFIG_MCORE2) += -march=i686 $(call tune,core2) --cflags-$(CONFIG_MATOM) += $(call cc-option,-march=atom,$(call cc-option,-march=core2,-march=i686)) \ -- $(call cc-option,-mtune=atom,$(call cc-option,-mtune=generic)) -+cflags-$(CONFIG_MNEHALEM) += -march=i686 $(call tune,nehalem) -+cflags-$(CONFIG_MWESTMERE) += -march=i686 $(call tune,westmere) -+cflags-$(CONFIG_MSANDYBRIDGE) += -march=i686 $(call tune,sandybridge) -+cflags-$(CONFIG_MIVYBRIDGE) += -march=i686 $(call tune,ivybridge) -+cflags-$(CONFIG_MHASWELL) += -march=i686 $(call tune,haswell) -+cflags-$(CONFIG_MBROADWELL) += -march=i686 $(call tune,broadwell) -+cflags-$(CONFIG_MATOM) += $(call cc-option,-march=bonnell,$(call cc-option,-march=core2,-march=i686)) \ -+ $(call cc-option,-mtune=bonnell,$(call cc-option,-mtune=generic)) - - # AMD Elan support - cflags-$(CONFIG_MELAN) += -march=i486 diff --git a/kernel/tools/perf/files/patches/linux/patch-5.10.15.xz b/kernel/tools/perf/files/patches/linux/patch-5.10.15.xz new file mode 100644 index 0000000000000000000000000000000000000000..42cda9d80206cef57bfc1c4addf747a20abaa615 GIT binary patch literal 486748 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
  • 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

    NVXRWv=&z;Y+WU3yzZedZsQWi%%MmWqbR&{r5 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⁣|ylP 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 literal 0 HcmV?d00001 diff --git a/kernel/tools/perf/files/patches/linux/patch-5.10.19.xz b/kernel/tools/perf/files/patches/linux/patch-5.10.19.xz new file mode 100644 index 0000000000000000000000000000000000000000..26b2fcba4b2bdb348aa5a14ebd3f1d5a1abd55db GIT binary patch literal 535612 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 z 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 z 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%0A!sThUeK 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 $=%fg*Za60 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 PvBYQl0ssI200dcD);I*6 diff --git a/kernel/tools/perf/files/patches/linux/patch-5.9.13.xz b/kernel/tools/perf/files/patches/linux/patch-5.9.13.xz deleted file mode 100644 index 42620bdaafbc364c1402b9a65a6897869d038cad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 621916 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�^{l}VIJS3Fd&`%H$`4RyQaHbRSyiAd|MON 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

  • @eDl(Y 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

    %F8#%05$4MKU7xOfR;oFW?N?}&Fo_EASZ#{b! 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 diff --git a/kernel/tools/perf/files/patches/mageia/3rd-fix-kconfig.patch b/kernel/tools/perf/files/patches/mageia/3rd-fix-kconfig.patch index a513aa07d3..6d1a440604 100644 --- a/kernel/tools/perf/files/patches/mageia/3rd-fix-kconfig.patch +++ b/kernel/tools/perf/files/patches/mageia/3rd-fix-kconfig.patch @@ -42,4 +42,4 @@ diff -up ./3rdparty/viahss/Kconfig.tv ./3rdparty/viahss/Kconfig + help VIA High Speed Serial is a little kernel module (1 KB) which enables high speed serial port modes of VIA VT82C686A or VT82C686B - southbridge-equipped motherboards. With this module, you can use the \ No newline at end of file + southbridge-equipped motherboards. With this module, you can use the diff --git a/kernel/tools/perf/files/patches/mageia/3rd-rtl8821ce-kernel-5.10.patch b/kernel/tools/perf/files/patches/mageia/3rd-rtl8821ce-kernel-5.10.patch new file mode 100644 index 0000000000..080058400c --- /dev/null +++ b/kernel/tools/perf/files/patches/mageia/3rd-rtl8821ce-kernel-5.10.patch @@ -0,0 +1,162 @@ +diff -urp linux-5.10/3rdparty/rtl8821ce.orig/core/rtw_btcoex.c linux-5.10/3rdparty/rtl8821ce/core/rtw_btcoex.c +--- linux-5.10/3rdparty/rtl8821ce.orig/core/rtw_btcoex.c 2021-01-19 22:18:00.924067581 +0200 ++++ linux-5.10/3rdparty/rtl8821ce/core/rtw_btcoex.c 2021-01-19 22:22:20.057518961 +0200 +@@ -1474,15 +1474,20 @@ u8 rtw_btcoex_sendmsgbysocket(_adapter * + udpmsg.msg_control = NULL; + udpmsg.msg_controllen = 0; + udpmsg.msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL; ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) + oldfs = get_fs(); + set_fs(KERNEL_DS); ++#endif + + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) + error = sock_sendmsg(pcoex_info->udpsock, &udpmsg); + #else + error = sock_sendmsg(pcoex_info->udpsock, &udpmsg, msg_size); + #endif ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) + set_fs(oldfs); ++#endif + if (error < 0) { + RTW_INFO("Error when sendimg msg, error:%d\n", error); + return _FAIL; +diff -urp linux-5.10/3rdparty/rtl8821ce.orig/core/rtw_wlan_util.c linux-5.10/3rdparty/rtl8821ce/core/rtw_wlan_util.c +--- linux-5.10/3rdparty/rtl8821ce.orig/core/rtw_wlan_util.c 2021-01-19 22:18:00.937068206 +0200 ++++ linux-5.10/3rdparty/rtl8821ce/core/rtw_wlan_util.c 2021-01-19 22:22:20.067519442 +0200 +@@ -4751,8 +4751,10 @@ int rtw_dev_nlo_info_set(struct pno_nlo_ + return 0; + } + ++#if (LINUX_VERSION_CODE <= KERNEL_VERSION(5, 10, 0)) + fs = get_fs(); + set_fs(KERNEL_DS); ++#endif + + source = rtw_zmalloc(2048); + +@@ -4762,7 +4764,9 @@ int rtw_dev_nlo_info_set(struct pno_nlo_ + rtw_mfree(source, 2048); + } + ++#if (LINUX_VERSION_CODE <= KERNEL_VERSION(5, 10, 0)) + set_fs(fs); ++#endif + filp_close(fp, NULL); + + RTW_INFO("-%s-\n", __func__); +diff -urp linux-5.10/3rdparty/rtl8821ce.orig/os_dep/linux/os_intfs.c linux-5.10/3rdparty/rtl8821ce/os_dep/linux/os_intfs.c +--- linux-5.10/3rdparty/rtl8821ce.orig/os_dep/linux/os_intfs.c 2021-01-19 22:18:01.078074981 +0200 ++++ linux-5.10/3rdparty/rtl8821ce/os_dep/linux/os_intfs.c 2021-01-19 22:22:20.068519490 +0200 +@@ -4008,14 +4008,18 @@ static int route_dump(u32 *gw_addr , int + msg.msg_controllen = 0; + msg.msg_flags = MSG_DONTWAIT; + ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) + oldfs = get_fs(); + set_fs(KERNEL_DS); ++#endif + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) + err = sock_sendmsg(sock, &msg); + #else + err = sock_sendmsg(sock, &msg, sizeof(req)); + #endif ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) + set_fs(oldfs); ++#endif + + if (err < 0) + goto out_sock; +@@ -4040,14 +4044,18 @@ restart: + iov_iter_init(&msg.msg_iter, READ, &iov, 1, PAGE_SIZE); + #endif + ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) + oldfs = get_fs(); + set_fs(KERNEL_DS); ++#endif + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)) + err = sock_recvmsg(sock, &msg, MSG_DONTWAIT); + #else + err = sock_recvmsg(sock, &msg, PAGE_SIZE, MSG_DONTWAIT); + #endif ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) + set_fs(oldfs); ++#endif + + if (err < 0) + goto out_sock_pg; +@@ -4118,14 +4126,18 @@ done: + msg.msg_controllen = 0; + msg.msg_flags = MSG_DONTWAIT; + ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) + oldfs = get_fs(); + set_fs(KERNEL_DS); ++#endif + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) + err = sock_sendmsg(sock, &msg); + #else + err = sock_sendmsg(sock, &msg, sizeof(req)); + #endif ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) + set_fs(oldfs); ++#endif + + if (err > 0) + goto restart; +diff -urp linux-5.10/3rdparty/rtl8821ce.orig/os_dep/osdep_service.c linux-5.10/3rdparty/rtl8821ce/os_dep/osdep_service.c +--- linux-5.10/3rdparty/rtl8821ce.orig/os_dep/osdep_service.c 2021-01-19 22:18:01.081075125 +0200 ++++ linux-5.10/3rdparty/rtl8821ce/os_dep/osdep_service.c 2021-01-19 22:22:20.068519490 +0200 +@@ -2200,8 +2200,10 @@ static int isFileReadable(const char *pa + if (IS_ERR(fp)) + ret = PTR_ERR(fp); + else { ++ #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) + oldfs = get_fs(); + set_fs(KERNEL_DS); ++ #endif + + if (1 != readFile(fp, &buf, 1)) + ret = PTR_ERR(fp); +@@ -2214,7 +2216,9 @@ static int isFileReadable(const char *pa + #endif + } + ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) + set_fs(oldfs); ++#endif + filp_close(fp, NULL); + } + return ret; +@@ -2238,10 +2242,14 @@ static int retriveFromFile(const char *p + if (0 == ret) { + RTW_INFO("%s openFile path:%s fp=%p\n", __FUNCTION__, path , fp); + ++ #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) + oldfs = get_fs(); + set_fs(KERNEL_DS); ++ #endif + ret = readFile(fp, buf, sz); ++ #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) + set_fs(oldfs); ++ #endif + closeFile(fp); + + RTW_INFO("%s readFile, ret:%d\n", __FUNCTION__, ret); +@@ -2273,10 +2281,14 @@ static int storeToFile(const char *path, + if (0 == ret) { + RTW_INFO("%s openFile path:%s fp=%p\n", __FUNCTION__, path , fp); + ++ #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) + oldfs = get_fs(); + set_fs(KERNEL_DS); ++ #endif + ret = writeFile(fp, buf, sz); ++ #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) + set_fs(oldfs); ++ #endif + closeFile(fp); + + RTW_INFO("%s writeFile, ret:%d\n", __FUNCTION__, ret); diff --git a/kernel/tools/perf/files/patches/mageia/fs-aufs-5.6-fix.patch b/kernel/tools/perf/files/patches/mageia/fs-aufs-5.6-fix.patch deleted file mode 100644 index 9fe6102ac3..0000000000 --- a/kernel/tools/perf/files/patches/mageia/fs-aufs-5.6-fix.patch +++ /dev/null @@ -1,39 +0,0 @@ -diff -Nurp linux-5.6.3-aufs/fs/aufs/procfs.c linux-5.6.3-aufs-fix/fs/aufs/procfs.c ---- linux-5.6.3-aufs/fs/aufs/procfs.c 2020-04-10 12:40:52.192049502 +0300 -+++ linux-5.6.3-aufs-fix/fs/aufs/procfs.c 2020-04-10 17:46:50.019444421 +0300 -@@ -116,10 +116,9 @@ out: - return err; - } - --static const struct file_operations au_procfs_plm_fop = { -- .write = au_procfs_plm_write, -- .release = au_procfs_plm_release, -- .owner = THIS_MODULE -+static const struct proc_ops au_procfs_plm_op = { -+ .proc_write = au_procfs_plm_write, -+ .proc_release = au_procfs_plm_release - }; - - /* ---------------------------------------------------------------------- */ -@@ -143,7 +142,7 @@ int __init au_procfs_init(void) - goto out; - - entry = proc_create(AUFS_PLINK_MAINT_NAME, S_IFREG | 0200, -- au_procfs_dir, &au_procfs_plm_fop); -+ au_procfs_dir, &au_procfs_plm_op); - if (unlikely(!entry)) - goto out_dir; - -diff -Nurp linux-5.6.3-aufs/fs/aufs/xino.c linux-5.6.3-aufs-fix/fs/aufs/xino.c ---- linux-5.6.3-aufs/fs/aufs/xino.c 2020-04-10 12:40:52.193049549 +0300 -+++ linux-5.6.3-aufs-fix/fs/aufs/xino.c 2020-04-10 17:46:25.165284147 +0300 -@@ -1344,7 +1344,8 @@ static void au_xino_release(struct kref - hlist_bl_lock(hbl); - hlist_bl_for_each_entry_safe(p, pos, n, hbl, node) { - hlist_bl_del(&p->node); -- au_kfree_rcu(p); -+ /* kmemleak reported au_kfree_rcu() doesn't free it */ -+ kfree(p); - } - hlist_bl_unlock(hbl); - } diff --git a/kernel/tools/perf/files/patches/mageia/fs-aufs-5.6-modular.patch b/kernel/tools/perf/files/patches/mageia/fs-aufs-5.6-modular.patch deleted file mode 100644 index ad296b9ac4..0000000000 --- a/kernel/tools/perf/files/patches/mageia/fs-aufs-5.6-modular.patch +++ /dev/null @@ -1,312 +0,0 @@ - - fs/aufs/Kconfig | 2 +- - fs/dcache.c | 2 ++ - fs/exec.c | 1 + - fs/fcntl.c | 1 + - fs/file_table.c | 2 ++ - fs/inode.c | 1 + - fs/namespace.c | 3 +++ - fs/notify/group.c | 1 + - fs/open.c | 1 + - fs/read_write.c | 4 ++++ - fs/splice.c | 2 ++ - fs/sync.c | 1 + - fs/xattr.c | 1 + - kernel/locking/lockdep.c | 1 + - kernel/task_work.c | 1 + - security/security.c | 8 ++++++++ - 16 files changed, 31 insertions(+), 1 deletion(-) - -diff -Nurp linux-5.6.3-aufs/fs/aufs/Kconfig linux-5.6.3-aufs-mod/fs/aufs/Kconfig ---- linux-5.6.3-aufs/fs/aufs/Kconfig 2020-04-10 12:40:52.187049268 +0300 -+++ linux-5.6.3-aufs-mod/fs/aufs/Kconfig 2020-04-10 13:15:44.979742386 +0300 -@@ -1,6 +1,6 @@ - # SPDX-License-Identifier: GPL-2.0 - config AUFS_FS -- bool "Aufs (Advanced multi layered unification filesystem) support" -+ 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 -diff -Nurp linux-5.6.3-aufs/fs/dcache.c linux-5.6.3-aufs-mod/fs/dcache.c ---- linux-5.6.3-aufs/fs/dcache.c 2020-04-10 12:40:52.194049596 +0300 -+++ linux-5.6.3-aufs-mod/fs/dcache.c 2020-04-10 13:15:44.979742386 +0300 -@@ -1371,6 +1371,7 @@ rename_retry: - seq = 1; - goto again; - } -+EXPORT_SYMBOL_GPL(d_walk); - - struct check_mount { - struct vfsmount *mnt; -@@ -2916,6 +2917,7 @@ void d_exchange(struct dentry *dentry1, - - write_sequnlock(&rename_lock); - } -+EXPORT_SYMBOL_GPL(d_exchange); - - /** - * d_ancestor - search for an ancestor -diff -Nurp linux-5.6.3-aufs/fs/exec.c linux-5.6.3-aufs-mod/fs/exec.c ---- linux-5.6.3-aufs/fs/exec.c 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs-mod/fs/exec.c 2020-04-10 13:15:44.979742386 +0300 -@@ -109,6 +109,7 @@ bool path_noexec(const struct path *path - return (path->mnt->mnt_flags & MNT_NOEXEC) || - (path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC); - } -+EXPORT_SYMBOL_GPL(path_noexec); - - #ifdef CONFIG_USELIB - /* -diff -Nurp linux-5.6.3-aufs/fs/fcntl.c linux-5.6.3-aufs-mod/fs/fcntl.c ---- linux-5.6.3-aufs/fs/fcntl.c 2020-04-10 12:40:52.194049596 +0300 -+++ linux-5.6.3-aufs-mod/fs/fcntl.c 2020-04-10 13:15:44.979742386 +0300 -@@ -85,6 +85,7 @@ int setfl(int fd, struct file *filp, uns - out: - return error; - } -+EXPORT_SYMBOL_GPL(setfl); - - static void f_modown(struct file *filp, struct pid *pid, enum pid_type type, - int force) -diff -Nurp linux-5.6.3-aufs/fs/file_table.c linux-5.6.3-aufs-mod/fs/file_table.c ---- linux-5.6.3-aufs/fs/file_table.c 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs-mod/fs/file_table.c 2020-04-10 13:15:44.979742386 +0300 -@@ -162,6 +162,7 @@ over: - } - return ERR_PTR(-ENFILE); - } -+EXPORT_SYMBOL_GPL(alloc_empty_file); - - /* - * Variant of alloc_empty_file() that doesn't check and modify nr_files. -@@ -375,6 +376,7 @@ void __fput_sync(struct file *file) - } - - EXPORT_SYMBOL(fput); -+EXPORT_SYMBOL_GPL(__fput_sync); - - void __init files_init(void) - { -diff -Nurp linux-5.6.3-aufs/fs/inode.c linux-5.6.3-aufs-mod/fs/inode.c ---- linux-5.6.3-aufs/fs/inode.c 2020-04-10 12:40:52.194049596 +0300 -+++ linux-5.6.3-aufs-mod/fs/inode.c 2020-04-10 13:15:44.980742432 +0300 -@@ -1694,6 +1694,7 @@ int update_time(struct inode *inode, str - return inode->i_op->update_time(inode, time, flags); - return generic_update_time(inode, time, flags); - } -+EXPORT_SYMBOL_GPL(update_time); - - /** - * touch_atime - update the access time -diff -Nurp linux-5.6.3-aufs/fs/namespace.c linux-5.6.3-aufs-mod/fs/namespace.c ---- linux-5.6.3-aufs/fs/namespace.c 2020-04-10 12:40:52.194049596 +0300 -+++ linux-5.6.3-aufs-mod/fs/namespace.c 2020-04-10 13:15:44.980742432 +0300 -@@ -431,6 +431,7 @@ void __mnt_drop_write(struct vfsmount *m - mnt_dec_writers(real_mount(mnt)); - preempt_enable(); - } -+EXPORT_SYMBOL_GPL(__mnt_drop_write); - - /** - * mnt_drop_write - give up write access to a mount -@@ -781,6 +782,7 @@ int is_current_mnt_ns(struct vfsmount *m - { - return check_mnt(real_mount(mnt)); - } -+EXPORT_SYMBOL_GPL(is_current_mnt_ns); - - /* - * vfsmount lock must be held for write -@@ -1903,6 +1905,7 @@ int iterate_mounts(int (*f)(struct vfsmo - } - return 0; - } -+EXPORT_SYMBOL_GPL(iterate_mounts); - - static void lock_mnt_tree(struct mount *mnt) - { -diff -Nurp linux-5.6.3-aufs/fs/notify/group.c linux-5.6.3-aufs-mod/fs/notify/group.c ---- linux-5.6.3-aufs/fs/notify/group.c 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs-mod/fs/notify/group.c 2020-04-10 13:15:44.980742432 +0300 -@@ -99,6 +99,7 @@ void fsnotify_get_group(struct fsnotify_ - { - refcount_inc(&group->refcnt); - } -+EXPORT_SYMBOL_GPL(fsnotify_get_group); - - /* - * Drop a reference to a group. Free it if it's through. -diff -Nurp linux-5.6.3-aufs/fs/open.c linux-5.6.3-aufs-mod/fs/open.c ---- linux-5.6.3-aufs/fs/open.c 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs-mod/fs/open.c 2020-04-10 13:15:44.980742432 +0300 -@@ -65,6 +65,7 @@ int do_truncate(struct dentry *dentry, l - inode_unlock(dentry->d_inode); - return ret; - } -+EXPORT_SYMBOL_GPL(do_truncate); - - long vfs_truncate(const struct path *path, loff_t length) - { -diff -Nurp linux-5.6.3-aufs/fs/read_write.c linux-5.6.3-aufs-mod/fs/read_write.c ---- linux-5.6.3-aufs/fs/read_write.c 2020-04-10 12:40:52.194049596 +0300 -+++ linux-5.6.3-aufs-mod/fs/read_write.c 2020-04-10 13:15:44.981742479 +0300 -@@ -468,6 +468,7 @@ ssize_t vfs_read(struct file *file, char - - return ret; - } -+EXPORT_SYMBOL_GPL(vfs_read); - - static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) - { -@@ -508,6 +509,7 @@ vfs_readf_t vfs_readf(struct file *file) - return new_sync_read; - return ERR_PTR(-ENOSYS); /* doesn't have ->read(|_iter)() op */ - } -+EXPORT_SYMBOL_GPL(vfs_readf); - - vfs_writef_t vfs_writef(struct file *file) - { -@@ -519,6 +521,7 @@ vfs_writef_t vfs_writef(struct file *fil - return new_sync_write; - return ERR_PTR(-ENOSYS); /* doesn't have ->write(|_iter)() op */ - } -+EXPORT_SYMBOL_GPL(vfs_writef); - - ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos) - { -@@ -588,6 +591,7 @@ ssize_t vfs_write(struct file *file, con - - return ret; - } -+EXPORT_SYMBOL_GPL(vfs_write); - - /* file_ppos returns &file->f_pos or NULL if file is stream */ - static inline loff_t *file_ppos(struct file *file) -diff -Nurp linux-5.6.3-aufs/fs/splice.c linux-5.6.3-aufs-mod/fs/splice.c ---- linux-5.6.3-aufs/fs/splice.c 2020-04-10 12:40:52.194049596 +0300 -+++ linux-5.6.3-aufs-mod/fs/splice.c 2020-04-10 13:15:44.981742479 +0300 -@@ -862,6 +862,7 @@ long do_splice_from(struct pipe_inode_in - - return splice_write(pipe, out, ppos, len, flags); - } -+EXPORT_SYMBOL_GPL(do_splice_from); - - /* - * Attempt to initiate a splice from a file to a pipe. -@@ -891,6 +892,7 @@ long do_splice_to(struct file *in, loff_ - - return splice_read(in, ppos, pipe, len, flags); - } -+EXPORT_SYMBOL_GPL(do_splice_to); - - /** - * splice_direct_to_actor - splices data directly between two non-pipes -diff -Nurp linux-5.6.3-aufs/fs/sync.c linux-5.6.3-aufs-mod/fs/sync.c ---- linux-5.6.3-aufs/fs/sync.c 2020-04-10 12:40:52.194049596 +0300 -+++ linux-5.6.3-aufs-mod/fs/sync.c 2020-04-10 13:15:44.981742479 +0300 -@@ -39,6 +39,7 @@ int __sync_filesystem(struct super_block - sb->s_op->sync_fs(sb, wait); - return __sync_blockdev(sb->s_bdev, wait); - } -+EXPORT_SYMBOL_GPL(__sync_filesystem); - - /* - * Write out and wait upon all dirty data associated with this -diff -Nurp linux-5.6.3-aufs/fs/xattr.c linux-5.6.3-aufs-mod/fs/xattr.c ---- linux-5.6.3-aufs/fs/xattr.c 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs-mod/fs/xattr.c 2020-04-10 13:15:44.981742479 +0300 -@@ -296,6 +296,7 @@ vfs_getxattr_alloc(struct dentry *dentry - *xattr_value = value; - return error; - } -+EXPORT_SYMBOL_GPL(vfs_getxattr_alloc); - - ssize_t - __vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name, -diff -Nurp linux-5.6.3-aufs/kernel/locking/lockdep.c linux-5.6.3-aufs-mod/kernel/locking/lockdep.c ---- linux-5.6.3-aufs/kernel/locking/lockdep.c 2020-04-10 12:40:52.195049643 +0300 -+++ linux-5.6.3-aufs-mod/kernel/locking/lockdep.c 2020-04-10 13:15:44.982742525 +0300 -@@ -174,6 +174,7 @@ inline struct lock_class *lockdep_hlock_ - */ - return lock_classes + class_idx; - } -+EXPORT_SYMBOL_GPL(lockdep_hlock_class); - #define hlock_class(hlock) lockdep_hlock_class(hlock) - - #ifdef CONFIG_LOCK_STAT -diff -Nurp linux-5.6.3-aufs/kernel/task_work.c linux-5.6.3-aufs-mod/kernel/task_work.c ---- linux-5.6.3-aufs/kernel/task_work.c 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs-mod/kernel/task_work.c 2020-04-10 13:15:44.982742525 +0300 -@@ -116,3 +116,4 @@ void task_work_run(void) - } while (work); - } - } -+EXPORT_SYMBOL_GPL(task_work_run); -diff -Nurp linux-5.6.3-aufs/security/security.c linux-5.6.3-aufs-mod/security/security.c ---- linux-5.6.3-aufs/security/security.c 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs-mod/security/security.c 2020-04-10 13:15:44.982742525 +0300 -@@ -1068,6 +1068,7 @@ int security_path_rmdir(const struct pat - return 0; - return call_int_hook(path_rmdir, 0, dir, dentry); - } -+EXPORT_SYMBOL_GPL(security_path_rmdir); - - int security_path_unlink(const struct path *dir, struct dentry *dentry) - { -@@ -1084,6 +1085,7 @@ int security_path_symlink(const struct p - return 0; - return call_int_hook(path_symlink, 0, dir, dentry, old_name); - } -+EXPORT_SYMBOL_GPL(security_path_symlink); - - int security_path_link(struct dentry *old_dentry, const struct path *new_dir, - struct dentry *new_dentry) -@@ -1092,6 +1094,7 @@ int security_path_link(struct dentry *ol - return 0; - return call_int_hook(path_link, 0, old_dentry, new_dir, new_dentry); - } -+EXPORT_SYMBOL_GPL(security_path_link); - - int security_path_rename(const struct path *old_dir, struct dentry *old_dentry, - const struct path *new_dir, struct dentry *new_dentry, -@@ -1119,6 +1122,7 @@ int security_path_truncate(const struct - return 0; - return call_int_hook(path_truncate, 0, path); - } -+EXPORT_SYMBOL_GPL(security_path_truncate); - - int security_path_chmod(const struct path *path, umode_t mode) - { -@@ -1126,6 +1130,7 @@ int security_path_chmod(const struct pat - return 0; - return call_int_hook(path_chmod, 0, path, mode); - } -+EXPORT_SYMBOL_GPL(security_path_chmod); - - int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid) - { -@@ -1133,6 +1138,7 @@ int security_path_chown(const struct pat - return 0; - return call_int_hook(path_chown, 0, path, uid, gid); - } -+EXPORT_SYMBOL_GPL(security_path_chown); - - int security_path_chroot(const struct path *path) - { -@@ -1233,6 +1239,7 @@ int security_inode_permission(struct ino - return 0; - return call_int_hook(inode_permission, 0, inode, mask); - } -+EXPORT_SYMBOL_GPL(security_inode_permission); - - int security_inode_setattr(struct dentry *dentry, struct iattr *attr) - { -@@ -1410,6 +1417,7 @@ int security_file_permission(struct file - - return fsnotify_perm(file, mask); - } -+EXPORT_SYMBOL_GPL(security_file_permission); - - int security_file_alloc(struct file *file) - { diff --git a/kernel/tools/perf/files/patches/mageia/fs-aufs-5.6.patch b/kernel/tools/perf/files/patches/mageia/fs-aufs-5.6.patch deleted file mode 100644 index 52c8cfbb71..0000000000 --- a/kernel/tools/perf/files/patches/mageia/fs-aufs-5.6.patch +++ /dev/null @@ -1,37834 +0,0 @@ - - Documentation/ABI/testing/debugfs-aufs | 55 - Documentation/ABI/testing/sysfs-aufs | 31 - Documentation/filesystems/aufs/README | 401 +++ - Documentation/filesystems/aufs/design/01intro.txt | 158 + - Documentation/filesystems/aufs/design/02struct.txt | 245 ++ - Documentation/filesystems/aufs/design/03atomic_open.txt | 72 - Documentation/filesystems/aufs/design/03lookup.txt | 100 - Documentation/filesystems/aufs/design/04branch.txt | 61 - Documentation/filesystems/aufs/design/05wbr_policy.txt | 51 - Documentation/filesystems/aufs/design/06dirren.dot | 31 - Documentation/filesystems/aufs/design/06dirren.txt | 89 - Documentation/filesystems/aufs/design/06fhsm.txt | 105 - Documentation/filesystems/aufs/design/06mmap.txt | 59 - Documentation/filesystems/aufs/design/06xattr.txt | 81 - Documentation/filesystems/aufs/design/07export.txt | 45 - Documentation/filesystems/aufs/design/08shwh.txt | 39 - Documentation/filesystems/aufs/design/10dynop.txt | 34 - MAINTAINERS | 13 - drivers/block/loop.c | 18 - fs/Kconfig | 1 - fs/Makefile | 1 - fs/aufs/Kconfig | 199 + - fs/aufs/Makefile | 39 - fs/aufs/aufs.h | 49 - fs/aufs/branch.c | 1415 +++++++++++ - fs/aufs/branch.h | 353 ++ - fs/aufs/cpup.c | 1445 +++++++++++ - fs/aufs/cpup.h | 87 - fs/aufs/dbgaufs.c | 513 ++++ - fs/aufs/dbgaufs.h | 40 - fs/aufs/dcsub.c | 212 + - fs/aufs/dcsub.h | 124 + - fs/aufs/debug.c | 428 +++ - fs/aufs/debug.h | 213 + - fs/aufs/dentry.c | 1141 +++++++++ - fs/aufs/dentry.h | 255 ++ - fs/aufs/dinfo.c | 541 ++++ - fs/aufs/dir.c | 750 ++++++ - fs/aufs/dir.h | 121 - fs/aufs/dirren.c | 1303 ++++++++++ - fs/aufs/dirren.h | 127 + - fs/aufs/dynop.c | 354 ++ - fs/aufs/dynop.h | 64 - fs/aufs/export.c | 825 ++++++ - fs/aufs/f_op.c | 806 ++++++ - fs/aufs/fhsm.c | 413 +++ - fs/aufs/file.c | 850 ++++++ - fs/aufs/file.h | 329 ++ - fs/aufs/finfo.c | 136 + - fs/aufs/fstype.h | 388 +++ - fs/aufs/hbl.h | 52 - fs/aufs/hfsnotify.c | 275 ++ - fs/aufs/hfsplus.c | 47 - fs/aufs/hnotify.c | 702 +++++ - fs/aufs/i_op.c | 1485 ++++++++++++ - fs/aufs/i_op_add.c | 923 +++++++ - fs/aufs/i_op_del.c | 500 ++++ - fs/aufs/i_op_ren.c | 1237 ++++++++++ - fs/aufs/iinfo.c | 273 ++ - fs/aufs/inode.c | 516 ++++ - fs/aufs/inode.h | 685 +++++ - fs/aufs/ioctl.c | 207 + - fs/aufs/lcnt.h | 173 + - fs/aufs/loop.c | 135 + - fs/aufs/loop.h | 42 - fs/aufs/magic.mk | 31 - fs/aufs/module.c | 259 ++ - fs/aufs/module.h | 153 + - fs/aufs/mvdown.c | 693 +++++ - fs/aufs/opts.c | 1867 +++++++++++++++ - fs/aufs/opts.h | 212 + - fs/aufs/plink.c | 503 ++++ - fs/aufs/poll.c | 38 - fs/aufs/posix_acl.c | 92 - fs/aufs/procfs.c | 158 + - fs/aufs/rdu.c | 371 +++ - fs/aufs/rwsem.h | 60 - fs/aufs/sbinfo.c | 301 ++ - fs/aufs/super.c | 1034 ++++++++ - fs/aufs/super.h | 576 ++++ - fs/aufs/sysaufs.c | 80 - fs/aufs/sysaufs.h | 89 - fs/aufs/sysfs.c | 338 ++ - fs/aufs/sysrq.c | 136 + - fs/aufs/vdir.c | 883 +++++++ - fs/aufs/vfsub.c | 889 +++++++ - fs/aufs/vfsub.h | 341 ++ - fs/aufs/wbr_policy.c | 817 ++++++ - fs/aufs/whout.c | 1049 ++++++++ - fs/aufs/whout.h | 73 - fs/aufs/wkq.c | 359 ++ - fs/aufs/wkq.h | 76 - fs/aufs/xattr.c | 343 ++ - fs/aufs/xino.c | 1952 ++++++++++++++++ - fs/dcache.c | 2 - fs/fcntl.c | 4 - fs/inode.c | 2 - fs/namespace.c | 6 - fs/proc/base.c | 2 - fs/proc/nommu.c | 5 - fs/proc/task_mmu.c | 7 - fs/proc/task_nommu.c | 5 - fs/read_write.c | 22 - fs/splice.c | 10 - fs/sync.c | 2 - include/linux/fs.h | 10 - include/linux/lockdep.h | 3 - include/linux/mm.h | 22 - include/linux/mm_types.h | 2 - include/linux/mnt_namespace.h | 3 - include/linux/splice.h | 6 - include/uapi/linux/aufs_type.h | 439 +++ - kernel/fork.c | 2 - kernel/locking/lockdep.c | 3 - mm/Makefile | 2 - mm/filemap.c | 2 - mm/mmap.c | 33 - mm/nommu.c | 10 - mm/prfile.c | 86 - 119 files changed, 36894 insertions(+), 31 deletions(-) - -diff -Nurp linux-5.6.3/Documentation/ABI/testing/debugfs-aufs linux-5.6.3-aufs/Documentation/ABI/testing/debugfs-aufs ---- linux-5.6.3/Documentation/ABI/testing/debugfs-aufs 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/Documentation/ABI/testing/debugfs-aufs 2020-04-10 12:40:52.184049128 +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_/xi0, xi1 ... xiN and xiN-N -+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 -Nurp linux-5.6.3/Documentation/ABI/testing/sysfs-aufs linux-5.6.3-aufs/Documentation/ABI/testing/sysfs-aufs ---- linux-5.6.3/Documentation/ABI/testing/sysfs-aufs 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/Documentation/ABI/testing/sysfs-aufs 2020-04-10 12:40:52.184049128 +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_/br0, br1 ... brN -+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_/brid0, brid1 ... bridN -+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 -Nurp linux-5.6.3/Documentation/filesystems/aufs/design/01intro.txt linux-5.6.3-aufs/Documentation/filesystems/aufs/design/01intro.txt ---- linux-5.6.3/Documentation/filesystems/aufs/design/01intro.txt 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/Documentation/filesystems/aufs/design/01intro.txt 2020-04-10 12:40:52.184049128 +0300 -@@ -0,0 +1,158 @@ -+ -+# Copyright (C) 2005-2020 Junjiro R. Okajima -+ -+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 -Nurp linux-5.6.3/Documentation/filesystems/aufs/design/02struct.txt linux-5.6.3-aufs/Documentation/filesystems/aufs/design/02struct.txt ---- linux-5.6.3/Documentation/filesystems/aufs/design/02struct.txt 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/Documentation/filesystems/aufs/design/02struct.txt 2020-04-10 12:40:52.184049128 +0300 -@@ -0,0 +1,245 @@ -+ -+# Copyright (C) 2005-2020 Junjiro R. Okajima -+ -+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 -Nurp linux-5.6.3/Documentation/filesystems/aufs/design/03atomic_open.txt linux-5.6.3-aufs/Documentation/filesystems/aufs/design/03atomic_open.txt ---- linux-5.6.3/Documentation/filesystems/aufs/design/03atomic_open.txt 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/Documentation/filesystems/aufs/design/03atomic_open.txt 2020-04-10 12:40:52.184049128 +0300 -@@ -0,0 +1,72 @@ -+ -+# Copyright (C) 2015-2020 Junjiro R. Okajima -+ -+Support for a branch who has its ->atomic_open() -+---------------------------------------------------------------------- -+The filesystems who implement its ->atomic_open() are not majority. For -+example NFSv4 does, and aufs should call NFSv4 ->atomic_open, -+particularly for open(O_CREAT|O_EXCL, 0400) case. Other than -+->atomic_open(), NFSv4 returns an error for this open(2). While I am not -+sure whether all filesystems who have ->atomic_open() behave like this, -+but NFSv4 surely returns the error. -+ -+In order to support ->atomic_open() for aufs, there are a few -+approaches. -+ -+A. Introduce aufs_atomic_open() -+ - calls one of VFS:do_last(), lookup_open() or atomic_open() for -+ branch fs. -+B. Introduce aufs_atomic_open() calling create, open and chmod. this is -+ an aufs user Pip Cet's approach -+ - calls aufs_create(), VFS finish_open() and notify_change(). -+ - pass fake-mode to finish_open(), and then correct the mode by -+ notify_change(). -+C. Extend aufs_open() to call branch fs's ->atomic_open() -+ - no aufs_atomic_open(). -+ - aufs_lookup() registers the TID to an aufs internal object. -+ - aufs_create() does nothing when the matching TID is registered, but -+ registers the mode. -+ - aufs_open() calls branch fs's ->atomic_open() when the matching -+ TID is registered. -+D. Extend aufs_open() to re-try branch fs's ->open() with superuser's -+ credential -+ - no aufs_atomic_open(). -+ - aufs_create() registers the TID to an internal object. this info -+ represents "this process created this file just now." -+ - when aufs gets EACCES from branch fs's ->open(), then confirm the -+ registered TID and re-try open() with superuser's credential. -+ -+Pros and cons for each approach. -+ -+A. -+ - straightforward but highly depends upon VFS internal. -+ - the atomic behavaiour is kept. -+ - some of parameters such as nameidata are hard to reproduce for -+ branch fs. -+ - large overhead. -+B. -+ - easy to implement. -+ - the atomic behavaiour is lost. -+C. -+ - the atomic behavaiour is kept. -+ - dirty and tricky. -+ - VFS checks whether the file is created correctly after calling -+ ->create(), which means this approach doesn't work. -+D. -+ - easy to implement. -+ - the atomic behavaiour is lost. -+ - to open a file with superuser's credential and give it to a user -+ process is a bad idea, since the file object keeps the credential -+ in it. It may affect LSM or something. This approach doesn't work -+ either. -+ -+The approach A is ideal, but it hard to implement. So here is a -+variation of A, which is to be implemented. -+ -+A-1. Introduce aufs_atomic_open() -+ - calls branch fs ->atomic_open() if exists. otherwise calls -+ vfs_create() and finish_open(). -+ - the demerit is that the several checks after branch fs -+ ->atomic_open() are lost. in the ordinary case, the checks are -+ done by VFS:do_last(), lookup_open() and atomic_open(). some can -+ be implemented in aufs, but not all I am afraid. -diff -Nurp linux-5.6.3/Documentation/filesystems/aufs/design/03lookup.txt linux-5.6.3-aufs/Documentation/filesystems/aufs/design/03lookup.txt ---- linux-5.6.3/Documentation/filesystems/aufs/design/03lookup.txt 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/Documentation/filesystems/aufs/design/03lookup.txt 2020-04-10 12:40:52.185049175 +0300 -@@ -0,0 +1,100 @@ -+ -+# Copyright (C) 2005-2020 Junjiro R. Okajima -+ -+Lookup in a Branch -+---------------------------------------------------------------------- -+Since aufs has a character of sub-VFS (see Introduction), it operates -+lookup for branches as VFS does. It may be a heavy work. 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 -Nurp linux-5.6.3/Documentation/filesystems/aufs/design/04branch.txt linux-5.6.3-aufs/Documentation/filesystems/aufs/design/04branch.txt ---- linux-5.6.3/Documentation/filesystems/aufs/design/04branch.txt 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/Documentation/filesystems/aufs/design/04branch.txt 2020-04-10 12:40:52.185049175 +0300 -@@ -0,0 +1,61 @@ -+ -+# Copyright (C) 2005-2020 Junjiro R. Okajima -+ -+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 -Nurp linux-5.6.3/Documentation/filesystems/aufs/design/05wbr_policy.txt linux-5.6.3-aufs/Documentation/filesystems/aufs/design/05wbr_policy.txt ---- linux-5.6.3/Documentation/filesystems/aufs/design/05wbr_policy.txt 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/Documentation/filesystems/aufs/design/05wbr_policy.txt 2020-04-10 12:40:52.185049175 +0300 -@@ -0,0 +1,51 @@ -+ -+# Copyright (C) 2005-2020 Junjiro R. Okajima -+ -+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 -Nurp linux-5.6.3/Documentation/filesystems/aufs/design/06dirren.dot linux-5.6.3-aufs/Documentation/filesystems/aufs/design/06dirren.dot ---- linux-5.6.3/Documentation/filesystems/aufs/design/06dirren.dot 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/Documentation/filesystems/aufs/design/06dirren.dot 2020-04-10 12:40:52.185049175 +0300 -@@ -0,0 +1,31 @@ -+ -+// to view this graph, run dot(1) command in GRAPHVIZ. -+ -+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 -Nurp linux-5.6.3/Documentation/filesystems/aufs/design/06dirren.txt linux-5.6.3-aufs/Documentation/filesystems/aufs/design/06dirren.txt ---- linux-5.6.3/Documentation/filesystems/aufs/design/06dirren.txt 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/Documentation/filesystems/aufs/design/06dirren.txt 2020-04-10 12:40:52.185049175 +0300 -@@ -0,0 +1,89 @@ -+ -+# Copyright (C) 2017-2020 Junjiro R. Okajima -+ -+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 refered 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 -Nurp linux-5.6.3/Documentation/filesystems/aufs/design/06fhsm.txt linux-5.6.3-aufs/Documentation/filesystems/aufs/design/06fhsm.txt ---- linux-5.6.3/Documentation/filesystems/aufs/design/06fhsm.txt 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/Documentation/filesystems/aufs/design/06fhsm.txt 2020-04-10 12:40:52.185049175 +0300 -@@ -0,0 +1,105 @@ -+ -+# Copyright (C) 2011-2020 Junjiro R. Okajima -+ -+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 -Nurp linux-5.6.3/Documentation/filesystems/aufs/design/06mmap.txt linux-5.6.3-aufs/Documentation/filesystems/aufs/design/06mmap.txt ---- linux-5.6.3/Documentation/filesystems/aufs/design/06mmap.txt 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/Documentation/filesystems/aufs/design/06mmap.txt 2020-04-10 12:40:52.185049175 +0300 -@@ -0,0 +1,59 @@ -+ -+# Copyright (C) 2005-2020 Junjiro R. Okajima -+ -+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 -Nurp linux-5.6.3/Documentation/filesystems/aufs/design/06xattr.txt linux-5.6.3-aufs/Documentation/filesystems/aufs/design/06xattr.txt ---- linux-5.6.3/Documentation/filesystems/aufs/design/06xattr.txt 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/Documentation/filesystems/aufs/design/06xattr.txt 2020-04-10 12:40:52.185049175 +0300 -@@ -0,0 +1,81 @@ -+ -+# Copyright (C) 2014-2020 Junjiro R. Okajima -+ -+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 -Nurp linux-5.6.3/Documentation/filesystems/aufs/design/07export.txt linux-5.6.3-aufs/Documentation/filesystems/aufs/design/07export.txt ---- linux-5.6.3/Documentation/filesystems/aufs/design/07export.txt 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/Documentation/filesystems/aufs/design/07export.txt 2020-04-10 12:40:52.185049175 +0300 -@@ -0,0 +1,45 @@ -+ -+# Copyright (C) 2005-2020 Junjiro R. Okajima -+ -+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 -Nurp linux-5.6.3/Documentation/filesystems/aufs/design/08shwh.txt linux-5.6.3-aufs/Documentation/filesystems/aufs/design/08shwh.txt ---- linux-5.6.3/Documentation/filesystems/aufs/design/08shwh.txt 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/Documentation/filesystems/aufs/design/08shwh.txt 2020-04-10 12:40:52.185049175 +0300 -@@ -0,0 +1,39 @@ -+ -+# Copyright (C) 2005-2020 Junjiro R. Okajima -+ -+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 -Nurp linux-5.6.3/Documentation/filesystems/aufs/design/10dynop.txt linux-5.6.3-aufs/Documentation/filesystems/aufs/design/10dynop.txt ---- linux-5.6.3/Documentation/filesystems/aufs/design/10dynop.txt 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/Documentation/filesystems/aufs/design/10dynop.txt 2020-04-10 12:40:52.185049175 +0300 -@@ -0,0 +1,34 @@ -+ -+# Copyright (C) 2010-2020 Junjiro R. Okajima -+ -+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 -Nurp linux-5.6.3/Documentation/filesystems/aufs/README linux-5.6.3-aufs/Documentation/filesystems/aufs/README ---- linux-5.6.3/Documentation/filesystems/aufs/README 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/Documentation/filesystems/aufs/README 2020-04-10 12:40:52.184049128 +0300 -@@ -0,0 +1,401 @@ -+ -+Aufs5 -- advanced multi layered unification filesystem version 5.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. -+ -+Aufs5 supports linux-v5.0 and later, If you want older kernel version -+support, -+- 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: 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 aufs5. -+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 aufs5, aufs5-linux.git, -+aufs5-standalone.git, and aufs-util.git. Note that there is no "5" in -+"aufs-util.git." -+While the aufs-util is always necessary, you need either of aufs5-linux -+or aufs5-standalone. -+ -+The aufs5-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 aufs5 as an external kernel module. -+Several extra patches are not included in this tree. Only -+aufs5-standalone tree contains them. They are described in the later -+section "Configuration and Compilation." -+ -+On the other hand, the aufs5-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 "aufs5.x" where "x" -+represents the linux kernel version, "linux-5.x". For instance, -+"aufs5.0" is for linux-5.0. For latest "linux-5.x-rcN", use -+"aufs5.x-rcN" branch. -+ -+o aufs5-linux tree -+$ git clone --reference /your/linux/git/tree \ -+ git://github.com/sfjro/aufs5-linux.git aufs5-linux.git -+- if you don't have linux GIT tree, then remove "--reference ..." -+$ cd aufs5-linux.git -+$ git checkout origin/aufs5.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 aufs5 git://github.com/sfjro/aufs5-linux.git -+$ git fetch aufs5 -+$ git checkout -b my5.0 v5.0 -+$ (add your local change...) -+$ git pull aufs5 aufs5.0 -+- now you have v5.0 + your_changes + aufs5.0 in you my5.0 branch. -+- you may need to solve some conflicts between your_changes and -+ aufs5.0. in this case, git-rerere is recommended so that you can -+ solve the similar conflicts automatically when you upgrade to 5.1 or -+ later in the future. -+ -+o aufs5-standalone tree -+$ git clone git://github.com/sfjro/aufs5-standalone.git aufs5-standalone.git -+$ cd aufs5-standalone.git -+$ git checkout origin/aufs5.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/aufs5.0 -+ -+Note: The 5.x-rcN branch is to be used with `rc' kernel versions ONLY. -+The minor version number, 'x' in '5.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-5.10" and the "aufs5.10" branch -+does not exist in aufs-util repository, then "aufs5.9", "aufs5.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 aufs5-linux tree, -+- enable CONFIG_AUFS_FS. -+- set other aufs configurations if necessary. -+ -+For aufs5-standalone tree, -+There are several ways to build. -+ -+1. -+- apply ./aufs5-kbuild.patch to your kernel source files. -+- apply ./aufs5-base.patch too. -+- apply ./aufs5-mmap.patch too. -+- apply ./aufs5-standalone.patch too, if you have a plan to set -+ CONFIG_AUFS_FS=m. otherwise you don't need ./aufs5-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 ./aufs5-base.patch to your kernel source files. -+- apply ./aufs5-mmap.patch too. -+- apply ./aufs5-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 aufs5-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 aufs5-standalone.git. They are all -+optional. When you meet some problems, they will help you. -+- aufs5-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". -+- proc_mounts.patch -+ When there are many mountpoints and many mount(2)/umount(2) are -+ running, then /proc/mounts may not show the all mountpoints. This -+ patch makes /proc/mounts always show the full mountpoints list. -+ If you don't want to apply this patch and meet such problem, then you -+ need to increase the value of 'ProcMounts_Times' make-variable in -+ aufs-util.git as a second best solution. -+- 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 -+ 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 apply this debug patch to expand several constant values. -+ If you don't know what LOCKDEP is, then you don't have apply this -+ patch. -+ -+ -+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 and 2015/7). -+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). -+ -+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 -Nurp linux-5.6.3/drivers/block/loop.c linux-5.6.3-aufs/drivers/block/loop.c ---- linux-5.6.3/drivers/block/loop.c 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs/drivers/block/loop.c 2020-04-10 12:40:52.187049268 +0300 -@@ -750,6 +750,24 @@ out_err: - return error; - } - -+/* -+ * for AUFS -+ * no get/put for file. -+ */ -+struct file *loop_backing_file(struct super_block *sb) -+{ -+ struct file *ret; -+ struct loop_device *l; -+ -+ ret = NULL; -+ if (MAJOR(sb->s_dev) == LOOP_MAJOR) { -+ l = sb->s_bdev->bd_disk->private_data; -+ ret = l->lo_backing_file; -+ } -+ return ret; -+} -+EXPORT_SYMBOL_GPL(loop_backing_file); -+ - /* loop sysfs attributes */ - - static ssize_t loop_attr_show(struct device *dev, char *page, -diff -Nurp linux-5.6.3/fs/aufs/aufs.h linux-5.6.3-aufs/fs/aufs/aufs.h ---- linux-5.6.3/fs/aufs/aufs.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/aufs.h 2020-04-10 12:40:52.187049268 +0300 -@@ -0,0 +1,49 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.6.3/fs/aufs/branch.c linux-5.6.3-aufs/fs/aufs/branch.c ---- linux-5.6.3/fs/aufs/branch.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/branch.c 2020-04-10 12:40:52.188049315 +0300 -@@ -0,0 +1,1415 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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(!inode->i_nlink)) { -+ 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); -+ put_write_access(h_inode); -+ __mnt_drop_write(hf->f_path.mnt); -+ if ((hf->f_mode & (FMODE_READ | FMODE_WRITE)) -+ == FMODE_READ) -+ i_readcount_inc(h_inode); -+ } -+ } -+ -+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 -Nurp linux-5.6.3/fs/aufs/branch.h linux-5.6.3-aufs/fs/aufs/branch.h ---- linux-5.6.3/fs/aufs/branch.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/branch.h 2020-04-10 12:40:52.188049315 +0300 -@@ -0,0 +1,353 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 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(vfs_readf_t func, struct file *file, void *buf, size_t size, -+ loff_t *pos); -+ssize_t xino_fwrite(vfs_writef_t func, struct file *file, void *buf, -+ size_t size, loff_t *pos); -+ -+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 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 -Nurp linux-5.6.3/fs/aufs/cpup.c linux-5.6.3-aufs/fs/aufs/cpup.c ---- linux-5.6.3/fs/aufs/cpup.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/cpup.c 2020-04-10 12:40:52.188049315 +0300 -@@ -0,0 +1,1445 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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. -+ */ -+ set_nlink(inode, h_inode->i_nlink); -+ -+ /* -+ * 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); -+ if (inode->i_nlink > 0) -+ 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 dentry *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; -+ -+ h_path.dentry = au_h_dptr(dst, bindex); -+ h_idst = d_inode(h_path.dentry); -+ br = au_sbr(dst->d_sb, bindex); -+ h_path.mnt = au_br_mnt(br); -+ h_isrc = d_inode(h_src); -+ ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID -+ | ATTR_ATIME | ATTR_MTIME -+ | ATTR_ATIME_SET | ATTR_MTIME_SET; -+ 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.dentry, 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_nfs(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, symlen; -+ mm_segment_t old_fs; -+ union { -+ char *k; -+ char __user *u; -+ } sym; -+ -+ err = -ENOMEM; -+ sym.k = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!sym.k)) -+ goto out; -+ -+ /* unnecessary to support mmap_sem since symlink is not mmap-able */ -+ old_fs = get_fs(); -+ set_fs(KERNEL_DS); -+ symlen = vfs_readlink(h_src, sym.u, PATH_MAX); -+ err = symlen; -+ set_fs(old_fs); -+ -+ if (symlen > 0) { -+ sym.k[symlen] = 0; -+ err = vfsub_symlink(h_dir, h_path, sym.k); -+ } -+ free_page((unsigned long)sym.k); -+ -+out: -+ 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 inode *h_dir, struct path *h_path, umode_t mode) -+{ -+ int err; -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ -+ h_dentry = h_path->dentry; -+ h_inode = d_inode(h_dentry); -+ /* forget_all_cached_acls(h_inode)); */ -+ err = vfsub_removexattr(h_dentry, XATTR_NAME_POSIX_ACL_ACCESS); -+ AuTraceErr(err); -+ if (err == -EOPNOTSUPP) -+ err = 0; -+ if (!err) -+ err = vfsub_acl_chmod(h_inode, 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; -+ -+ err = vfsub_removexattr(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_dir, &h_path, mode); -+ -+ mnt_flags = au_mntflags(sb); -+ if (!au_opt_test(mnt_flags, UDBA_NONE) -+ && !isdir -+ && au_opt_test(mnt_flags, XINO) -+ && (h_inode->i_nlink == 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 inode *h_dir; -+ aufs_bindex_t bdst; -+ -+ dentry = cpg->dentry; -+ bdst = cpg->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_parent = au_h_dptr(parent, bdst); -+ dput(parent); -+ h_path->dentry = vfsub_lkup_one(&dentry->d_name, h_parent); -+ 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; -+ /* 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 (dst_inode->i_nlink) { -+ 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); */ -+ -+ err = cpup_iattr(cpg->dentry, cpg->bdst, h_src, &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 -+ && (src_inode->i_nlink > 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; -+ -+ 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); -+ if (!au_test_h_perm_sio(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; -+ -+ 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 (!h_dir->i_nlink) { -+ 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; -+ } -+ -+ if (!au_test_h_perm_sio(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 -Nurp linux-5.6.3/fs/aufs/cpup.h linux-5.6.3-aufs/fs/aufs/cpup.h ---- linux-5.6.3/fs/aufs/cpup.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/cpup.h 2020-04-10 12:40:52.188049315 +0300 -@@ -0,0 +1,87 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.6.3/fs/aufs/dbgaufs.c linux-5.6.3-aufs/fs/aufs/dbgaufs.c ---- linux-5.6.3/fs/aufs/dbgaufs.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/dbgaufs.c 2020-04-10 12:40:52.188049315 +0300 -@@ -0,0 +1,513 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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; -+ strcpy(p->a, 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 -Nurp linux-5.6.3/fs/aufs/dbgaufs.h linux-5.6.3-aufs/fs/aufs/dbgaufs.h ---- linux-5.6.3/fs/aufs/dbgaufs.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/dbgaufs.h 2020-04-10 12:40:52.188049315 +0300 -@@ -0,0 +1,40 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.6.3/fs/aufs/dcsub.c linux-5.6.3-aufs/fs/aufs/dcsub.c ---- linux-5.6.3/fs/aufs/dcsub.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/dcsub.c 2020-04-10 12:40:52.189049362 +0300 -@@ -0,0 +1,212 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.6.3/fs/aufs/dcsub.h linux-5.6.3-aufs/fs/aufs/dcsub.h ---- linux-5.6.3/fs/aufs/dcsub.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/dcsub.h 2020-04-10 12:40:52.189049362 +0300 -@@ -0,0 +1,124 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * sub-routines for dentry cache -+ */ -+ -+#ifndef __AUFS_DCSUB_H__ -+#define __AUFS_DCSUB_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+ -+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) -+ || !inode->i_nlink)) -+ 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) -+ || !inode->i_nlink)) -+ err = -ENOENT; -+ } -+ return err; -+} -+ -+static inline int au_alive_dir(struct dentry *d) -+{ -+ int err; -+ -+ err = au_d_alive(d); -+ if (unlikely(err || IS_DEADDIR(d_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 -Nurp linux-5.6.3/fs/aufs/debug.c linux-5.6.3-aufs/fs/aufs/debug.c ---- linux-5.6.3/fs/aufs/debug.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/debug.c 2020-04-10 12:40:52.189049362 +0300 -@@ -0,0 +1,428 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 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; -+ -+ 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; -+ } -+ -+ dpri("i%d: %p, i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu," -+ " hn %d, ct %lld, np %lu, st 0x%lx, f 0x%x, v %llu, g %x%s%.*s\n", -+ bindex, inode, -+ inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??", -+ atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode, -+ i_size_read(inode), (unsigned long long)inode->i_blocks, -+ hn, (long long)timespec64_to_ns(&inode->i_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(); -+ 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 -Nurp linux-5.6.3/fs/aufs/debug.h linux-5.6.3-aufs/fs/aufs/debug.h ---- linux-5.6.3/fs/aufs/debug.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/debug.h 2020-04-10 12:40:52.189049362 +0300 -@@ -0,0 +1,213 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -+#define AuDebugOn(a) do {} while (0) -+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; -+#ifdef CONFIG_AUFS_DEBUG -+extern struct mutex au_dbg_mtx; -+extern char *au_plevel; -+struct au_nhash; -+void au_dpri_whlist(struct au_nhash *whlist); -+struct au_vdir; -+void au_dpri_vdir(struct au_vdir *vdir); -+struct inode; -+void au_dpri_inode(struct inode *inode); -+void au_dpri_dalias(struct inode *inode); -+void au_dpri_dentry(struct dentry *dentry); -+struct file; -+void au_dpri_file(struct file *filp); -+struct super_block; -+void au_dpri_sb(struct super_block *sb); -+ -+#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) -+ -+#define AuDbgWhlist(w) do {} while (0) -+#define AuDbgVdir(v) do {} while (0) -+#define AuDbgInode(i) do {} while (0) -+#define AuDbgDAlias(i) do {} while (0) -+#define AuDbgDentry(d) do {} while (0) -+#define AuDbgFile(f) do {} while (0) -+#define AuDbgSb(sb) do {} while (0) -+#define AuDbgSym(addr) do {} while (0) -+#endif /* CONFIG_AUFS_DEBUG */ -+ -+/* ---------------------------------------------------------------------- */ -+ -+#ifdef CONFIG_AUFS_MAGIC_SYSRQ -+int __init au_sysrq_init(void); -+void au_sysrq_fin(void); -+ -+#ifdef CONFIG_HW_CONSOLE -+#define au_dbg_blocked() do { \ -+ WARN_ON(1); \ -+ handle_sysrq('w'); \ -+} while (0) -+#else -+AuStubVoid(au_dbg_blocked, void) -+#endif -+ -+#else -+AuStubInt0(__init au_sysrq_init, void) -+AuStubVoid(au_sysrq_fin, void) -+AuStubVoid(au_dbg_blocked, void) -+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */ -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_DEBUG_H__ */ -diff -Nurp linux-5.6.3/fs/aufs/dentry.c linux-5.6.3-aufs/fs/aufs/dentry.c ---- linux-5.6.3/fs/aufs/dentry.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/dentry.c 2020-04-10 12:40:52.189049362 +0300 -@@ -0,0 +1,1141 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * lookup and dentry operations -+ */ -+ -+#include -+#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; -+ 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); -+ wh_able = !!au_br_whable(br->br_perm); -+ if (wh_able) -+ wh_found = au_wh_test(h_parent, &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_parent); -+ else -+ h_dentry = au_sio_lkup_one(args->name, h_parent); -+ 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 */ -+ -+ inode_lock_shared_nested(h_inode, AuLsc_I_CHILD); -+ opq = au_diropq_test(h_dentry); -+ 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 qstr *name, struct dentry *parent) -+{ -+ struct dentry *dentry; -+ int wkq_err; -+ -+ if (!au_test_h_perm_sio(d_inode(parent), MAY_EXEC)) -+ dentry = vfsub_lkup_one(name, parent); -+ else { -+ struct vfsub_lkup_one_args args = { -+ .errp = &dentry, -+ .name = name, -+ .parent = parent -+ }; -+ -+ 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_parent, *h_dentry; -+ struct au_branch *br; -+ -+ parent = dget_parent(dentry); -+ h_parent = au_h_dptr(parent, bindex); -+ br = au_sbr(dentry->d_sb, bindex); -+ if (wh) -+ h_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name); -+ else -+ h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent); -+ 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; -+ -+ 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_d = vfsub_lkup_one(&h_dentry->d_name, h_parent); -+ 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 (inode->i_nlink && !d_unhashed(dentry)) -+ drop_nlink(inode); -+ } else { -+ 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; -+ 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 = (inode->i_nlink > 0); -+ ibs = au_ibtop(inode); -+ ibe = au_ibbot(inode); -+ } -+ -+ btop = au_dbtop(dentry); -+ 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) -+ 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 -+ && !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) { -+ h_mode = (h_inode->i_mode & S_IFMT); -+ h_plus = (h_inode->i_nlink > 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) || !inode->i_nlink)) { -+ 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 -Nurp linux-5.6.3/fs/aufs/dentry.h linux-5.6.3-aufs/fs/aufs/dentry.h ---- linux-5.6.3/fs/aufs/dentry.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/dentry.h 2020-04-10 12:40:52.189049362 +0300 -@@ -0,0 +1,255 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 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 qstr *name, struct dentry *parent); -+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 -Nurp linux-5.6.3/fs/aufs/dinfo.c linux-5.6.3-aufs/fs/aufs/dinfo.c ---- linux-5.6.3/fs/aufs/dinfo.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/dinfo.c 2020-04-10 12:40:52.189049362 +0300 -@@ -0,0 +1,541 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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; -+ 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 -Nurp linux-5.6.3/fs/aufs/dir.c linux-5.6.3-aufs/fs/aufs/dir.c ---- linux-5.6.3/fs/aufs/dir.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/dir.c 2020-04-10 12:40:52.189049362 +0300 -@@ -0,0 +1,750 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * directory operations -+ */ -+ -+#include -+#include -+#include "aufs.h" -+ -+void au_add_nlink(struct inode *dir, struct inode *h_dir) -+{ -+ unsigned int nlink; -+ -+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode)); -+ -+ nlink = dir->i_nlink; -+ nlink += h_dir->i_nlink - 2; -+ if (h_dir->i_nlink < 2) -+ nlink += 2; -+ smp_mb(); /* for i_nlink */ -+ /* 0 can happen in revaliding */ -+ set_nlink(dir, nlink); -+} -+ -+void au_sub_nlink(struct inode *dir, struct inode *h_dir) -+{ -+ unsigned int nlink; -+ -+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode)); -+ -+ nlink = dir->i_nlink; -+ nlink -= h_dir->i_nlink - 2; -+ if (h_dir->i_nlink < 2) -+ nlink -= 2; -+ smp_mb(); /* for i_nlink */ -+ /* nlink == 0 means the branch-fs is broken */ -+ 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 (h_dir->i_nlink -+ && 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 int 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) -+ && !file_inode(h_file)->i_nlink) -+ 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; -+ -+ 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_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 -Nurp linux-5.6.3/fs/aufs/dir.h linux-5.6.3-aufs/fs/aufs/dir.h ---- linux-5.6.3/fs/aufs/dir.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/dir.h 2020-04-10 12:40:52.189049362 +0300 -@@ -0,0 +1,121 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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[0]; -+} __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 -Nurp linux-5.6.3/fs/aufs/dirren.c linux-5.6.3-aufs/fs/aufs/dirren.c ---- linux-5.6.3/fs/aufs/dirren.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/dirren.c 2020-04-10 12:40:52.190049409 +0300 -@@ -0,0 +1,1303 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2017-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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.dentry = vfsub_lkup_one(&hinoname, path->dentry); -+ 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; -+ } -+ hinopath.mnt = path->mnt; -+ 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[0]; -+}; -+ -+/* 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.dentry, -+ 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); -+ strcpy(w->whname, 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->dentry, -+ 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 -Nurp linux-5.6.3/fs/aufs/dirren.h linux-5.6.3-aufs/fs/aufs/dirren.h ---- linux-5.6.3/fs/aufs/dirren.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/dirren.h 2020-04-10 12:40:52.190049409 +0300 -@@ -0,0 +1,127 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2017-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.6.3/fs/aufs/dynop.c linux-5.6.3-aufs/fs/aufs/dynop.c ---- linux-5.6.3/fs/aufs/dynop.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/dynop.c 2020-04-10 12:40:52.190049409 +0300 -@@ -0,0 +1,354 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2010-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * dynamically customizable operations for regular files -+ */ -+ -+#include "aufs.h" -+ -+#define DyPrSym(key) AuDbgSym(key->dk_op.dy_hop) -+ -+/* -+ * How large will these lists be? -+ * Usually just a few elements, 20-30 at most for each, I guess. -+ */ -+static struct 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 *)) -+ -+#ifdef CONFIG_AUFS_DEBUG -+#define DyDbgDeclare(cnt) unsigned int cnt = 0 -+#define DyDbgInc(cnt) do { cnt++; } while (0) -+#else -+#define DyDbgDeclare(cnt) do {} while (0) -+#define DyDbgInc(cnt) do {} while (0) -+#endif -+ -+#define DySet(func, dst, src, h_op, h_sb) do { \ -+ DyDbgInc(cnt); \ -+ if (h_op->func) { \ -+ if (src.func) \ -+ dst.func = src.func; \ -+ else \ -+ AuDbg("%s %s\n", au_sbtype(h_sb), #func); \ -+ } \ -+} while (0) -+ -+#define DySetForce(func, dst, src) do { \ -+ AuDebugOn(!src.func); \ -+ DyDbgInc(cnt); \ -+ dst.func = src.func; \ -+} while (0) -+ -+#define DySetAop(func) \ -+ DySet(func, dyaop->da_op, aufs_aop, h_aop, h_sb) -+#define DySetAopForce(func) \ -+ DySetForce(func, dyaop->da_op, aufs_aop) -+ -+static void dy_aop(struct au_dykey *key, const void *h_op, -+ struct super_block *h_sb __maybe_unused) -+{ -+ struct au_dyaop *dyaop = (void *)key; -+ const struct address_space_operations *h_aop = h_op; -+ DyDbgDeclare(cnt); -+ -+ AuDbg("%s\n", au_sbtype(h_sb)); -+ -+ DySetAop(writepage); -+ DySetAopForce(readpage); /* force */ -+ DySetAop(writepages); -+ DySetAop(set_page_dirty); -+ DySetAop(readpages); -+ DySetAop(write_begin); -+ DySetAop(write_end); -+ DySetAop(bmap); -+ DySetAop(invalidatepage); -+ DySetAop(releasepage); -+ DySetAop(freepage); -+ /* this one will be changed according to an aufs mount option */ -+ DySetAop(direct_IO); -+ DySetAop(migratepage); -+ DySetAop(isolate_page); -+ DySetAop(putback_page); -+ DySetAop(launder_page); -+ DySetAop(is_partially_uptodate); -+ DySetAop(is_dirty_writeback); -+ DySetAop(error_remove_page); -+ DySetAop(swap_activate); -+ DySetAop(swap_deactivate); -+ -+ 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 -Nurp linux-5.6.3/fs/aufs/dynop.h linux-5.6.3-aufs/fs/aufs/dynop.h ---- linux-5.6.3/fs/aufs/dynop.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/dynop.h 2020-04-10 12:40:52.190049409 +0300 -@@ -0,0 +1,64 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2010-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.6.3/fs/aufs/export.c linux-5.6.3-aufs/fs/aufs/export.c ---- linux-5.6.3/fs/aufs/export.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/export.c 2020-04-10 12:40:52.190049409 +0300 -@@ -0,0 +1,825 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * export via nfs -+ */ -+ -+#include -+#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_xwrite, sbinfo->si_xigen, &igen, -+ sizeof(igen), &pos); -+ if (sz == sizeof(igen)) -+ return; /* success */ -+ -+ if (unlikely(sz >= 0)) -+ AuIOErr("xigen error (%zd)\n", sz); -+} -+ -+int au_xigen_new(struct inode *inode) -+{ -+ int err; -+ loff_t pos; -+ ssize_t sz; -+ struct super_block *sb; -+ struct au_sbinfo *sbinfo; -+ struct file *file; -+ -+ err = 0; -+ /* todo: dirty, at mount time */ -+ if (inode->i_ino == AUFS_ROOT_INO) -+ goto out; -+ sb = inode->i_sb; -+ SiMustAnyLock(sb); -+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO))) -+ goto out; -+ -+ err = -EFBIG; -+ pos = inode->i_ino; -+ if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) { -+ AuIOErr1("too large i%lld\n", pos); -+ goto out; -+ } -+ pos *= sizeof(inode->i_generation); -+ -+ err = 0; -+ sbinfo = au_sbi(sb); -+ file = sbinfo->si_xigen; -+ BUG_ON(!file); -+ -+ if (vfsub_f_size_read(file) -+ < pos + sizeof(inode->i_generation)) { -+ inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next); -+ sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation, -+ sizeof(inode->i_generation), &pos); -+ } else -+ sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation, -+ sizeof(inode->i_generation), &pos); -+ if (sz == sizeof(inode->i_generation)) -+ goto out; /* success */ -+ -+ err = sz; -+ if (unlikely(sz >= 0)) { -+ err = -EIO; -+ AuIOErr("xigen error (%zd)\n", sz); -+ } -+ -+out: -+ return err; -+} -+ -+int au_xigen_set(struct super_block *sb, struct 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 int -+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 0; -+ -+ memcpy(a->name, name, namelen); -+ a->namelen = namelen; -+ a->found = 1; -+ return 1; -+} -+ -+static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino, -+ struct au_nfsd_si_lock *nsi_lock) -+{ -+ struct dentry *dentry, *parent; -+ struct file *file; -+ struct inode *dir; -+ struct find_name_by_ino arg = { -+ .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, parent, 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 { -+ struct writeback_control wbc = { -+ .sync_mode = WB_SYNC_ALL, -+ .nr_to_write = 0 /* metadata only */ -+ }; -+ -+ err = sync_inode(h_inode, &wbc); -+ } -+ -+ au_cpup_attr_timesizes(inode); -+ ii_write_unlock(inode); -+ si_read_unlock(sb); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static struct export_operations aufs_export_op = { -+ .fh_to_dentry = aufs_fh_to_dentry, -+ /* .fh_to_parent = aufs_fh_to_parent, */ -+ .encode_fh = aufs_encode_fh, -+ .commit_metadata = aufs_commit_metadata -+}; -+ -+void au_export_init(struct super_block *sb) -+{ -+ struct au_sbinfo *sbinfo; -+ __u32 u; -+ -+ 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 -Nurp linux-5.6.3/fs/aufs/fhsm.c linux-5.6.3-aufs/fs/aufs/fhsm.c ---- linux-5.6.3/fs/aufs/fhsm.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/fhsm.c 2020-04-10 12:40:52.190049409 +0300 -@@ -0,0 +1,413 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2011-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.6.3/fs/aufs/file.c linux-5.6.3-aufs/fs/aufs/file.c ---- linux-5.6.3/fs/aufs/file.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/file.c 2020-04-10 12:40:52.190049409 +0300 -@@ -0,0 +1,850 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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); -+ 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); -+ di_downgrade_lock(dentry, AuLock_IR); -+ if (!err) { -+ if (!aopen) -+ err = args->open(file, vfsub_file_flags(file), NULL); -+ else { -+ 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); -+ /* 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 -+ && (inode->i_nlink > 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_readpage(struct file *file __maybe_unused, struct page *page) -+{ -+ unlock_page(page); -+ return 0; -+} -+ -+/* it will never be called, but necessary to support O_DIRECT */ -+static ssize_t aufs_direct_IO(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, unsigned flags, -+ struct page **pagep, void **fsdata) -+{ AuUnsupport(); return 0; } -+static int aufs_write_end(struct file *file, struct address_space *mapping, -+ loff_t pos, unsigned len, unsigned copied, -+ struct page *page, void *fsdata) -+{ AuUnsupport(); return 0; } -+static int aufs_writepage(struct page *page, struct writeback_control *wbc) -+{ AuUnsupport(); return 0; } -+ -+static int aufs_set_page_dirty(struct page *page) -+{ AuUnsupport(); return 0; } -+static void aufs_invalidatepage(struct page *page, unsigned int offset, -+ unsigned int length) -+{ AuUnsupport(); } -+static int aufs_releasepage(struct page *page, gfp_t gfp) -+{ AuUnsupport(); return 0; } -+#if 0 /* called by memory compaction regardless file */ -+static int aufs_migratepage(struct address_space *mapping, struct page *newpage, -+ struct page *page, enum migrate_mode mode) -+{ AuUnsupport(); return 0; } -+#endif -+static bool aufs_isolate_page(struct page *page, isolate_mode_t mode) -+{ AuUnsupport(); return true; } -+static void aufs_putback_page(struct page *page) -+{ AuUnsupport(); } -+static int aufs_launder_page(struct page *page) -+{ AuUnsupport(); return 0; } -+static int aufs_is_partially_uptodate(struct page *page, -+ unsigned long from, -+ unsigned long count) -+{ AuUnsupport(); return 0; } -+static void aufs_is_dirty_writeback(struct page *page, 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(); } -+#endif /* CONFIG_AUFS_DEBUG */ -+ -+const struct address_space_operations aufs_aop = { -+ .readpage = aufs_readpage, -+ .direct_IO = aufs_direct_IO, -+#ifdef CONFIG_AUFS_DEBUG -+ .writepage = aufs_writepage, -+ /* no writepages, because of writepage */ -+ .set_page_dirty = aufs_set_page_dirty, -+ /* no readpages, because of readpage */ -+ .write_begin = aufs_write_begin, -+ .write_end = aufs_write_end, -+ /* no bmap, no block device */ -+ .invalidatepage = aufs_invalidatepage, -+ .releasepage = aufs_releasepage, -+ /* is fallback_migrate_page ok? */ -+ /* .migratepage = aufs_migratepage, */ -+ .isolate_page = aufs_isolate_page, -+ .putback_page = aufs_putback_page, -+ .launder_page = aufs_launder_page, -+ .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 -+#endif /* CONFIG_AUFS_DEBUG */ -+}; -diff -Nurp linux-5.6.3/fs/aufs/file.h linux-5.6.3-aufs/fs/aufs/file.h ---- linux-5.6.3/fs/aufs/file.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/file.h 2020-04-10 12:40:52.190049409 +0300 -@@ -0,0 +1,329 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -+#define AuDbgVmRegion(file, vma) do {} while (0) -+ -+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 -Nurp linux-5.6.3/fs/aufs/finfo.c linux-5.6.3-aufs/fs/aufs/finfo.c ---- linux-5.6.3/fs/aufs/finfo.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/finfo.c 2020-04-10 12:40:52.190049409 +0300 -@@ -0,0 +1,136 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.6.3/fs/aufs/f_op.c linux-5.6.3-aufs/fs/aufs/f_op.c ---- linux-5.6.3/fs/aufs/f_op.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/f_op.c 2020-04-10 12:40:52.190049409 +0300 -@@ -0,0 +1,806 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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) -+ && !(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); -+ /* 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); -+ -+out_fi: -+ fi_write_unlock(file); -+out: -+ return h_file; -+} -+ -+static void au_write_post(struct inode *inode, struct file *h_file, -+ struct au_write_pre *wpre, ssize_t written) -+{ -+ struct inode *h_inode; -+ -+ au_cpup_attr_timesizes(inode); -+ AuDebugOn(au_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); -+} -+ -+static ssize_t aufs_read(struct file *file, char __user *buf, size_t count, -+ loff_t *ppos) -+{ -+ ssize_t err; -+ struct inode *inode; -+ struct file *h_file; -+ 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; -+ -+ /* filedata may be obsoleted by concurrent copyup, but no problem */ -+ err = vfsub_read_u(h_file, buf, count, ppos); -+ /* todo: necessary? */ -+ /* file->f_ra = h_file->f_ra; */ -+ au_read_post(inode, h_file); -+ -+out: -+ si_read_unlock(sb); -+ return err; -+} -+ -+/* -+ * todo: very ugly -+ * it locks both of i_mutex and si_rwsem for read in safe. -+ * if the plink maintenance mode continues forever (that is the problem), -+ * may loop forever. -+ */ -+static void au_mtx_and_read_lock(struct inode *inode) -+{ -+ int err; -+ struct super_block *sb = inode->i_sb; -+ -+ while (1) { -+ 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 aufs_write(struct file *file, const char __user *ubuf, -+ size_t count, loff_t *ppos) -+{ -+ ssize_t err; -+ struct au_write_pre wpre; -+ struct inode *inode; -+ struct file *h_file; -+ char __user *buf = (char __user *)ubuf; -+ -+ 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_write_u(h_file, buf, count, ppos); -+ au_write_post(inode, h_file, &wpre, err); -+ -+out: -+ si_read_unlock(inode->i_sb); -+ inode_unlock(inode); -+ return err; -+} -+ -+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); -+ 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; -+ -+ 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; -+} -+ -+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_to(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(); -+ 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; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* no one supports this operation, currently */ -+#if 0 /* reserved for future use */ -+static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset, -+ size_t len, loff_t *pos, int more) -+{ -+} -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+const struct file_operations aufs_file_fop = { -+ .owner = THIS_MODULE, -+ -+ .llseek = default_llseek, -+ -+ .read = aufs_read, -+ .write = aufs_write, -+ .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, -+ /* .sendpage = aufs_sendpage, */ -+ .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 -Nurp linux-5.6.3/fs/aufs/fstype.h linux-5.6.3-aufs/fs/aufs/fstype.h ---- linux-5.6.3/fs/aufs/fstype.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/fstype.h 2020-04-10 12:40:52.190049409 +0300 -@@ -0,0 +1,388 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -+} -+ -+/* ---------------------------------------------------------------------- */ -+/* -+ * 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); -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_FSTYPE_H__ */ -diff -Nurp linux-5.6.3/fs/aufs/hbl.h linux-5.6.3-aufs/fs/aufs/hbl.h ---- linux-5.6.3/fs/aufs/hbl.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/hbl.h 2020-04-10 12:40:52.190049409 +0300 -@@ -0,0 +1,52 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2017-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.6.3/fs/aufs/hfsnotify.c linux-5.6.3-aufs/fs/aufs/hfsnotify.c ---- linux-5.6.3/fs/aufs/hfsnotify.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/hfsnotify.c 2020-04-10 12:40:52.190049409 +0300 -@@ -0,0 +1,275 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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, -+ struct inode *inode, -+ u32 mask, const void *data, int data_type, -+ 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); -+ -+ 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 = inode; -+ h_inode = NULL; -+#ifdef AuDbgHnotify -+ au_debug_on(); -+ if (1 || h_child_qstr.len != sizeof(AUFS_XINO_FNAME) - 1 -+ || strncmp(h_child_qstr.name, AUFS_XINO_FNAME, h_child_qstr.len)) { -+ AuDbg("i%lu, mask 0x%x %s, hcname %.*s, hi%lu\n", -+ h_dir->i_ino, mask, au_hfsn_name(mask), -+ AuLNPair(&h_child_qstr), 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); -+ 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 -Nurp linux-5.6.3/fs/aufs/hfsplus.c linux-5.6.3-aufs/fs/aufs/hfsplus.c ---- linux-5.6.3/fs/aufs/hfsplus.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/hfsplus.c 2020-04-10 12:40:52.190049409 +0300 -@@ -0,0 +1,47 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2010-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.6.3/fs/aufs/hnotify.c linux-5.6.3-aufs/fs/aufs/hnotify.c ---- linux-5.6.3/fs/aufs/hnotify.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/hnotify.c 2020-04-10 12:40:52.190049409 +0300 -@@ -0,0 +1,702 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 (!a->h_inode->i_nlink -+ && !(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 (!dir->i_nlink -+ || (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 -Nurp linux-5.6.3/fs/aufs/iinfo.c linux-5.6.3-aufs/fs/aufs/iinfo.c ---- linux-5.6.3/fs/aufs/iinfo.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/iinfo.c 2020-04-10 12:40:52.191049456 +0300 -@@ -0,0 +1,273 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -+ && !h_i->i_nlink -+ && !(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); -+} -+ -+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 = !inode->i_nlink; -+ -+ 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 -Nurp linux-5.6.3/fs/aufs/inode.c linux-5.6.3-aufs/fs/aufs/inode.c ---- linux-5.6.3/fs/aufs/inode.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/inode.c 2020-04-10 12:40:52.191049456 +0300 -@@ -0,0 +1,516 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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_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) && h_inode->i_nlink > 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) && inode->i_nlink) { -+ /* -+ * 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 inode *h_inode, int mask) -+{ -+ if (uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) -+ return 0; -+ return inode_permission(h_inode, mask); -+} -+ -+int au_test_h_perm_sio(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_inode, mask); -+} -diff -Nurp linux-5.6.3/fs/aufs/inode.h linux-5.6.3-aufs/fs/aufs/inode.h ---- linux-5.6.3/fs/aufs/inode.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/inode.h 2020-04-10 12:40:52.191049456 +0300 -@@ -0,0 +1,685 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * inode operations -+ */ -+ -+#ifndef __AUFS_INODE_H__ -+#define __AUFS_INODE_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#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; -+ 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); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* 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 inode *h_inode, int mask); -+int au_test_h_perm_sio(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, 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 inode *dir, struct dentry *dentry, umode_t mode, -+ dev_t dev); -+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname); -+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode, -+ bool want_excl); -+struct vfsub_aopen_args; -+int au_aopen_or_create(struct inode *dir, struct dentry *dentry, -+ struct vfsub_aopen_args *args); -+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode); -+int aufs_link(struct dentry *src_dentry, struct inode *dir, -+ struct dentry *dentry); -+int aufs_mkdir(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 inode *src_dir, struct dentry *src_dentry, -+ struct inode *dir, struct dentry *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 dentry *h_dst, struct dentry *h_src, int ignore_flags, -+ unsigned int verbose); -+ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size); -+void au_xattr_init(struct super_block *sb); -+#else -+AuStubInt0(au_cpup_xattr, struct dentry *h_dst, struct dentry *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_acl(struct inode *inode, int type); -+int aufs_set_acl(struct inode *inode, 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 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 -Nurp linux-5.6.3/fs/aufs/ioctl.c linux-5.6.3-aufs/fs/aufs/ioctl.c ---- linux-5.6.3/fs/aufs/ioctl.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/ioctl.c 2020-04-10 12:40:52.191049456 +0300 -@@ -0,0 +1,207 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.6.3/fs/aufs/i_op_add.c linux-5.6.3-aufs/fs/aufs/i_op_add.c ---- linux-5.6.3/fs/aufs/i_op_add.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/i_op_add.c 2020-04-10 12:40:52.191049456 +0300 -@@ -0,0 +1,923 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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(!h_inode->i_nlink)) -+ 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 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 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 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 inode *dir, struct dentry *dentry, umode_t mode) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ struct super_block *sb; -+ struct dentry *parent, *h_parent, *h_dentry; -+ struct inode *h_dir, *inode; -+ struct vfsmount *h_mnt; -+ struct au_wr_dir_args wr_dir_args = { -+ .force_btgt = -1, -+ .flags = AuWrDir_TMPFILE -+ }; -+ -+ /* copy-up may happen */ -+ inode_lock(dir); -+ -+ sb = dir->i_sb; -+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (unlikely(err)) -+ goto out; -+ -+ 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; -+ -+ h_mnt = au_sbr_mnt(sb, bindex); -+ err = vfsub_mnt_want_write(h_mnt); -+ if (unlikely(err)) -+ goto out_parent; -+ -+ h_parent = au_h_dptr(parent, bindex); -+ h_dentry = vfs_tmpfile(h_parent, mode, /*open_flag*/0); -+ if (IS_ERR(h_dentry)) { -+ err = PTR_ERR(h_dentry); -+ goto out_mnt; -+ } -+ -+ 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); -+ } else { -+ if (!inode->i_nlink) -+ set_nlink(inode, 1); -+ d_tmpfile(dentry, inode); -+ au_di(dentry)->di_tmpfile = 1; -+ -+ /* update without i_mutex */ -+ if (au_ibtop(dir) == au_dbtop(dentry)) -+ au_cpup_attr_timesizes(dir); -+ } -+ dput(h_dentry); -+ -+out_mnt: -+ vfsub_mnt_drop_write(h_mnt); -+out_parent: -+ di_write_unlock(parent); -+ dput(parent); -+ di_write_unlock(dentry); -+ if (unlikely(err)) { -+ au_di_fin(dentry); -+ dentry->d_fsdata = NULL; -+ } -+out_si: -+ si_read_unlock(sb); -+out: -+ inode_unlock(dir); -+ 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 || !h_inode->i_nlink) { -+ /* 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); -+ inc_nlink(inode); -+ inode->i_ctime = dir->i_ctime; -+ 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 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) { -+ 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 -Nurp linux-5.6.3/fs/aufs/i_op.c linux-5.6.3-aufs/fs/aufs/i_op.c ---- linux-5.6.3/fs/aufs/i_op.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/i_op.c 2020-04-10 12:40:52.191049456 +0300 -@@ -0,0 +1,1485 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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)); -+ -+ 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. -+ */ -+ if ((write_mask && !au_br_writable(brperm)) -+ || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode) -+ && write_mask && !(mask & MAY_READ)) -+ || !h_inode->i_op->permission) { -+ /* AuLabel(generic_permission); */ -+ /* AuDbg("get_acl %ps\n", h_inode->i_op->get_acl); */ -+ err = generic_permission(h_inode, mask); -+ if (err == -EOPNOTSUPP && au_test_nfs_noacl(h_inode)) -+ err = h_inode->i_op->permission(h_inode, mask); -+ AuTraceErr(err); -+ } else { -+ /* AuLabel(h_inode->permission); */ -+ err = h_inode->i_op->permission(h_inode, mask); -+ 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 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 = !h_i->i_nlink; -+ } -+ } -+ -+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 dentry *dentry, struct iattr *ia) -+{ -+ int err; -+ struct inode *inode, *delegated; -+ struct super_block *sb; -+ struct file *file; -+ struct au_icpup_args *a; -+ -+ inode = d_inode(dentry); -+ IMustLock(inode); -+ -+ err = setattr_prepare(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)) -+ err = vfsub_acl_chmod(a->h_inode, 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; -+ -+ 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; -+ -+ inode_unlock(a->h_inode); -+ switch (arg->type) { -+ case AU_XATTR_SET: -+ AuDebugOn(d_is_negative(h_path.dentry)); -+ err = vfsub_setxattr(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_inode, -+ 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->i_ctime = st->ctime; -+ -+ au_cpup_attr_nlink(inode, /*force*/0); -+ if (S_ISDIR(inode->i_mode)) { -+ n = inode->i_nlink; -+ n -= nlink; -+ n += st->nlink; -+ smp_mb(); /* for i_nlink */ -+ /* 0 can happen */ -+ 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, 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; -+ struct inode *inode; -+ -+ 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: -+ inode = d_inode(dentry); -+ 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(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, /*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 */ -+ err = vfs_getattr(&h_path, st, request, query); -+ if (!err) { -+ if (positive) -+ au_refresh_iattr(inode, st, -+ d_inode(h_path.dentry)->i_nlink); -+ goto out_fill; /* success */ -+ } -+ AuTraceErr(err); -+ goto out_di; -+ -+out_fill: -+ generic_fillattr(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, struct timespec64 *ts, -+ 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, ts, 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_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_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_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 -Nurp linux-5.6.3/fs/aufs/i_op_del.c linux-5.6.3-aufs/fs/aufs/i_op_del.c ---- linux-5.6.3/fs/aufs/i_op_del.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/i_op_del.c 2020-04-10 12:40:52.191049456 +0300 -@@ -0,0 +1,500 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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; -+ -+ 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(!h_inode->i_nlink)) -+ 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; -+ if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1) -+ && au_test_h_perm(d_inode(h_parent), -+ MAY_EXEC | MAY_WRITE))) -+ goto out; -+ -+ h_latest = au_sio_lkup_one(&dentry->d_name, h_parent); -+ 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->i_ctime = dir->i_ctime; -+ -+ 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; -+ 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*/ -+ inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime; -+ } else -+ /* todo: this timestamp may be reverted later */ -+ inode->i_ctime = h_dir->i_ctime; -+ 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 -Nurp linux-5.6.3/fs/aufs/i_op_ren.c linux-5.6.3-aufs/fs/aufs/i_op_ren.c ---- linux-5.6.3/fs/aufs/i_op_ren.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/i_op_ren.c 2020-04-10 12:40:52.191049456 +0300 -@@ -0,0 +1,1237 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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; -+ -+ a->h_path.dentry = vfsub_lkup_one(&a->src_dentry->d_name, -+ a->src_h_parent); -+ 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; -+ -+ a->h_path.dentry = vfsub_lkup_one(&a->dst_dentry->d_name, -+ a->dst_h_parent); -+ 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; -+ -+ 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*/ -+ a->dst_inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime; -+ } -+ 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*/ -+ a->src_inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime; -+ -+ 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 (h_inode->i_nlink) -+ 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 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(!a->dst_inode->i_nlink)) -+ 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 -Nurp linux-5.6.3/fs/aufs/Kconfig linux-5.6.3-aufs/fs/aufs/Kconfig ---- linux-5.6.3/fs/aufs/Kconfig 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/Kconfig 2020-04-10 12:40:52.187049268 +0300 -@@ -0,0 +1,199 @@ -+# SPDX-License-Identifier: GPL-2.0 -+config AUFS_FS -+ bool "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 = y -+ 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 infromation 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 -Nurp linux-5.6.3/fs/aufs/lcnt.h linux-5.6.3-aufs/fs/aufs/lcnt.h ---- linux-5.6.3/fs/aufs/lcnt.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/lcnt.h 2020-04-10 12:40:52.191049456 +0300 -@@ -0,0 +1,173 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2018-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -+#define AuLCntZero(val) do {} while (0) -+#endif -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_LCNT_H__ */ -diff -Nurp linux-5.6.3/fs/aufs/loop.c linux-5.6.3-aufs/fs/aufs/loop.c ---- linux-5.6.3/fs/aufs/loop.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/loop.c 2020-04-10 12:40:52.191049456 +0300 -@@ -0,0 +1,135 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.6.3/fs/aufs/loop.h linux-5.6.3-aufs/fs/aufs/loop.h ---- linux-5.6.3/fs/aufs/loop.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/loop.h 2020-04-10 12:40:52.191049456 +0300 -@@ -0,0 +1,42 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.6.3/fs/aufs/magic.mk linux-5.6.3-aufs/fs/aufs/magic.mk ---- linux-5.6.3/fs/aufs/magic.mk 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/magic.mk 2020-04-10 12:40:52.191049456 +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 -Nurp linux-5.6.3/fs/aufs/Makefile linux-5.6.3-aufs/fs/aufs/Makefile ---- linux-5.6.3/fs/aufs/Makefile 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/Makefile 2020-04-10 12:40:52.187049268 +0300 -@@ -0,0 +1,39 @@ -+# SPDX-License-Identifier: GPL-2.0 -+ -+include ${srctree}/${src}/magic.mk -+-include ${srctree}/${src}/priv_def.mk -+ -+# cf. include/linux/kernel.h -+# enable pr_debug -+ccflags-y += -DDEBUG -+# sparse requires the full pathname -+ccflags-y += -include ${srctree}/include/uapi/linux/aufs_type.h -+ -+obj-$(CONFIG_AUFS_FS) += aufs.o -+aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \ -+ wkq.o vfsub.o dcsub.o \ -+ cpup.o whout.o wbr_policy.o \ -+ dinfo.o dentry.o \ -+ dynop.o \ -+ finfo.o file.o f_op.o \ -+ dir.o vdir.o \ -+ iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \ -+ 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 -Nurp linux-5.6.3/fs/aufs/module.c linux-5.6.3-aufs/fs/aufs/module.c ---- linux-5.6.3/fs/aufs/module.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/module.c 2020-04-10 12:40:52.191049456 +0300 -@@ -0,0 +1,259 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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); -+ -+/* 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 -Nurp linux-5.6.3/fs/aufs/module.h linux-5.6.3-aufs/fs/aufs/module.h ---- linux-5.6.3/fs/aufs/module.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/module.h 2020-04-10 12:40:52.191049456 +0300 -@@ -0,0 +1,153 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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) - kmalloc_index(new_sz); -+#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 AuCacheFuncs(name, index) \ -+ static inline struct au_##name *au_cache_alloc_##name(void) \ -+ { return kmem_cache_alloc(au_cache[AuCache_##index], GFP_NOFS); } \ -+ 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); -+AuCacheFuncs(icntnr, ICNTNR); -+AuCacheFuncs(finfo, FINFO); -+AuCacheFuncs(vdir, VDIR); -+AuCacheFuncs(vdir_dehstr, DEHSTR); -+#ifdef CONFIG_AUFS_HNOTIFY -+AuCacheFuncs(hnotify, HNOTIFY); -+#endif -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_MODULE_H__ */ -diff -Nurp linux-5.6.3/fs/aufs/mvdown.c linux-5.6.3-aufs/fs/aufs/mvdown.c ---- linux-5.6.3/fs/aufs/mvdown.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/mvdown.c 2020-04-10 12:40:52.192049502 +0300 -@@ -0,0 +1,693 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2011-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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)) -+ && a->inode->i_nlink == 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), a->inode->i_nlink, -+ a->mvd_h_src_inode->i_nlink, -+ 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 -Nurp linux-5.6.3/fs/aufs/opts.c linux-5.6.3-aufs/fs/aufs/opts.c ---- linux-5.6.3/fs/aufs/opts.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/opts.c 2020-04-10 12:40:52.192049502 +0300 -@@ -0,0 +1,1867 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * mount options/flags -+ */ -+ -+#include -+#include /* a distribution requires */ -+#include -+#include "aufs.h" -+ -+/* ---------------------------------------------------------------------- */ -+ -+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_rdblk_def, Opt_rdhash_def, -+ Opt_xino, Opt_noxino, -+ Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino, -+ Opt_trunc_xino_path, Opt_itrunc_xino, -+ Opt_trunc_xib, Opt_notrunc_xib, -+ Opt_shwh, Opt_noshwh, -+ Opt_plink, Opt_noplink, Opt_list_plink, -+ Opt_udba, -+ Opt_dio, Opt_nodio, -+ Opt_diropq_a, Opt_diropq_w, -+ Opt_warn_perm, Opt_nowarn_perm, -+ Opt_wbr_copyup, Opt_wbr_create, -+ Opt_fhsm_sec, -+ Opt_verbose, Opt_noverbose, -+ Opt_sum, Opt_nosum, Opt_wsum, -+ Opt_dirperm1, Opt_nodirperm1, -+ Opt_dirren, Opt_nodirren, -+ Opt_acl, Opt_noacl, -+ Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err -+}; -+ -+static match_table_t options = { -+ {Opt_br, "br=%s"}, -+ {Opt_br, "br:%s"}, -+ -+ {Opt_add, "add=%d:%s"}, -+ {Opt_add, "add:%d:%s"}, -+ {Opt_add, "ins=%d:%s"}, -+ {Opt_add, "ins:%d:%s"}, -+ {Opt_append, "append=%s"}, -+ {Opt_append, "append:%s"}, -+ {Opt_prepend, "prepend=%s"}, -+ {Opt_prepend, "prepend:%s"}, -+ -+ {Opt_del, "del=%s"}, -+ {Opt_del, "del:%s"}, -+ /* {Opt_idel, "idel:%d"}, */ -+ {Opt_mod, "mod=%s"}, -+ {Opt_mod, "mod:%s"}, -+ /* {Opt_imod, "imod:%d:%s"}, */ -+ -+ {Opt_dirwh, "dirwh=%d"}, -+ -+ {Opt_xino, "xino=%s"}, -+ {Opt_noxino, "noxino"}, -+ {Opt_trunc_xino, "trunc_xino"}, -+ {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"}, -+ {Opt_notrunc_xino, "notrunc_xino"}, -+ {Opt_trunc_xino_path, "trunc_xino=%s"}, -+ {Opt_itrunc_xino, "itrunc_xino=%d"}, -+ /* {Opt_zxino, "zxino=%s"}, */ -+ {Opt_trunc_xib, "trunc_xib"}, -+ {Opt_notrunc_xib, "notrunc_xib"}, -+ -+#ifdef CONFIG_PROC_FS -+ {Opt_plink, "plink"}, -+#else -+ {Opt_ignore_silent, "plink"}, -+#endif -+ -+ {Opt_noplink, "noplink"}, -+ -+#ifdef CONFIG_AUFS_DEBUG -+ {Opt_list_plink, "list_plink"}, -+#endif -+ -+ {Opt_udba, "udba=%s"}, -+ -+ {Opt_dio, "dio"}, -+ {Opt_nodio, "nodio"}, -+ -+#ifdef CONFIG_AUFS_DIRREN -+ {Opt_dirren, "dirren"}, -+ {Opt_nodirren, "nodirren"}, -+#else -+ {Opt_ignore, "dirren"}, -+ {Opt_ignore_silent, "nodirren"}, -+#endif -+ -+#ifdef CONFIG_AUFS_FHSM -+ {Opt_fhsm_sec, "fhsm_sec=%d"}, -+#else -+ {Opt_ignore, "fhsm_sec=%d"}, -+#endif -+ -+ {Opt_diropq_a, "diropq=always"}, -+ {Opt_diropq_a, "diropq=a"}, -+ {Opt_diropq_w, "diropq=whiteouted"}, -+ {Opt_diropq_w, "diropq=w"}, -+ -+ {Opt_warn_perm, "warn_perm"}, -+ {Opt_nowarn_perm, "nowarn_perm"}, -+ -+ /* keep them temporary */ -+ {Opt_ignore_silent, "nodlgt"}, -+ {Opt_ignore, "clean_plink"}, -+ -+#ifdef CONFIG_AUFS_SHWH -+ {Opt_shwh, "shwh"}, -+#endif -+ {Opt_noshwh, "noshwh"}, -+ -+ {Opt_dirperm1, "dirperm1"}, -+ {Opt_nodirperm1, "nodirperm1"}, -+ -+ {Opt_verbose, "verbose"}, -+ {Opt_verbose, "v"}, -+ {Opt_noverbose, "noverbose"}, -+ {Opt_noverbose, "quiet"}, -+ {Opt_noverbose, "q"}, -+ {Opt_noverbose, "silent"}, -+ -+ {Opt_sum, "sum"}, -+ {Opt_nosum, "nosum"}, -+ {Opt_wsum, "wsum"}, -+ -+ {Opt_rdcache, "rdcache=%d"}, -+ {Opt_rdblk, "rdblk=%d"}, -+ {Opt_rdblk_def, "rdblk=def"}, -+ {Opt_rdhash, "rdhash=%d"}, -+ {Opt_rdhash_def, "rdhash=def"}, -+ -+ {Opt_wbr_create, "create=%s"}, -+ {Opt_wbr_create, "create_policy=%s"}, -+ {Opt_wbr_copyup, "cpup=%s"}, -+ {Opt_wbr_copyup, "copyup=%s"}, -+ {Opt_wbr_copyup, "copyup_policy=%s"}, -+ -+ /* generic VFS flag */ -+#ifdef CONFIG_FS_POSIX_ACL -+ {Opt_acl, "acl"}, -+ {Opt_noacl, "noacl"}, -+#else -+ {Opt_ignore, "acl"}, -+ {Opt_ignore_silent, "noacl"}, -+#endif -+ -+ /* internal use for the scripts */ -+ {Opt_ignore_silent, "si=%s"}, -+ -+ {Opt_br, "dirs=%s"}, -+ {Opt_ignore, "debug=%d"}, -+ {Opt_ignore, "delete=whiteout"}, -+ {Opt_ignore, "delete=all"}, -+ {Opt_ignore, "imap=%s"}, -+ -+ /* temporary workaround, due to old mount(8)? */ -+ {Opt_ignore_silent, "relatime"}, -+ -+ {Opt_err, NULL} -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+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; -+} -+ -+static int noinline_for_stack 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} -+}; -+ -+static int noinline_for_stack 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; -+} -+ -+static int noinline_for_stack -+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} -+}; -+ -+static int noinline_for_stack 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); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY; -+ -+static void dump_opts(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: -+ case Opt_idel: -+ u.del = &opt->del; -+ AuDbg("del {%s, %p}\n", -+ u.del->pathname, u.del->h_path.dentry); -+ break; -+ case Opt_mod: -+ 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 %u\n", opt->rdblk); -+ break; -+ case Opt_rdblk_def: -+ AuDbg("rdblk_def\n"); -+ break; -+ case Opt_rdhash: -+ AuDbg("rdhash %u\n", opt->rdhash); -+ break; -+ case Opt_rdhash_def: -+ AuDbg("rdhash_def\n"); -+ break; -+ case Opt_xino: -+ u.xino = &opt->xino; -+ AuDbg("xino {%s %pD}\n", u.xino->path, u.xino->file); -+ break; -+ case Opt_trunc_xino: -+ AuLabel(trunc_xino); -+ break; -+ case Opt_notrunc_xino: -+ AuLabel(notrunc_xino); -+ break; -+ case Opt_trunc_xino_path: -+ 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_trunc_xib: -+ AuLabel(trunc_xib); -+ break; -+ case Opt_notrunc_xib: -+ AuLabel(notrunc_xib); -+ break; -+ case Opt_shwh: -+ AuLabel(shwh); -+ break; -+ case Opt_noshwh: -+ AuLabel(noshwh); -+ break; -+ case Opt_dirperm1: -+ AuLabel(dirperm1); -+ break; -+ case Opt_nodirperm1: -+ AuLabel(nodirperm1); -+ break; -+ case Opt_plink: -+ AuLabel(plink); -+ break; -+ case Opt_noplink: -+ AuLabel(noplink); -+ 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_dio: -+ AuLabel(dio); -+ break; -+ case Opt_nodio: -+ AuLabel(nodio); -+ break; -+ case Opt_diropq_a: -+ AuLabel(diropq_a); -+ break; -+ case Opt_diropq_w: -+ AuLabel(diropq_w); -+ break; -+ case Opt_warn_perm: -+ AuLabel(warn_perm); -+ break; -+ case Opt_nowarn_perm: -+ AuLabel(nowarn_perm); -+ break; -+ case Opt_verbose: -+ AuLabel(verbose); -+ break; -+ case Opt_noverbose: -+ AuLabel(noverbose); -+ break; -+ case Opt_sum: -+ AuLabel(sum); -+ break; -+ case Opt_nosum: -+ AuLabel(nosum); -+ 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: -+ case AuWbrCreate_PMFSV: -+ AuDbg("%d sec\n", u.create->mfs_second); -+ break; -+ case AuWbrCreate_MFSRR: -+ case AuWbrCreate_TDMFS: -+ AuDbg("%llu watermark\n", -+ u.create->mfsrr_watermark); -+ break; -+ case AuWbrCreate_MFSRRV: -+ case AuWbrCreate_TDMFSV: -+ 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; -+ case Opt_dirren: -+ AuLabel(dirren); -+ break; -+ case Opt_nodirren: -+ AuLabel(nodirren); -+ break; -+ case Opt_acl: -+ AuLabel(acl); -+ break; -+ case Opt_noacl: -+ AuLabel(noacl); -+ break; -+ default: -+ BUG(); -+ } -+ opt++; -+ } -+#endif -+} -+ -+void au_opts_free(struct au_opts *opts) -+{ -+ struct au_opt *opt; -+ -+ opt = opts->opt; -+ while (opt->type != Opt_tail) { -+ switch (opt->type) { -+ case Opt_add: -+ case Opt_append: -+ case Opt_prepend: -+ path_put(&opt->add.path); -+ break; -+ case Opt_del: -+ case Opt_idel: -+ path_put(&opt->del.h_path); -+ break; -+ case Opt_mod: -+ case Opt_imod: -+ dput(opt->mod.h_root); -+ break; -+ case Opt_xino: -+ fput(opt->xino.file); -+ break; -+ } -+ opt++; -+ } -+} -+ -+static int 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 = br_perm_val(p); -+ } -+ -+ err = vfsub_kern_path(add->pathname, lkup_dirflags, &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_opts_parse_del(struct au_opt_del *del, substring_t args[]) -+{ -+ int err; -+ -+ del->pathname = args[0].from; -+ AuDbg("del path %s\n", del->pathname); -+ -+ err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path); -+ if (unlikely(err)) -+ pr_err("lookup failed %s (%d)\n", del->pathname, err); -+ -+ return err; -+} -+ -+#if 0 /* reserved for future use */ -+static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex, -+ struct au_opt_del *del, substring_t args[]) -+{ -+ int err; -+ struct dentry *root; -+ -+ err = -EINVAL; -+ root = sb->s_root; -+ aufs_read_lock(root, AuLock_FLUSH); -+ if (bindex < 0 || au_sbbot(sb) < bindex) { -+ pr_err("out of bounds, %d\n", 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); -+ return err; -+} -+#endif -+ -+static int noinline_for_stack -+au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[]) -+{ -+ int err; -+ struct path path; -+ char *p; -+ -+ err = -EINVAL; -+ mod->path = args[0].from; -+ p = strchr(mod->path, '='); -+ if (unlikely(!p)) { -+ pr_err("no permission %s\n", args[0].from); -+ goto out; -+ } -+ -+ *p++ = 0; -+ err = vfsub_kern_path(mod->path, lkup_dirflags, &path); -+ if (unlikely(err)) { -+ pr_err("lookup failed %s (%d)\n", mod->path, err); -+ goto out; -+ } -+ -+ mod->perm = br_perm_val(p); -+ AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p); -+ mod->h_root = dget(path.dentry); -+ path_put(&path); -+ -+out: -+ return err; -+} -+ -+#if 0 /* reserved for future use */ -+static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex, -+ struct au_opt_mod *mod, substring_t args[]) -+{ -+ int err; -+ struct dentry *root; -+ -+ err = -EINVAL; -+ root = sb->s_root; -+ aufs_read_lock(root, AuLock_FLUSH); -+ if (bindex < 0 || au_sbbot(sb) < bindex) { -+ pr_err("out of bounds, %d\n", bindex); -+ goto out; -+ } -+ -+ err = 0; -+ mod->perm = br_perm_val(args[1].from); -+ AuDbg("mod path %s, perm 0x%x, %s\n", -+ mod->path, mod->perm, args[1].from); -+ mod->h_root = dget(au_h_dptr(root, bindex)); -+ -+out: -+ aufs_read_unlock(root, !AuLock_IR); -+ return err; -+} -+#endif -+ -+static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino, -+ substring_t args[]) -+{ -+ int err; -+ struct file *file; -+ -+ file = au_xino_create(sb, args[0].from, /*silent*/0, /*wbrtop*/0); -+ err = PTR_ERR(file); -+ if (IS_ERR(file)) -+ goto out; -+ -+ err = -EINVAL; -+ if (unlikely(file->f_path.dentry->d_sb == sb)) { -+ fput(file); -+ pr_err("%s must be outside\n", args[0].from); -+ goto out; -+ } -+ -+ err = 0; -+ xino->file = file; -+ xino->path = args[0].from; -+ -+out: -+ return err; -+} -+ -+static int noinline_for_stack -+au_opts_parse_xino_itrunc_path(struct super_block *sb, -+ struct au_opt_xino_itrunc *xino_itrunc, -+ substring_t args[]) -+{ -+ int err; -+ aufs_bindex_t bbot, bindex; -+ struct path path; -+ struct dentry *root; -+ -+ err = vfsub_kern_path(args[0].from, lkup_dirflags, &path); -+ if (unlikely(err)) { -+ pr_err("lookup failed %s (%d)\n", args[0].from, err); -+ goto out; -+ } -+ -+ xino_itrunc->bindex = -1; -+ root = sb->s_root; -+ aufs_read_lock(root, AuLock_FLUSH); -+ bbot = au_sbbot(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)) { -+ pr_err("no such branch %s\n", args[0].from); -+ err = -EINVAL; -+ } -+ -+out: -+ return err; -+} -+ -+/* called without aufs lock */ -+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts) -+{ -+ int err, n, token; -+ aufs_bindex_t bindex; -+ unsigned char skipped; -+ struct dentry *root; -+ struct au_opt *opt, *opt_tail; -+ char *opt_str; -+ /* reduce the stack space */ -+ union { -+ struct au_opt_xino_itrunc *xino_itrunc; -+ struct au_opt_wbr_create *create; -+ } u; -+ struct { -+ substring_t args[MAX_OPT_ARGS]; -+ } *a; -+ -+ err = -ENOMEM; -+ a = kmalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ -+ root = sb->s_root; -+ err = 0; -+ bindex = 0; -+ opt = opts->opt; -+ opt_tail = opt + opts->max_opt - 1; -+ opt->type = Opt_tail; -+ while (!err && (opt_str = strsep(&str, ",")) && *opt_str) { -+ err = -EINVAL; -+ skipped = 0; -+ token = match_token(opt_str, options, a->args); -+ switch (token) { -+ case Opt_br: -+ err = 0; -+ while (!err && (opt_str = strsep(&a->args[0].from, ":")) -+ && *opt_str) { -+ err = opt_add(opt, opt_str, opts->sb_flags, -+ bindex++); -+ if (unlikely(!err && ++opt > opt_tail)) { -+ err = -E2BIG; -+ break; -+ } -+ opt->type = Opt_tail; -+ skipped = 1; -+ } -+ break; -+ case Opt_add: -+ if (unlikely(match_int(&a->args[0], &n))) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ bindex = n; -+ err = opt_add(opt, a->args[1].from, opts->sb_flags, -+ bindex); -+ if (!err) -+ opt->type = token; -+ break; -+ case Opt_append: -+ err = opt_add(opt, a->args[0].from, opts->sb_flags, -+ /*dummy bindex*/1); -+ if (!err) -+ opt->type = token; -+ break; -+ case Opt_prepend: -+ err = opt_add(opt, a->args[0].from, opts->sb_flags, -+ /*bindex*/0); -+ if (!err) -+ opt->type = token; -+ break; -+ case Opt_del: -+ err = au_opts_parse_del(&opt->del, a->args); -+ if (!err) -+ opt->type = token; -+ break; -+#if 0 /* reserved for future use */ -+ case Opt_idel: -+ del->pathname = "(indexed)"; -+ if (unlikely(match_int(&args[0], &n))) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ err = au_opts_parse_idel(sb, n, &opt->del, a->args); -+ if (!err) -+ opt->type = token; -+ break; -+#endif -+ case Opt_mod: -+ err = au_opts_parse_mod(&opt->mod, a->args); -+ if (!err) -+ opt->type = token; -+ break; -+#ifdef IMOD /* reserved for future use */ -+ case Opt_imod: -+ u.mod->path = "(indexed)"; -+ if (unlikely(match_int(&a->args[0], &n))) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ err = au_opts_parse_imod(sb, n, &opt->mod, a->args); -+ if (!err) -+ opt->type = token; -+ break; -+#endif -+ case Opt_xino: -+ err = au_opts_parse_xino(sb, &opt->xino, a->args); -+ if (!err) -+ opt->type = token; -+ break; -+ -+ case Opt_trunc_xino_path: -+ err = au_opts_parse_xino_itrunc_path -+ (sb, &opt->xino_itrunc, a->args); -+ if (!err) -+ opt->type = token; -+ break; -+ -+ case Opt_itrunc_xino: -+ u.xino_itrunc = &opt->xino_itrunc; -+ if (unlikely(match_int(&a->args[0], &n))) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ u.xino_itrunc->bindex = n; -+ aufs_read_lock(root, AuLock_FLUSH); -+ if (n < 0 || au_sbbot(sb) < n) { -+ pr_err("out of bounds, %d\n", n); -+ aufs_read_unlock(root, !AuLock_IR); -+ break; -+ } -+ aufs_read_unlock(root, !AuLock_IR); -+ err = 0; -+ opt->type = token; -+ break; -+ -+ case Opt_dirwh: -+ if (unlikely(match_int(&a->args[0], &opt->dirwh))) -+ break; -+ err = 0; -+ opt->type = token; -+ break; -+ -+ case Opt_rdcache: -+ if (unlikely(match_int(&a->args[0], &n))) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ if (unlikely(n > AUFS_RDCACHE_MAX)) { -+ pr_err("rdcache must be smaller than %d\n", -+ AUFS_RDCACHE_MAX); -+ break; -+ } -+ opt->rdcache = n; -+ err = 0; -+ opt->type = token; -+ break; -+ case Opt_rdblk: -+ if (unlikely(match_int(&a->args[0], &n) -+ || n < 0 -+ || n > KMALLOC_MAX_SIZE)) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ if (unlikely(n && n < NAME_MAX)) { -+ pr_err("rdblk must be larger than %d\n", -+ NAME_MAX); -+ break; -+ } -+ opt->rdblk = n; -+ err = 0; -+ opt->type = token; -+ break; -+ case Opt_rdhash: -+ if (unlikely(match_int(&a->args[0], &n) -+ || n < 0 -+ || n * sizeof(struct hlist_head) -+ > KMALLOC_MAX_SIZE)) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ opt->rdhash = n; -+ err = 0; -+ opt->type = token; -+ break; -+ -+ case Opt_trunc_xino: -+ case Opt_notrunc_xino: -+ case Opt_noxino: -+ case Opt_trunc_xib: -+ case Opt_notrunc_xib: -+ case Opt_shwh: -+ case Opt_noshwh: -+ case Opt_dirperm1: -+ case Opt_nodirperm1: -+ case Opt_plink: -+ case Opt_noplink: -+ case Opt_list_plink: -+ case Opt_dio: -+ case Opt_nodio: -+ case Opt_diropq_a: -+ case Opt_diropq_w: -+ case Opt_warn_perm: -+ case Opt_nowarn_perm: -+ case Opt_verbose: -+ case Opt_noverbose: -+ case Opt_sum: -+ case Opt_nosum: -+ case Opt_wsum: -+ case Opt_rdblk_def: -+ case Opt_rdhash_def: -+ case Opt_dirren: -+ case Opt_nodirren: -+ case Opt_acl: -+ case Opt_noacl: -+ err = 0; -+ opt->type = token; -+ break; -+ -+ case Opt_udba: -+ opt->udba = udba_val(a->args[0].from); -+ if (opt->udba >= 0) { -+ err = 0; -+ opt->type = token; -+ } else -+ pr_err("wrong value, %s\n", opt_str); -+ break; -+ -+ case Opt_wbr_create: -+ u.create = &opt->wbr_create; -+ u.create->wbr_create -+ = au_wbr_create_val(a->args[0].from, u.create); -+ if (u.create->wbr_create >= 0) { -+ err = 0; -+ opt->type = token; -+ } else -+ pr_err("wrong value, %s\n", opt_str); -+ break; -+ case Opt_wbr_copyup: -+ opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from); -+ if (opt->wbr_copyup >= 0) { -+ err = 0; -+ opt->type = token; -+ } else -+ pr_err("wrong value, %s\n", opt_str); -+ break; -+ -+ case Opt_fhsm_sec: -+ if (unlikely(match_int(&a->args[0], &n) -+ || n < 0)) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ if (sysaufs_brs) { -+ opt->fhsm_second = n; -+ opt->type = token; -+ } else -+ pr_warn("ignored %s\n", opt_str); -+ err = 0; -+ break; -+ -+ case Opt_ignore: -+ pr_warn("ignored %s\n", opt_str); -+ /*FALLTHROUGH*/ -+ case Opt_ignore_silent: -+ skipped = 1; -+ err = 0; -+ break; -+ case Opt_err: -+ pr_err("unknown option %s\n", opt_str); -+ break; -+ } -+ -+ if (!err && !skipped) { -+ if (unlikely(++opt > opt_tail)) { -+ err = -E2BIG; -+ opt--; -+ opt->type = Opt_tail; -+ break; -+ } -+ opt->type = Opt_tail; -+ } -+ } -+ -+ au_kfree_rcu(a); -+ dump_opts(opts); -+ if (unlikely(err)) -+ au_opts_free(opts); -+ -+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: -+ au_opt_set(sbinfo->si_mntflags, PLINK); -+ break; -+ case Opt_noplink: -+ 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: -+ au_opt_set(sbinfo->si_mntflags, DIO); -+ au_fset_opts(opts->flags, REFRESH_DYAOP); -+ break; -+ case Opt_nodio: -+ 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: -+ au_opt_set(sbinfo->si_mntflags, WARN_PERM); -+ break; -+ case Opt_nowarn_perm: -+ au_opt_clr(sbinfo->si_mntflags, WARN_PERM); -+ break; -+ -+ case Opt_verbose: -+ au_opt_set(sbinfo->si_mntflags, VERBOSE); -+ break; -+ case Opt_noverbose: -+ au_opt_clr(sbinfo->si_mntflags, VERBOSE); -+ break; -+ -+ case Opt_sum: -+ au_opt_set(sbinfo->si_mntflags, SUM); -+ break; -+ case Opt_wsum: -+ au_opt_clr(sbinfo->si_mntflags, SUM); -+ au_opt_set(sbinfo->si_mntflags, SUM_W); -+ break; -+ case Opt_nosum: -+ au_opt_clr(sbinfo->si_mntflags, SUM); -+ au_opt_clr(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_rdblk_def: -+ sbinfo->si_rdblk = AUFS_RDBLK_DEF; -+ break; -+ case Opt_rdhash: -+ sbinfo->si_rdhash = opt->rdhash; -+ break; -+ case Opt_rdhash_def: -+ sbinfo->si_rdhash = AUFS_RDHASH_DEF; -+ break; -+ -+ case Opt_shwh: -+ au_opt_set(sbinfo->si_mntflags, SHWH); -+ break; -+ case Opt_noshwh: -+ au_opt_clr(sbinfo->si_mntflags, SHWH); -+ break; -+ -+ case Opt_dirperm1: -+ au_opt_set(sbinfo->si_mntflags, DIRPERM1); -+ break; -+ case Opt_nodirperm1: -+ au_opt_clr(sbinfo->si_mntflags, DIRPERM1); -+ break; -+ -+ case Opt_trunc_xino: -+ au_opt_set(sbinfo->si_mntflags, TRUNC_XINO); -+ break; -+ case Opt_notrunc_xino: -+ 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: -+ au_fset_opts(opts->flags, TRUNC_XIB); -+ break; -+ case Opt_notrunc_xib: -+ au_fclr_opts(opts->flags, TRUNC_XIB); -+ break; -+ -+ case Opt_dirren: -+ err = 1; -+ 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); -+ break; -+ case Opt_nodirren: -+ err = 1; -+ 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: -+ sb->s_flags |= SB_POSIXACL; -+ break; -+ case Opt_noacl: -+ 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 */ -+ add: /* indented label */ -+ case Opt_add: -+ 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 (unlikely(err)) -+ break; -+ -+ *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 -Nurp linux-5.6.3/fs/aufs/opts.h linux-5.6.3-aufs/fs/aufs/opts.h ---- linux-5.6.3/fs/aufs/opts.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/opts.h 2020-04-10 12:40:52.192049502 +0300 -@@ -0,0 +1,212 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * mount options/flags -+ */ -+ -+#ifndef __AUFS_OPTS_H__ -+#define __AUFS_OPTS_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+ -+struct file; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* 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 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 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; -+ }; -+}; -+ -+/* 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 */ -+void au_optstr_br_perm(au_br_perm_str_t *str, int perm); -+const char *au_optstr_udba(int udba); -+const char *au_optstr_wbr_copyup(int wbr_copyup); -+const char *au_optstr_wbr_create(int wbr_create); -+ -+void au_opts_free(struct au_opts *opts); -+struct super_block; -+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts); -+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); -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_OPTS_H__ */ -diff -Nurp linux-5.6.3/fs/aufs/plink.c linux-5.6.3-aufs/fs/aufs/plink.c ---- linux-5.6.3/fs/aufs/plink.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/plink.c 2020-04-10 12:40:52.192049502 +0300 -@@ -0,0 +1,503 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 dentry *h_parent; -+ struct au_branch *br; -+}; -+ -+static struct dentry *au_do_plink_lkup(struct qstr *tgtname, -+ struct dentry *h_parent, -+ struct au_branch *br) -+{ -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ -+ h_inode = d_inode(h_parent); -+ inode_lock_shared_nested(h_inode, AuLsc_I_CHILD2); -+ h_dentry = vfsub_lkup_one(tgtname, h_parent); -+ 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_parent, a->br); -+} -+ -+/* 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, *h_parent; -+ struct au_branch *br; -+ 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_parent = br->br_wbr->wbr_plink; -+ 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_parent = h_parent, -+ .br = br -+ }; -+ -+ 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_parent, br); -+ -+ return h_dentry; -+} -+ -+/* create a pseudo-link */ -+static int do_whplink(struct qstr *tgt, struct dentry *h_parent, -+ struct dentry *h_dentry, struct au_branch *br) -+{ -+ int err; -+ struct path h_path = { -+ .mnt = au_br_mnt(br) -+ }; -+ struct inode *h_dir, *delegated; -+ -+ h_dir = d_inode(h_parent); -+ inode_lock_nested(h_dir, AuLsc_I_CHILD2); -+again: -+ h_path.dentry = vfsub_lkup_one(tgt, h_parent); -+ 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 dentry *h_parent; -+ struct dentry *h_dentry; -+ struct au_branch *br; -+}; -+ -+static void call_do_whplink(void *args) -+{ -+ struct do_whplink_args *a = args; -+ *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br); -+} -+ -+static int whplink(struct dentry *h_dentry, struct inode *inode, -+ aufs_bindex_t bindex, struct au_branch *br) -+{ -+ int err, wkq_err; -+ struct au_wbr *wbr; -+ struct dentry *h_parent; -+ char a[PLINK_NAME_LEN]; -+ struct qstr tgtname = QSTR_INIT(a, 0); -+ -+ wbr = au_sbr(inode->i_sb, bindex)->br_wbr; -+ h_parent = wbr->wbr_plink; -+ 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_parent = h_parent, -+ .h_dentry = h_dentry, -+ .br = br -+ }; -+ wkq_err = au_wkq_wait(call_do_whplink, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } else -+ err = do_whplink(&tgtname, h_parent, h_dentry, br); -+ -+ 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, au_sbr(sb, 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 -Nurp linux-5.6.3/fs/aufs/poll.c linux-5.6.3-aufs/fs/aufs/poll.c ---- linux-5.6.3/fs/aufs/poll.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/poll.c 2020-04-10 12:40:52.192049502 +0300 -@@ -0,0 +1,38 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.6.3/fs/aufs/posix_acl.c linux-5.6.3-aufs/fs/aufs/posix_acl.c ---- linux-5.6.3/fs/aufs/posix_acl.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/posix_acl.c 2020-04-10 12:40:52.192049502 +0300 -@@ -0,0 +1,92 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2014-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * posix acl operations -+ */ -+ -+#include -+#include "aufs.h" -+ -+struct posix_acl *aufs_get_acl(struct inode *inode, int type) -+{ -+ struct posix_acl *acl; -+ int err; -+ aufs_bindex_t bindex; -+ struct inode *h_inode; -+ struct super_block *sb; -+ -+ acl = NULL; -+ sb = inode->i_sb; -+ si_read_lock(sb, AuLock_FLUSH); -+ ii_read_lock_child(inode); -+ if (!(sb->s_flags & SB_POSIXACL)) -+ goto out; -+ -+ 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 out; -+ } -+ -+ /* always topmost only */ -+ acl = get_acl(h_inode, type); -+ if (IS_ERR(acl)) -+ forget_cached_acl(inode, type); -+ else -+ set_cached_acl(inode, type, acl); -+ -+out: -+ ii_read_unlock(inode); -+ si_read_unlock(sb); -+ -+ AuTraceErrPtr(acl); -+ return acl; -+} -+ -+int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type) -+{ -+ int err; -+ ssize_t ssz; -+ struct dentry *dentry; -+ struct au_sxattr arg = { -+ .type = AU_ACL_SET, -+ .u.acl_set = { -+ .acl = acl, -+ .type = type -+ }, -+ }; -+ -+ IMustLock(inode); -+ -+ if (inode->i_ino == AUFS_ROOT_INO) -+ dentry = dget(inode->i_sb->s_root); -+ else { -+ dentry = d_find_alias(inode); -+ if (!dentry) -+ dentry = d_find_any_alias(inode); -+ if (!dentry) { -+ pr_warn("cannot handle this inode, " -+ "please report to aufs-users ML\n"); -+ err = -ENOENT; -+ goto out; -+ } -+ } -+ -+ ssz = au_sxattr(dentry, inode, &arg); -+ /* forget even it if succeeds since the branch might set differently */ -+ forget_cached_acl(inode, type); -+ dput(dentry); -+ err = ssz; -+ if (ssz >= 0) -+ err = 0; -+ -+out: -+ return err; -+} -diff -Nurp linux-5.6.3/fs/aufs/procfs.c linux-5.6.3-aufs/fs/aufs/procfs.c ---- linux-5.6.3/fs/aufs/procfs.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/procfs.c 2020-04-10 12:40:52.192049502 +0300 -@@ -0,0 +1,158 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2010-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 file_operations au_procfs_plm_fop = { -+ .write = au_procfs_plm_write, -+ .release = au_procfs_plm_release, -+ .owner = THIS_MODULE -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+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_fop); -+ 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 -Nurp linux-5.6.3/fs/aufs/rdu.c linux-5.6.3-aufs/fs/aufs/rdu.c ---- linux-5.6.3/fs/aufs/rdu.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/rdu.c 2020-04-10 12:40:52.192049502 +0300 -@@ -0,0 +1,371 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 int 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 && !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 -Nurp linux-5.6.3/fs/aufs/rwsem.h linux-5.6.3-aufs/fs/aufs/rwsem.h ---- linux-5.6.3/fs/aufs/rwsem.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/rwsem.h 2020-04-10 12:40:52.192049502 +0300 -@@ -0,0 +1,60 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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)) -+/* rwsem_is_locked() is unusable */ -+#define AuRwMustReadLock(rw) AuDebugOn(!lockdep_recursing(current) \ -+ && debug_locks \ -+ && !lockdep_is_held_type(rw, 1)) -+#define AuRwMustWriteLock(rw) AuDebugOn(!lockdep_recursing(current) \ -+ && debug_locks \ -+ && !lockdep_is_held_type(rw, 0)) -+#define AuRwMustAnyLock(rw) AuDebugOn(!lockdep_recursing(current) \ -+ && debug_locks \ -+ && !lockdep_is_held(rw)) -+#define AuRwDestroy(rw) AuDebugOn(!lockdep_recursing(current) \ -+ && debug_locks \ -+ && lockdep_is_held(rw)) -+ -+#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 -Nurp linux-5.6.3/fs/aufs/sbinfo.c linux-5.6.3-aufs/fs/aufs/sbinfo.c ---- linux-5.6.3/fs/aufs/sbinfo.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/sbinfo.c 2020-04-10 12:40:52.192049502 +0300 -@@ -0,0 +1,301 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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); -+} -+ -+int au_si_alloc(struct super_block *sb) -+{ -+ int err, i; -+ struct au_sbinfo *sbinfo; -+ -+ 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; -+ sb->s_fs_info = sbinfo; -+ si_pid_set(sb); -+ return 0; /* success */ -+ -+out_br: -+ au_kfree_try_rcu(sbinfo->si_branch); -+out_sbinfo: -+ au_kfree_rcu(sbinfo); -+out: -+ return 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 -Nurp linux-5.6.3/fs/aufs/super.c linux-5.6.3-aufs/fs/aufs/super.c ---- linux-5.6.3/fs/aufs/super.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/super.c 2020-04-10 12:40:52.192049502 +0300 -@@ -0,0 +1,1034 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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(); -+ 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 __maybe_unused, const char *pat, -+ const char *append) -+{ -+ char *p; -+ -+ p = fmt; -+ while (*pat != ':') -+ *p++ = *pat++; -+ *p++ = *pat++; -+ strcpy(p, append); -+ 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, wait); -+ 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; -+} -+ -+static 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); -+} -+ -+/* 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 aufs_remount_fs(struct super_block *sb, int *flags, char *data) -+{ -+ int err, do_dx; -+ unsigned int mntflags; -+ struct au_opts opts = { -+ .opt = NULL -+ }; -+ struct dentry *root; -+ struct inode *inode; -+ struct au_sbinfo *sbinfo; -+ -+ err = 0; -+ root = sb->s_root; -+ if (!data || !*data) { -+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (!err) { -+ di_write_lock_child(root); -+ err = au_opts_verify(sb, *flags, /*pending*/0); -+ aufs_write_unlock(root); -+ } -+ goto out; -+ } -+ -+ err = -ENOMEM; -+ opts.opt = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!opts.opt)) -+ goto out; -+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt); -+ opts.flags = AuOpts_REMOUNT; -+ opts.sb_flags = *flags; -+ -+ /* parse it before aufs lock */ -+ err = au_opts_parse(sb, data, &opts); -+ if (unlikely(err)) -+ goto out_opts; -+ -+ sbinfo = au_sbi(sb); -+ inode = d_inode(root); -+ inode_lock(inode); -+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (unlikely(err)) -+ goto out_mtx; -+ di_write_lock_child(root); -+ -+ /* au_opts_remount() may return an error */ -+ err = au_opts_remount(sb, &opts); -+ au_opts_free(&opts); -+ -+ if (au_ftest_opts(opts.flags, REFRESH)) -+ au_remount_refresh(sb, au_ftest_opts(opts.flags, REFRESH_IDOP)); -+ -+ if (au_ftest_opts(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_mtx: -+ inode_unlock(inode); -+out_opts: -+ free_page((unsigned long)opts.opt); -+out: -+ err = cvt_err(err); -+ AuTraceErr(err); -+ return err; -+} -+ -+static 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, -+ .remount_fs = aufs_remount_fs -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int 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; -+ set_nlink(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 int aufs_fill_super(struct super_block *sb, void *raw_data, -+ int silent __maybe_unused) -+{ -+ int err; -+ struct au_opts opts = { -+ .opt = NULL -+ }; -+ struct au_sbinfo *sbinfo; -+ struct dentry *root; -+ struct inode *inode; -+ char *arg = raw_data; -+ -+ if (unlikely(!arg || !*arg)) { -+ err = -EINVAL; -+ pr_err("no arg\n"); -+ goto out; -+ } -+ -+ err = -ENOMEM; -+ opts.opt = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!opts.opt)) -+ goto out; -+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt); -+ opts.sb_flags = sb->s_flags; -+ -+ err = au_si_alloc(sb); -+ if (unlikely(err)) -+ goto out_opts; -+ sbinfo = au_sbi(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 = alloc_root(sb); -+ if (unlikely(err)) { -+ si_write_unlock(sb); -+ goto out_info; -+ } -+ root = sb->s_root; -+ inode = d_inode(root); -+ -+ /* -+ * actually we can parse options regardless aufs lock here. -+ * but at remount time, parsing must be done before aufs lock. -+ * so we follow the same rule. -+ */ -+ ii_write_lock_parent(inode); -+ aufs_write_unlock(root); -+ err = au_opts_parse(sb, arg, &opts); -+ if (unlikely(err)) -+ goto out_root; -+ -+ /* lock vfs_inode first, then aufs. */ -+ inode_lock(inode); -+ aufs_write_lock(root); -+ err = au_opts_mount(sb, &opts); -+ au_opts_free(&opts); -+ if (!err && au_ftest_si(sbinfo, NO_DREVAL)) { -+ sb->s_d_op = &aufs_dop_noreval; -+ 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_opts; /* success */ -+ -+out_root: -+ dput(root); -+ sb->s_root = NULL; -+out_info: -+ kobject_put(&sbinfo->si_kobj); -+ sb->s_fs_info = NULL; -+out_opts: -+ free_page((unsigned long)opts.opt); -+out: -+ AuTraceErr(err); -+ err = cvt_err(err); -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static struct dentry *aufs_mount(struct file_system_type *fs_type, int flags, -+ const char *dev_name __maybe_unused, -+ void *raw_data) -+{ -+ struct dentry *root; -+ -+ /* all timestamps always follow the ones on the branch */ -+ /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */ -+ root = mount_nodev(fs_type, flags, raw_data, aufs_fill_super); -+ if (IS_ERR(root)) -+ goto out; -+ -+ au_sbilist_add(root->d_sb); -+ -+out: -+ return root; -+} -+ -+static void aufs_kill_sb(struct super_block *sb) -+{ -+ struct au_sbinfo *sbinfo; -+ -+ sbinfo = au_sbi(sb); -+ if (sbinfo) { -+ au_sbilist_del(sb); -+ aufs_write_lock(sb->s_root); -+ 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); -+ au_dr_opt_flush(sb); -+ sbinfo->si_sb = NULL; -+ aufs_write_unlock(sb->s_root); -+ au_nwt_flush(&sbinfo->si_nowait); -+ } -+ 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, -+ .mount = aufs_mount, -+ .kill_sb = aufs_kill_sb, -+ /* no need to __module_get() and module_put(). */ -+ .owner = THIS_MODULE, -+}; -diff -Nurp linux-5.6.3/fs/aufs/super.h linux-5.6.3-aufs/fs/aufs/super.h ---- linux-5.6.3/fs/aufs/super.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/super.h 2020-04-10 12:40:52.192049502 +0300 -@@ -0,0 +1,576 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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) */ -+ vfs_readf_t si_xread; -+ vfs_writef_t si_xwrite; -+ 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 */ -+extern struct file_system_type aufs_fs_type; -+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); -+ -+/* sbinfo.c */ -+void au_si_free(struct kobject *kobj); -+int 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 -Nurp linux-5.6.3/fs/aufs/sysaufs.c linux-5.6.3-aufs/fs/aufs/sysaufs.c ---- linux-5.6.3/fs/aufs/sysaufs.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/sysaufs.c 2020-04-10 12:40:52.192049502 +0300 -@@ -0,0 +1,80 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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, -+}; -+ -+static const struct sysfs_ops au_sbi_ops = { -+ .show = sysaufs_si_show -+}; -+ -+static struct kobj_type au_sbi_ktype = { -+ .release = au_si_free, -+ .sysfs_ops = &au_sbi_ops, -+ .default_attrs = sysaufs_si_attrs -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+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 -Nurp linux-5.6.3/fs/aufs/sysaufs.h linux-5.6.3-aufs/fs/aufs/sysaufs.h ---- linux-5.6.3/fs/aufs/sysaufs.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/sysaufs.h 2020-04-10 12:40:52.192049502 +0300 -@@ -0,0 +1,89 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.6.3/fs/aufs/sysfs.c linux-5.6.3-aufs/fs/aufs/sysfs.c ---- linux-5.6.3/fs/aufs/sysfs.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/sysfs.c 2020-04-10 12:40:52.192049502 +0300 -@@ -0,0 +1,338 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * sysfs interface -+ */ -+ -+#include -+#include -+#include "aufs.h" -+ -+static struct attribute *au_attr[] = { -+ 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 -Nurp linux-5.6.3/fs/aufs/sysrq.c linux-5.6.3-aufs/fs/aufs/sysrq.c ---- linux-5.6.3/fs/aufs/sysrq.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/sysrq.c 2020-04-10 12:40:52.192049502 +0300 -@@ -0,0 +1,136 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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(int 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 -Nurp linux-5.6.3/fs/aufs/wbr_policy.c linux-5.6.3-aufs/fs/aufs/wbr_policy.c ---- linux-5.6.3/fs/aufs/wbr_policy.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/wbr_policy.c 2020-04-10 12:40:52.193049549 +0300 -@@ -0,0 +1,817 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.6.3/fs/aufs/vdir.c linux-5.6.3-aufs/fs/aufs/vdir.c ---- linux-5.6.3/fs/aufs/vdir.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/vdir.c 2020-04-10 12:40:52.193049549 +0300 -@@ -0,0 +1,883 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 int 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 -Nurp linux-5.6.3/fs/aufs/vfsub.c linux-5.6.3-aufs/fs/aufs/vfsub.c ---- linux-5.6.3/fs/aufs/vfsub.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/vfsub.c 2020-04-10 12:40:52.193049549 +0300 -@@ -0,0 +1,889 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * sub-routines for VFS -+ */ -+ -+#include -+#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 wait) -+{ -+ int err; -+ -+ lockdep_off(); -+ down_read(&h_sb->s_umount); -+ err = __sync_filesystem(h_sb, wait); -+ up_read(&h_sb->s_umount); -+ lockdep_on(); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int vfsub_update_h_iattr(struct path *h_path, int *did) -+{ -+ int err; -+ struct kstat st; -+ struct super_block *h_sb; -+ -+ /* 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) -+{ -+ struct file *file; -+ -+ file = dentry_open(path, flags /* | __FMODE_NONOTIFY */, -+ current_cred()); -+ if (!IS_ERR_OR_NULL(file) -+ && (file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) -+ i_readcount_inc(d_inode(path->dentry)); -+ -+ return file; -+} -+ -+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 dentry *parent, int len) -+{ -+ struct path path = { -+ .mnt = NULL -+ }; -+ -+ path.dentry = lookup_one_len_unlocked(name, parent, len); -+ if (IS_ERR(path.dentry)) -+ goto out; -+ if (d_is_positive(path.dentry)) -+ 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 dentry *parent, -+ int len) -+{ -+ struct path path = { -+ .mnt = NULL -+ }; -+ -+ /* VFS checks it too, but by WARN_ON_ONCE() */ -+ IMustLock(d_inode(parent)); -+ -+ path.dentry = lookup_one_len(name, parent, len); -+ if (IS_ERR(path.dentry)) -+ goto out; -+ if (d_is_positive(path.dentry)) -+ 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->parent); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+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; -+ -+ 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; -+ -+ lockdep_off(); -+ err = vfs_create(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; -+ -+ 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; -+ -+ lockdep_off(); -+ err = vfs_symlink(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; -+ -+ 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; -+ -+ lockdep_off(); -+ err = vfs_mknod(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) -+ || inode->i_nlink < 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; -+ -+ 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; -+ -+ lockdep_off(); -+ err = vfs_link(src_dentry, 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 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; -+ -+ lockdep_off(); -+ err = vfs_rename(src_dir, src_dentry, dir, path->dentry, -+ delegated_inode, flags); -+ 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; -+ -+ 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; -+ -+ lockdep_off(); -+ err = vfs_mkdir(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; -+ -+ IMustLock(dir); -+ -+ d = path->dentry; -+ path->dentry = d->d_parent; -+ err = security_path_rmdir(path, d); -+ path->dentry = d; -+ if (unlikely(err)) -+ goto out; -+ -+ lockdep_off(); -+ err = vfs_rmdir(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; -+} -+ -+/* todo: kernel_read()? */ -+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count, -+ loff_t *ppos) -+{ -+ ssize_t err; -+ mm_segment_t oldfs; -+ union { -+ void *k; -+ char __user *u; -+ } buf; -+ -+ buf.k = kbuf; -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); -+ err = vfsub_read_u(file, buf.u, count, ppos); -+ set_fs(oldfs); -+ 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; -+ mm_segment_t oldfs; -+ union { -+ void *k; -+ const char __user *u; -+ } buf; -+ -+ buf.k = kbuf; -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); -+ err = vfsub_write_u(file, buf.u, count, ppos); -+ set_fs(oldfs); -+ 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_to(struct file *in, loff_t *ppos, -+ struct pipe_inode_info *pipe, size_t len, -+ unsigned int flags) -+{ -+ long err; -+ -+ lockdep_off(); -+ err = do_splice_to(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; -+ -+ 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 = locks_verify_truncate(h_inode, h_file, length); -+ if (!err) -+ err = security_path_truncate(h_path); -+ if (!err) { -+ lockdep_off(); -+ err = do_truncate(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; -+ -+ do_sio = au_test_h_perm_sio(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; -+ -+ do_sio = au_test_h_perm_sio(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; -+ -+ h_inode = d_inode(a->path->dentry); -+ IMustLock(h_inode); -+ -+ *a->errp = -EPERM; -+ if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) { -+ lockdep_off(); -+ *a->errp = notify_change(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; -+ 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); -+ } -+ -+ lockdep_off(); -+ *a->errp = vfs_unlink(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 -Nurp linux-5.6.3/fs/aufs/vfsub.h linux-5.6.3-aufs/fs/aufs/vfsub.h ---- linux-5.6.3/fs/aufs/vfsub.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/vfsub.h 2020-04-10 12:40:52.193049549 +0300 -@@ -0,0 +1,341 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * sub-routines for VFS -+ */ -+ -+#ifndef __AUFS_VFSUB_H__ -+#define __AUFS_VFSUB_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+#include -+#include -+#include "debug.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)) -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline void vfsub_drop_nlink(struct inode *inode) -+{ -+ AuDebugOn(!inode->i_nlink); -+ drop_nlink(inode); -+} -+ -+static inline void vfsub_dead_dir(struct inode *inode) -+{ -+ AuDebugOn(!S_ISDIR(inode->i_mode)); -+ inode->i_flags |= S_DEAD; -+ 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 wait); -+ -+/* ---------------------------------------------------------------------- */ -+ -+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 dentry *parent, int len); -+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent, -+ int len); -+ -+struct vfsub_lkup_one_args { -+ struct dentry **errp; -+ struct qstr *name; -+ struct dentry *parent; -+}; -+ -+static inline struct dentry *vfsub_lkup_one(struct qstr *name, -+ struct dentry *parent) -+{ -+ return vfsub_lookup_one_len(name->name, parent, 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 -+ -+/* ---------------------------------------------------------------------- */ -+ -+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, -+ struct timespec64 *ts, int flags) -+{ -+ return update_time(h_inode, ts, 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 inode *h_inode, umode_t h_mode) -+{ -+ int err; -+ -+ err = posix_acl_chmod(h_inode, h_mode); -+ if (err == -EOPNOTSUPP) -+ err = 0; -+ return err; -+} -+#else -+AuStubInt0(vfsub_acl_chmod, struct inode *h_inode, umode_t h_mode); -+#endif -+ -+long vfsub_splice_to(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 dentry *dentry, const char *name, -+ const void *value, size_t size, int flags) -+{ -+ int err; -+ -+ lockdep_off(); -+ err = vfs_setxattr(dentry, name, value, size, flags); -+ lockdep_on(); -+ -+ return err; -+} -+ -+static inline int vfsub_removexattr(struct dentry *dentry, const char *name) -+{ -+ int err; -+ -+ lockdep_off(); -+ err = vfs_removexattr(dentry, name); -+ lockdep_on(); -+ -+ return err; -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_VFSUB_H__ */ -diff -Nurp linux-5.6.3/fs/aufs/whout.c linux-5.6.3-aufs/fs/aufs/whout.c ---- linux-5.6.3/fs/aufs/whout.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/whout.c 2020-04-10 12:40:52.193049549 +0300 -@@ -0,0 +1,1049 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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_parent. -+ * @try_sio specifies the necessary of super-io. -+ */ -+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio) -+{ -+ int err; -+ struct dentry *wh_dentry; -+ -+ if (!try_sio) -+ wh_dentry = vfsub_lkup_one(wh_name, h_parent); -+ else -+ wh_dentry = au_sio_lkup_one(wh_name, h_parent); -+ 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_dentry sets opaque or not. -+ */ -+int au_diropq_test(struct dentry *h_dentry) -+{ -+ int err; -+ struct inode *h_dir; -+ -+ h_dir = d_inode(h_dentry); -+ err = au_wh_test(h_dentry, &diropq_name, -+ au_test_h_perm_sio(h_dir, MAY_EXEC)); -+ return err; -+} -+ -+/* -+ * 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; -+ -+ 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); -+ -+ qs.name = name; -+ for (i = 0; i < 3; i++) { -+ sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++); -+ dentry = au_sio_lkup_one(&qs, h_parent); -+ if (IS_ERR(dentry) || 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 dentry *h_parent, struct qstr *wh, -+ struct au_branch *br) -+{ -+ int err; -+ struct path h_path = { -+ .mnt = au_br_mnt(br) -+ }; -+ -+ err = 0; -+ h_path.dentry = vfsub_lkup_one(wh, h_parent); -+ if (IS_ERR(h_path.dentry)) -+ err = PTR_ERR(h_path.dentry); -+ else { -+ if (d_is_reg(h_path.dentry)) -+ err = do_unlink_wh(d_inode(h_parent), &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, *h_dentry; -+ struct super_block *sb; -+ struct au_branch *br; -+ int err; -+ -+ sb = dentry->d_sb; -+ br = au_sbr(sb, bindex); -+ h_dentry = au_h_dptr(dentry, bindex); -+ opq_dentry = vfsub_lkup_one(&diropq_name, h_dentry); -+ 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 { -+ struct path tmp = { -+ .dentry = opq_dentry, -+ .mnt = au_br_mnt(br) -+ }; -+ err = do_unlink_wh(au_h_iptr(d_inode(dentry), bindex), &tmp); -+ 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; -+ -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (!au_test_h_perm_sio(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; -+ -+ err = au_wh_name_alloc(&wh_name, base_name); -+ wh_dentry = ERR_PTR(err); -+ if (!err) { -+ wh_dentry = vfsub_lkup_one(&wh_name, h_parent); -+ 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 dentry *h_dentry, struct au_nhash *whlist, -+ aufs_bindex_t bindex, struct au_branch *br) -+{ -+ 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_dentry, &wh_name, br); -+ 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 dentry *h_dentry; -+ struct au_nhash *whlist; -+ aufs_bindex_t bindex; -+ struct au_branch *br; -+}; -+ -+static void call_del_wh_children(void *args) -+{ -+ struct del_wh_children_args *a = args; -+ *a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->br); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+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 h_tmp; -+ struct inode *wh_inode, *h_dir; -+ struct au_branch *br; -+ -+ h_dir = d_inode(wh_dentry->d_parent); /* dir inode is locked */ -+ IMustLock(h_dir); -+ -+ br = au_sbr(dir->i_sb, bindex); -+ 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(wh_inode, MAY_EXEC | MAY_WRITE)) -+ err = del_wh_children(wh_dentry, whlist, bindex, br); -+ else { -+ int wkq_err; -+ struct del_wh_children_args args = { -+ .errp = &err, -+ .h_dentry = wh_dentry, -+ .whlist = whlist, -+ .bindex = bindex, -+ .br = br -+ }; -+ -+ wkq_err = au_wkq_wait(call_del_wh_children, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } -+ inode_unlock(wh_inode); -+ -+ if (!err) { -+ h_tmp.dentry = wh_dentry; -+ h_tmp.mnt = au_br_mnt(br); -+ h_nlink = h_dir->i_nlink; -+ err = vfsub_rmdir(h_dir, &h_tmp); -+ /* some fs doesn't change the parent nlink in some cases */ -+ h_nlink -= h_dir->i_nlink; -+ } -+ -+ 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 -Nurp linux-5.6.3/fs/aufs/whout.h linux-5.6.3-aufs/fs/aufs/whout.h ---- linux-5.6.3/fs/aufs/whout.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/whout.h 2020-04-10 12:40:52.193049549 +0300 -@@ -0,0 +1,73 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 dentry *h_parent, struct qstr *wh_name, int try_sio); -+int au_diropq_test(struct dentry *h_dentry); -+struct au_branch; -+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br, -+ struct qstr *prefix); -+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br); -+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 -Nurp linux-5.6.3/fs/aufs/wkq.c linux-5.6.3-aufs/fs/aufs/wkq.c ---- linux-5.6.3/fs/aufs/wkq.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/wkq.c 2020-04-10 12:40:52.193049549 +0300 -@@ -0,0 +1,359 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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. -+ */ -+#define AuWkqCompDeclare(name) struct completion *comp = NULL -+ -+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; -+ AuWkqCompDeclare(comp); -+ 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 -Nurp linux-5.6.3/fs/aufs/wkq.h linux-5.6.3-aufs/fs/aufs/wkq.h ---- linux-5.6.3/fs/aufs/wkq.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/wkq.h 2020-04-10 12:40:52.193049549 +0300 -@@ -0,0 +1,76 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.6.3/fs/aufs/xattr.c linux-5.6.3-aufs/fs/aufs/xattr.c ---- linux-5.6.3/fs/aufs/xattr.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/xattr.c 2020-04-10 12:40:52.193049549 +0300 -@@ -0,0 +1,343 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2014-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * handling xattr functions -+ */ -+ -+#include -+#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 dentry *h_dst, struct dentry *h_src, -+ char *name, char **buf, unsigned int ignore_flags, -+ unsigned int verbose) -+{ -+ int err; -+ ssize_t ssz; -+ struct inode *h_idst; -+ -+ ssz = vfs_getxattr_alloc(h_src, name, buf, 0, GFP_NOFS); -+ err = ssz; -+ if (unlikely(err <= 0)) { -+ if (err == -ENODATA -+ || (err == -EOPNOTSUPP -+ && ((ignore_flags & au_xattr_out_of_list) -+ || (au_test_nfs_noacl(d_inode(h_src)) -+ && (!strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS) -+ || !strcmp(name, -+ XATTR_NAME_POSIX_ACL_DEFAULT)))) -+ )) -+ err = 0; -+ if (err && (verbose || au_debug_test())) -+ pr_err("%s, err %d\n", name, err); -+ goto out; -+ } -+ -+ /* unlock it temporary */ -+ h_idst = d_inode(h_dst); -+ inode_unlock(h_idst); -+ err = vfsub_setxattr(h_dst, 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 dentry *h_dst, struct dentry *h_src, int ignore_flags, -+ unsigned int verbose) -+{ -+ int err, unlocked, acl_access, acl_default; -+ ssize_t ssz; -+ 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_isrc = d_inode(h_src); -+ h_idst = d_inode(h_dst); -+ 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, 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, 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; -+ acl_access = 0; -+ acl_default = 0; -+ while (!err && p < e) { -+ acl_access |= !strncmp(p, XATTR_NAME_POSIX_ACL_ACCESS, -+ sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1); -+ acl_default |= !strncmp(p, XATTR_NAME_POSIX_ACL_DEFAULT, -+ sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) -+ - 1); -+ err = au_do_cpup_xattr(h_dst, h_src, p, &value, ignore_flags, -+ verbose); -+ p += strlen(p) + 1; -+ } -+ AuTraceErr(err); -+ ignore_flags |= au_xattr_out_of_list; -+ if (!err && !acl_access) { -+ err = au_do_cpup_xattr(h_dst, h_src, -+ XATTR_NAME_POSIX_ACL_ACCESS, &value, -+ ignore_flags, verbose); -+ AuTraceErr(err); -+ } -+ if (!err && !acl_default) { -+ err = au_do_cpup_xattr(h_dst, h_src, -+ XATTR_NAME_POSIX_ACL_DEFAULT, &value, -+ ignore_flags, verbose); -+ AuTraceErr(err); -+ } -+ -+ 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) -+ /* -+ * 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 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, /*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(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, &arg); -+} -+ -+static ssize_t au_getxattr(struct dentry *dentry, -+ struct inode *inode __maybe_unused, -+ 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, &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 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[] = { -+#ifdef CONFIG_FS_POSIX_ACL -+ &posix_acl_access_xattr_handler, -+ &posix_acl_default_xattr_handler, -+#endif -+ &au_xattr_handler, /* must be last */ -+ NULL -+}; -+ -+void au_xattr_init(struct super_block *sb) -+{ -+ sb->s_xattr = au_xattr_handlers; -+} -diff -Nurp linux-5.6.3/fs/aufs/xino.c linux-5.6.3-aufs/fs/aufs/xino.c ---- linux-5.6.3/fs/aufs/xino.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/fs/aufs/xino.c 2020-04-10 12:40:52.193049549 +0300 -@@ -0,0 +1,1952 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 (inode->i_nlink) -+ 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 == 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, *parent; -+ struct inode *dir, *delegated; -+ struct qstr *name; -+ struct path path; -+ int err, do_unlock; -+ struct au_xino_lock_dir ldir; -+ -+ do_unlock = 1; -+ au_xino_lock_dir(sb, base, &ldir); -+ dentry = base->dentry; -+ parent = dentry->d_parent; /* dir inode is locked */ -+ dir = d_inode(parent); -+ IMustLock(dir); -+ -+ name = &dentry->d_name; -+ path.dentry = vfsub_lookup_one_len(name->name, parent, 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(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(vfs_writef_t 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(sbi->si_xwrite, 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(sbinfo->si_xread, 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(vfs_writef_t write, struct file *file, -+ struct au_xi_calc *calc, ino_t ino) -+{ -+ ssize_t sz; -+ -+ sz = xino_fwrite(write, 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(au_sbi(sb)->si_xwrite, 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(vfs_readf_t func, struct file *file, void *buf, -+ size_t size, loff_t *pos); -+ -+/* todo: unnecessary to support mmap_sem since kernel-space? */ -+ssize_t xino_fread(vfs_readf_t func, struct file *file, void *kbuf, size_t size, -+ loff_t *pos) -+{ -+ ssize_t err; -+ mm_segment_t oldfs; -+ union { -+ void *k; -+ char __user *u; -+ } buf; -+ int i; -+ const int prevent_endless = 10; -+ -+ i = 0; -+ buf.k = kbuf; -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); -+ do { -+ err = func(file, buf.u, size, pos); -+ if (err == -EINTR -+ && !au_wkq_test() -+ && fatal_signal_pending(current)) { -+ set_fs(oldfs); -+ err = xino_fread_wkq(func, file, kbuf, size, pos); -+ BUG_ON(err == -EINTR); -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); -+ } -+ } while (i++ < prevent_endless -+ && (err == -EAGAIN || err == -EINTR)); -+ set_fs(oldfs); -+ -+#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; -+ vfs_readf_t func; -+ 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->func, a->file, a->buf, a->size, a->pos); -+} -+ -+static ssize_t xino_fread_wkq(vfs_readf_t func, struct file *file, void *buf, -+ size_t size, loff_t *pos) -+{ -+ ssize_t err; -+ int wkq_err; -+ struct xino_fread_args args = { -+ .errp = &err, -+ .func = func, -+ .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(vfs_writef_t func, struct file *file, void *buf, -+ size_t size, loff_t *pos); -+ -+static ssize_t do_xino_fwrite(vfs_writef_t func, struct file *file, void *kbuf, -+ size_t size, loff_t *pos) -+{ -+ ssize_t err; -+ mm_segment_t oldfs; -+ union { -+ void *k; -+ const char __user *u; -+ } buf; -+ int i; -+ const int prevent_endless = 10; -+ -+ i = 0; -+ buf.k = kbuf; -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); -+ do { -+ err = func(file, buf.u, size, pos); -+ if (err == -EINTR -+ && !au_wkq_test() -+ && fatal_signal_pending(current)) { -+ set_fs(oldfs); -+ err = xino_fwrite_wkq(func, file, kbuf, size, pos); -+ BUG_ON(err == -EINTR); -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); -+ } -+ } while (i++ < prevent_endless -+ && (err == -EAGAIN || err == -EINTR)); -+ set_fs(oldfs); -+ -+#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; -+ vfs_writef_t func; -+ 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->func, a->file, a->buf, a->size, a->pos); -+} -+ -+static ssize_t xino_fwrite_wkq(vfs_writef_t func, 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, -+ .func = func, -+ .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(vfs_writef_t func, 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(func, file, buf, size, pos); -+ lockdep_on(); -+ } else { -+ lockdep_off(); -+ err = xino_fwrite_wkq(func, 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(sbinfo->si_xwrite, 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(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos); -+ else { -+ memset(p, 0, PAGE_SIZE); -+ sz = xino_fwrite(sbinfo->si_xwrite, 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(inode->i_nlink); -+ -+ 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; -+ vfs_readf_t func; -+ ino_t *ino; -+ unsigned long *p; -+ -+ err = 0; -+ sbinfo = au_sbi(sb); -+ MtxMustLock(&sbinfo->si_xib_mtx); -+ p = sbinfo->si_xib_buf; -+ func = sbinfo->si_xread; -+ pend = vfsub_f_size_read(file); -+ pos = 0; -+ while (pos < pend) { -+ sz = xino_fread(func, 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_xwrite, 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); -+ au_kfree_rcu(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); -+ /* unnecessary to clear sbinfo->si_xread and ->si_xwrite */ -+ 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; -+ sbinfo->si_xread = vfs_readf(file); -+ sbinfo->si_xwrite = vfs_writef(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(sbinfo->si_xwrite, 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 { -+ vfs_writef_t writef; -+ 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(args->writef, 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); -+ args.writef = au_sbi(sb)->si_xwrite; -+ 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.writef = au_sbi(sb)->si_xwrite; -+ 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; -+ vfs_writef_t xwrite; -+ 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; -+ -+ xwrite = au_sbi(sb)->si_xwrite; -+ 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 && h_inode->i_nlink)) -+ 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(xwrite, 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 -Nurp linux-5.6.3/fs/dcache.c linux-5.6.3-aufs/fs/dcache.c ---- linux-5.6.3/fs/dcache.c 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs/fs/dcache.c 2020-04-10 12:40:52.194049596 +0300 -@@ -1266,7 +1266,7 @@ enum d_walk_ret { - * - * The @enter() callbacks are called with d_lock held. - */ --static void d_walk(struct dentry *parent, void *data, -+void d_walk(struct dentry *parent, void *data, - enum d_walk_ret (*enter)(void *, struct dentry *)) - { - struct dentry *this_parent; -diff -Nurp linux-5.6.3/fs/fcntl.c linux-5.6.3-aufs/fs/fcntl.c ---- linux-5.6.3/fs/fcntl.c 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs/fs/fcntl.c 2020-04-10 12:40:52.194049596 +0300 -@@ -32,7 +32,7 @@ - - #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME) - --static int setfl(int fd, struct file * filp, unsigned long arg) -+int setfl(int fd, struct file *filp, unsigned long arg) - { - struct inode * inode = file_inode(filp); - int error = 0; -@@ -63,6 +63,8 @@ static int setfl(int fd, struct file * f - - if (filp->f_op->check_flags) - error = filp->f_op->check_flags(arg); -+ if (!error && filp->f_op->setfl) -+ error = filp->f_op->setfl(filp, arg); - if (error) - return error; - -diff -Nurp linux-5.6.3/fs/inode.c linux-5.6.3-aufs/fs/inode.c ---- linux-5.6.3/fs/inode.c 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs/fs/inode.c 2020-04-10 12:40:52.194049596 +0300 -@@ -1688,7 +1688,7 @@ EXPORT_SYMBOL(generic_update_time); - * This does the actual work of updating an inodes time or version. Must have - * had called mnt_want_write() before calling this. - */ --static int update_time(struct inode *inode, struct timespec64 *time, int flags) -+int update_time(struct inode *inode, struct timespec64 *time, int flags) - { - if (inode->i_op->update_time) - return inode->i_op->update_time(inode, time, flags); -diff -Nurp linux-5.6.3/fs/Kconfig linux-5.6.3-aufs/fs/Kconfig ---- linux-5.6.3/fs/Kconfig 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs/fs/Kconfig 2020-04-10 13:14:44.904937004 +0300 -@@ -122,6 +122,7 @@ source "fs/quota/Kconfig" - source "fs/autofs/Kconfig" - source "fs/fuse/Kconfig" - source "fs/overlayfs/Kconfig" -+source "fs/aufs/Kconfig" - - menu "Caches" - -diff -Nurp linux-5.6.3/fs/Makefile linux-5.6.3-aufs/fs/Makefile ---- linux-5.6.3/fs/Makefile 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs/fs/Makefile 2020-04-10 13:13:53.450534347 +0300 -@@ -111,6 +111,7 @@ obj-$(CONFIG_AUTOFS_FS) += autofs/ - obj-$(CONFIG_ADFS_FS) += adfs/ - obj-$(CONFIG_FUSE_FS) += fuse/ - obj-$(CONFIG_OVERLAY_FS) += overlayfs/ -+obj-$(CONFIG_AUFS_FS) += aufs/ - obj-$(CONFIG_ORANGEFS_FS) += orangefs/ - obj-$(CONFIG_UDF_FS) += udf/ - obj-$(CONFIG_SUN_OPENPROMFS) += openpromfs/ -diff -Nurp linux-5.6.3/fs/namespace.c linux-5.6.3-aufs/fs/namespace.c ---- linux-5.6.3/fs/namespace.c 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs/fs/namespace.c 2020-04-10 12:40:52.194049596 +0300 -@@ -776,6 +776,12 @@ static inline int check_mnt(struct mount - return mnt->mnt_ns == current->nsproxy->mnt_ns; - } - -+/* for aufs, CONFIG_AUFS_BR_FUSE */ -+int is_current_mnt_ns(struct vfsmount *mnt) -+{ -+ return check_mnt(real_mount(mnt)); -+} -+ - /* - * vfsmount lock must be held for write - */ -diff -Nurp linux-5.6.3/fs/proc/base.c linux-5.6.3-aufs/fs/proc/base.c ---- linux-5.6.3/fs/proc/base.c 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs/fs/proc/base.c 2020-04-10 12:40:52.194049596 +0300 -@@ -2128,7 +2128,7 @@ static int map_files_get_link(struct den - rc = -ENOENT; - vma = find_exact_vma(mm, vm_start, vm_end); - if (vma && vma->vm_file) { -- *path = vma->vm_file->f_path; -+ *path = vma_pr_or_file(vma)->f_path; - path_get(path); - rc = 0; - } -diff -Nurp linux-5.6.3/fs/proc/nommu.c linux-5.6.3-aufs/fs/proc/nommu.c ---- linux-5.6.3/fs/proc/nommu.c 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs/fs/proc/nommu.c 2020-04-10 12:40:52.194049596 +0300 -@@ -41,7 +41,10 @@ static int nommu_region_show(struct seq_ - file = region->vm_file; - - if (file) { -- struct inode *inode = file_inode(region->vm_file); -+ struct inode *inode; -+ -+ file = vmr_pr_or_file(region); -+ inode = file_inode(file); - dev = inode->i_sb->s_dev; - ino = inode->i_ino; - } -diff -Nurp linux-5.6.3/fs/proc/task_mmu.c linux-5.6.3-aufs/fs/proc/task_mmu.c ---- linux-5.6.3/fs/proc/task_mmu.c 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs/fs/proc/task_mmu.c 2020-04-10 12:40:52.194049596 +0300 -@@ -309,7 +309,10 @@ show_map_vma(struct seq_file *m, struct - const char *name = NULL; - - 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; -@@ -1819,7 +1822,7 @@ static int show_numa_map(struct seq_file - 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]; -diff -Nurp linux-5.6.3/fs/proc/task_nommu.c linux-5.6.3-aufs/fs/proc/task_nommu.c ---- linux-5.6.3/fs/proc/task_nommu.c 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs/fs/proc/task_nommu.c 2020-04-10 12:40:52.194049596 +0300 -@@ -155,7 +155,10 @@ static int nommu_vma_show(struct seq_fil - file = vma->vm_file; - - 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; -diff -Nurp linux-5.6.3/fs/read_write.c linux-5.6.3-aufs/fs/read_write.c ---- linux-5.6.3/fs/read_write.c 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs/fs/read_write.c 2020-04-10 12:40:52.194049596 +0300 -@@ -498,6 +498,28 @@ static ssize_t __vfs_write(struct file * - return -EINVAL; - } - -+vfs_readf_t vfs_readf(struct file *file) -+{ -+ const struct file_operations *fop = file->f_op; -+ -+ if (fop->read) -+ return fop->read; -+ if (fop->read_iter) -+ return new_sync_read; -+ return ERR_PTR(-ENOSYS); /* doesn't have ->read(|_iter)() op */ -+} -+ -+vfs_writef_t vfs_writef(struct file *file) -+{ -+ const struct file_operations *fop = file->f_op; -+ -+ if (fop->write) -+ return fop->write; -+ if (fop->write_iter) -+ return new_sync_write; -+ return ERR_PTR(-ENOSYS); /* doesn't have ->write(|_iter)() op */ -+} -+ - ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos) - { - mm_segment_t old_fs; -diff -Nurp linux-5.6.3/fs/splice.c linux-5.6.3-aufs/fs/splice.c ---- linux-5.6.3/fs/splice.c 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs/fs/splice.c 2020-04-10 12:40:52.194049596 +0300 -@@ -849,8 +849,8 @@ EXPORT_SYMBOL(generic_splice_sendpage); - /* - * Attempt to initiate a splice from pipe to file. - */ --static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, -- loff_t *ppos, size_t len, unsigned int flags) -+long do_splice_from(struct pipe_inode_info *pipe, struct file *out, -+ loff_t *ppos, size_t len, unsigned int flags) - { - ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, - loff_t *, size_t, unsigned int); -@@ -866,9 +866,9 @@ static long do_splice_from(struct pipe_i - /* - * Attempt to initiate a splice from a file to a pipe. - */ --static long do_splice_to(struct file *in, loff_t *ppos, -- struct pipe_inode_info *pipe, size_t len, -- unsigned int flags) -+long do_splice_to(struct file *in, loff_t *ppos, -+ struct pipe_inode_info *pipe, size_t len, -+ unsigned int flags) - { - ssize_t (*splice_read)(struct file *, loff_t *, - struct pipe_inode_info *, size_t, unsigned int); -diff -Nurp linux-5.6.3/fs/sync.c linux-5.6.3-aufs/fs/sync.c ---- linux-5.6.3/fs/sync.c 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs/fs/sync.c 2020-04-10 12:40:52.194049596 +0300 -@@ -28,7 +28,7 @@ - * wait == 1 case since in that case write_inode() functions do - * sync_dirty_buffer() and thus effectively write one block at a time. - */ --static int __sync_filesystem(struct super_block *sb, int wait) -+int __sync_filesystem(struct super_block *sb, int wait) - { - if (wait) - sync_inodes_sb(sb); -diff -Nurp linux-5.6.3/include/linux/fs.h linux-5.6.3-aufs/include/linux/fs.h ---- linux-5.6.3/include/linux/fs.h 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs/include/linux/fs.h 2020-04-10 12:40:52.195049643 +0300 -@@ -1350,6 +1350,7 @@ extern void fasync_free(struct fasync_st - /* can be called from interrupts */ - extern void kill_fasync(struct fasync_struct **, int, int); - -+extern int setfl(int fd, struct file *filp, unsigned long arg); - extern void __f_setown(struct file *filp, struct pid *, enum pid_type, int force); - extern int f_setown(struct file *filp, unsigned long arg, int force); - extern void f_delown(struct file *filp); -@@ -1842,6 +1843,7 @@ struct file_operations { - ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); - unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); - int (*check_flags)(int); -+ int (*setfl)(struct file *, unsigned long); - int (*flock) (struct file *, int, struct file_lock *); - 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); -@@ -1912,6 +1914,12 @@ ssize_t rw_copy_check_uvector(int type, - struct iovec *fast_pointer, - struct iovec **ret_pointer); - -+typedef ssize_t (*vfs_readf_t)(struct file *, char __user *, size_t, loff_t *); -+typedef ssize_t (*vfs_writef_t)(struct file *, const char __user *, size_t, -+ loff_t *); -+vfs_readf_t vfs_readf(struct file *file); -+vfs_writef_t vfs_writef(struct file *file); -+ - extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *); - extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *); - extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *); -@@ -2344,6 +2352,7 @@ extern int current_umask(void); - extern void ihold(struct inode * inode); - extern void iput(struct inode *); - extern int generic_update_time(struct inode *, struct timespec64 *, int); -+extern int update_time(struct inode *, struct timespec64 *, int); - - /* /sys/fs */ - extern struct kobject *fs_kobj; -@@ -2628,6 +2637,7 @@ static inline bool sb_is_blkdev_sb(struc - return false; - } - #endif -+extern int __sync_filesystem(struct super_block *, int); - extern int sync_filesystem(struct super_block *); - extern const struct file_operations def_blk_fops; - extern const struct file_operations def_chr_fops; -diff -Nurp linux-5.6.3/include/linux/lockdep.h linux-5.6.3-aufs/include/linux/lockdep.h ---- linux-5.6.3/include/linux/lockdep.h 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs/include/linux/lockdep.h 2020-04-10 12:40:52.195049643 +0300 -@@ -331,6 +331,8 @@ static inline int lockdep_match_key(stru - return lock->key == key; - } - -+struct lock_class *lockdep_hlock_class(struct held_lock *hlock); -+ - /* - * Acquire a lock. - * -@@ -472,6 +474,7 @@ struct lockdep_map { }; - - #define lockdep_depth(tsk) (0) - -+#define lockdep_is_held(lock) (1) - #define lockdep_is_held_type(l, r) (1) - - #define lockdep_assert_held(l) do { (void)(l); } while (0) -diff -Nurp linux-5.6.3/include/linux/mm.h linux-5.6.3-aufs/include/linux/mm.h ---- linux-5.6.3/include/linux/mm.h 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs/include/linux/mm.h 2020-04-10 12:40:52.195049643 +0300 -@@ -1487,6 +1487,28 @@ static inline void unmap_shared_mapping_ - unmap_mapping_range(mapping, holebegin, holelen, 0); - } - -+extern void vma_do_file_update_time(struct vm_area_struct *, const char[], int); -+extern struct file *vma_do_pr_or_file(struct vm_area_struct *, const char[], -+ int); -+extern void vma_do_get_file(struct vm_area_struct *, const char[], int); -+extern void vma_do_fput(struct vm_area_struct *, const char[], int); -+ -+#define vma_file_update_time(vma) vma_do_file_update_time(vma, __func__, \ -+ __LINE__) -+#define vma_pr_or_file(vma) vma_do_pr_or_file(vma, __func__, \ -+ __LINE__) -+#define vma_get_file(vma) vma_do_get_file(vma, __func__, __LINE__) -+#define vma_fput(vma) vma_do_fput(vma, __func__, __LINE__) -+ -+#ifndef CONFIG_MMU -+extern struct file *vmr_do_pr_or_file(struct vm_region *, const char[], int); -+extern void vmr_do_fput(struct vm_region *, const char[], int); -+ -+#define vmr_pr_or_file(region) vmr_do_pr_or_file(region, __func__, \ -+ __LINE__) -+#define vmr_fput(region) vmr_do_fput(region, __func__, __LINE__) -+#endif /* !CONFIG_MMU */ -+ - extern int access_process_vm(struct task_struct *tsk, unsigned long addr, - void *buf, int len, unsigned int gup_flags); - extern int access_remote_vm(struct mm_struct *mm, unsigned long addr, -diff -Nurp linux-5.6.3/include/linux/mm_types.h linux-5.6.3-aufs/include/linux/mm_types.h ---- linux-5.6.3/include/linux/mm_types.h 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs/include/linux/mm_types.h 2020-04-10 12:40:52.195049643 +0300 -@@ -267,6 +267,7 @@ struct vm_region { - unsigned long vm_top; /* region allocated to here */ - unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */ - struct file *vm_file; /* the backing file or NULL */ -+ struct file *vm_prfile; /* the virtual backing file or NULL */ - - int vm_usage; /* region usage count (access under nommu_region_sem) */ - bool vm_icache_flushed : 1; /* true if the icache has been flushed for -@@ -346,6 +347,7 @@ 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). */ -+ struct file *vm_prfile; /* shadow of vm_file */ - void * vm_private_data; /* was vm_pte (shared mem) */ - - #ifdef CONFIG_SWAP -diff -Nurp linux-5.6.3/include/linux/mnt_namespace.h linux-5.6.3-aufs/include/linux/mnt_namespace.h ---- linux-5.6.3/include/linux/mnt_namespace.h 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs/include/linux/mnt_namespace.h 2020-04-10 12:40:52.195049643 +0300 -@@ -6,11 +6,14 @@ - struct mnt_namespace; - struct fs_struct; - struct user_namespace; -+struct vfsmount; - - 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); - -+extern int is_current_mnt_ns(struct vfsmount *mnt); -+ - extern const struct file_operations proc_mounts_operations; - extern const struct file_operations proc_mountinfo_operations; - extern const struct file_operations proc_mountstats_operations; -diff -Nurp linux-5.6.3/include/linux/splice.h linux-5.6.3-aufs/include/linux/splice.h ---- linux-5.6.3/include/linux/splice.h 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs/include/linux/splice.h 2020-04-10 12:40:52.195049643 +0300 -@@ -87,4 +87,10 @@ extern void splice_shrink_spd(struct spl - - 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 long do_splice_to(struct file *in, loff_t *ppos, -+ struct pipe_inode_info *pipe, size_t len, -+ unsigned int flags); - #endif -diff -Nurp linux-5.6.3/include/uapi/linux/aufs_type.h linux-5.6.3-aufs/include/uapi/linux/aufs_type.h ---- linux-5.6.3/include/uapi/linux/aufs_type.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/include/uapi/linux/aufs_type.h 2020-04-10 12:40:52.195049643 +0300 -@@ -0,0 +1,439 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+#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 "5.5" -+ -+/* 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[0]; -+} __aligned(8); -+ -+static inline int au_rdu_len(int nlen) -+{ -+ /* include the terminating NULL */ -+ return ALIGN(sizeof(struct au_rdu_ent) + nlen + 1, -+ sizeof(uint64_t)); -+} -+ -+union au_rdu_ent_ul { -+ struct au_rdu_ent __user *e; -+ uint64_t ul; -+}; -+ -+enum { -+ AufsCtlRduV_SZ, -+ AufsCtlRduV_End -+}; -+ -+struct aufs_rdu { -+ /* input */ -+ union { -+ uint64_t sz; /* AuCtl_RDU */ -+ uint64_t nent; /* AuCtl_RDU_INO */ -+ }; -+ union au_rdu_ent_ul ent; -+ uint16_t verify[AufsCtlRduV_End]; -+ -+ /* input/output */ -+ uint32_t blk; -+ -+ /* output */ -+ union au_rdu_ent_ul tail; -+ /* number of entries which were added in a single call */ -+ uint64_t rent; -+ uint8_t full; -+ uint8_t shwh; -+ -+ struct au_rdu_cookie cookie; -+} __aligned(8); -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* 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[0]; -+} __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[0]; -+ }; -+} __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 -Nurp linux-5.6.3/kernel/fork.c linux-5.6.3-aufs/kernel/fork.c ---- linux-5.6.3/kernel/fork.c 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs/kernel/fork.c 2020-04-10 12:40:52.195049643 +0300 -@@ -565,7 +565,7 @@ static __latent_entropy int dup_mmap(str - struct inode *inode = file_inode(file); - struct address_space *mapping = file->f_mapping; - -- get_file(file); -+ vma_get_file(tmp); - if (tmp->vm_flags & VM_DENYWRITE) - atomic_dec(&inode->i_writecount); - i_mmap_lock_write(mapping); -diff -Nurp linux-5.6.3/kernel/locking/lockdep.c linux-5.6.3-aufs/kernel/locking/lockdep.c ---- linux-5.6.3/kernel/locking/lockdep.c 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs/kernel/locking/lockdep.c 2020-04-10 12:40:52.195049643 +0300 -@@ -153,7 +153,7 @@ static - struct lock_class lock_classes[MAX_LOCKDEP_KEYS]; - static DECLARE_BITMAP(lock_classes_in_use, MAX_LOCKDEP_KEYS); - --static inline struct lock_class *hlock_class(struct held_lock *hlock) -+inline struct lock_class *lockdep_hlock_class(struct held_lock *hlock) - { - unsigned int class_idx = hlock->class_idx; - -@@ -174,6 +174,7 @@ static inline struct lock_class *hlock_c - */ - return lock_classes + class_idx; - } -+#define hlock_class(hlock) lockdep_hlock_class(hlock) - - #ifdef CONFIG_LOCK_STAT - static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], cpu_lock_stats); -diff -Nurp linux-5.6.3/MAINTAINERS linux-5.6.3-aufs/MAINTAINERS ---- linux-5.6.3/MAINTAINERS 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs/MAINTAINERS 2020-04-10 12:40:52.187049268 +0300 -@@ -2919,6 +2919,19 @@ F: include/linux/audit.h - F: include/uapi/linux/audit.h - F: kernel/audit* - -+AUFS (advanced multi layered unification filesystem) FILESYSTEM -+M: "J. R. Okajima" -+L: aufs-users@lists.sourceforge.net (members only) -+L: linux-unionfs@vger.kernel.org -+W: http://aufs.sourceforge.net -+T: git://github.com/sfjro/aufs4-linux.git -+S: Supported -+F: Documentation/filesystems/aufs/ -+F: Documentation/ABI/testing/debugfs-aufs -+F: Documentation/ABI/testing/sysfs-aufs -+F: fs/aufs/ -+F: include/uapi/linux/aufs_type.h -+ - AUXILIARY DISPLAY DRIVERS - M: Miguel Ojeda Sandonis - S: Maintained -diff -Nurp linux-5.6.3/mm/filemap.c linux-5.6.3-aufs/mm/filemap.c ---- linux-5.6.3/mm/filemap.c 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs/mm/filemap.c 2020-04-10 12:40:52.196049690 +0300 -@@ -2653,7 +2653,7 @@ vm_fault_t filemap_page_mkwrite(struct v - vm_fault_t ret = VM_FAULT_LOCKED; - - sb_start_pagefault(inode->i_sb); -- file_update_time(vmf->vma->vm_file); -+ vma_file_update_time(vmf->vma); - lock_page(page); - if (page->mapping != inode->i_mapping) { - unlock_page(page); -diff -Nurp linux-5.6.3/mm/Makefile linux-5.6.3-aufs/mm/Makefile ---- linux-5.6.3/mm/Makefile 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs/mm/Makefile 2020-04-10 12:40:52.195049643 +0300 -@@ -43,7 +43,7 @@ obj-y := filemap.o mempool.o oom_kill. - mm_init.o mmu_context.o percpu.o slab_common.o \ - compaction.o vmacache.o \ - interval_tree.o list_lru.o workingset.o \ -- debug.o gup.o $(mmu-y) -+ prfile.o debug.o gup.o $(mmu-y) - - # Give 'page_alloc' its own module-parameter namespace - page-alloc-y := page_alloc.o -diff -Nurp linux-5.6.3/mm/mmap.c linux-5.6.3-aufs/mm/mmap.c ---- linux-5.6.3/mm/mmap.c 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs/mm/mmap.c 2020-04-10 12:40:52.196049690 +0300 -@@ -176,7 +176,7 @@ static struct vm_area_struct *remove_vma - if (vma->vm_ops && vma->vm_ops->close) - vma->vm_ops->close(vma); - if (vma->vm_file) -- fput(vma->vm_file); -+ vma_fput(vma); - mpol_put(vma_policy(vma)); - vm_area_free(vma); - return next; -@@ -907,7 +907,7 @@ again: - if (remove_next) { - if (file) { - uprobe_munmap(next, next->vm_start, next->vm_end); -- fput(file); -+ vma_fput(vma); - } - if (next->anon_vma) - anon_vma_merge(vma, next); -@@ -1829,8 +1829,8 @@ out: - return addr; - - unmap_and_free_vma: -+ vma_fput(vma); - vma->vm_file = NULL; -- fput(file); - - /* Undo any partial mapping done by a device driver. */ - unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end); -@@ -2659,7 +2659,7 @@ int __split_vma(struct mm_struct *mm, st - 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); -@@ -2678,7 +2678,7 @@ int __split_vma(struct mm_struct *mm, st - if (new->vm_ops && new->vm_ops->close) - new->vm_ops->close(new); - if (new->vm_file) -- fput(new->vm_file); -+ vma_fput(new); - unlink_anon_vmas(new); - out_free_mpol: - mpol_put(vma_policy(new)); -@@ -2870,7 +2870,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsign - struct vm_area_struct *vma; - unsigned long populate = 0; - unsigned long ret = -EINVAL; -- struct file *file; -+ struct file *file, *prfile; - - pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. See Documentation/vm/remap_file_pages.rst.\n", - current->comm, current->pid); -@@ -2945,10 +2945,27 @@ SYSCALL_DEFINE5(remap_file_pages, unsign - } - } - -- file = get_file(vma->vm_file); -+ vma_get_file(vma); -+ file = vma->vm_file; -+ prfile = vma->vm_prfile; - ret = do_mmap_pgoff(vma->vm_file, start, size, - prot, flags, pgoff, &populate, NULL); -+ if (!IS_ERR_VALUE(ret) && file && prfile) { -+ struct vm_area_struct *new_vma; -+ -+ new_vma = find_vma(mm, ret); -+ if (!new_vma->vm_prfile) -+ new_vma->vm_prfile = prfile; -+ if (new_vma != vma) -+ get_file(prfile); -+ } -+ /* -+ * two fput()s instead of vma_fput(vma), -+ * coz vma may not be available anymore. -+ */ - fput(file); -+ if (prfile) -+ fput(prfile); - out: - up_write(&mm->mmap_sem); - if (populate) -@@ -3239,7 +3256,7 @@ struct vm_area_struct *copy_vma(struct v - 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); - vma_link(mm, new_vma, prev, rb_link, rb_parent); -diff -Nurp linux-5.6.3/mm/nommu.c linux-5.6.3-aufs/mm/nommu.c ---- linux-5.6.3/mm/nommu.c 2020-03-30 01:25:41.000000000 +0300 -+++ linux-5.6.3-aufs/mm/nommu.c 2020-04-10 12:40:52.196049690 +0300 -@@ -567,7 +567,7 @@ static void __put_nommu_region(struct vm - up_write(&nommu_region_sem); - - if (region->vm_file) -- fput(region->vm_file); -+ vmr_fput(region); - - /* IO memory and memory shared directly out of the pagecache - * from ramfs/tmpfs mustn't be released here */ -@@ -699,7 +699,7 @@ static void delete_vma(struct mm_struct - if (vma->vm_ops && vma->vm_ops->close) - vma->vm_ops->close(vma); - if (vma->vm_file) -- fput(vma->vm_file); -+ vma_fput(vma); - put_nommu_region(vma->vm_region); - vm_area_free(vma); - } -@@ -1222,7 +1222,7 @@ unsigned long do_mmap(struct file *file, - goto error_just_free; - } - } -- fput(region->vm_file); -+ vmr_fput(region); - kmem_cache_free(vm_region_jar, region); - region = pregion; - result = start; -@@ -1299,10 +1299,10 @@ error_just_free: - up_write(&nommu_region_sem); - error: - if (region->vm_file) -- fput(region->vm_file); -+ vmr_fput(region); - kmem_cache_free(vm_region_jar, region); - if (vma->vm_file) -- fput(vma->vm_file); -+ vma_fput(vma); - vm_area_free(vma); - return ret; - -diff -Nurp linux-5.6.3/mm/prfile.c linux-5.6.3-aufs/mm/prfile.c ---- linux-5.6.3/mm/prfile.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.6.3-aufs/mm/prfile.c 2020-04-10 12:40:52.196049690 +0300 -@@ -0,0 +1,86 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Mainly for aufs which mmap(2) different file and wants to print different -+ * path in /proc/PID/maps. -+ * Call these functions via macros defined in linux/mm.h. -+ * -+ * See Documentation/filesystems/aufs/design/06mmap.txt -+ * -+ * Copyright (c) 2014-2020 Junjro R. Okajima -+ * Copyright (c) 2014 Ian Campbell -+ */ -+ -+#include -+#include -+#include -+ -+/* #define PRFILE_TRACE */ -+static inline void prfile_trace(struct file *f, struct file *pr, -+ const char func[], int line, const char func2[]) -+{ -+#ifdef PRFILE_TRACE -+ if (pr) -+ pr_info("%s:%d: %s, %pD2\n", func, line, func2, f); -+#endif -+} -+ -+void vma_do_file_update_time(struct vm_area_struct *vma, const char func[], -+ int line) -+{ -+ struct file *f = vma->vm_file, *pr = vma->vm_prfile; -+ -+ prfile_trace(f, pr, func, line, __func__); -+ file_update_time(f); -+ if (f && pr) -+ file_update_time(pr); -+} -+ -+struct file *vma_do_pr_or_file(struct vm_area_struct *vma, const char func[], -+ int line) -+{ -+ struct file *f = vma->vm_file, *pr = vma->vm_prfile; -+ -+ prfile_trace(f, pr, func, line, __func__); -+ return (f && pr) ? pr : f; -+} -+ -+void vma_do_get_file(struct vm_area_struct *vma, const char func[], int line) -+{ -+ struct file *f = vma->vm_file, *pr = vma->vm_prfile; -+ -+ prfile_trace(f, pr, func, line, __func__); -+ get_file(f); -+ if (f && pr) -+ get_file(pr); -+} -+ -+void vma_do_fput(struct vm_area_struct *vma, const char func[], int line) -+{ -+ struct file *f = vma->vm_file, *pr = vma->vm_prfile; -+ -+ prfile_trace(f, pr, func, line, __func__); -+ fput(f); -+ if (f && pr) -+ fput(pr); -+} -+ -+#ifndef CONFIG_MMU -+struct file *vmr_do_pr_or_file(struct vm_region *region, const char func[], -+ int line) -+{ -+ struct file *f = region->vm_file, *pr = region->vm_prfile; -+ -+ prfile_trace(f, pr, func, line, __func__); -+ return (f && pr) ? pr : f; -+} -+ -+void vmr_do_fput(struct vm_region *region, const char func[], int line) -+{ -+ struct file *f = region->vm_file, *pr = region->vm_prfile; -+ -+ prfile_trace(f, pr, func, line, __func__); -+ fput(f); -+ if (f && pr) -+ fput(pr); -+} -+#endif /* !CONFIG_MMU */ diff --git a/kernel/tools/perf/files/patches/mageia/fs-aufs5.10-symbol-exports.patch b/kernel/tools/perf/files/patches/mageia/fs-aufs5.10-symbol-exports.patch new file mode 100644 index 0000000000..49e6ec396b --- /dev/null +++ b/kernel/tools/perf/files/patches/mageia/fs-aufs5.10-symbol-exports.patch @@ -0,0 +1,284 @@ +SPDX-License-Identifier: GPL-2.0 +aufs5.x-rcN standalone patch + +diff --git a/fs/dcache.c b/fs/dcache.c +index ddca6240e0db4..30dec552278dc 100644 +--- a/fs/dcache.c ++++ b/fs/dcache.c +@@ -1390,6 +1390,7 @@ void d_walk(struct dentry *parent, void *data, + seq = 1; + goto again; + } ++EXPORT_SYMBOL_GPL(d_walk); + + struct check_mount { + struct vfsmount *mnt; +@@ -2935,6 +2936,7 @@ void d_exchange(struct dentry *dentry1, struct dentry *dentry2) + + write_sequnlock(&rename_lock); + } ++EXPORT_SYMBOL_GPL(d_exchange); + + /** + * d_ancestor - search for an ancestor +diff --git a/fs/exec.c b/fs/exec.c +index 547a2390baf54..18d51d0face68 100644 +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -113,6 +113,7 @@ bool path_noexec(const struct path *path) + return (path->mnt->mnt_flags & MNT_NOEXEC) || + (path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC); + } ++EXPORT_SYMBOL_GPL(path_noexec); + + #ifdef CONFIG_USELIB + /* +diff --git a/fs/fcntl.c b/fs/fcntl.c +index 073ca6af500f3..b18afdf81e762 100644 +--- a/fs/fcntl.c ++++ b/fs/fcntl.c +@@ -85,6 +85,7 @@ int setfl(int fd, struct file *filp, unsigned long arg) + out: + return error; + } ++EXPORT_SYMBOL_GPL(setfl); + + static void f_modown(struct file *filp, struct pid *pid, enum pid_type type, + int force) +diff --git a/fs/file_table.c b/fs/file_table.c +index 709ada3151da5..27a3e3c9f2a82 100644 +--- a/fs/file_table.c ++++ b/fs/file_table.c +@@ -162,6 +162,7 @@ struct file *alloc_empty_file(int flags, const struct cred *cred) + } + return ERR_PTR(-ENFILE); + } ++EXPORT_SYMBOL_GPL(alloc_empty_file); + + /* + * Variant of alloc_empty_file() that doesn't check and modify nr_files. +@@ -376,6 +377,7 @@ void __fput_sync(struct file *file) + } + + EXPORT_SYMBOL(fput); ++EXPORT_SYMBOL_GPL(__fput_sync); + + void __init files_init(void) + { +diff --git a/fs/inode.c b/fs/inode.c +index e7f0c614a58f3..6fe0a92a4c93c 100644 +--- a/fs/inode.c ++++ b/fs/inode.c +@@ -1776,6 +1776,7 @@ int update_time(struct inode *inode, struct timespec64 *time, int flags) + return inode->i_op->update_time(inode, time, flags); + return generic_update_time(inode, time, flags); + } ++EXPORT_SYMBOL_GPL(update_time); + + /** + * touch_atime - update the access time +diff --git a/fs/namespace.c b/fs/namespace.c +index 451dee24a546a..38078cbede431 100644 +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -431,6 +431,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 +@@ -797,6 +798,7 @@ int is_current_mnt_ns(struct vfsmount *mnt) + { + return check_mnt(real_mount(mnt)); + } ++EXPORT_SYMBOL_GPL(is_current_mnt_ns); + + /* + * vfsmount lock must be held for write +@@ -1961,6 +1963,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg, + } + return 0; + } ++EXPORT_SYMBOL_GPL(iterate_mounts); + + static void lock_mnt_tree(struct mount *mnt) + { +diff --git a/fs/notify/group.c b/fs/notify/group.c +index a4a4b1c64d32a..86dc2efb1850c 100644 +--- a/fs/notify/group.c ++++ b/fs/notify/group.c +@@ -100,6 +100,7 @@ void fsnotify_get_group(struct fsnotify_group *group) + { + refcount_inc(&group->refcnt); + } ++EXPORT_SYMBOL_GPL(fsnotify_get_group); + + /* + * Drop a reference to a group. Free it if it's through. +diff --git a/fs/open.c b/fs/open.c +index 9af548fb841b0..2ff09b709f7bf 100644 +--- a/fs/open.c ++++ b/fs/open.c +@@ -65,6 +65,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, + inode_unlock(dentry->d_inode); + return ret; + } ++EXPORT_SYMBOL_GPL(do_truncate); + + long vfs_truncate(const struct path *path, loff_t length) + { +diff --git a/fs/read_write.c b/fs/read_write.c +index 75f764b434184..7582bb3fb634b 100644 +--- a/fs/read_write.c ++++ b/fs/read_write.c +@@ -503,6 +503,7 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) + inc_syscr(current); + return ret; + } ++EXPORT_SYMBOL_GPL(vfs_read); + + static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) + { +@@ -613,6 +614,7 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_ + file_end_write(file); + return ret; + } ++EXPORT_SYMBOL_GPL(vfs_write); + + /* 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 55b5356262085..c13ac0fbac318 100644 +--- a/fs/splice.c ++++ b/fs/splice.c +@@ -763,6 +763,7 @@ long 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); + } ++EXPORT_SYMBOL_GPL(do_splice_from); + + /* + * Attempt to initiate a splice from a file to a pipe. +@@ -787,6 +788,7 @@ long do_splice_to(struct file *in, loff_t *ppos, + return warn_unsupported(in, "read"); + return in->f_op->splice_read(in, ppos, pipe, len, flags); + } ++EXPORT_SYMBOL_GPL(do_splice_to); + + /** + * splice_direct_to_actor - splices data directly between two non-pipes +diff --git a/fs/sync.c b/fs/sync.c +index b7b5a0a0df6ff..fa5c7fba7f1ba 100644 +--- a/fs/sync.c ++++ b/fs/sync.c +@@ -39,6 +39,7 @@ int __sync_filesystem(struct super_block *sb, int wait) + sb->s_op->sync_fs(sb, wait); + return __sync_blockdev(sb->s_bdev, wait); + } ++EXPORT_SYMBOL_GPL(__sync_filesystem); + + /* + * Write out and wait upon all dirty data associated with this +diff --git a/fs/xattr.c b/fs/xattr.c +index cd7a563e8bcd4..7d989d57b0f0d 100644 +--- a/fs/xattr.c ++++ b/fs/xattr.c +@@ -360,6 +360,7 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value, + *xattr_value = value; + return error; + } ++EXPORT_SYMBOL_GPL(vfs_getxattr_alloc); + + 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 7f006a47790cf..be002c3a30833 100644 +--- a/kernel/locking/lockdep.c ++++ b/kernel/locking/lockdep.c +@@ -209,6 +209,7 @@ inline struct lock_class *lockdep_hlock_class(struct held_lock *hlock) + */ + return lock_classes + class_idx; + } ++EXPORT_SYMBOL_GPL(lockdep_hlock_class); + #define hlock_class(hlock) lockdep_hlock_class(hlock) + + #ifdef CONFIG_LOCK_STAT +diff --git a/kernel/task_work.c b/kernel/task_work.c +index 8d6e1217c451c..0e73637adda86 100644 +--- a/kernel/task_work.c ++++ b/kernel/task_work.c +@@ -154,3 +154,4 @@ void task_work_run(void) + } while (work); + } + } ++EXPORT_SYMBOL_GPL(task_work_run); +diff --git a/security/security.c b/security/security.c +index a28045dc9e7f6..310cf38efeec7 100644 +--- a/security/security.c ++++ b/security/security.c +@@ -1093,6 +1093,7 @@ int security_path_rmdir(const struct path *dir, struct dentry *dentry) + return 0; + return call_int_hook(path_rmdir, 0, dir, dentry); + } ++EXPORT_SYMBOL_GPL(security_path_rmdir); + + int security_path_unlink(const struct path *dir, struct dentry *dentry) + { +@@ -1109,6 +1110,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); + } ++EXPORT_SYMBOL_GPL(security_path_symlink); + + int security_path_link(struct dentry *old_dentry, const struct path *new_dir, + struct dentry *new_dentry) +@@ -1117,6 +1119,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); + } ++EXPORT_SYMBOL_GPL(security_path_link); + + int security_path_rename(const struct path *old_dir, struct dentry *old_dentry, + const struct path *new_dir, struct dentry *new_dentry, +@@ -1144,6 +1147,7 @@ int security_path_truncate(const struct path *path) + return 0; + return call_int_hook(path_truncate, 0, path); + } ++EXPORT_SYMBOL_GPL(security_path_truncate); + + int security_path_chmod(const struct path *path, umode_t mode) + { +@@ -1151,6 +1155,7 @@ int security_path_chmod(const struct path *path, umode_t mode) + return 0; + return call_int_hook(path_chmod, 0, path, mode); + } ++EXPORT_SYMBOL_GPL(security_path_chmod); + + int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid) + { +@@ -1158,6 +1163,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); + } ++EXPORT_SYMBOL_GPL(security_path_chown); + + int security_path_chroot(const struct path *path) + { +@@ -1258,6 +1264,7 @@ int security_inode_permission(struct inode *inode, int mask) + return 0; + return call_int_hook(inode_permission, 0, inode, mask); + } ++EXPORT_SYMBOL_GPL(security_inode_permission); + + int security_inode_setattr(struct dentry *dentry, struct iattr *attr) + { +@@ -1450,6 +1457,7 @@ int security_file_permission(struct file *file, int mask) + + return fsnotify_perm(file, mask); + } ++EXPORT_SYMBOL_GPL(security_file_permission); + + int security_file_alloc(struct file *file) + { diff --git a/kernel/tools/perf/files/patches/mageia/fs-aufs5.10-tristate.patch b/kernel/tools/perf/files/patches/mageia/fs-aufs5.10-tristate.patch new file mode 100644 index 0000000000..f95f4ab698 --- /dev/null +++ b/kernel/tools/perf/files/patches/mageia/fs-aufs5.10-tristate.patch @@ -0,0 +1,24 @@ + +Allow aufs to be built as module. + +Signed-off-by: Thomas Backlund + +--- a/fs/aufs/Kconfig ++++ b/fs/aufs/Kconfig +@@ -1,6 +1,6 @@ + # SPDX-License-Identifier: GPL-2.0 + config AUFS_FS +- bool "Aufs (Advanced multi layered unification filesystem) support" ++ 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 +@@ -72,7 +72,7 @@ endchoice + + config AUFS_EXPORT + bool "NFS-exportable aufs" +- depends on EXPORTFS = y ++ 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. diff --git a/kernel/tools/perf/files/patches/mageia/aufs5.patch b/kernel/tools/perf/files/patches/mageia/fs-aufs5.10.patch similarity index 98% rename from kernel/tools/perf/files/patches/mageia/aufs5.patch rename to kernel/tools/perf/files/patches/mageia/fs-aufs5.10.patch index 9f4dcd013a..34eab23c6a 100644 --- a/kernel/tools/perf/files/patches/mageia/aufs5.patch +++ b/kernel/tools/perf/files/patches/mageia/fs-aufs5.10.patch @@ -1,3 +1,123 @@ + Documentation/ABI/testing/debugfs-aufs | 55 + + Documentation/ABI/testing/sysfs-aufs | 31 + + Documentation/filesystems/aufs/README | 401 ++++ + Documentation/filesystems/aufs/design/01intro.txt | 158 ++ + Documentation/filesystems/aufs/design/02struct.txt | 245 +++ + .../filesystems/aufs/design/03atomic_open.txt | 72 + + Documentation/filesystems/aufs/design/03lookup.txt | 100 + + Documentation/filesystems/aufs/design/04branch.txt | 61 + + .../filesystems/aufs/design/05wbr_policy.txt | 51 + + Documentation/filesystems/aufs/design/06dirren.dot | 31 + + Documentation/filesystems/aufs/design/06dirren.txt | 89 + + Documentation/filesystems/aufs/design/06fhsm.txt | 105 ++ + Documentation/filesystems/aufs/design/06mmap.txt | 59 + + Documentation/filesystems/aufs/design/06xattr.txt | 81 + + Documentation/filesystems/aufs/design/07export.txt | 45 + + Documentation/filesystems/aufs/design/08shwh.txt | 39 + + Documentation/filesystems/aufs/design/10dynop.txt | 34 + + MAINTAINERS | 13 + + drivers/block/loop.c | 18 + + fs/Kconfig | 1 + + fs/Makefile | 1 + + fs/aufs/Kconfig | 199 ++ + fs/aufs/Makefile | 39 + + fs/aufs/aufs.h | 49 + + fs/aufs/branch.c | 1414 +++++++++++++++ + fs/aufs/branch.h | 351 ++++ + fs/aufs/cpup.c | 1432 +++++++++++++++ + fs/aufs/cpup.h | 87 + + fs/aufs/dbgaufs.c | 513 ++++++ + fs/aufs/dbgaufs.h | 40 + + fs/aufs/dcsub.c | 212 +++ + fs/aufs/dcsub.h | 124 ++ + fs/aufs/debug.c | 428 +++++ + fs/aufs/debug.h | 213 +++ + fs/aufs/dentry.c | 1141 ++++++++++++ + fs/aufs/dentry.h | 255 +++ + fs/aufs/dinfo.c | 541 ++++++ + fs/aufs/dir.c | 750 ++++++++ + fs/aufs/dir.h | 121 ++ + fs/aufs/dirren.c | 1303 +++++++++++++ + fs/aufs/dirren.h | 127 ++ + fs/aufs/dynop.c | 355 ++++ + fs/aufs/dynop.h | 64 + + fs/aufs/export.c | 824 +++++++++ + fs/aufs/f_op.c | 749 ++++++++ + fs/aufs/fhsm.c | 413 +++++ + fs/aufs/file.c | 850 +++++++++ + fs/aufs/file.h | 329 ++++ + fs/aufs/finfo.c | 136 ++ + fs/aufs/fstype.h | 388 ++++ + fs/aufs/hbl.h | 52 + + fs/aufs/hfsnotify.c | 275 +++ + fs/aufs/hfsplus.c | 47 + + fs/aufs/hnotify.c | 702 +++++++ + fs/aufs/i_op.c | 1489 +++++++++++++++ + fs/aufs/i_op_add.c | 923 ++++++++++ + fs/aufs/i_op_del.c | 500 +++++ + fs/aufs/i_op_ren.c | 1237 +++++++++++++ + fs/aufs/iinfo.c | 273 +++ + fs/aufs/inode.c | 516 ++++++ + fs/aufs/inode.h | 685 +++++++ + fs/aufs/ioctl.c | 207 +++ + fs/aufs/lcnt.h | 173 ++ + fs/aufs/loop.c | 135 ++ + fs/aufs/loop.h | 42 + + fs/aufs/magic.mk | 31 + + fs/aufs/module.c | 259 +++ + fs/aufs/module.h | 153 ++ + fs/aufs/mvdown.c | 693 +++++++ + fs/aufs/opts.c | 1867 +++++++++++++++++++ + fs/aufs/opts.h | 212 +++ + fs/aufs/plink.c | 503 +++++ + fs/aufs/poll.c | 38 + + fs/aufs/posix_acl.c | 92 + + fs/aufs/procfs.c | 157 ++ + fs/aufs/rdu.c | 371 ++++ + fs/aufs/rwsem.h | 60 + + fs/aufs/sbinfo.c | 301 +++ + fs/aufs/super.c | 1034 +++++++++++ + fs/aufs/super.h | 574 ++++++ + fs/aufs/sysaufs.c | 80 + + fs/aufs/sysaufs.h | 89 + + fs/aufs/sysfs.c | 338 ++++ + fs/aufs/sysrq.c | 136 ++ + fs/aufs/vdir.c | 883 +++++++++ + fs/aufs/vfsub.c | 872 +++++++++ + fs/aufs/vfsub.h | 341 ++++ + fs/aufs/wbr_policy.c | 817 +++++++++ + fs/aufs/whout.c | 1049 +++++++++++ + fs/aufs/whout.h | 73 + + fs/aufs/wkq.c | 359 ++++ + fs/aufs/wkq.h | 76 + + fs/aufs/xattr.c | 343 ++++ + fs/aufs/xino.c | 1912 ++++++++++++++++++++ + fs/dcache.c | 2 +- + fs/fcntl.c | 4 +- + fs/inode.c | 2 +- + fs/namespace.c | 6 + + fs/proc/base.c | 2 +- + fs/proc/nommu.c | 5 +- + fs/proc/task_mmu.c | 7 +- + fs/proc/task_nommu.c | 5 +- + fs/splice.c | 10 +- + fs/sync.c | 2 +- + include/linux/fs.h | 4 + + include/linux/lockdep.h | 3 + + include/linux/mm.h | 22 + + include/linux/mm_types.h | 2 + + include/linux/mnt_namespace.h | 3 + + include/linux/splice.h | 6 + + include/uapi/linux/aufs_type.h | 439 +++++ + kernel/fork.c | 2 +- + kernel/locking/lockdep.c | 3 +- + mm/Makefile | 2 +- + mm/filemap.c | 2 +- + mm/mmap.c | 33 +- + mm/nommu.c | 10 +- + mm/prfile.c | 86 + + 118 files changed, 36737 insertions(+), 31 deletions(-) + diff --git a/Documentation/ABI/testing/debugfs-aufs b/Documentation/ABI/testing/debugfs-aufs new file mode 100644 index 000000000000..4a6694194ba6 @@ -1758,10 +1878,10 @@ index 000000000000..2b90eecb267d +Currently this approach is applied to address_space_operations for +regular files only. diff --git a/MAINTAINERS b/MAINTAINERS -index 4e2698cc7e23..491f32f3b072 100644 +index 281de213ef47..ffc3c1c539ea 100644 --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -2984,6 +2984,19 @@ F: include/linux/audit.h +@@ -3009,6 +3009,19 @@ F: include/linux/audit.h F: include/uapi/linux/audit.h F: kernel/audit* @@ -1769,12 +1889,12 @@ index 4e2698cc7e23..491f32f3b072 100644 +M: "J. R. Okajima" +L: aufs-users@lists.sourceforge.net (members only) +L: linux-unionfs@vger.kernel.org ++S: Supported +W: http://aufs.sourceforge.net +T: git://github.com/sfjro/aufs4-linux.git -+S: Supported -+F: Documentation/filesystems/aufs/ +F: Documentation/ABI/testing/debugfs-aufs +F: Documentation/ABI/testing/sysfs-aufs ++F: Documentation/filesystems/aufs/ +F: fs/aufs/ +F: include/uapi/linux/aufs_type.h + @@ -1782,10 +1902,10 @@ index 4e2698cc7e23..491f32f3b072 100644 M: Miguel Ojeda Sandonis S: Maintained diff --git a/drivers/block/loop.c b/drivers/block/loop.c -index 475e1a738560..8d77e68aa52b 100644 +index a58084c2ed7c..7be7ca3f5454 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c -@@ -763,6 +763,24 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, +@@ -765,6 +765,24 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, return error; } @@ -1811,10 +1931,10 @@ index 475e1a738560..8d77e68aa52b 100644 static ssize_t loop_attr_show(struct device *dev, char *page, diff --git a/fs/Kconfig b/fs/Kconfig -index a88aa3af73c1..0f0caa023fb9 100644 +index aa4c12282301..b29bad13b249 100644 --- a/fs/Kconfig +++ b/fs/Kconfig -@@ -267,6 +267,7 @@ source "fs/sysv/Kconfig" +@@ -288,6 +288,7 @@ source "fs/sysv/Kconfig" source "fs/ufs/Kconfig" source "fs/erofs/Kconfig" source "fs/vboxsf/Kconfig" @@ -1823,7 +1943,7 @@ index a88aa3af73c1..0f0caa023fb9 100644 endif # MISC_FILESYSTEMS diff --git a/fs/Makefile b/fs/Makefile -index 2ce5112b02c8..d9b4a5198553 100644 +index 999d1a23f036..0cd76857ca76 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -136,3 +136,4 @@ obj-$(CONFIG_EFIVAR_FS) += efivarfs/ @@ -1833,13 +1953,13 @@ index 2ce5112b02c8..d9b4a5198553 100644 +obj-$(CONFIG_AUFS_FS) += aufs/ diff --git a/fs/aufs/Kconfig b/fs/aufs/Kconfig new file mode 100644 -index 000000000000..d9ef85bc962e +index 000000000000..0b442aeb7b45 --- /dev/null +++ b/fs/aufs/Kconfig @@ -0,0 +1,199 @@ +# SPDX-License-Identifier: GPL-2.0 +config AUFS_FS -+ tristate "Aufs (Advanced multi layered unification filesystem) support" ++ bool "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 @@ -3558,10 +3678,10 @@ index 000000000000..3319245c0361 +} diff --git a/fs/aufs/branch.h b/fs/aufs/branch.h new file mode 100644 -index 000000000000..0bac9a6c9557 +index 000000000000..5632781b7bcc --- /dev/null +++ b/fs/aufs/branch.h -@@ -0,0 +1,353 @@ +@@ -0,0 +1,351 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2005-2020 Junjiro R. Okajima @@ -3792,10 +3912,8 @@ index 000000000000..0bac9a6c9557 + 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(vfs_readf_t func, struct file *file, void *buf, size_t size, -+ loff_t *pos); -+ssize_t xino_fwrite(vfs_writef_t func, struct file *file, void *buf, -+ size_t size, loff_t *pos); ++ssize_t 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); @@ -3917,10 +4035,10 @@ index 000000000000..0bac9a6c9557 +#endif /* __AUFS_BRANCH_H__ */ diff --git a/fs/aufs/cpup.c b/fs/aufs/cpup.c new file mode 100644 -index 000000000000..69a60ddc3474 +index 000000000000..d413ad06ca89 --- /dev/null +++ b/fs/aufs/cpup.c -@@ -0,0 +1,1445 @@ +@@ -0,0 +1,1432 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005-2020 Junjiro R. Okajima @@ -4479,32 +4597,19 @@ index 000000000000..69a60ddc3474 +static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src, + struct inode *h_dir) +{ -+ int err, symlen; -+ mm_segment_t old_fs; -+ union { -+ char *k; -+ char __user *u; -+ } sym; ++ int err; ++ DEFINE_DELAYED_CALL(done); ++ const char *sym; + -+ err = -ENOMEM; -+ sym.k = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!sym.k)) ++ sym = vfs_get_link(h_src, &done); ++ err = PTR_ERR(sym); ++ if (IS_ERR(sym)) + goto out; + -+ /* unnecessary to support mmap_sem since symlink is not mmap-able */ -+ old_fs = get_fs(); -+ set_fs(KERNEL_DS); -+ symlen = vfs_readlink(h_src, sym.u, PATH_MAX); -+ err = symlen; -+ set_fs(old_fs); -+ -+ if (symlen > 0) { -+ sym.k[symlen] = 0; -+ err = vfsub_symlink(h_dir, h_path, sym.k); -+ } -+ free_page((unsigned long)sym.k); ++ err = vfsub_symlink(h_dir, h_path, sym); + +out: ++ do_delayed_call(&done); + return err; +} + @@ -4619,7 +4724,7 @@ index 000000000000..69a60ddc3474 + case S_IFCHR: + case S_IFBLK: + AuDebugOn(!capable(CAP_MKNOD)); -+ /*FALLTHROUGH*/ ++ fallthrough; + case S_IFIFO: + case S_IFSOCK: + err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev); @@ -11307,10 +11412,10 @@ index 000000000000..ade589d2e75c +#endif /* __AUFS_DIRREN_H__ */ diff --git a/fs/aufs/dynop.c b/fs/aufs/dynop.c new file mode 100644 -index 000000000000..3c3e7812a021 +index 000000000000..5dbb7193591b --- /dev/null +++ b/fs/aufs/dynop.c -@@ -0,0 +1,354 @@ +@@ -0,0 +1,355 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2010-2020 Junjiro R. Okajima @@ -11480,6 +11585,7 @@ index 000000000000..3c3e7812a021 + DySetAop(writepages); + DySetAop(set_page_dirty); + DySetAop(readpages); ++ DySetAop(readahead); + DySetAop(write_begin); + DySetAop(write_end); + DySetAop(bmap); @@ -11737,10 +11843,10 @@ index 000000000000..66ac96bbf2ff +#endif /* __AUFS_DYNOP_H__ */ diff --git a/fs/aufs/export.c b/fs/aufs/export.c new file mode 100644 -index 000000000000..33ae8ac42c5c +index 000000000000..94005688ac0b --- /dev/null +++ b/fs/aufs/export.c -@@ -0,0 +1,825 @@ +@@ -0,0 +1,824 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005-2020 Junjiro R. Okajima @@ -11851,8 +11957,7 @@ index 000000000000..33ae8ac42c5c + pos = inode->i_ino; + pos *= sizeof(igen); + igen = inode->i_generation + 1; -+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen, -+ sizeof(igen), &pos); ++ sz = xino_fwrite(sbinfo->si_xigen, &igen, sizeof(igen), &pos); + if (sz == sizeof(igen)) + return; /* success */ + @@ -11894,10 +11999,10 @@ index 000000000000..33ae8ac42c5c + if (vfsub_f_size_read(file) + < pos + sizeof(inode->i_generation)) { + inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next); -+ sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation, ++ sz = xino_fwrite(file, &inode->i_generation, + sizeof(inode->i_generation), &pos); + } else -+ sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation, ++ sz = xino_fread(file, &inode->i_generation, + sizeof(inode->i_generation), &pos); + if (sz == sizeof(inode->i_generation)) + goto out; /* success */ @@ -12568,10 +12673,10 @@ index 000000000000..33ae8ac42c5c +} diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c new file mode 100644 -index 000000000000..c359b1441e96 +index 000000000000..7e9298b963aa --- /dev/null +++ b/fs/aufs/f_op.c -@@ -0,0 +1,806 @@ +@@ -0,0 +1,749 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005-2020 Junjiro R. Okajima @@ -12803,34 +12908,6 @@ index 000000000000..c359b1441e96 + fput(h_file); +} + -+static ssize_t aufs_read(struct file *file, char __user *buf, size_t count, -+ loff_t *ppos) -+{ -+ ssize_t err; -+ struct inode *inode; -+ struct file *h_file; -+ 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; -+ -+ /* filedata may be obsoleted by concurrent copyup, but no problem */ -+ err = vfsub_read_u(h_file, buf, count, ppos); -+ /* todo: necessary? */ -+ /* file->f_ra = h_file->f_ra; */ -+ au_read_post(inode, h_file); -+ -+out: -+ si_read_unlock(sb); -+ return err; -+} -+ +/* + * todo: very ugly + * it locks both of i_mutex and si_rwsem for read in safe. @@ -12853,33 +12930,6 @@ index 000000000000..c359b1441e96 + } +} + -+static ssize_t aufs_write(struct file *file, const char __user *ubuf, -+ size_t count, loff_t *ppos) -+{ -+ ssize_t err; -+ struct au_write_pre wpre; -+ struct inode *inode; -+ struct file *h_file; -+ char __user *buf = (char __user *)ubuf; -+ -+ 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_write_u(h_file, buf, count, ppos); -+ au_write_post(inode, h_file, &wpre, err); -+ -+out: -+ si_read_unlock(inode->i_sb); -+ inode_unlock(inode); -+ return err; -+} -+ +static ssize_t au_do_iter(struct file *h_file, int rw, struct kiocb *kio, + struct iov_iter *iov_iter) +{ @@ -13349,8 +13399,6 @@ index 000000000000..c359b1441e96 + + .llseek = default_llseek, + -+ .read = aufs_read, -+ .write = aufs_write, + .read_iter = aufs_read_iter, + .write_iter = aufs_write_iter, + @@ -15584,7 +15632,7 @@ index 000000000000..571efb1e2300 +#endif /* __AUFS_HBL_H__ */ diff --git a/fs/aufs/hfsnotify.c b/fs/aufs/hfsnotify.c new file mode 100644 -index 000000000000..65acdd7f5b69 +index 000000000000..db3a2605521b --- /dev/null +++ b/fs/aufs/hfsnotify.c @@ -0,0 +1,275 @@ @@ -15737,8 +15785,8 @@ index 000000000000..65acdd7f5b69 +} + +static int au_hfsn_handle_event(struct fsnotify_group *group, -+ struct inode *inode, + u32 mask, const void *data, int data_type, ++ struct inode *dir, + const struct qstr *file_name, u32 cookie, + struct fsnotify_iter_info *iter_info) +{ @@ -15755,7 +15803,7 @@ index 000000000000..65acdd7f5b69 + if (mask & (FS_IN_IGNORED | FS_UNMOUNT)) + goto out; + -+ h_dir = inode; ++ h_dir = dir; + h_inode = NULL; +#ifdef AuDbgHnotify + au_debug_on(); @@ -15918,7 +15966,7 @@ index 000000000000..3d4fed48bf16 +} diff --git a/fs/aufs/hnotify.c b/fs/aufs/hnotify.c new file mode 100644 -index 000000000000..e082f63ccaf9 +index 000000000000..ea1060fb7de0 --- /dev/null +++ b/fs/aufs/hnotify.c @@ -0,0 +1,702 @@ @@ -16495,7 +16543,7 @@ index 000000000000..e082f63ccaf9 + case FS_MOVED_TO: + au_fset_hnjob(flags[AuHn_CHILD], XINO0); + au_fset_hnjob(flags[AuHn_CHILD], MNTPNT); -+ /*FALLTHROUGH*/ ++ fallthrough; + case FS_CREATE: + AuDebugOn(!h_child_name); + break; @@ -21600,7 +21648,7 @@ index 000000000000..c071e525f499 +} diff --git a/fs/aufs/inode.h b/fs/aufs/inode.h new file mode 100644 -index 000000000000..833d2ce64e81 +index 000000000000..7f1992a3ef5c --- /dev/null +++ b/fs/aufs/inode.h @@ -0,0 +1,685 @@ @@ -22186,7 +22234,7 @@ index 000000000000..833d2ce64e81 + int (*alloc)(struct au_hinode *hinode); + + /* -+ * if it returns true, the the caller should free hinode->hi_notify, ++ * if it returns true, the caller should free hinode->hi_notify, + * otherwise ->free() frees it. + */ + int (*free)(struct au_hinode *hinode, @@ -24032,7 +24080,7 @@ index 000000000000..d28a33f4a944 +} diff --git a/fs/aufs/opts.c b/fs/aufs/opts.c new file mode 100644 -index 000000000000..7448ed020e38 +index 000000000000..26ecf5604117 --- /dev/null +++ b/fs/aufs/opts.c @@ -0,0 +1,1867 @@ @@ -24532,7 +24580,7 @@ index 000000000000..7448ed020e38 + err = e; + break; + } -+ /*FALLTHROUGH*/ ++ fallthrough; + case AuWbrCreate_MFS: + case AuWbrCreate_PMFS: + create->mfs_second = AUFS_MFS_DEF_SEC; @@ -25264,7 +25312,7 @@ index 000000000000..7448ed020e38 + + case Opt_ignore: + pr_warn("ignored %s\n", opt_str); -+ /*FALLTHROUGH*/ ++ fallthrough; + case Opt_ignore_silent: + skipped = 1; + err = 0; @@ -25320,7 +25368,7 @@ index 000000000000..7448ed020e38 + case AuWbrCreate_PMFSRR: + case AuWbrCreate_PMFSRRV: + sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark; -+ /*FALLTHROUGH*/ ++ fallthrough; + case AuWbrCreate_MFS: + case AuWbrCreate_MFSV: + case AuWbrCreate_PMFS: @@ -25540,7 +25588,7 @@ index 000000000000..7448ed020e38 + /* Always goto add, not fallthrough */ + case Opt_prepend: + opt->add.bindex = 0; -+ /* fallthrough */ ++ fallthrough; + add: /* indented label */ + case Opt_add: + err = au_br_add(sb, &opt->add, @@ -28727,10 +28775,10 @@ index 000000000000..589dd0122020 +}; diff --git a/fs/aufs/super.h b/fs/aufs/super.h new file mode 100644 -index 000000000000..37205202c272 +index 000000000000..f840eedbd572 --- /dev/null +++ b/fs/aufs/super.h -@@ -0,0 +1,576 @@ +@@ -0,0 +1,574 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2005-2020 Junjiro R. Okajima @@ -28851,8 +28899,6 @@ index 000000000000..37205202c272 + unsigned int si_mntflags; + + /* external inode number (bitmap and translation table) */ -+ vfs_readf_t si_xread; -+ vfs_writef_t si_xwrite; + loff_t si_ximaxent; /* max entries in a xino */ + + struct file *si_xib; @@ -30865,10 +30911,10 @@ index 000000000000..6cc7ecf0b0e1 +} diff --git a/fs/aufs/vfsub.c b/fs/aufs/vfsub.c new file mode 100644 -index 000000000000..3217455dc21b +index 000000000000..fa29c543cc28 --- /dev/null +++ b/fs/aufs/vfsub.c -@@ -0,0 +1,882 @@ +@@ -0,0 +1,872 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005-2020 Junjiro R. Okajima @@ -31371,22 +31417,17 @@ index 000000000000..3217455dc21b + return err; +} + -+/* todo: kernel_read()? */ +ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count, + loff_t *ppos) +{ + ssize_t err; -+ mm_segment_t oldfs; -+ union { -+ void *k; -+ char __user *u; -+ } buf; + -+ buf.k = kbuf; -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); -+ err = vfsub_read_u(file, buf.u, count, ppos); -+ set_fs(oldfs); ++ 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; +} + @@ -31406,17 +31447,12 @@ index 000000000000..3217455dc21b +ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos) +{ + ssize_t err; -+ mm_segment_t oldfs; -+ union { -+ void *k; -+ const char __user *u; -+ } buf; + -+ buf.k = kbuf; -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); -+ err = vfsub_write_u(file, buf.u, count, ppos); -+ set_fs(oldfs); ++ 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; +} + @@ -34853,10 +34889,10 @@ index 000000000000..a71145b741b1 +} diff --git a/fs/aufs/xino.c b/fs/aufs/xino.c new file mode 100644 -index 000000000000..ad2895dd6055 +index 000000000000..753e92a3d6d7 --- /dev/null +++ b/fs/aufs/xino.c -@@ -0,0 +1,1953 @@ +@@ -0,0 +1,1912 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005-2020 Junjiro R. Okajima @@ -35506,8 +35542,8 @@ index 000000000000..ad2895dd6055 + ino_t h_ino, ino; +}; + -+static int au_xino_do_write(vfs_writef_t write, struct file *file, -+ struct au_xi_calc *calc, ino_t 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) +{ @@ -35536,7 +35572,7 @@ index 000000000000..ad2895dd6055 + + file = au_xino_file(br->br_xino, a->calc.idx); + AuDebugOn(!file); -+ err = au_xino_do_write(sbi->si_xwrite, file, &a->calc, a->ino); ++ err = au_xino_do_write(file, &a->calc, a->ino); + if (unlikely(err)) { + AuIOErr("err %d\n", err); + goto out; @@ -35637,7 +35673,7 @@ index 000000000000..ad2895dd6055 + return 0; /* no xino */ + + sbinfo = au_sbi(sb); -+ sz = xino_fread(sbinfo->si_xread, file, ino, sizeof(*ino), &calc.pos); ++ sz = xino_fread(file, ino, sizeof(*ino), &calc.pos); + if (sz == sizeof(*ino)) + return 0; /* success */ + @@ -35649,12 +35685,12 @@ index 000000000000..ad2895dd6055 + return err; +} + -+static int au_xino_do_write(vfs_writef_t write, struct file *file, -+ struct au_xi_calc *calc, ino_t ino) ++static int au_xino_do_write(struct file *file, struct au_xi_calc *calc, ++ ino_t ino) +{ + ssize_t sz; + -+ sz = xino_fwrite(write, file, &ino, sizeof(ino), &calc->pos); ++ sz = xino_fwrite(file, &ino, sizeof(ino), &calc->pos); + if (sz == sizeof(ino)) + return 0; /* success */ + @@ -35704,7 +35740,7 @@ index 000000000000..ad2895dd6055 + goto out; + } + -+ err = au_xino_do_write(au_sbi(sb)->si_xwrite, file, &calc, ino); ++ err = au_xino_do_write(file, &calc, ino); + if (!err) { + br = au_sbr(sb, bindex); + if (au_opt_test(mnt_flags, TRUNC_XINO) @@ -35718,40 +35754,27 @@ index 000000000000..ad2895dd6055 + return -EIO; +} + -+static ssize_t xino_fread_wkq(vfs_readf_t func, struct file *file, void *buf, -+ size_t size, loff_t *pos); ++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(vfs_readf_t func, struct file *file, void *kbuf, size_t size, -+ loff_t *pos) ++ssize_t xino_fread(struct file *file, void *kbuf, size_t size, loff_t *pos) +{ + ssize_t err; -+ mm_segment_t oldfs; -+ union { -+ void *k; -+ char __user *u; -+ } buf; + int i; + const int prevent_endless = 10; + + i = 0; -+ buf.k = kbuf; -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); + do { -+ err = func(file, buf.u, size, pos); ++ err = vfsub_read_k(file, kbuf, size, pos); + if (err == -EINTR + && !au_wkq_test() + && fatal_signal_pending(current)) { -+ set_fs(oldfs); -+ err = xino_fread_wkq(func, file, kbuf, size, pos); ++ err = xino_fread_wkq(file, kbuf, size, pos); + BUG_ON(err == -EINTR); -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); + } + } while (i++ < prevent_endless + && (err == -EAGAIN || err == -EINTR)); -+ set_fs(oldfs); + +#if 0 /* reserved for future use */ + if (err > 0) @@ -35763,7 +35786,6 @@ index 000000000000..ad2895dd6055 + +struct xino_fread_args { + ssize_t *errp; -+ vfs_readf_t func; + struct file *file; + void *buf; + size_t size; @@ -35773,17 +35795,16 @@ index 000000000000..ad2895dd6055 +static void call_xino_fread(void *args) +{ + struct xino_fread_args *a = args; -+ *a->errp = xino_fread(a->func, a->file, a->buf, a->size, a->pos); ++ *a->errp = xino_fread(a->file, a->buf, a->size, a->pos); +} + -+static ssize_t xino_fread_wkq(vfs_readf_t func, struct file *file, void *buf, -+ size_t size, loff_t *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, -+ .func = func, + .file = file, + .buf = buf, + .size = size, @@ -35797,39 +35818,27 @@ index 000000000000..ad2895dd6055 + return err; +} + -+static ssize_t xino_fwrite_wkq(vfs_writef_t func, struct file *file, void *buf, -+ size_t size, loff_t *pos); ++static ssize_t xino_fwrite_wkq(struct file *file, void *buf, size_t size, ++ loff_t *pos); + -+static ssize_t do_xino_fwrite(vfs_writef_t func, struct file *file, void *kbuf, -+ 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; -+ mm_segment_t oldfs; -+ union { -+ void *k; -+ const char __user *u; -+ } buf; + int i; + const int prevent_endless = 10; + + i = 0; -+ buf.k = kbuf; -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); + do { -+ err = func(file, buf.u, size, pos); ++ err = vfsub_write_k(file, kbuf, size, pos); + if (err == -EINTR + && !au_wkq_test() + && fatal_signal_pending(current)) { -+ set_fs(oldfs); -+ err = xino_fwrite_wkq(func, file, kbuf, size, pos); ++ err = xino_fwrite_wkq(file, kbuf, size, pos); + BUG_ON(err == -EINTR); -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); + } + } while (i++ < prevent_endless + && (err == -EAGAIN || err == -EINTR)); -+ set_fs(oldfs); + +#if 0 /* reserved for future use */ + if (err > 0) @@ -35841,7 +35850,6 @@ index 000000000000..ad2895dd6055 + +struct do_xino_fwrite_args { + ssize_t *errp; -+ vfs_writef_t func; + struct file *file; + void *buf; + size_t size; @@ -35851,17 +35859,16 @@ index 000000000000..ad2895dd6055 +static void call_do_xino_fwrite(void *args) +{ + struct do_xino_fwrite_args *a = args; -+ *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos); ++ *a->errp = do_xino_fwrite(a->file, a->buf, a->size, a->pos); +} + -+static ssize_t xino_fwrite_wkq(vfs_writef_t func, struct file *file, void *buf, -+ size_t size, loff_t *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, -+ .func = func, + .file = file, + .buf = buf, + .size = size, @@ -35879,18 +35886,17 @@ index 000000000000..ad2895dd6055 + return err; +} + -+ssize_t xino_fwrite(vfs_writef_t func, 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) +{ + ssize_t err; + + if (rlimit(RLIMIT_FSIZE) == RLIM_INFINITY) { + lockdep_off(); -+ err = do_xino_fwrite(func, file, buf, size, pos); ++ err = do_xino_fwrite(file, buf, size, pos); + lockdep_on(); + } else { + lockdep_off(); -+ err = xino_fwrite_wkq(func, file, buf, size, pos); ++ err = xino_fwrite_wkq(file, buf, size, pos); + lockdep_on(); + } + @@ -35941,17 +35947,17 @@ index 000000000000..ad2895dd6055 + p = sbinfo->si_xib_buf; + pos = sbinfo->si_xib_last_pindex; + pos *= PAGE_SIZE; -+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos); ++ 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(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos); ++ sz = xino_fread(xib, p, PAGE_SIZE, &pos); + else { + memset(p, 0, PAGE_SIZE); -+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos); ++ sz = xino_fwrite(xib, p, PAGE_SIZE, &pos); + } + if (sz == PAGE_SIZE) { + sbinfo->si_xib_last_pindex = pindex; @@ -36002,7 +36008,6 @@ index 000000000000..ad2895dd6055 + unsigned long pindex; + loff_t pos, pend; + struct au_sbinfo *sbinfo; -+ vfs_readf_t func; + ino_t *ino; + unsigned long *p; + @@ -36010,11 +36015,10 @@ index 000000000000..ad2895dd6055 + sbinfo = au_sbi(sb); + MtxMustLock(&sbinfo->si_xib_mtx); + p = sbinfo->si_xib_buf; -+ func = sbinfo->si_xread; + pend = vfsub_f_size_read(file); + pos = 0; + while (pos < pend) { -+ sz = xino_fread(func, file, page, PAGE_SIZE, &pos); ++ sz = xino_fread(file, page, PAGE_SIZE, &pos); + err = sz; + if (unlikely(sz <= 0)) + goto out; @@ -36103,7 +36107,7 @@ index 000000000000..ad2895dd6055 + p = sbinfo->si_xib_buf; + memset(p, 0, PAGE_SIZE); + pos = 0; -+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos); ++ sz = xino_fwrite(sbinfo->si_xib, p, PAGE_SIZE, &pos); + if (unlikely(sz != PAGE_SIZE)) { + err = sz; + AuIOErr("err %d\n", err); @@ -36242,7 +36246,6 @@ index 000000000000..ad2895dd6055 + SiMustWriteLock(sb); + + sbinfo = au_sbi(sb); -+ /* unnecessary to clear sbinfo->si_xread and ->si_xwrite */ + if (sbinfo->si_xib) + fput(sbinfo->si_xib); + sbinfo->si_xib = NULL; @@ -36269,8 +36272,6 @@ index 000000000000..ad2895dd6055 + if (sbinfo->si_xib) + fput(sbinfo->si_xib); + sbinfo->si_xib = file; -+ sbinfo->si_xread = vfs_readf(file); -+ sbinfo->si_xwrite = vfs_writef(file); + xi_sb = file_inode(file)->i_sb; + sbinfo->si_ximaxent = xi_sb->s_maxbytes; + if (unlikely(sbinfo->si_ximaxent < PAGE_SIZE)) { @@ -36291,8 +36292,7 @@ index 000000000000..ad2895dd6055 + sbinfo->si_xib_next_bit = 0; + if (vfsub_f_size_read(file) < PAGE_SIZE) { + pos = 0; -+ err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf, -+ PAGE_SIZE, &pos); ++ err = xino_fwrite(file, sbinfo->si_xib_buf, PAGE_SIZE, &pos); + if (unlikely(err != PAGE_SIZE)) + goto out_free; + } @@ -36343,7 +36343,6 @@ index 000000000000..ad2895dd6055 +} + +struct au_xino_do_set_br { -+ vfs_writef_t writef; + struct au_branch *br; + ino_t h_ino; + aufs_bindex_t bshared; @@ -36385,7 +36384,7 @@ index 000000000000..ad2895dd6055 + goto out; + AuDebugOn(!file); + -+ err = au_xino_do_write(args->writef, file, &calc, AUFS_ROOT_INO); ++ err = au_xino_do_write(file, &calc, AUFS_ROOT_INO); + if (unlikely(err)) + au_xino_put(br); + @@ -36405,7 +36404,6 @@ index 000000000000..ad2895dd6055 + + bbot = au_sbbot(sb); + inode = d_inode(sb->s_root); -+ args.writef = au_sbi(sb)->si_xwrite; + for (bindex = 0; bindex <= bbot; bindex++) { + args.h_ino = au_h_iptr(inode, bindex)->i_ino; + args.br = au_sbr(sb, bindex); @@ -36560,7 +36558,6 @@ index 000000000000..ad2895dd6055 + .br = br + }; + -+ args.writef = au_sbi(sb)->si_xwrite; + args.bshared = sbr_find_shared(sb, /*btop*/0, au_sbbot(sb), + au_br_sb(br)); + err = au_xino_do_set_br(sb, base, &args); @@ -36644,7 +36641,6 @@ index 000000000000..ad2895dd6055 + struct au_hinode *hi; + struct inode *h_inode; + struct au_branch *br; -+ vfs_writef_t xwrite; + struct au_xi_calc calc; + struct file *file; + @@ -36666,7 +36662,6 @@ index 000000000000..ad2895dd6055 + if (bindex < 0) + return; + -+ xwrite = au_sbi(sb)->si_xwrite; + try_trunc = !!au_opt_test(mnt_flags, TRUNC_XINO); + hi = au_hinode(iinfo, bindex); + bbot = iinfo->ii_bbot; @@ -36687,7 +36682,7 @@ index 000000000000..ad2895dd6055 + if (IS_ERR_OR_NULL(file)) + continue; + -+ err = au_xino_do_write(xwrite, file, &calc, /*ino*/0); ++ 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); @@ -36811,7 +36806,7 @@ index 000000000000..ad2895dd6055 + return err; +} diff --git a/fs/dcache.c b/fs/dcache.c -index 361ea7ab30ea..e6e467c9e86c 100644 +index ea0485861d93..ddca6240e0db 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1285,7 +1285,7 @@ enum d_walk_ret { @@ -36823,36 +36818,8 @@ index 361ea7ab30ea..e6e467c9e86c 100644 enum d_walk_ret (*enter)(void *, struct dentry *)) { struct dentry *this_parent; -@@ -1390,6 +1390,7 @@ static void d_walk(struct dentry *parent, void *data, - seq = 1; - goto again; - } -+EXPORT_SYMBOL_GPL(d_walk); - - struct check_mount { - struct vfsmount *mnt; -@@ -2935,6 +2936,7 @@ void d_exchange(struct dentry *dentry1, struct dentry *dentry2) - - write_sequnlock(&rename_lock); - } -+EXPORT_SYMBOL_GPL(d_exchange); - - /** - * d_ancestor - search for an ancestor -diff --git a/fs/exec.c b/fs/exec.c -index e6e8a9a70327..a72a0dbfcc45 100644 ---- a/fs/exec.c -+++ b/fs/exec.c -@@ -111,6 +111,7 @@ bool path_noexec(const struct path *path) - return (path->mnt->mnt_flags & MNT_NOEXEC) || - (path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC); - } -+EXPORT_SYMBOL_GPL(path_noexec); - - #ifdef CONFIG_USELIB - /* diff --git a/fs/fcntl.c b/fs/fcntl.c -index 2e4c0fa2074b..f2c90a416b75 100644 +index 19ac5baad50f..073ca6af500f 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -32,7 +32,7 @@ @@ -36873,39 +36840,11 @@ index 2e4c0fa2074b..f2c90a416b75 100644 if (error) return error; -@@ -83,6 +85,7 @@ static int setfl(int fd, struct file * filp, unsigned long arg) - out: - return error; - } -+EXPORT_SYMBOL_GPL(setfl); - - static void f_modown(struct file *filp, struct pid *pid, enum pid_type type, - int force) -diff --git a/fs/file_table.c b/fs/file_table.c -index 656647f9575a..6e11f3dc333f 100644 ---- a/fs/file_table.c -+++ b/fs/file_table.c -@@ -162,6 +162,7 @@ struct file *alloc_empty_file(int flags, const struct cred *cred) - } - return ERR_PTR(-ENFILE); - } -+EXPORT_SYMBOL_GPL(alloc_empty_file); - - /* - * Variant of alloc_empty_file() that doesn't check and modify nr_files. -@@ -376,6 +377,7 @@ void __fput_sync(struct file *file) - } - - EXPORT_SYMBOL(fput); -+EXPORT_SYMBOL_GPL(__fput_sync); - - void __init files_init(void) - { diff --git a/fs/inode.c b/fs/inode.c -index 72c4c347afb7..07d0cb8d5c98 100644 +index 9d78c37b00b8..e7f0c614a58f 100644 --- a/fs/inode.c +++ b/fs/inode.c -@@ -1768,12 +1768,13 @@ EXPORT_SYMBOL(generic_update_time); +@@ -1770,7 +1770,7 @@ EXPORT_SYMBOL(generic_update_time); * This does the actual work of updating an inodes time or version. Must have * had called mnt_want_write() before calling this. */ @@ -36914,25 +36853,11 @@ index 72c4c347afb7..07d0cb8d5c98 100644 { if (inode->i_op->update_time) return inode->i_op->update_time(inode, time, flags); - return generic_update_time(inode, time, flags); - } -+EXPORT_SYMBOL_GPL(update_time); - - /** - * touch_atime - update the access time diff --git a/fs/namespace.c b/fs/namespace.c -index 4a0f600a3328..2b7e1ac8c4c5 100644 +index cebaa3e81794..451dee24a546 100644 --- a/fs/namespace.c +++ b/fs/namespace.c -@@ -431,6 +431,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 -@@ -792,6 +793,13 @@ static inline int check_mnt(struct mount *mnt) +@@ -792,6 +792,12 @@ static inline int check_mnt(struct mount *mnt) return mnt->mnt_ns == current->nsproxy->mnt_ns; } @@ -36941,48 +36866,15 @@ index 4a0f600a3328..2b7e1ac8c4c5 100644 +{ + return check_mnt(real_mount(mnt)); +} -+EXPORT_SYMBOL_GPL(is_current_mnt_ns); + /* * vfsmount lock must be held for write */ -@@ -1955,6 +1963,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg, - } - return 0; - } -+EXPORT_SYMBOL_GPL(iterate_mounts); - - static void lock_mnt_tree(struct mount *mnt) - { -diff --git a/fs/notify/group.c b/fs/notify/group.c -index a4a4b1c64d32..86dc2efb1850 100644 ---- a/fs/notify/group.c -+++ b/fs/notify/group.c -@@ -100,6 +100,7 @@ void fsnotify_get_group(struct fsnotify_group *group) - { - refcount_inc(&group->refcnt); - } -+EXPORT_SYMBOL_GPL(fsnotify_get_group); - - /* - * Drop a reference to a group. Free it if it's through. -diff --git a/fs/open.c b/fs/open.c -index 6cd48a61cda3..bb623ca6397e 100644 ---- a/fs/open.c -+++ b/fs/open.c -@@ -65,6 +65,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, - inode_unlock(dentry->d_inode); - return ret; - } -+EXPORT_SYMBOL_GPL(do_truncate); - - long vfs_truncate(const struct path *path, loff_t length) - { diff --git a/fs/proc/base.c b/fs/proc/base.c -index d86c0afc8a85..ae484a4d2070 100644 +index b362523a9829..669448bb8a73 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c -@@ -2170,7 +2170,7 @@ static int map_files_get_link(struct dentry *dentry, struct path *path) +@@ -2184,7 +2184,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) { @@ -37008,7 +36900,7 @@ index 13452b32e2bd..38acccfef9d4 100644 ino = inode->i_ino; } diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c -index dbda4499a859..5f6fdf574d83 100644 +index ee5a235b3056..80a46dcede7b 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -280,7 +280,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma) @@ -37023,7 +36915,7 @@ index dbda4499a859..5f6fdf574d83 100644 dev = inode->i_sb->s_dev; ino = inode->i_ino; pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT; -@@ -1793,7 +1796,7 @@ static int show_numa_map(struct seq_file *m, void *v) +@@ -1855,7 +1858,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; @@ -37048,62 +36940,11 @@ index a6d21fc0033c..02c2de31196e 100644 dev = inode->i_sb->s_dev; ino = inode->i_ino; pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT; -diff --git a/fs/read_write.c b/fs/read_write.c -index 4fb797822567..71397019587a 100644 ---- a/fs/read_write.c -+++ b/fs/read_write.c -@@ -488,6 +488,7 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) - inc_syscr(current); - return ret; - } -+EXPORT_SYMBOL_GPL(vfs_read); - - static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) - { -@@ -508,6 +509,30 @@ static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t - } - - /* caller is responsible for file_start_write/file_end_write */ -+vfs_readf_t vfs_readf(struct file *file) -+{ -+ const struct file_operations *fop = file->f_op; -+ -+ if (fop->read) -+ return fop->read; -+ if (fop->read_iter) -+ return new_sync_read; -+ return ERR_PTR(-ENOSYS); /* doesn't have ->read(|_iter)() op */ -+} -+EXPORT_SYMBOL_GPL(vfs_readf); -+ -+vfs_writef_t vfs_writef(struct file *file) -+{ -+ const struct file_operations *fop = file->f_op; -+ -+ if (fop->write) -+ return fop->write; -+ if (fop->write_iter) -+ return new_sync_write; -+ return ERR_PTR(-ENOSYS); /* doesn't have ->write(|_iter)() op */ -+} -+EXPORT_SYMBOL_GPL(vfs_writef); -+ - ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos) - { - mm_segment_t old_fs; -@@ -586,6 +611,7 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_ - file_end_write(file); - return ret; - } -+EXPORT_SYMBOL_GPL(vfs_write); - - /* 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 d7c8a7c4db07..663e01ab2779 100644 +index 866d5c2367b2..55b535626208 100644 --- a/fs/splice.c +++ b/fs/splice.c -@@ -839,8 +839,8 @@ EXPORT_SYMBOL(generic_splice_sendpage); +@@ -756,8 +756,8 @@ static int warn_unsupported(struct file *file, const char *op) /* * Attempt to initiate a splice from pipe to file. */ @@ -37112,9 +36953,9 @@ index d7c8a7c4db07..663e01ab2779 100644 +long do_splice_from(struct pipe_inode_info *pipe, struct file *out, + loff_t *ppos, size_t len, unsigned int flags) { - if (out->f_op->splice_write) - return out->f_op->splice_write(pipe, out, ppos, len, flags); -@@ -850,9 +850,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, + if (unlikely(!out->f_op->splice_write)) + return warn_unsupported(out, "write"); +@@ -767,9 +767,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, /* * Attempt to initiate a splice from a file to a pipe. */ @@ -37127,24 +36968,8 @@ index d7c8a7c4db07..663e01ab2779 100644 { int ret; -@@ -870,6 +870,7 @@ static long do_splice_to(struct file *in, loff_t *ppos, - return in->f_op->splice_read(in, ppos, pipe, len, flags); - return default_file_splice_read(in, ppos, pipe, len, flags); - } -+EXPORT_SYMBOL_GPL(do_splice_from); - - /** - * splice_direct_to_actor - splices data directly between two non-pipes -@@ -1016,6 +1017,7 @@ static int direct_splice_actor(struct pipe_inode_info *pipe, - return do_splice_from(pipe, file, sd->opos, sd->total_len, - sd->flags); - } -+EXPORT_SYMBOL_GPL(do_splice_to); - - /** - * do_splice_direct - splices data directly between two files diff --git a/fs/sync.c b/fs/sync.c -index 1373a610dc78..fa5c7fba7f1b 100644 +index 1373a610dc78..b7b5a0a0df6f 100644 --- a/fs/sync.c +++ b/fs/sync.c @@ -28,7 +28,7 @@ @@ -37156,31 +36981,11 @@ index 1373a610dc78..fa5c7fba7f1b 100644 { if (wait) sync_inodes_sb(sb); -@@ -39,6 +39,7 @@ static int __sync_filesystem(struct super_block *sb, int wait) - sb->s_op->sync_fs(sb, wait); - return __sync_blockdev(sb->s_bdev, wait); - } -+EXPORT_SYMBOL_GPL(__sync_filesystem); - - /* - * Write out and wait upon all dirty data associated with this -diff --git a/fs/xattr.c b/fs/xattr.c -index 95f38f57347f..f01b5bd9c102 100644 ---- a/fs/xattr.c -+++ b/fs/xattr.c -@@ -333,6 +333,7 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value, - *xattr_value = value; - return error; - } -+EXPORT_SYMBOL_GPL(vfs_getxattr_alloc); - - ssize_t - __vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name, diff --git a/include/linux/fs.h b/include/linux/fs.h -index f5abba86107d..0b008da5678d 100644 +index 8667d0cdc71e..837dd6e727e4 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h -@@ -1360,6 +1360,7 @@ extern void fasync_free(struct fasync_struct *); +@@ -1332,6 +1332,7 @@ extern void fasync_free(struct fasync_struct *); /* can be called from interrupts */ extern void kill_fasync(struct fasync_struct **, int, int); @@ -37188,7 +36993,7 @@ index f5abba86107d..0b008da5678d 100644 extern void __f_setown(struct file *filp, struct pid *, enum pid_type, int force); extern int f_setown(struct file *filp, unsigned long arg, int force); extern void f_delown(struct file *filp); -@@ -1848,6 +1849,7 @@ struct file_operations { +@@ -1843,6 +1844,7 @@ struct file_operations { ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); int (*check_flags)(int); @@ -37196,20 +37001,7 @@ index f5abba86107d..0b008da5678d 100644 int (*flock) (struct file *, int, struct file_lock *); 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); -@@ -1918,6 +1920,12 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, - struct iovec *fast_pointer, - struct iovec **ret_pointer); - -+typedef ssize_t (*vfs_readf_t)(struct file *, char __user *, size_t, loff_t *); -+typedef ssize_t (*vfs_writef_t)(struct file *, const char __user *, size_t, -+ loff_t *); -+vfs_readf_t vfs_readf(struct file *file); -+vfs_writef_t vfs_writef(struct file *file); -+ - extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *); - extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *); - extern ssize_t vfs_readv(struct file *, const struct iovec __user *, -@@ -2352,6 +2360,7 @@ extern int current_umask(void); +@@ -2328,6 +2330,7 @@ extern int current_umask(void); extern void ihold(struct inode * inode); extern void iput(struct inode *); extern int generic_update_time(struct inode *, struct timespec64 *, int); @@ -37217,7 +37009,7 @@ index f5abba86107d..0b008da5678d 100644 /* /sys/fs */ extern struct kobject *fs_kobj; -@@ -2633,6 +2642,7 @@ static inline bool sb_is_blkdev_sb(struct super_block *sb) +@@ -2564,6 +2567,7 @@ static inline bool sb_is_blkdev_sb(struct super_block *sb) } void emergency_thaw_all(void); @@ -37226,10 +37018,10 @@ index f5abba86107d..0b008da5678d 100644 extern const struct file_operations def_blk_fops; extern const struct file_operations def_chr_fops; diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h -index 8fce5c98a4b0..c1a3f172e97a 100644 +index f5594879175a..93bb86198167 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h -@@ -395,6 +395,8 @@ static inline int lockdep_match_key(struct lockdep_map *lock, +@@ -241,6 +241,8 @@ static inline int lockdep_match_key(struct lockdep_map *lock, return lock->key == key; } @@ -37238,7 +37030,7 @@ index 8fce5c98a4b0..c1a3f172e97a 100644 /* * Acquire a lock. * -@@ -540,6 +542,7 @@ struct lockdep_map { }; +@@ -375,6 +377,7 @@ static inline void lockdep_unregister_key(struct lock_class_key *key) #define lockdep_depth(tsk) (0) @@ -37247,10 +37039,10 @@ index 8fce5c98a4b0..c1a3f172e97a 100644 #define lockdep_assert_held(l) do { (void)(l); } while (0) diff --git a/include/linux/mm.h b/include/linux/mm.h -index dc7b87310c10..40e450bbf00f 100644 +index db6ae4d3fb4e..1a632192d9d9 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h -@@ -1684,6 +1684,28 @@ static inline void unmap_shared_mapping_range(struct address_space *mapping, +@@ -1712,6 +1712,28 @@ static inline void unmap_shared_mapping_range(struct address_space *mapping, unmap_mapping_range(mapping, holebegin, holelen, 0); } @@ -37280,10 +37072,10 @@ index dc7b87310c10..40e450bbf00f 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 64ede5f150dc..1c899fd6bda4 100644 +index 5a9238f6caad..ad387c3cb14f 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h -@@ -276,6 +276,7 @@ struct vm_region { +@@ -280,6 +280,7 @@ struct vm_region { unsigned long vm_top; /* region allocated to here */ unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */ struct file *vm_file; /* the backing file or NULL */ @@ -37291,7 +37083,7 @@ index 64ede5f150dc..1c899fd6bda4 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 -@@ -355,6 +356,7 @@ struct vm_area_struct { +@@ -359,6 +360,7 @@ 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). */ @@ -37320,7 +37112,7 @@ index 8f882f5881e8..6b9808f09843 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 5c47013f708e..fef6c59ed92a 100644 +index a55179fd60fc..8e21c53cf883 100644 --- a/include/linux/splice.h +++ b/include/linux/splice.h @@ -93,4 +93,10 @@ extern void splice_shrink_spd(struct splice_pipe_desc *); @@ -37336,7 +37128,7 @@ index 5c47013f708e..fef6c59ed92a 100644 #endif diff --git a/include/uapi/linux/aufs_type.h b/include/uapi/linux/aufs_type.h new file mode 100644 -index 000000000000..71501ea96e0b +index 000000000000..a1f4e7081d06 --- /dev/null +++ b/include/uapi/linux/aufs_type.h @@ -0,0 +1,439 @@ @@ -37369,7 +37161,7 @@ index 000000000000..71501ea96e0b +#include +#endif /* __KERNEL__ */ + -+#define AUFS_VERSION "5.7" ++#define AUFS_VERSION "5.x-rcN" + +/* todo? move this to linux-2.6.19/include/magic.h */ +#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's') @@ -37780,23 +37572,23 @@ index 000000000000..71501ea96e0b + +#endif /* __AUFS_TYPE_H__ */ diff --git a/kernel/fork.c b/kernel/fork.c -index efc5493203ae..ba1174fb5d91 100644 +index 6d266388d380..dd7f13c3bee7 100644 --- a/kernel/fork.c +++ b/kernel/fork.c -@@ -570,7 +570,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, +@@ -554,7 +554,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, struct inode *inode = file_inode(file); struct address_space *mapping = file->f_mapping; - get_file(file); + vma_get_file(tmp); if (tmp->vm_flags & VM_DENYWRITE) - atomic_dec(&inode->i_writecount); + put_write_access(inode); i_mmap_lock_write(mapping); diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c -index 29a8de4c50b9..1d54603f1f56 100644 +index c1418b47f625..7f006a47790c 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c -@@ -169,7 +169,7 @@ static +@@ -188,7 +188,7 @@ static struct lock_class lock_classes[MAX_LOCKDEP_KEYS]; static DECLARE_BITMAP(lock_classes_in_use, MAX_LOCKDEP_KEYS); @@ -37805,26 +37597,16 @@ index 29a8de4c50b9..1d54603f1f56 100644 { unsigned int class_idx = hlock->class_idx; -@@ -190,6 +190,8 @@ static inline struct lock_class *hlock_class(struct held_lock *hlock) +@@ -209,6 +209,7 @@ static inline struct lock_class *hlock_class(struct held_lock *hlock) */ return lock_classes + class_idx; } -+EXPORT_SYMBOL_GPL(lockdep_hlock_class); +#define hlock_class(hlock) lockdep_hlock_class(hlock) #ifdef CONFIG_LOCK_STAT static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], cpu_lock_stats); -diff --git a/kernel/task_work.c b/kernel/task_work.c -index 5c0848ca1287..87f09e627840 100644 ---- a/kernel/task_work.c -+++ b/kernel/task_work.c -@@ -138,3 +138,4 @@ void task_work_run(void) - } while (work); - } - } -+EXPORT_SYMBOL_GPL(task_work_run); diff --git a/mm/Makefile b/mm/Makefile -index 6e9d46b2efc9..a432b5664d83 100644 +index d73aed0fc99c..93076a66ad6a 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -52,7 +52,7 @@ obj-y := filemap.o mempool.o oom_kill.o fadvise.o \ @@ -37837,10 +37619,10 @@ index 6e9d46b2efc9..a432b5664d83 100644 # Give 'page_alloc' its own module-parameter namespace page-alloc-y := page_alloc.o diff --git a/mm/filemap.c b/mm/filemap.c -index 385759c4ce4b..570f4e1bc4d3 100644 +index 0b2067b3c328..3334207431c7 100644 --- a/mm/filemap.c +++ b/mm/filemap.c -@@ -2676,7 +2676,7 @@ vm_fault_t filemap_page_mkwrite(struct vm_fault *vmf) +@@ -2909,7 +2909,7 @@ vm_fault_t filemap_page_mkwrite(struct vm_fault *vmf) vm_fault_t ret = VM_FAULT_LOCKED; sb_start_pagefault(inode->i_sb); @@ -37850,7 +37632,7 @@ index 385759c4ce4b..570f4e1bc4d3 100644 if (page->mapping != inode->i_mapping) { unlock_page(page); diff --git a/mm/mmap.c b/mm/mmap.c -index 8c7ca737a19b..c4e2b1383925 100644 +index 5c8b4485860d..59f2f758d77e 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -179,7 +179,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma) @@ -37862,7 +37644,7 @@ index 8c7ca737a19b..c4e2b1383925 100644 mpol_put(vma_policy(vma)); vm_area_free(vma); return next; -@@ -910,7 +910,7 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start, +@@ -951,7 +951,7 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start, if (remove_next) { if (file) { uprobe_munmap(next, next->vm_start, next->vm_end); @@ -37871,7 +37653,7 @@ index 8c7ca737a19b..c4e2b1383925 100644 } if (next->anon_vma) anon_vma_merge(vma, next); -@@ -1831,8 +1831,8 @@ unsigned long mmap_region(struct file *file, unsigned long addr, +@@ -1897,8 +1897,8 @@ unsigned long mmap_region(struct file *file, unsigned long addr, return addr; unmap_and_free_vma: @@ -37881,7 +37663,7 @@ index 8c7ca737a19b..c4e2b1383925 100644 /* Undo any partial mapping done by a device driver. */ unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end); -@@ -2694,7 +2694,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -2757,7 +2757,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, goto out_free_mpol; if (new->vm_file) @@ -37890,7 +37672,7 @@ index 8c7ca737a19b..c4e2b1383925 100644 if (new->vm_ops && new->vm_ops->open) new->vm_ops->open(new); -@@ -2713,7 +2713,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -2776,7 +2776,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, if (new->vm_ops && new->vm_ops->close) new->vm_ops->close(new); if (new->vm_file) @@ -37899,7 +37681,7 @@ index 8c7ca737a19b..c4e2b1383925 100644 unlink_anon_vmas(new); out_free_mpol: mpol_put(vma_policy(new)); -@@ -2906,7 +2906,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, +@@ -2969,7 +2969,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, struct vm_area_struct *vma; unsigned long populate = 0; unsigned long ret = -EINVAL; @@ -37908,7 +37690,7 @@ index 8c7ca737a19b..c4e2b1383925 100644 pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. See Documentation/vm/remap_file_pages.rst.\n", current->comm, current->pid); -@@ -2981,10 +2981,27 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, +@@ -3044,10 +3044,27 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, } } @@ -37937,7 +37719,7 @@ index 8c7ca737a19b..c4e2b1383925 100644 out: mmap_write_unlock(mm); if (populate) -@@ -3275,7 +3292,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, +@@ -3334,7 +3351,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) @@ -37947,10 +37729,10 @@ index 8c7ca737a19b..c4e2b1383925 100644 new_vma->vm_ops->open(new_vma); vma_link(mm, new_vma, prev, rb_link, rb_parent); diff --git a/mm/nommu.c b/mm/nommu.c -index f32a69095d50..26cd21666185 100644 +index 0faf39b32cdb..78ecad7204c8 100644 --- a/mm/nommu.c +++ b/mm/nommu.c -@@ -540,7 +540,7 @@ static void __put_nommu_region(struct vm_region *region) +@@ -533,7 +533,7 @@ static void __put_nommu_region(struct vm_region *region) up_write(&nommu_region_sem); if (region->vm_file) @@ -37959,7 +37741,7 @@ index f32a69095d50..26cd21666185 100644 /* IO memory and memory shared directly out of the pagecache * from ramfs/tmpfs mustn't be released here */ -@@ -672,7 +672,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma) +@@ -665,7 +665,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma) if (vma->vm_ops && vma->vm_ops->close) vma->vm_ops->close(vma); if (vma->vm_file) @@ -37968,7 +37750,7 @@ index f32a69095d50..26cd21666185 100644 put_nommu_region(vma->vm_region); vm_area_free(vma); } -@@ -1195,7 +1195,7 @@ unsigned long do_mmap(struct file *file, +@@ -1188,7 +1188,7 @@ unsigned long do_mmap(struct file *file, goto error_just_free; } } @@ -37977,7 +37759,7 @@ index f32a69095d50..26cd21666185 100644 kmem_cache_free(vm_region_jar, region); region = pregion; result = start; -@@ -1272,10 +1272,10 @@ unsigned long do_mmap(struct file *file, +@@ -1265,10 +1265,10 @@ unsigned long do_mmap(struct file *file, up_write(&nommu_region_sem); error: if (region->vm_file) @@ -38082,71 +37864,3 @@ index 000000000000..00d51187c325 + fput(pr); +} +#endif /* !CONFIG_MMU */ -diff --git a/security/security.c b/security/security.c -index 70a7ad357bc6..d55b72977544 100644 ---- a/security/security.c -+++ b/security/security.c -@@ -1092,6 +1092,7 @@ int security_path_rmdir(const struct path *dir, struct dentry *dentry) - return 0; - return call_int_hook(path_rmdir, 0, dir, dentry); - } -+EXPORT_SYMBOL_GPL(security_path_rmdir); - - int security_path_unlink(const struct path *dir, struct dentry *dentry) - { -@@ -1108,6 +1109,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); - } -+EXPORT_SYMBOL_GPL(security_path_symlink); - - int security_path_link(struct dentry *old_dentry, const struct path *new_dir, - struct dentry *new_dentry) -@@ -1116,6 +1118,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); - } -+EXPORT_SYMBOL_GPL(security_path_link); - - int security_path_rename(const struct path *old_dir, struct dentry *old_dentry, - const struct path *new_dir, struct dentry *new_dentry, -@@ -1143,6 +1146,7 @@ int security_path_truncate(const struct path *path) - return 0; - return call_int_hook(path_truncate, 0, path); - } -+EXPORT_SYMBOL_GPL(security_path_truncate); - - int security_path_chmod(const struct path *path, umode_t mode) - { -@@ -1150,6 +1154,7 @@ int security_path_chmod(const struct path *path, umode_t mode) - return 0; - return call_int_hook(path_chmod, 0, path, mode); - } -+EXPORT_SYMBOL_GPL(security_path_chmod); - - int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid) - { -@@ -1157,6 +1162,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); - } -+EXPORT_SYMBOL_GPL(security_path_chown); - - int security_path_chroot(const struct path *path) - { -@@ -1257,6 +1263,7 @@ int security_inode_permission(struct inode *inode, int mask) - return 0; - return call_int_hook(inode_permission, 0, inode, mask); - } -+EXPORT_SYMBOL_GPL(security_inode_permission); - - int security_inode_setattr(struct dentry *dentry, struct iattr *attr) - { -@@ -1449,6 +1456,7 @@ int security_file_permission(struct file *file, int mask) - - return fsnotify_perm(file, mask); - } -+EXPORT_SYMBOL_GPL(security_file_permission); - - int security_file_alloc(struct file *file) - { diff --git a/kernel/tools/perf/files/patches/mageia/fs-aufs5.patch b/kernel/tools/perf/files/patches/mageia/fs-aufs5.patch deleted file mode 100644 index ebbde97d01..0000000000 --- a/kernel/tools/perf/files/patches/mageia/fs-aufs5.patch +++ /dev/null @@ -1,37934 +0,0 @@ -diff -Nurp linux-5.10-rc6/Documentation/ABI/testing/debugfs-aufs linux-5.10-rc6.aufs/Documentation/ABI/testing/debugfs-aufs ---- linux-5.10-rc6/Documentation/ABI/testing/debugfs-aufs 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/Documentation/ABI/testing/debugfs-aufs 2020-12-02 21:19:51.876036518 +0200 -@@ -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_/xi0, xi1 ... xiN and xiN-N -+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 -Nurp linux-5.10-rc6/Documentation/ABI/testing/sysfs-aufs linux-5.10-rc6.aufs/Documentation/ABI/testing/sysfs-aufs ---- linux-5.10-rc6/Documentation/ABI/testing/sysfs-aufs 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/Documentation/ABI/testing/sysfs-aufs 2020-12-02 21:19:51.876036518 +0200 -@@ -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_/br0, br1 ... brN -+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_/brid0, brid1 ... bridN -+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 -Nurp linux-5.10-rc6/Documentation/filesystems/aufs/design/01intro.txt linux-5.10-rc6.aufs/Documentation/filesystems/aufs/design/01intro.txt ---- linux-5.10-rc6/Documentation/filesystems/aufs/design/01intro.txt 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/Documentation/filesystems/aufs/design/01intro.txt 2020-12-02 21:19:51.876036518 +0200 -@@ -0,0 +1,158 @@ -+ -+# Copyright (C) 2005-2020 Junjiro R. Okajima -+ -+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 -Nurp linux-5.10-rc6/Documentation/filesystems/aufs/design/02struct.txt linux-5.10-rc6.aufs/Documentation/filesystems/aufs/design/02struct.txt ---- linux-5.10-rc6/Documentation/filesystems/aufs/design/02struct.txt 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/Documentation/filesystems/aufs/design/02struct.txt 2020-12-02 21:19:51.876036518 +0200 -@@ -0,0 +1,245 @@ -+ -+# Copyright (C) 2005-2020 Junjiro R. Okajima -+ -+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 -Nurp linux-5.10-rc6/Documentation/filesystems/aufs/design/03atomic_open.txt linux-5.10-rc6.aufs/Documentation/filesystems/aufs/design/03atomic_open.txt ---- linux-5.10-rc6/Documentation/filesystems/aufs/design/03atomic_open.txt 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/Documentation/filesystems/aufs/design/03atomic_open.txt 2020-12-02 21:19:51.876036518 +0200 -@@ -0,0 +1,72 @@ -+ -+# Copyright (C) 2015-2020 Junjiro R. Okajima -+ -+Support for a branch who has its ->atomic_open() -+---------------------------------------------------------------------- -+The filesystems who implement its ->atomic_open() are not majority. For -+example NFSv4 does, and aufs should call NFSv4 ->atomic_open, -+particularly for open(O_CREAT|O_EXCL, 0400) case. Other than -+->atomic_open(), NFSv4 returns an error for this open(2). While I am not -+sure whether all filesystems who have ->atomic_open() behave like this, -+but NFSv4 surely returns the error. -+ -+In order to support ->atomic_open() for aufs, there are a few -+approaches. -+ -+A. Introduce aufs_atomic_open() -+ - calls one of VFS:do_last(), lookup_open() or atomic_open() for -+ branch fs. -+B. Introduce aufs_atomic_open() calling create, open and chmod. this is -+ an aufs user Pip Cet's approach -+ - calls aufs_create(), VFS finish_open() and notify_change(). -+ - pass fake-mode to finish_open(), and then correct the mode by -+ notify_change(). -+C. Extend aufs_open() to call branch fs's ->atomic_open() -+ - no aufs_atomic_open(). -+ - aufs_lookup() registers the TID to an aufs internal object. -+ - aufs_create() does nothing when the matching TID is registered, but -+ registers the mode. -+ - aufs_open() calls branch fs's ->atomic_open() when the matching -+ TID is registered. -+D. Extend aufs_open() to re-try branch fs's ->open() with superuser's -+ credential -+ - no aufs_atomic_open(). -+ - aufs_create() registers the TID to an internal object. this info -+ represents "this process created this file just now." -+ - when aufs gets EACCES from branch fs's ->open(), then confirm the -+ registered TID and re-try open() with superuser's credential. -+ -+Pros and cons for each approach. -+ -+A. -+ - straightforward but highly depends upon VFS internal. -+ - the atomic behavaiour is kept. -+ - some of parameters such as nameidata are hard to reproduce for -+ branch fs. -+ - large overhead. -+B. -+ - easy to implement. -+ - the atomic behavaiour is lost. -+C. -+ - the atomic behavaiour is kept. -+ - dirty and tricky. -+ - VFS checks whether the file is created correctly after calling -+ ->create(), which means this approach doesn't work. -+D. -+ - easy to implement. -+ - the atomic behavaiour is lost. -+ - to open a file with superuser's credential and give it to a user -+ process is a bad idea, since the file object keeps the credential -+ in it. It may affect LSM or something. This approach doesn't work -+ either. -+ -+The approach A is ideal, but it hard to implement. So here is a -+variation of A, which is to be implemented. -+ -+A-1. Introduce aufs_atomic_open() -+ - calls branch fs ->atomic_open() if exists. otherwise calls -+ vfs_create() and finish_open(). -+ - the demerit is that the several checks after branch fs -+ ->atomic_open() are lost. in the ordinary case, the checks are -+ done by VFS:do_last(), lookup_open() and atomic_open(). some can -+ be implemented in aufs, but not all I am afraid. -diff -Nurp linux-5.10-rc6/Documentation/filesystems/aufs/design/03lookup.txt linux-5.10-rc6.aufs/Documentation/filesystems/aufs/design/03lookup.txt ---- linux-5.10-rc6/Documentation/filesystems/aufs/design/03lookup.txt 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/Documentation/filesystems/aufs/design/03lookup.txt 2020-12-02 21:19:51.877036563 +0200 -@@ -0,0 +1,100 @@ -+ -+# Copyright (C) 2005-2020 Junjiro R. Okajima -+ -+Lookup in a Branch -+---------------------------------------------------------------------- -+Since aufs has a character of sub-VFS (see Introduction), it operates -+lookup for branches as VFS does. It may be a heavy work. 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 -Nurp linux-5.10-rc6/Documentation/filesystems/aufs/design/04branch.txt linux-5.10-rc6.aufs/Documentation/filesystems/aufs/design/04branch.txt ---- linux-5.10-rc6/Documentation/filesystems/aufs/design/04branch.txt 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/Documentation/filesystems/aufs/design/04branch.txt 2020-12-02 21:19:51.877036563 +0200 -@@ -0,0 +1,61 @@ -+ -+# Copyright (C) 2005-2020 Junjiro R. Okajima -+ -+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 -Nurp linux-5.10-rc6/Documentation/filesystems/aufs/design/05wbr_policy.txt linux-5.10-rc6.aufs/Documentation/filesystems/aufs/design/05wbr_policy.txt ---- linux-5.10-rc6/Documentation/filesystems/aufs/design/05wbr_policy.txt 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/Documentation/filesystems/aufs/design/05wbr_policy.txt 2020-12-02 21:19:51.877036563 +0200 -@@ -0,0 +1,51 @@ -+ -+# Copyright (C) 2005-2020 Junjiro R. Okajima -+ -+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 -Nurp linux-5.10-rc6/Documentation/filesystems/aufs/design/06dirren.dot linux-5.10-rc6.aufs/Documentation/filesystems/aufs/design/06dirren.dot ---- linux-5.10-rc6/Documentation/filesystems/aufs/design/06dirren.dot 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/Documentation/filesystems/aufs/design/06dirren.dot 2020-12-02 21:19:51.877036563 +0200 -@@ -0,0 +1,31 @@ -+ -+// to view this graph, run dot(1) command in GRAPHVIZ. -+ -+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 -Nurp linux-5.10-rc6/Documentation/filesystems/aufs/design/06dirren.txt linux-5.10-rc6.aufs/Documentation/filesystems/aufs/design/06dirren.txt ---- linux-5.10-rc6/Documentation/filesystems/aufs/design/06dirren.txt 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/Documentation/filesystems/aufs/design/06dirren.txt 2020-12-02 21:19:51.877036563 +0200 -@@ -0,0 +1,89 @@ -+ -+# Copyright (C) 2017-2020 Junjiro R. Okajima -+ -+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 refered 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 -Nurp linux-5.10-rc6/Documentation/filesystems/aufs/design/06fhsm.txt linux-5.10-rc6.aufs/Documentation/filesystems/aufs/design/06fhsm.txt ---- linux-5.10-rc6/Documentation/filesystems/aufs/design/06fhsm.txt 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/Documentation/filesystems/aufs/design/06fhsm.txt 2020-12-02 21:19:51.877036563 +0200 -@@ -0,0 +1,105 @@ -+ -+# Copyright (C) 2011-2020 Junjiro R. Okajima -+ -+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 -Nurp linux-5.10-rc6/Documentation/filesystems/aufs/design/06mmap.txt linux-5.10-rc6.aufs/Documentation/filesystems/aufs/design/06mmap.txt ---- linux-5.10-rc6/Documentation/filesystems/aufs/design/06mmap.txt 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/Documentation/filesystems/aufs/design/06mmap.txt 2020-12-02 21:19:51.877036563 +0200 -@@ -0,0 +1,59 @@ -+ -+# Copyright (C) 2005-2020 Junjiro R. Okajima -+ -+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 -Nurp linux-5.10-rc6/Documentation/filesystems/aufs/design/06xattr.txt linux-5.10-rc6.aufs/Documentation/filesystems/aufs/design/06xattr.txt ---- linux-5.10-rc6/Documentation/filesystems/aufs/design/06xattr.txt 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/Documentation/filesystems/aufs/design/06xattr.txt 2020-12-02 21:19:51.877036563 +0200 -@@ -0,0 +1,81 @@ -+ -+# Copyright (C) 2014-2020 Junjiro R. Okajima -+ -+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 -Nurp linux-5.10-rc6/Documentation/filesystems/aufs/design/07export.txt linux-5.10-rc6.aufs/Documentation/filesystems/aufs/design/07export.txt ---- linux-5.10-rc6/Documentation/filesystems/aufs/design/07export.txt 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/Documentation/filesystems/aufs/design/07export.txt 2020-12-02 21:19:51.877036563 +0200 -@@ -0,0 +1,45 @@ -+ -+# Copyright (C) 2005-2020 Junjiro R. Okajima -+ -+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 -Nurp linux-5.10-rc6/Documentation/filesystems/aufs/design/08shwh.txt linux-5.10-rc6.aufs/Documentation/filesystems/aufs/design/08shwh.txt ---- linux-5.10-rc6/Documentation/filesystems/aufs/design/08shwh.txt 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/Documentation/filesystems/aufs/design/08shwh.txt 2020-12-02 21:19:51.877036563 +0200 -@@ -0,0 +1,39 @@ -+ -+# Copyright (C) 2005-2020 Junjiro R. Okajima -+ -+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 -Nurp linux-5.10-rc6/Documentation/filesystems/aufs/design/10dynop.txt linux-5.10-rc6.aufs/Documentation/filesystems/aufs/design/10dynop.txt ---- linux-5.10-rc6/Documentation/filesystems/aufs/design/10dynop.txt 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/Documentation/filesystems/aufs/design/10dynop.txt 2020-12-02 21:19:51.877036563 +0200 -@@ -0,0 +1,34 @@ -+ -+# Copyright (C) 2010-2020 Junjiro R. Okajima -+ -+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 -Nurp linux-5.10-rc6/Documentation/filesystems/aufs/README linux-5.10-rc6.aufs/Documentation/filesystems/aufs/README ---- linux-5.10-rc6/Documentation/filesystems/aufs/README 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/Documentation/filesystems/aufs/README 2020-12-02 21:19:51.876036518 +0200 -@@ -0,0 +1,401 @@ -+ -+Aufs5 -- advanced multi layered unification filesystem version 5.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. -+ -+Aufs5 supports linux-v5.0 and later, If you want older kernel version -+support, -+- 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: 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 aufs5. -+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 aufs5, aufs5-linux.git, -+aufs5-standalone.git, and aufs-util.git. Note that there is no "5" in -+"aufs-util.git." -+While the aufs-util is always necessary, you need either of aufs5-linux -+or aufs5-standalone. -+ -+The aufs5-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 aufs5 as an external kernel module. -+Several extra patches are not included in this tree. Only -+aufs5-standalone tree contains them. They are described in the later -+section "Configuration and Compilation." -+ -+On the other hand, the aufs5-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 "aufs5.x" where "x" -+represents the linux kernel version, "linux-5.x". For instance, -+"aufs5.0" is for linux-5.0. For latest "linux-5.x-rcN", use -+"aufs5.x-rcN" branch. -+ -+o aufs5-linux tree -+$ git clone --reference /your/linux/git/tree \ -+ git://github.com/sfjro/aufs5-linux.git aufs5-linux.git -+- if you don't have linux GIT tree, then remove "--reference ..." -+$ cd aufs5-linux.git -+$ git checkout origin/aufs5.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 aufs5 git://github.com/sfjro/aufs5-linux.git -+$ git fetch aufs5 -+$ git checkout -b my5.0 v5.0 -+$ (add your local change...) -+$ git pull aufs5 aufs5.0 -+- now you have v5.0 + your_changes + aufs5.0 in you my5.0 branch. -+- you may need to solve some conflicts between your_changes and -+ aufs5.0. in this case, git-rerere is recommended so that you can -+ solve the similar conflicts automatically when you upgrade to 5.1 or -+ later in the future. -+ -+o aufs5-standalone tree -+$ git clone git://github.com/sfjro/aufs5-standalone.git aufs5-standalone.git -+$ cd aufs5-standalone.git -+$ git checkout origin/aufs5.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/aufs5.0 -+ -+Note: The 5.x-rcN branch is to be used with `rc' kernel versions ONLY. -+The minor version number, 'x' in '5.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-5.10" and the "aufs5.10" branch -+does not exist in aufs-util repository, then "aufs5.9", "aufs5.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 aufs5-linux tree, -+- enable CONFIG_AUFS_FS. -+- set other aufs configurations if necessary. -+ -+For aufs5-standalone tree, -+There are several ways to build. -+ -+1. -+- apply ./aufs5-kbuild.patch to your kernel source files. -+- apply ./aufs5-base.patch too. -+- apply ./aufs5-mmap.patch too. -+- apply ./aufs5-standalone.patch too, if you have a plan to set -+ CONFIG_AUFS_FS=m. otherwise you don't need ./aufs5-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 ./aufs5-base.patch to your kernel source files. -+- apply ./aufs5-mmap.patch too. -+- apply ./aufs5-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 aufs5-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 aufs5-standalone.git. They are all -+optional. When you meet some problems, they will help you. -+- aufs5-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". -+- proc_mounts.patch -+ When there are many mountpoints and many mount(2)/umount(2) are -+ running, then /proc/mounts may not show the all mountpoints. This -+ patch makes /proc/mounts always show the full mountpoints list. -+ If you don't want to apply this patch and meet such problem, then you -+ need to increase the value of 'ProcMounts_Times' make-variable in -+ aufs-util.git as a second best solution. -+- 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 -+ 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 apply this debug patch to expand several constant values. -+ If you don't know what LOCKDEP is, then you don't have apply this -+ patch. -+ -+ -+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 and 2015/7). -+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). -+ -+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 -Nurp linux-5.10-rc6/drivers/block/loop.c linux-5.10-rc6.aufs/drivers/block/loop.c ---- linux-5.10-rc6/drivers/block/loop.c 2020-12-02 21:18:30.377394775 +0200 -+++ linux-5.10-rc6.aufs/drivers/block/loop.c 2020-12-02 21:19:51.879036653 +0200 -@@ -765,6 +765,24 @@ out_err: - return error; - } - -+/* -+ * for AUFS -+ * no get/put for file. -+ */ -+struct file *loop_backing_file(struct super_block *sb) -+{ -+ struct file *ret; -+ struct loop_device *l; -+ -+ ret = NULL; -+ if (MAJOR(sb->s_dev) == LOOP_MAJOR) { -+ l = sb->s_bdev->bd_disk->private_data; -+ ret = l->lo_backing_file; -+ } -+ return ret; -+} -+EXPORT_SYMBOL_GPL(loop_backing_file); -+ - /* loop sysfs attributes */ - - static ssize_t loop_attr_show(struct device *dev, char *page, -diff -Nurp linux-5.10-rc6/fs/aufs/aufs.h linux-5.10-rc6.aufs/fs/aufs/aufs.h ---- linux-5.10-rc6/fs/aufs/aufs.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/aufs.h 2020-12-02 21:19:51.879036653 +0200 -@@ -0,0 +1,49 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.10-rc6/fs/aufs/branch.c linux-5.10-rc6.aufs/fs/aufs/branch.c ---- linux-5.10-rc6/fs/aufs/branch.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/branch.c 2020-12-02 21:19:51.880036698 +0200 -@@ -0,0 +1,1414 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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(!inode->i_nlink)) { -+ 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 -Nurp linux-5.10-rc6/fs/aufs/branch.h linux-5.10-rc6.aufs/fs/aufs/branch.h ---- linux-5.10-rc6/fs/aufs/branch.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/branch.h 2020-12-02 21:19:51.880036698 +0200 -@@ -0,0 +1,353 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 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(vfs_readf_t func, struct file *file, void *buf, size_t size, -+ loff_t *pos); -+ssize_t xino_fwrite(vfs_writef_t func, struct file *file, void *buf, -+ size_t size, loff_t *pos); -+ -+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 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 -Nurp linux-5.10-rc6/fs/aufs/cpup.c linux-5.10-rc6.aufs/fs/aufs/cpup.c ---- linux-5.10-rc6/fs/aufs/cpup.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/cpup.c 2020-12-02 21:19:51.880036698 +0200 -@@ -0,0 +1,1445 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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. -+ */ -+ set_nlink(inode, h_inode->i_nlink); -+ -+ /* -+ * 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); -+ if (inode->i_nlink > 0) -+ 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 dentry *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; -+ -+ h_path.dentry = au_h_dptr(dst, bindex); -+ h_idst = d_inode(h_path.dentry); -+ br = au_sbr(dst->d_sb, bindex); -+ h_path.mnt = au_br_mnt(br); -+ h_isrc = d_inode(h_src); -+ ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID -+ | ATTR_ATIME | ATTR_MTIME -+ | ATTR_ATIME_SET | ATTR_MTIME_SET; -+ 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.dentry, 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_nfs(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, symlen; -+ mm_segment_t old_fs; -+ union { -+ char *k; -+ char __user *u; -+ } sym; -+ -+ err = -ENOMEM; -+ sym.k = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!sym.k)) -+ goto out; -+ -+ /* unnecessary to support mmap_sem since symlink is not mmap-able */ -+ old_fs = get_fs(); -+ set_fs(KERNEL_DS); -+ symlen = vfs_readlink(h_src, sym.u, PATH_MAX); -+ err = symlen; -+ set_fs(old_fs); -+ -+ if (symlen > 0) { -+ sym.k[symlen] = 0; -+ err = vfsub_symlink(h_dir, h_path, sym.k); -+ } -+ free_page((unsigned long)sym.k); -+ -+out: -+ 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 inode *h_dir, struct path *h_path, umode_t mode) -+{ -+ int err; -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ -+ h_dentry = h_path->dentry; -+ h_inode = d_inode(h_dentry); -+ /* forget_all_cached_acls(h_inode)); */ -+ err = vfsub_removexattr(h_dentry, XATTR_NAME_POSIX_ACL_ACCESS); -+ AuTraceErr(err); -+ if (err == -EOPNOTSUPP) -+ err = 0; -+ if (!err) -+ err = vfsub_acl_chmod(h_inode, 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; -+ -+ err = vfsub_removexattr(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_dir, &h_path, mode); -+ -+ mnt_flags = au_mntflags(sb); -+ if (!au_opt_test(mnt_flags, UDBA_NONE) -+ && !isdir -+ && au_opt_test(mnt_flags, XINO) -+ && (h_inode->i_nlink == 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 inode *h_dir; -+ aufs_bindex_t bdst; -+ -+ dentry = cpg->dentry; -+ bdst = cpg->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_parent = au_h_dptr(parent, bdst); -+ dput(parent); -+ h_path->dentry = vfsub_lkup_one(&dentry->d_name, h_parent); -+ 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; -+ /* 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 (dst_inode->i_nlink) { -+ 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); */ -+ -+ err = cpup_iattr(cpg->dentry, cpg->bdst, h_src, &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 -+ && (src_inode->i_nlink > 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; -+ -+ 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); -+ if (!au_test_h_perm_sio(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; -+ -+ 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 (!h_dir->i_nlink) { -+ 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; -+ } -+ -+ if (!au_test_h_perm_sio(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 -Nurp linux-5.10-rc6/fs/aufs/cpup.h linux-5.10-rc6.aufs/fs/aufs/cpup.h ---- linux-5.10-rc6/fs/aufs/cpup.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/cpup.h 2020-12-02 21:19:51.880036698 +0200 -@@ -0,0 +1,87 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.10-rc6/fs/aufs/dbgaufs.c linux-5.10-rc6.aufs/fs/aufs/dbgaufs.c ---- linux-5.10-rc6/fs/aufs/dbgaufs.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/dbgaufs.c 2020-12-02 21:19:51.880036698 +0200 -@@ -0,0 +1,513 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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; -+ strcpy(p->a, 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 -Nurp linux-5.10-rc6/fs/aufs/dbgaufs.h linux-5.10-rc6.aufs/fs/aufs/dbgaufs.h ---- linux-5.10-rc6/fs/aufs/dbgaufs.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/dbgaufs.h 2020-12-02 21:19:51.880036698 +0200 -@@ -0,0 +1,40 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.10-rc6/fs/aufs/dcsub.c linux-5.10-rc6.aufs/fs/aufs/dcsub.c ---- linux-5.10-rc6/fs/aufs/dcsub.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/dcsub.c 2020-12-02 21:19:51.880036698 +0200 -@@ -0,0 +1,212 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.10-rc6/fs/aufs/dcsub.h linux-5.10-rc6.aufs/fs/aufs/dcsub.h ---- linux-5.10-rc6/fs/aufs/dcsub.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/dcsub.h 2020-12-02 21:19:51.880036698 +0200 -@@ -0,0 +1,124 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * sub-routines for dentry cache -+ */ -+ -+#ifndef __AUFS_DCSUB_H__ -+#define __AUFS_DCSUB_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+ -+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) -+ || !inode->i_nlink)) -+ 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) -+ || !inode->i_nlink)) -+ err = -ENOENT; -+ } -+ return err; -+} -+ -+static inline int au_alive_dir(struct dentry *d) -+{ -+ int err; -+ -+ err = au_d_alive(d); -+ if (unlikely(err || IS_DEADDIR(d_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 -Nurp linux-5.10-rc6/fs/aufs/debug.c linux-5.10-rc6.aufs/fs/aufs/debug.c ---- linux-5.10-rc6/fs/aufs/debug.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/debug.c 2020-12-02 21:19:51.880036698 +0200 -@@ -0,0 +1,428 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 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; -+ -+ 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; -+ } -+ -+ dpri("i%d: %p, i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu," -+ " hn %d, ct %lld, np %lu, st 0x%lx, f 0x%x, v %llu, g %x%s%.*s\n", -+ bindex, inode, -+ inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??", -+ atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode, -+ i_size_read(inode), (unsigned long long)inode->i_blocks, -+ hn, (long long)timespec64_to_ns(&inode->i_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(); -+ 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 -Nurp linux-5.10-rc6/fs/aufs/debug.h linux-5.10-rc6.aufs/fs/aufs/debug.h ---- linux-5.10-rc6/fs/aufs/debug.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/debug.h 2020-12-02 21:19:51.880036698 +0200 -@@ -0,0 +1,213 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -+#define AuDebugOn(a) do {} while (0) -+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; -+#ifdef CONFIG_AUFS_DEBUG -+extern struct mutex au_dbg_mtx; -+extern char *au_plevel; -+struct au_nhash; -+void au_dpri_whlist(struct au_nhash *whlist); -+struct au_vdir; -+void au_dpri_vdir(struct au_vdir *vdir); -+struct inode; -+void au_dpri_inode(struct inode *inode); -+void au_dpri_dalias(struct inode *inode); -+void au_dpri_dentry(struct dentry *dentry); -+struct file; -+void au_dpri_file(struct file *filp); -+struct super_block; -+void au_dpri_sb(struct super_block *sb); -+ -+#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) -+ -+#define AuDbgWhlist(w) do {} while (0) -+#define AuDbgVdir(v) do {} while (0) -+#define AuDbgInode(i) do {} while (0) -+#define AuDbgDAlias(i) do {} while (0) -+#define AuDbgDentry(d) do {} while (0) -+#define AuDbgFile(f) do {} while (0) -+#define AuDbgSb(sb) do {} while (0) -+#define AuDbgSym(addr) do {} while (0) -+#endif /* CONFIG_AUFS_DEBUG */ -+ -+/* ---------------------------------------------------------------------- */ -+ -+#ifdef CONFIG_AUFS_MAGIC_SYSRQ -+int __init au_sysrq_init(void); -+void au_sysrq_fin(void); -+ -+#ifdef CONFIG_HW_CONSOLE -+#define au_dbg_blocked() do { \ -+ WARN_ON(1); \ -+ handle_sysrq('w'); \ -+} while (0) -+#else -+AuStubVoid(au_dbg_blocked, void) -+#endif -+ -+#else -+AuStubInt0(__init au_sysrq_init, void) -+AuStubVoid(au_sysrq_fin, void) -+AuStubVoid(au_dbg_blocked, void) -+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */ -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_DEBUG_H__ */ -diff -Nurp linux-5.10-rc6/fs/aufs/dentry.c linux-5.10-rc6.aufs/fs/aufs/dentry.c ---- linux-5.10-rc6/fs/aufs/dentry.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/dentry.c 2020-12-02 21:19:51.880036698 +0200 -@@ -0,0 +1,1141 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * lookup and dentry operations -+ */ -+ -+#include -+#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; -+ 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); -+ wh_able = !!au_br_whable(br->br_perm); -+ if (wh_able) -+ wh_found = au_wh_test(h_parent, &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_parent); -+ else -+ h_dentry = au_sio_lkup_one(args->name, h_parent); -+ 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 */ -+ -+ inode_lock_shared_nested(h_inode, AuLsc_I_CHILD); -+ opq = au_diropq_test(h_dentry); -+ 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 qstr *name, struct dentry *parent) -+{ -+ struct dentry *dentry; -+ int wkq_err; -+ -+ if (!au_test_h_perm_sio(d_inode(parent), MAY_EXEC)) -+ dentry = vfsub_lkup_one(name, parent); -+ else { -+ struct vfsub_lkup_one_args args = { -+ .errp = &dentry, -+ .name = name, -+ .parent = parent -+ }; -+ -+ 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_parent, *h_dentry; -+ struct au_branch *br; -+ -+ parent = dget_parent(dentry); -+ h_parent = au_h_dptr(parent, bindex); -+ br = au_sbr(dentry->d_sb, bindex); -+ if (wh) -+ h_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name); -+ else -+ h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent); -+ 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; -+ -+ 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_d = vfsub_lkup_one(&h_dentry->d_name, h_parent); -+ 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 (inode->i_nlink && !d_unhashed(dentry)) -+ drop_nlink(inode); -+ } else { -+ 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; -+ 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 = (inode->i_nlink > 0); -+ ibs = au_ibtop(inode); -+ ibe = au_ibbot(inode); -+ } -+ -+ btop = au_dbtop(dentry); -+ 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) -+ 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 -+ && !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) { -+ h_mode = (h_inode->i_mode & S_IFMT); -+ h_plus = (h_inode->i_nlink > 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) || !inode->i_nlink)) { -+ 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 -Nurp linux-5.10-rc6/fs/aufs/dentry.h linux-5.10-rc6.aufs/fs/aufs/dentry.h ---- linux-5.10-rc6/fs/aufs/dentry.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/dentry.h 2020-12-02 21:19:51.880036698 +0200 -@@ -0,0 +1,255 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 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 qstr *name, struct dentry *parent); -+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 -Nurp linux-5.10-rc6/fs/aufs/dinfo.c linux-5.10-rc6.aufs/fs/aufs/dinfo.c ---- linux-5.10-rc6/fs/aufs/dinfo.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/dinfo.c 2020-12-02 21:19:51.880036698 +0200 -@@ -0,0 +1,541 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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; -+ 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 -Nurp linux-5.10-rc6/fs/aufs/dir.c linux-5.10-rc6.aufs/fs/aufs/dir.c ---- linux-5.10-rc6/fs/aufs/dir.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/dir.c 2020-12-02 21:19:51.881036743 +0200 -@@ -0,0 +1,750 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * directory operations -+ */ -+ -+#include -+#include -+#include "aufs.h" -+ -+void au_add_nlink(struct inode *dir, struct inode *h_dir) -+{ -+ unsigned int nlink; -+ -+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode)); -+ -+ nlink = dir->i_nlink; -+ nlink += h_dir->i_nlink - 2; -+ if (h_dir->i_nlink < 2) -+ nlink += 2; -+ smp_mb(); /* for i_nlink */ -+ /* 0 can happen in revaliding */ -+ set_nlink(dir, nlink); -+} -+ -+void au_sub_nlink(struct inode *dir, struct inode *h_dir) -+{ -+ unsigned int nlink; -+ -+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode)); -+ -+ nlink = dir->i_nlink; -+ nlink -= h_dir->i_nlink - 2; -+ if (h_dir->i_nlink < 2) -+ nlink -= 2; -+ smp_mb(); /* for i_nlink */ -+ /* nlink == 0 means the branch-fs is broken */ -+ 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 (h_dir->i_nlink -+ && 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 int 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) -+ && !file_inode(h_file)->i_nlink) -+ 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; -+ -+ 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_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 -Nurp linux-5.10-rc6/fs/aufs/dir.h linux-5.10-rc6.aufs/fs/aufs/dir.h ---- linux-5.10-rc6/fs/aufs/dir.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/dir.h 2020-12-02 21:19:51.881036743 +0200 -@@ -0,0 +1,121 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.10-rc6/fs/aufs/dirren.c linux-5.10-rc6.aufs/fs/aufs/dirren.c ---- linux-5.10-rc6/fs/aufs/dirren.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/dirren.c 2020-12-02 21:19:51.881036743 +0200 -@@ -0,0 +1,1303 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2017-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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.dentry = vfsub_lkup_one(&hinoname, path->dentry); -+ 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; -+ } -+ hinopath.mnt = path->mnt; -+ 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.dentry, -+ 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); -+ strcpy(w->whname, 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->dentry, -+ 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 -Nurp linux-5.10-rc6/fs/aufs/dirren.h linux-5.10-rc6.aufs/fs/aufs/dirren.h ---- linux-5.10-rc6/fs/aufs/dirren.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/dirren.h 2020-12-02 21:19:51.881036743 +0200 -@@ -0,0 +1,127 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2017-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.10-rc6/fs/aufs/dynop.c linux-5.10-rc6.aufs/fs/aufs/dynop.c ---- linux-5.10-rc6/fs/aufs/dynop.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/dynop.c 2020-12-02 21:19:51.881036743 +0200 -@@ -0,0 +1,354 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2010-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * dynamically customizable operations for regular files -+ */ -+ -+#include "aufs.h" -+ -+#define DyPrSym(key) AuDbgSym(key->dk_op.dy_hop) -+ -+/* -+ * How large will these lists be? -+ * Usually just a few elements, 20-30 at most for each, I guess. -+ */ -+static struct 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 *)) -+ -+#ifdef CONFIG_AUFS_DEBUG -+#define DyDbgDeclare(cnt) unsigned int cnt = 0 -+#define DyDbgInc(cnt) do { cnt++; } while (0) -+#else -+#define DyDbgDeclare(cnt) do {} while (0) -+#define DyDbgInc(cnt) do {} while (0) -+#endif -+ -+#define DySet(func, dst, src, h_op, h_sb) do { \ -+ DyDbgInc(cnt); \ -+ if (h_op->func) { \ -+ if (src.func) \ -+ dst.func = src.func; \ -+ else \ -+ AuDbg("%s %s\n", au_sbtype(h_sb), #func); \ -+ } \ -+} while (0) -+ -+#define DySetForce(func, dst, src) do { \ -+ AuDebugOn(!src.func); \ -+ DyDbgInc(cnt); \ -+ dst.func = src.func; \ -+} while (0) -+ -+#define DySetAop(func) \ -+ DySet(func, dyaop->da_op, aufs_aop, h_aop, h_sb) -+#define DySetAopForce(func) \ -+ DySetForce(func, dyaop->da_op, aufs_aop) -+ -+static void dy_aop(struct au_dykey *key, const void *h_op, -+ struct super_block *h_sb __maybe_unused) -+{ -+ struct au_dyaop *dyaop = (void *)key; -+ const struct address_space_operations *h_aop = h_op; -+ DyDbgDeclare(cnt); -+ -+ AuDbg("%s\n", au_sbtype(h_sb)); -+ -+ DySetAop(writepage); -+ DySetAopForce(readpage); /* force */ -+ DySetAop(writepages); -+ DySetAop(set_page_dirty); -+ DySetAop(readpages); -+ DySetAop(write_begin); -+ DySetAop(write_end); -+ DySetAop(bmap); -+ DySetAop(invalidatepage); -+ DySetAop(releasepage); -+ DySetAop(freepage); -+ /* this one will be changed according to an aufs mount option */ -+ DySetAop(direct_IO); -+ DySetAop(migratepage); -+ DySetAop(isolate_page); -+ DySetAop(putback_page); -+ DySetAop(launder_page); -+ DySetAop(is_partially_uptodate); -+ DySetAop(is_dirty_writeback); -+ DySetAop(error_remove_page); -+ DySetAop(swap_activate); -+ DySetAop(swap_deactivate); -+ -+ 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 -Nurp linux-5.10-rc6/fs/aufs/dynop.h linux-5.10-rc6.aufs/fs/aufs/dynop.h ---- linux-5.10-rc6/fs/aufs/dynop.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/dynop.h 2020-12-02 21:19:51.881036743 +0200 -@@ -0,0 +1,64 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2010-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.10-rc6/fs/aufs/export.c linux-5.10-rc6.aufs/fs/aufs/export.c ---- linux-5.10-rc6/fs/aufs/export.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/export.c 2020-12-02 21:19:51.881036743 +0200 -@@ -0,0 +1,825 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * export via nfs -+ */ -+ -+#include -+#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_xwrite, sbinfo->si_xigen, &igen, -+ sizeof(igen), &pos); -+ if (sz == sizeof(igen)) -+ return; /* success */ -+ -+ if (unlikely(sz >= 0)) -+ AuIOErr("xigen error (%zd)\n", sz); -+} -+ -+int au_xigen_new(struct inode *inode) -+{ -+ int err; -+ loff_t pos; -+ ssize_t sz; -+ struct super_block *sb; -+ struct au_sbinfo *sbinfo; -+ struct file *file; -+ -+ err = 0; -+ /* todo: dirty, at mount time */ -+ if (inode->i_ino == AUFS_ROOT_INO) -+ goto out; -+ sb = inode->i_sb; -+ SiMustAnyLock(sb); -+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO))) -+ goto out; -+ -+ err = -EFBIG; -+ pos = inode->i_ino; -+ if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) { -+ AuIOErr1("too large i%lld\n", pos); -+ goto out; -+ } -+ pos *= sizeof(inode->i_generation); -+ -+ err = 0; -+ sbinfo = au_sbi(sb); -+ file = sbinfo->si_xigen; -+ BUG_ON(!file); -+ -+ if (vfsub_f_size_read(file) -+ < pos + sizeof(inode->i_generation)) { -+ inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next); -+ sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation, -+ sizeof(inode->i_generation), &pos); -+ } else -+ sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation, -+ sizeof(inode->i_generation), &pos); -+ if (sz == sizeof(inode->i_generation)) -+ goto out; /* success */ -+ -+ err = sz; -+ if (unlikely(sz >= 0)) { -+ err = -EIO; -+ AuIOErr("xigen error (%zd)\n", sz); -+ } -+ -+out: -+ return err; -+} -+ -+int au_xigen_set(struct super_block *sb, struct 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 int -+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 0; -+ -+ memcpy(a->name, name, namelen); -+ a->namelen = namelen; -+ a->found = 1; -+ return 1; -+} -+ -+static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino, -+ struct au_nfsd_si_lock *nsi_lock) -+{ -+ struct dentry *dentry, *parent; -+ struct file *file; -+ struct inode *dir; -+ struct find_name_by_ino arg = { -+ .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, parent, 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 { -+ struct writeback_control wbc = { -+ .sync_mode = WB_SYNC_ALL, -+ .nr_to_write = 0 /* metadata only */ -+ }; -+ -+ err = sync_inode(h_inode, &wbc); -+ } -+ -+ au_cpup_attr_timesizes(inode); -+ ii_write_unlock(inode); -+ si_read_unlock(sb); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static struct export_operations aufs_export_op = { -+ .fh_to_dentry = aufs_fh_to_dentry, -+ /* .fh_to_parent = aufs_fh_to_parent, */ -+ .encode_fh = aufs_encode_fh, -+ .commit_metadata = aufs_commit_metadata -+}; -+ -+void au_export_init(struct super_block *sb) -+{ -+ struct au_sbinfo *sbinfo; -+ __u32 u; -+ -+ 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 -Nurp linux-5.10-rc6/fs/aufs/fhsm.c linux-5.10-rc6.aufs/fs/aufs/fhsm.c ---- linux-5.10-rc6/fs/aufs/fhsm.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/fhsm.c 2020-12-02 21:19:51.881036743 +0200 -@@ -0,0 +1,413 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2011-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.10-rc6/fs/aufs/file.c linux-5.10-rc6.aufs/fs/aufs/file.c ---- linux-5.10-rc6/fs/aufs/file.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/file.c 2020-12-02 21:19:51.881036743 +0200 -@@ -0,0 +1,850 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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); -+ 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); -+ di_downgrade_lock(dentry, AuLock_IR); -+ if (!err) { -+ if (!aopen) -+ err = args->open(file, vfsub_file_flags(file), NULL); -+ else { -+ 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); -+ /* 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 -+ && (inode->i_nlink > 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_readpage(struct file *file __maybe_unused, struct page *page) -+{ -+ unlock_page(page); -+ return 0; -+} -+ -+/* it will never be called, but necessary to support O_DIRECT */ -+static ssize_t aufs_direct_IO(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, unsigned flags, -+ struct page **pagep, void **fsdata) -+{ AuUnsupport(); return 0; } -+static int aufs_write_end(struct file *file, struct address_space *mapping, -+ loff_t pos, unsigned len, unsigned copied, -+ struct page *page, void *fsdata) -+{ AuUnsupport(); return 0; } -+static int aufs_writepage(struct page *page, struct writeback_control *wbc) -+{ AuUnsupport(); return 0; } -+ -+static int aufs_set_page_dirty(struct page *page) -+{ AuUnsupport(); return 0; } -+static void aufs_invalidatepage(struct page *page, unsigned int offset, -+ unsigned int length) -+{ AuUnsupport(); } -+static int aufs_releasepage(struct page *page, gfp_t gfp) -+{ AuUnsupport(); return 0; } -+#if 0 /* called by memory compaction regardless file */ -+static int aufs_migratepage(struct address_space *mapping, struct page *newpage, -+ struct page *page, enum migrate_mode mode) -+{ AuUnsupport(); return 0; } -+#endif -+static bool aufs_isolate_page(struct page *page, isolate_mode_t mode) -+{ AuUnsupport(); return true; } -+static void aufs_putback_page(struct page *page) -+{ AuUnsupport(); } -+static int aufs_launder_page(struct page *page) -+{ AuUnsupport(); return 0; } -+static int aufs_is_partially_uptodate(struct page *page, -+ unsigned long from, -+ unsigned long count) -+{ AuUnsupport(); return 0; } -+static void aufs_is_dirty_writeback(struct page *page, 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(); } -+#endif /* CONFIG_AUFS_DEBUG */ -+ -+const struct address_space_operations aufs_aop = { -+ .readpage = aufs_readpage, -+ .direct_IO = aufs_direct_IO, -+#ifdef CONFIG_AUFS_DEBUG -+ .writepage = aufs_writepage, -+ /* no writepages, because of writepage */ -+ .set_page_dirty = aufs_set_page_dirty, -+ /* no readpages, because of readpage */ -+ .write_begin = aufs_write_begin, -+ .write_end = aufs_write_end, -+ /* no bmap, no block device */ -+ .invalidatepage = aufs_invalidatepage, -+ .releasepage = aufs_releasepage, -+ /* is fallback_migrate_page ok? */ -+ /* .migratepage = aufs_migratepage, */ -+ .isolate_page = aufs_isolate_page, -+ .putback_page = aufs_putback_page, -+ .launder_page = aufs_launder_page, -+ .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 -+#endif /* CONFIG_AUFS_DEBUG */ -+}; -diff -Nurp linux-5.10-rc6/fs/aufs/file.h linux-5.10-rc6.aufs/fs/aufs/file.h ---- linux-5.10-rc6/fs/aufs/file.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/file.h 2020-12-02 21:19:51.881036743 +0200 -@@ -0,0 +1,329 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -+#define AuDbgVmRegion(file, vma) do {} while (0) -+ -+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 -Nurp linux-5.10-rc6/fs/aufs/finfo.c linux-5.10-rc6.aufs/fs/aufs/finfo.c ---- linux-5.10-rc6/fs/aufs/finfo.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/finfo.c 2020-12-02 21:19:51.881036743 +0200 -@@ -0,0 +1,136 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.10-rc6/fs/aufs/f_op.c linux-5.10-rc6.aufs/fs/aufs/f_op.c ---- linux-5.10-rc6/fs/aufs/f_op.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/f_op.c 2020-12-02 21:19:51.881036743 +0200 -@@ -0,0 +1,806 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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) -+ && !(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); -+ /* 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); -+ -+out_fi: -+ fi_write_unlock(file); -+out: -+ return h_file; -+} -+ -+static void au_write_post(struct inode *inode, struct file *h_file, -+ struct au_write_pre *wpre, ssize_t written) -+{ -+ struct inode *h_inode; -+ -+ au_cpup_attr_timesizes(inode); -+ AuDebugOn(au_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); -+} -+ -+static ssize_t aufs_read(struct file *file, char __user *buf, size_t count, -+ loff_t *ppos) -+{ -+ ssize_t err; -+ struct inode *inode; -+ struct file *h_file; -+ 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; -+ -+ /* filedata may be obsoleted by concurrent copyup, but no problem */ -+ err = vfsub_read_u(h_file, buf, count, ppos); -+ /* todo: necessary? */ -+ /* file->f_ra = h_file->f_ra; */ -+ au_read_post(inode, h_file); -+ -+out: -+ si_read_unlock(sb); -+ return err; -+} -+ -+/* -+ * todo: very ugly -+ * it locks both of i_mutex and si_rwsem for read in safe. -+ * if the plink maintenance mode continues forever (that is the problem), -+ * may loop forever. -+ */ -+static void au_mtx_and_read_lock(struct inode *inode) -+{ -+ int err; -+ struct super_block *sb = inode->i_sb; -+ -+ while (1) { -+ 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 aufs_write(struct file *file, const char __user *ubuf, -+ size_t count, loff_t *ppos) -+{ -+ ssize_t err; -+ struct au_write_pre wpre; -+ struct inode *inode; -+ struct file *h_file; -+ char __user *buf = (char __user *)ubuf; -+ -+ 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_write_u(h_file, buf, count, ppos); -+ au_write_post(inode, h_file, &wpre, err); -+ -+out: -+ si_read_unlock(inode->i_sb); -+ inode_unlock(inode); -+ return err; -+} -+ -+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); -+ 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; -+ -+ 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; -+} -+ -+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_to(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(); -+ 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; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* no one supports this operation, currently */ -+#if 0 /* reserved for future use */ -+static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset, -+ size_t len, loff_t *pos, int more) -+{ -+} -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+const struct file_operations aufs_file_fop = { -+ .owner = THIS_MODULE, -+ -+ .llseek = default_llseek, -+ -+ .read = aufs_read, -+ .write = aufs_write, -+ .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, -+ /* .sendpage = aufs_sendpage, */ -+ .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 -Nurp linux-5.10-rc6/fs/aufs/fstype.h linux-5.10-rc6.aufs/fs/aufs/fstype.h ---- linux-5.10-rc6/fs/aufs/fstype.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/fstype.h 2020-12-02 21:19:51.881036743 +0200 -@@ -0,0 +1,388 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -+} -+ -+/* ---------------------------------------------------------------------- */ -+/* -+ * 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); -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_FSTYPE_H__ */ -diff -Nurp linux-5.10-rc6/fs/aufs/hbl.h linux-5.10-rc6.aufs/fs/aufs/hbl.h ---- linux-5.10-rc6/fs/aufs/hbl.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/hbl.h 2020-12-02 21:19:51.881036743 +0200 -@@ -0,0 +1,52 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2017-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.10-rc6/fs/aufs/hfsnotify.c linux-5.10-rc6.aufs/fs/aufs/hfsnotify.c ---- linux-5.10-rc6/fs/aufs/hfsnotify.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/hfsnotify.c 2020-12-02 21:19:51.881036743 +0200 -@@ -0,0 +1,275 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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, -+ struct inode *inode, -+ u32 mask, const void *data, int data_type, -+ 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); -+ -+ 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 = inode; -+ h_inode = NULL; -+#ifdef AuDbgHnotify -+ au_debug_on(); -+ if (1 || h_child_qstr.len != sizeof(AUFS_XINO_FNAME) - 1 -+ || strncmp(h_child_qstr.name, AUFS_XINO_FNAME, h_child_qstr.len)) { -+ AuDbg("i%lu, mask 0x%x %s, hcname %.*s, hi%lu\n", -+ h_dir->i_ino, mask, au_hfsn_name(mask), -+ AuLNPair(&h_child_qstr), 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); -+ 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 -Nurp linux-5.10-rc6/fs/aufs/hfsplus.c linux-5.10-rc6.aufs/fs/aufs/hfsplus.c ---- linux-5.10-rc6/fs/aufs/hfsplus.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/hfsplus.c 2020-12-02 21:19:51.881036743 +0200 -@@ -0,0 +1,47 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2010-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.10-rc6/fs/aufs/hnotify.c linux-5.10-rc6.aufs/fs/aufs/hnotify.c ---- linux-5.10-rc6/fs/aufs/hnotify.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/hnotify.c 2020-12-02 21:19:51.882036788 +0200 -@@ -0,0 +1,702 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 (!a->h_inode->i_nlink -+ && !(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 (!dir->i_nlink -+ || (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 -Nurp linux-5.10-rc6/fs/aufs/iinfo.c linux-5.10-rc6.aufs/fs/aufs/iinfo.c ---- linux-5.10-rc6/fs/aufs/iinfo.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/iinfo.c 2020-12-02 21:19:51.882036788 +0200 -@@ -0,0 +1,273 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -+ && !h_i->i_nlink -+ && !(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); -+} -+ -+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 = !inode->i_nlink; -+ -+ 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 -Nurp linux-5.10-rc6/fs/aufs/inode.c linux-5.10-rc6.aufs/fs/aufs/inode.c ---- linux-5.10-rc6/fs/aufs/inode.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/inode.c 2020-12-02 21:19:51.882036788 +0200 -@@ -0,0 +1,516 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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_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) && h_inode->i_nlink > 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) && inode->i_nlink) { -+ /* -+ * 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 inode *h_inode, int mask) -+{ -+ if (uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) -+ return 0; -+ return inode_permission(h_inode, mask); -+} -+ -+int au_test_h_perm_sio(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_inode, mask); -+} -diff -Nurp linux-5.10-rc6/fs/aufs/inode.h linux-5.10-rc6.aufs/fs/aufs/inode.h ---- linux-5.10-rc6/fs/aufs/inode.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/inode.h 2020-12-02 21:19:51.882036788 +0200 -@@ -0,0 +1,685 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * inode operations -+ */ -+ -+#ifndef __AUFS_INODE_H__ -+#define __AUFS_INODE_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#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; -+ 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); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* 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 inode *h_inode, int mask); -+int au_test_h_perm_sio(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 inode *dir, struct dentry *dentry, umode_t mode, -+ dev_t dev); -+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname); -+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode, -+ bool want_excl); -+struct vfsub_aopen_args; -+int au_aopen_or_create(struct inode *dir, struct dentry *dentry, -+ struct vfsub_aopen_args *args); -+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode); -+int aufs_link(struct dentry *src_dentry, struct inode *dir, -+ struct dentry *dentry); -+int aufs_mkdir(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 inode *src_dir, struct dentry *src_dentry, -+ struct inode *dir, struct dentry *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 dentry *h_dst, struct dentry *h_src, int ignore_flags, -+ unsigned int verbose); -+ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size); -+void au_xattr_init(struct super_block *sb); -+#else -+AuStubInt0(au_cpup_xattr, struct dentry *h_dst, struct dentry *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_acl(struct inode *inode, int type); -+int aufs_set_acl(struct inode *inode, 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 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 -Nurp linux-5.10-rc6/fs/aufs/ioctl.c linux-5.10-rc6.aufs/fs/aufs/ioctl.c ---- linux-5.10-rc6/fs/aufs/ioctl.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/ioctl.c 2020-12-02 21:19:51.882036788 +0200 -@@ -0,0 +1,207 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.10-rc6/fs/aufs/i_op_add.c linux-5.10-rc6.aufs/fs/aufs/i_op_add.c ---- linux-5.10-rc6/fs/aufs/i_op_add.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/i_op_add.c 2020-12-02 21:19:51.882036788 +0200 -@@ -0,0 +1,923 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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(!h_inode->i_nlink)) -+ 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 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 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 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 inode *dir, struct dentry *dentry, umode_t mode) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ struct super_block *sb; -+ struct dentry *parent, *h_parent, *h_dentry; -+ struct inode *h_dir, *inode; -+ struct vfsmount *h_mnt; -+ struct au_wr_dir_args wr_dir_args = { -+ .force_btgt = -1, -+ .flags = AuWrDir_TMPFILE -+ }; -+ -+ /* copy-up may happen */ -+ inode_lock(dir); -+ -+ sb = dir->i_sb; -+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (unlikely(err)) -+ goto out; -+ -+ 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; -+ -+ h_mnt = au_sbr_mnt(sb, bindex); -+ err = vfsub_mnt_want_write(h_mnt); -+ if (unlikely(err)) -+ goto out_parent; -+ -+ h_parent = au_h_dptr(parent, bindex); -+ h_dentry = vfs_tmpfile(h_parent, mode, /*open_flag*/0); -+ if (IS_ERR(h_dentry)) { -+ err = PTR_ERR(h_dentry); -+ goto out_mnt; -+ } -+ -+ 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); -+ } else { -+ if (!inode->i_nlink) -+ set_nlink(inode, 1); -+ d_tmpfile(dentry, inode); -+ au_di(dentry)->di_tmpfile = 1; -+ -+ /* update without i_mutex */ -+ if (au_ibtop(dir) == au_dbtop(dentry)) -+ au_cpup_attr_timesizes(dir); -+ } -+ dput(h_dentry); -+ -+out_mnt: -+ vfsub_mnt_drop_write(h_mnt); -+out_parent: -+ di_write_unlock(parent); -+ dput(parent); -+ di_write_unlock(dentry); -+ if (unlikely(err)) { -+ au_di_fin(dentry); -+ dentry->d_fsdata = NULL; -+ } -+out_si: -+ si_read_unlock(sb); -+out: -+ inode_unlock(dir); -+ 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 || !h_inode->i_nlink) { -+ /* 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); -+ inc_nlink(inode); -+ inode->i_ctime = dir->i_ctime; -+ 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 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) { -+ 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 -Nurp linux-5.10-rc6/fs/aufs/i_op.c linux-5.10-rc6.aufs/fs/aufs/i_op.c ---- linux-5.10-rc6/fs/aufs/i_op.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/i_op.c 2020-12-02 21:19:51.882036788 +0200 -@@ -0,0 +1,1489 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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)); -+ -+ 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. -+ */ -+ if ((write_mask && !au_br_writable(brperm)) -+ || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode) -+ && write_mask && !(mask & MAY_READ)) -+ || !h_inode->i_op->permission) { -+ /* AuLabel(generic_permission); */ -+ /* AuDbg("get_acl %ps\n", h_inode->i_op->get_acl); */ -+ err = generic_permission(h_inode, mask); -+ if (err == -EOPNOTSUPP && au_test_nfs_noacl(h_inode)) -+ err = h_inode->i_op->permission(h_inode, mask); -+ AuTraceErr(err); -+ } else { -+ /* AuLabel(h_inode->permission); */ -+ err = h_inode->i_op->permission(h_inode, mask); -+ 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 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 = !h_i->i_nlink; -+ } -+ } -+ -+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 dentry *dentry, struct iattr *ia) -+{ -+ int err; -+ struct inode *inode, *delegated; -+ struct super_block *sb; -+ struct file *file; -+ struct au_icpup_args *a; -+ -+ inode = d_inode(dentry); -+ IMustLock(inode); -+ -+ err = setattr_prepare(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)) -+ err = vfsub_acl_chmod(a->h_inode, 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; -+ -+ 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; -+ -+ inode_unlock(a->h_inode); -+ switch (arg->type) { -+ case AU_XATTR_SET: -+ AuDebugOn(d_is_negative(h_path.dentry)); -+ err = vfsub_setxattr(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_inode, -+ 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->i_ctime = st->ctime; -+ -+ au_cpup_attr_nlink(inode, /*force*/0); -+ if (S_ISDIR(inode->i_mode)) { -+ n = inode->i_nlink; -+ n -= nlink; -+ n += st->nlink; -+ smp_mb(); /* for i_nlink */ -+ /* 0 can happen */ -+ 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(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 */ -+ err = vfs_getattr(&h_path, st, request, query); -+ if (!err) { -+ if (positive) -+ au_refresh_iattr(inode, st, -+ d_inode(h_path.dentry)->i_nlink); -+ goto out_fill; /* success */ -+ } -+ AuTraceErr(err); -+ goto out_di; -+ -+out_fill: -+ generic_fillattr(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, struct timespec64 *ts, -+ 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, ts, 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_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_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_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 -Nurp linux-5.10-rc6/fs/aufs/i_op_del.c linux-5.10-rc6.aufs/fs/aufs/i_op_del.c ---- linux-5.10-rc6/fs/aufs/i_op_del.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/i_op_del.c 2020-12-02 21:19:51.882036788 +0200 -@@ -0,0 +1,500 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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; -+ -+ 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(!h_inode->i_nlink)) -+ 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; -+ if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1) -+ && au_test_h_perm(d_inode(h_parent), -+ MAY_EXEC | MAY_WRITE))) -+ goto out; -+ -+ h_latest = au_sio_lkup_one(&dentry->d_name, h_parent); -+ 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->i_ctime = dir->i_ctime; -+ -+ 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; -+ 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*/ -+ inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime; -+ } else -+ /* todo: this timestamp may be reverted later */ -+ inode->i_ctime = h_dir->i_ctime; -+ 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 -Nurp linux-5.10-rc6/fs/aufs/i_op_ren.c linux-5.10-rc6.aufs/fs/aufs/i_op_ren.c ---- linux-5.10-rc6/fs/aufs/i_op_ren.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/i_op_ren.c 2020-12-02 21:19:51.882036788 +0200 -@@ -0,0 +1,1237 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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; -+ -+ a->h_path.dentry = vfsub_lkup_one(&a->src_dentry->d_name, -+ a->src_h_parent); -+ 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; -+ -+ a->h_path.dentry = vfsub_lkup_one(&a->dst_dentry->d_name, -+ a->dst_h_parent); -+ 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; -+ -+ 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*/ -+ a->dst_inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime; -+ } -+ 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*/ -+ a->src_inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime; -+ -+ 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 (h_inode->i_nlink) -+ 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 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(!a->dst_inode->i_nlink)) -+ 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 -Nurp linux-5.10-rc6/fs/aufs/Kconfig linux-5.10-rc6.aufs/fs/aufs/Kconfig ---- linux-5.10-rc6/fs/aufs/Kconfig 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/Kconfig 2020-12-02 21:19:51.879036653 +0200 -@@ -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 = y -+ 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 infromation 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 -Nurp linux-5.10-rc6/fs/aufs/lcnt.h linux-5.10-rc6.aufs/fs/aufs/lcnt.h ---- linux-5.10-rc6/fs/aufs/lcnt.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/lcnt.h 2020-12-02 21:19:51.882036788 +0200 -@@ -0,0 +1,173 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2018-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -+#define AuLCntZero(val) do {} while (0) -+#endif -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_LCNT_H__ */ -diff -Nurp linux-5.10-rc6/fs/aufs/loop.c linux-5.10-rc6.aufs/fs/aufs/loop.c ---- linux-5.10-rc6/fs/aufs/loop.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/loop.c 2020-12-02 21:19:51.882036788 +0200 -@@ -0,0 +1,135 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.10-rc6/fs/aufs/loop.h linux-5.10-rc6.aufs/fs/aufs/loop.h ---- linux-5.10-rc6/fs/aufs/loop.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/loop.h 2020-12-02 21:19:51.882036788 +0200 -@@ -0,0 +1,42 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.10-rc6/fs/aufs/magic.mk linux-5.10-rc6.aufs/fs/aufs/magic.mk ---- linux-5.10-rc6/fs/aufs/magic.mk 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/magic.mk 2020-12-02 21:19:51.882036788 +0200 -@@ -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 -Nurp linux-5.10-rc6/fs/aufs/Makefile linux-5.10-rc6.aufs/fs/aufs/Makefile ---- linux-5.10-rc6/fs/aufs/Makefile 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/Makefile 2020-12-02 21:19:51.879036653 +0200 -@@ -0,0 +1,39 @@ -+# SPDX-License-Identifier: GPL-2.0 -+ -+include ${srctree}/${src}/magic.mk -+-include ${srctree}/${src}/priv_def.mk -+ -+# cf. include/linux/kernel.h -+# enable pr_debug -+ccflags-y += -DDEBUG -+# sparse requires the full pathname -+ccflags-y += -include ${srctree}/include/uapi/linux/aufs_type.h -+ -+obj-$(CONFIG_AUFS_FS) += aufs.o -+aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \ -+ wkq.o vfsub.o dcsub.o \ -+ cpup.o whout.o wbr_policy.o \ -+ dinfo.o dentry.o \ -+ dynop.o \ -+ finfo.o file.o f_op.o \ -+ dir.o vdir.o \ -+ iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \ -+ 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 -Nurp linux-5.10-rc6/fs/aufs/module.c linux-5.10-rc6.aufs/fs/aufs/module.c ---- linux-5.10-rc6/fs/aufs/module.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/module.c 2020-12-02 21:19:51.882036788 +0200 -@@ -0,0 +1,259 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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); -+ -+/* 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 -Nurp linux-5.10-rc6/fs/aufs/module.h linux-5.10-rc6.aufs/fs/aufs/module.h ---- linux-5.10-rc6/fs/aufs/module.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/module.h 2020-12-02 21:19:51.882036788 +0200 -@@ -0,0 +1,153 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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) - kmalloc_index(new_sz); -+#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 AuCacheFuncs(name, index) \ -+ static inline struct au_##name *au_cache_alloc_##name(void) \ -+ { return kmem_cache_alloc(au_cache[AuCache_##index], GFP_NOFS); } \ -+ 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); -+AuCacheFuncs(icntnr, ICNTNR); -+AuCacheFuncs(finfo, FINFO); -+AuCacheFuncs(vdir, VDIR); -+AuCacheFuncs(vdir_dehstr, DEHSTR); -+#ifdef CONFIG_AUFS_HNOTIFY -+AuCacheFuncs(hnotify, HNOTIFY); -+#endif -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_MODULE_H__ */ -diff -Nurp linux-5.10-rc6/fs/aufs/mvdown.c linux-5.10-rc6.aufs/fs/aufs/mvdown.c ---- linux-5.10-rc6/fs/aufs/mvdown.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/mvdown.c 2020-12-02 21:19:51.883036833 +0200 -@@ -0,0 +1,693 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2011-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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)) -+ && a->inode->i_nlink == 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), a->inode->i_nlink, -+ a->mvd_h_src_inode->i_nlink, -+ 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 -Nurp linux-5.10-rc6/fs/aufs/opts.c linux-5.10-rc6.aufs/fs/aufs/opts.c ---- linux-5.10-rc6/fs/aufs/opts.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/opts.c 2020-12-02 21:19:51.883036833 +0200 -@@ -0,0 +1,1867 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * mount options/flags -+ */ -+ -+#include -+#include /* a distribution requires */ -+#include -+#include "aufs.h" -+ -+/* ---------------------------------------------------------------------- */ -+ -+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_rdblk_def, Opt_rdhash_def, -+ Opt_xino, Opt_noxino, -+ Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino, -+ Opt_trunc_xino_path, Opt_itrunc_xino, -+ Opt_trunc_xib, Opt_notrunc_xib, -+ Opt_shwh, Opt_noshwh, -+ Opt_plink, Opt_noplink, Opt_list_plink, -+ Opt_udba, -+ Opt_dio, Opt_nodio, -+ Opt_diropq_a, Opt_diropq_w, -+ Opt_warn_perm, Opt_nowarn_perm, -+ Opt_wbr_copyup, Opt_wbr_create, -+ Opt_fhsm_sec, -+ Opt_verbose, Opt_noverbose, -+ Opt_sum, Opt_nosum, Opt_wsum, -+ Opt_dirperm1, Opt_nodirperm1, -+ Opt_dirren, Opt_nodirren, -+ Opt_acl, Opt_noacl, -+ Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err -+}; -+ -+static match_table_t options = { -+ {Opt_br, "br=%s"}, -+ {Opt_br, "br:%s"}, -+ -+ {Opt_add, "add=%d:%s"}, -+ {Opt_add, "add:%d:%s"}, -+ {Opt_add, "ins=%d:%s"}, -+ {Opt_add, "ins:%d:%s"}, -+ {Opt_append, "append=%s"}, -+ {Opt_append, "append:%s"}, -+ {Opt_prepend, "prepend=%s"}, -+ {Opt_prepend, "prepend:%s"}, -+ -+ {Opt_del, "del=%s"}, -+ {Opt_del, "del:%s"}, -+ /* {Opt_idel, "idel:%d"}, */ -+ {Opt_mod, "mod=%s"}, -+ {Opt_mod, "mod:%s"}, -+ /* {Opt_imod, "imod:%d:%s"}, */ -+ -+ {Opt_dirwh, "dirwh=%d"}, -+ -+ {Opt_xino, "xino=%s"}, -+ {Opt_noxino, "noxino"}, -+ {Opt_trunc_xino, "trunc_xino"}, -+ {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"}, -+ {Opt_notrunc_xino, "notrunc_xino"}, -+ {Opt_trunc_xino_path, "trunc_xino=%s"}, -+ {Opt_itrunc_xino, "itrunc_xino=%d"}, -+ /* {Opt_zxino, "zxino=%s"}, */ -+ {Opt_trunc_xib, "trunc_xib"}, -+ {Opt_notrunc_xib, "notrunc_xib"}, -+ -+#ifdef CONFIG_PROC_FS -+ {Opt_plink, "plink"}, -+#else -+ {Opt_ignore_silent, "plink"}, -+#endif -+ -+ {Opt_noplink, "noplink"}, -+ -+#ifdef CONFIG_AUFS_DEBUG -+ {Opt_list_plink, "list_plink"}, -+#endif -+ -+ {Opt_udba, "udba=%s"}, -+ -+ {Opt_dio, "dio"}, -+ {Opt_nodio, "nodio"}, -+ -+#ifdef CONFIG_AUFS_DIRREN -+ {Opt_dirren, "dirren"}, -+ {Opt_nodirren, "nodirren"}, -+#else -+ {Opt_ignore, "dirren"}, -+ {Opt_ignore_silent, "nodirren"}, -+#endif -+ -+#ifdef CONFIG_AUFS_FHSM -+ {Opt_fhsm_sec, "fhsm_sec=%d"}, -+#else -+ {Opt_ignore, "fhsm_sec=%d"}, -+#endif -+ -+ {Opt_diropq_a, "diropq=always"}, -+ {Opt_diropq_a, "diropq=a"}, -+ {Opt_diropq_w, "diropq=whiteouted"}, -+ {Opt_diropq_w, "diropq=w"}, -+ -+ {Opt_warn_perm, "warn_perm"}, -+ {Opt_nowarn_perm, "nowarn_perm"}, -+ -+ /* keep them temporary */ -+ {Opt_ignore_silent, "nodlgt"}, -+ {Opt_ignore, "clean_plink"}, -+ -+#ifdef CONFIG_AUFS_SHWH -+ {Opt_shwh, "shwh"}, -+#endif -+ {Opt_noshwh, "noshwh"}, -+ -+ {Opt_dirperm1, "dirperm1"}, -+ {Opt_nodirperm1, "nodirperm1"}, -+ -+ {Opt_verbose, "verbose"}, -+ {Opt_verbose, "v"}, -+ {Opt_noverbose, "noverbose"}, -+ {Opt_noverbose, "quiet"}, -+ {Opt_noverbose, "q"}, -+ {Opt_noverbose, "silent"}, -+ -+ {Opt_sum, "sum"}, -+ {Opt_nosum, "nosum"}, -+ {Opt_wsum, "wsum"}, -+ -+ {Opt_rdcache, "rdcache=%d"}, -+ {Opt_rdblk, "rdblk=%d"}, -+ {Opt_rdblk_def, "rdblk=def"}, -+ {Opt_rdhash, "rdhash=%d"}, -+ {Opt_rdhash_def, "rdhash=def"}, -+ -+ {Opt_wbr_create, "create=%s"}, -+ {Opt_wbr_create, "create_policy=%s"}, -+ {Opt_wbr_copyup, "cpup=%s"}, -+ {Opt_wbr_copyup, "copyup=%s"}, -+ {Opt_wbr_copyup, "copyup_policy=%s"}, -+ -+ /* generic VFS flag */ -+#ifdef CONFIG_FS_POSIX_ACL -+ {Opt_acl, "acl"}, -+ {Opt_noacl, "noacl"}, -+#else -+ {Opt_ignore, "acl"}, -+ {Opt_ignore_silent, "noacl"}, -+#endif -+ -+ /* internal use for the scripts */ -+ {Opt_ignore_silent, "si=%s"}, -+ -+ {Opt_br, "dirs=%s"}, -+ {Opt_ignore, "debug=%d"}, -+ {Opt_ignore, "delete=whiteout"}, -+ {Opt_ignore, "delete=all"}, -+ {Opt_ignore, "imap=%s"}, -+ -+ /* temporary workaround, due to old mount(8)? */ -+ {Opt_ignore_silent, "relatime"}, -+ -+ {Opt_err, NULL} -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+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; -+} -+ -+static int noinline_for_stack 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} -+}; -+ -+static int noinline_for_stack 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; -+} -+ -+static int noinline_for_stack -+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} -+}; -+ -+static int noinline_for_stack 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); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY; -+ -+static void dump_opts(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: -+ case Opt_idel: -+ u.del = &opt->del; -+ AuDbg("del {%s, %p}\n", -+ u.del->pathname, u.del->h_path.dentry); -+ break; -+ case Opt_mod: -+ 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 %u\n", opt->rdblk); -+ break; -+ case Opt_rdblk_def: -+ AuDbg("rdblk_def\n"); -+ break; -+ case Opt_rdhash: -+ AuDbg("rdhash %u\n", opt->rdhash); -+ break; -+ case Opt_rdhash_def: -+ AuDbg("rdhash_def\n"); -+ break; -+ case Opt_xino: -+ u.xino = &opt->xino; -+ AuDbg("xino {%s %pD}\n", u.xino->path, u.xino->file); -+ break; -+ case Opt_trunc_xino: -+ AuLabel(trunc_xino); -+ break; -+ case Opt_notrunc_xino: -+ AuLabel(notrunc_xino); -+ break; -+ case Opt_trunc_xino_path: -+ 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_trunc_xib: -+ AuLabel(trunc_xib); -+ break; -+ case Opt_notrunc_xib: -+ AuLabel(notrunc_xib); -+ break; -+ case Opt_shwh: -+ AuLabel(shwh); -+ break; -+ case Opt_noshwh: -+ AuLabel(noshwh); -+ break; -+ case Opt_dirperm1: -+ AuLabel(dirperm1); -+ break; -+ case Opt_nodirperm1: -+ AuLabel(nodirperm1); -+ break; -+ case Opt_plink: -+ AuLabel(plink); -+ break; -+ case Opt_noplink: -+ AuLabel(noplink); -+ 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_dio: -+ AuLabel(dio); -+ break; -+ case Opt_nodio: -+ AuLabel(nodio); -+ break; -+ case Opt_diropq_a: -+ AuLabel(diropq_a); -+ break; -+ case Opt_diropq_w: -+ AuLabel(diropq_w); -+ break; -+ case Opt_warn_perm: -+ AuLabel(warn_perm); -+ break; -+ case Opt_nowarn_perm: -+ AuLabel(nowarn_perm); -+ break; -+ case Opt_verbose: -+ AuLabel(verbose); -+ break; -+ case Opt_noverbose: -+ AuLabel(noverbose); -+ break; -+ case Opt_sum: -+ AuLabel(sum); -+ break; -+ case Opt_nosum: -+ AuLabel(nosum); -+ 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: -+ case AuWbrCreate_PMFSV: -+ AuDbg("%d sec\n", u.create->mfs_second); -+ break; -+ case AuWbrCreate_MFSRR: -+ case AuWbrCreate_TDMFS: -+ AuDbg("%llu watermark\n", -+ u.create->mfsrr_watermark); -+ break; -+ case AuWbrCreate_MFSRRV: -+ case AuWbrCreate_TDMFSV: -+ 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; -+ case Opt_dirren: -+ AuLabel(dirren); -+ break; -+ case Opt_nodirren: -+ AuLabel(nodirren); -+ break; -+ case Opt_acl: -+ AuLabel(acl); -+ break; -+ case Opt_noacl: -+ AuLabel(noacl); -+ break; -+ default: -+ BUG(); -+ } -+ opt++; -+ } -+#endif -+} -+ -+void au_opts_free(struct au_opts *opts) -+{ -+ struct au_opt *opt; -+ -+ opt = opts->opt; -+ while (opt->type != Opt_tail) { -+ switch (opt->type) { -+ case Opt_add: -+ case Opt_append: -+ case Opt_prepend: -+ path_put(&opt->add.path); -+ break; -+ case Opt_del: -+ case Opt_idel: -+ path_put(&opt->del.h_path); -+ break; -+ case Opt_mod: -+ case Opt_imod: -+ dput(opt->mod.h_root); -+ break; -+ case Opt_xino: -+ fput(opt->xino.file); -+ break; -+ } -+ opt++; -+ } -+} -+ -+static int 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 = br_perm_val(p); -+ } -+ -+ err = vfsub_kern_path(add->pathname, lkup_dirflags, &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_opts_parse_del(struct au_opt_del *del, substring_t args[]) -+{ -+ int err; -+ -+ del->pathname = args[0].from; -+ AuDbg("del path %s\n", del->pathname); -+ -+ err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path); -+ if (unlikely(err)) -+ pr_err("lookup failed %s (%d)\n", del->pathname, err); -+ -+ return err; -+} -+ -+#if 0 /* reserved for future use */ -+static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex, -+ struct au_opt_del *del, substring_t args[]) -+{ -+ int err; -+ struct dentry *root; -+ -+ err = -EINVAL; -+ root = sb->s_root; -+ aufs_read_lock(root, AuLock_FLUSH); -+ if (bindex < 0 || au_sbbot(sb) < bindex) { -+ pr_err("out of bounds, %d\n", 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); -+ return err; -+} -+#endif -+ -+static int noinline_for_stack -+au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[]) -+{ -+ int err; -+ struct path path; -+ char *p; -+ -+ err = -EINVAL; -+ mod->path = args[0].from; -+ p = strchr(mod->path, '='); -+ if (unlikely(!p)) { -+ pr_err("no permission %s\n", args[0].from); -+ goto out; -+ } -+ -+ *p++ = 0; -+ err = vfsub_kern_path(mod->path, lkup_dirflags, &path); -+ if (unlikely(err)) { -+ pr_err("lookup failed %s (%d)\n", mod->path, err); -+ goto out; -+ } -+ -+ mod->perm = br_perm_val(p); -+ AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p); -+ mod->h_root = dget(path.dentry); -+ path_put(&path); -+ -+out: -+ return err; -+} -+ -+#if 0 /* reserved for future use */ -+static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex, -+ struct au_opt_mod *mod, substring_t args[]) -+{ -+ int err; -+ struct dentry *root; -+ -+ err = -EINVAL; -+ root = sb->s_root; -+ aufs_read_lock(root, AuLock_FLUSH); -+ if (bindex < 0 || au_sbbot(sb) < bindex) { -+ pr_err("out of bounds, %d\n", bindex); -+ goto out; -+ } -+ -+ err = 0; -+ mod->perm = br_perm_val(args[1].from); -+ AuDbg("mod path %s, perm 0x%x, %s\n", -+ mod->path, mod->perm, args[1].from); -+ mod->h_root = dget(au_h_dptr(root, bindex)); -+ -+out: -+ aufs_read_unlock(root, !AuLock_IR); -+ return err; -+} -+#endif -+ -+static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino, -+ substring_t args[]) -+{ -+ int err; -+ struct file *file; -+ -+ file = au_xino_create(sb, args[0].from, /*silent*/0, /*wbrtop*/0); -+ err = PTR_ERR(file); -+ if (IS_ERR(file)) -+ goto out; -+ -+ err = -EINVAL; -+ if (unlikely(file->f_path.dentry->d_sb == sb)) { -+ fput(file); -+ pr_err("%s must be outside\n", args[0].from); -+ goto out; -+ } -+ -+ err = 0; -+ xino->file = file; -+ xino->path = args[0].from; -+ -+out: -+ return err; -+} -+ -+static int noinline_for_stack -+au_opts_parse_xino_itrunc_path(struct super_block *sb, -+ struct au_opt_xino_itrunc *xino_itrunc, -+ substring_t args[]) -+{ -+ int err; -+ aufs_bindex_t bbot, bindex; -+ struct path path; -+ struct dentry *root; -+ -+ err = vfsub_kern_path(args[0].from, lkup_dirflags, &path); -+ if (unlikely(err)) { -+ pr_err("lookup failed %s (%d)\n", args[0].from, err); -+ goto out; -+ } -+ -+ xino_itrunc->bindex = -1; -+ root = sb->s_root; -+ aufs_read_lock(root, AuLock_FLUSH); -+ bbot = au_sbbot(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)) { -+ pr_err("no such branch %s\n", args[0].from); -+ err = -EINVAL; -+ } -+ -+out: -+ return err; -+} -+ -+/* called without aufs lock */ -+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts) -+{ -+ int err, n, token; -+ aufs_bindex_t bindex; -+ unsigned char skipped; -+ struct dentry *root; -+ struct au_opt *opt, *opt_tail; -+ char *opt_str; -+ /* reduce the stack space */ -+ union { -+ struct au_opt_xino_itrunc *xino_itrunc; -+ struct au_opt_wbr_create *create; -+ } u; -+ struct { -+ substring_t args[MAX_OPT_ARGS]; -+ } *a; -+ -+ err = -ENOMEM; -+ a = kmalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ -+ root = sb->s_root; -+ err = 0; -+ bindex = 0; -+ opt = opts->opt; -+ opt_tail = opt + opts->max_opt - 1; -+ opt->type = Opt_tail; -+ while (!err && (opt_str = strsep(&str, ",")) && *opt_str) { -+ err = -EINVAL; -+ skipped = 0; -+ token = match_token(opt_str, options, a->args); -+ switch (token) { -+ case Opt_br: -+ err = 0; -+ while (!err && (opt_str = strsep(&a->args[0].from, ":")) -+ && *opt_str) { -+ err = opt_add(opt, opt_str, opts->sb_flags, -+ bindex++); -+ if (unlikely(!err && ++opt > opt_tail)) { -+ err = -E2BIG; -+ break; -+ } -+ opt->type = Opt_tail; -+ skipped = 1; -+ } -+ break; -+ case Opt_add: -+ if (unlikely(match_int(&a->args[0], &n))) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ bindex = n; -+ err = opt_add(opt, a->args[1].from, opts->sb_flags, -+ bindex); -+ if (!err) -+ opt->type = token; -+ break; -+ case Opt_append: -+ err = opt_add(opt, a->args[0].from, opts->sb_flags, -+ /*dummy bindex*/1); -+ if (!err) -+ opt->type = token; -+ break; -+ case Opt_prepend: -+ err = opt_add(opt, a->args[0].from, opts->sb_flags, -+ /*bindex*/0); -+ if (!err) -+ opt->type = token; -+ break; -+ case Opt_del: -+ err = au_opts_parse_del(&opt->del, a->args); -+ if (!err) -+ opt->type = token; -+ break; -+#if 0 /* reserved for future use */ -+ case Opt_idel: -+ del->pathname = "(indexed)"; -+ if (unlikely(match_int(&args[0], &n))) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ err = au_opts_parse_idel(sb, n, &opt->del, a->args); -+ if (!err) -+ opt->type = token; -+ break; -+#endif -+ case Opt_mod: -+ err = au_opts_parse_mod(&opt->mod, a->args); -+ if (!err) -+ opt->type = token; -+ break; -+#ifdef IMOD /* reserved for future use */ -+ case Opt_imod: -+ u.mod->path = "(indexed)"; -+ if (unlikely(match_int(&a->args[0], &n))) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ err = au_opts_parse_imod(sb, n, &opt->mod, a->args); -+ if (!err) -+ opt->type = token; -+ break; -+#endif -+ case Opt_xino: -+ err = au_opts_parse_xino(sb, &opt->xino, a->args); -+ if (!err) -+ opt->type = token; -+ break; -+ -+ case Opt_trunc_xino_path: -+ err = au_opts_parse_xino_itrunc_path -+ (sb, &opt->xino_itrunc, a->args); -+ if (!err) -+ opt->type = token; -+ break; -+ -+ case Opt_itrunc_xino: -+ u.xino_itrunc = &opt->xino_itrunc; -+ if (unlikely(match_int(&a->args[0], &n))) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ u.xino_itrunc->bindex = n; -+ aufs_read_lock(root, AuLock_FLUSH); -+ if (n < 0 || au_sbbot(sb) < n) { -+ pr_err("out of bounds, %d\n", n); -+ aufs_read_unlock(root, !AuLock_IR); -+ break; -+ } -+ aufs_read_unlock(root, !AuLock_IR); -+ err = 0; -+ opt->type = token; -+ break; -+ -+ case Opt_dirwh: -+ if (unlikely(match_int(&a->args[0], &opt->dirwh))) -+ break; -+ err = 0; -+ opt->type = token; -+ break; -+ -+ case Opt_rdcache: -+ if (unlikely(match_int(&a->args[0], &n))) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ if (unlikely(n > AUFS_RDCACHE_MAX)) { -+ pr_err("rdcache must be smaller than %d\n", -+ AUFS_RDCACHE_MAX); -+ break; -+ } -+ opt->rdcache = n; -+ err = 0; -+ opt->type = token; -+ break; -+ case Opt_rdblk: -+ if (unlikely(match_int(&a->args[0], &n) -+ || n < 0 -+ || n > KMALLOC_MAX_SIZE)) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ if (unlikely(n && n < NAME_MAX)) { -+ pr_err("rdblk must be larger than %d\n", -+ NAME_MAX); -+ break; -+ } -+ opt->rdblk = n; -+ err = 0; -+ opt->type = token; -+ break; -+ case Opt_rdhash: -+ if (unlikely(match_int(&a->args[0], &n) -+ || n < 0 -+ || n * sizeof(struct hlist_head) -+ > KMALLOC_MAX_SIZE)) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ opt->rdhash = n; -+ err = 0; -+ opt->type = token; -+ break; -+ -+ case Opt_trunc_xino: -+ case Opt_notrunc_xino: -+ case Opt_noxino: -+ case Opt_trunc_xib: -+ case Opt_notrunc_xib: -+ case Opt_shwh: -+ case Opt_noshwh: -+ case Opt_dirperm1: -+ case Opt_nodirperm1: -+ case Opt_plink: -+ case Opt_noplink: -+ case Opt_list_plink: -+ case Opt_dio: -+ case Opt_nodio: -+ case Opt_diropq_a: -+ case Opt_diropq_w: -+ case Opt_warn_perm: -+ case Opt_nowarn_perm: -+ case Opt_verbose: -+ case Opt_noverbose: -+ case Opt_sum: -+ case Opt_nosum: -+ case Opt_wsum: -+ case Opt_rdblk_def: -+ case Opt_rdhash_def: -+ case Opt_dirren: -+ case Opt_nodirren: -+ case Opt_acl: -+ case Opt_noacl: -+ err = 0; -+ opt->type = token; -+ break; -+ -+ case Opt_udba: -+ opt->udba = udba_val(a->args[0].from); -+ if (opt->udba >= 0) { -+ err = 0; -+ opt->type = token; -+ } else -+ pr_err("wrong value, %s\n", opt_str); -+ break; -+ -+ case Opt_wbr_create: -+ u.create = &opt->wbr_create; -+ u.create->wbr_create -+ = au_wbr_create_val(a->args[0].from, u.create); -+ if (u.create->wbr_create >= 0) { -+ err = 0; -+ opt->type = token; -+ } else -+ pr_err("wrong value, %s\n", opt_str); -+ break; -+ case Opt_wbr_copyup: -+ opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from); -+ if (opt->wbr_copyup >= 0) { -+ err = 0; -+ opt->type = token; -+ } else -+ pr_err("wrong value, %s\n", opt_str); -+ break; -+ -+ case Opt_fhsm_sec: -+ if (unlikely(match_int(&a->args[0], &n) -+ || n < 0)) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ if (sysaufs_brs) { -+ opt->fhsm_second = n; -+ opt->type = token; -+ } else -+ pr_warn("ignored %s\n", opt_str); -+ err = 0; -+ break; -+ -+ case Opt_ignore: -+ pr_warn("ignored %s\n", opt_str); -+ /*FALLTHROUGH*/ -+ case Opt_ignore_silent: -+ skipped = 1; -+ err = 0; -+ break; -+ case Opt_err: -+ pr_err("unknown option %s\n", opt_str); -+ break; -+ } -+ -+ if (!err && !skipped) { -+ if (unlikely(++opt > opt_tail)) { -+ err = -E2BIG; -+ opt--; -+ opt->type = Opt_tail; -+ break; -+ } -+ opt->type = Opt_tail; -+ } -+ } -+ -+ au_kfree_rcu(a); -+ dump_opts(opts); -+ if (unlikely(err)) -+ au_opts_free(opts); -+ -+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: -+ au_opt_set(sbinfo->si_mntflags, PLINK); -+ break; -+ case Opt_noplink: -+ 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: -+ au_opt_set(sbinfo->si_mntflags, DIO); -+ au_fset_opts(opts->flags, REFRESH_DYAOP); -+ break; -+ case Opt_nodio: -+ 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: -+ au_opt_set(sbinfo->si_mntflags, WARN_PERM); -+ break; -+ case Opt_nowarn_perm: -+ au_opt_clr(sbinfo->si_mntflags, WARN_PERM); -+ break; -+ -+ case Opt_verbose: -+ au_opt_set(sbinfo->si_mntflags, VERBOSE); -+ break; -+ case Opt_noverbose: -+ au_opt_clr(sbinfo->si_mntflags, VERBOSE); -+ break; -+ -+ case Opt_sum: -+ au_opt_set(sbinfo->si_mntflags, SUM); -+ break; -+ case Opt_wsum: -+ au_opt_clr(sbinfo->si_mntflags, SUM); -+ au_opt_set(sbinfo->si_mntflags, SUM_W); -+ break; -+ case Opt_nosum: -+ au_opt_clr(sbinfo->si_mntflags, SUM); -+ au_opt_clr(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_rdblk_def: -+ sbinfo->si_rdblk = AUFS_RDBLK_DEF; -+ break; -+ case Opt_rdhash: -+ sbinfo->si_rdhash = opt->rdhash; -+ break; -+ case Opt_rdhash_def: -+ sbinfo->si_rdhash = AUFS_RDHASH_DEF; -+ break; -+ -+ case Opt_shwh: -+ au_opt_set(sbinfo->si_mntflags, SHWH); -+ break; -+ case Opt_noshwh: -+ au_opt_clr(sbinfo->si_mntflags, SHWH); -+ break; -+ -+ case Opt_dirperm1: -+ au_opt_set(sbinfo->si_mntflags, DIRPERM1); -+ break; -+ case Opt_nodirperm1: -+ au_opt_clr(sbinfo->si_mntflags, DIRPERM1); -+ break; -+ -+ case Opt_trunc_xino: -+ au_opt_set(sbinfo->si_mntflags, TRUNC_XINO); -+ break; -+ case Opt_notrunc_xino: -+ 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: -+ au_fset_opts(opts->flags, TRUNC_XIB); -+ break; -+ case Opt_notrunc_xib: -+ au_fclr_opts(opts->flags, TRUNC_XIB); -+ break; -+ -+ case Opt_dirren: -+ err = 1; -+ 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); -+ break; -+ case Opt_nodirren: -+ err = 1; -+ 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: -+ sb->s_flags |= SB_POSIXACL; -+ break; -+ case Opt_noacl: -+ 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 */ -+ add: /* indented label */ -+ case Opt_add: -+ 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 (unlikely(err)) -+ break; -+ -+ *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 -Nurp linux-5.10-rc6/fs/aufs/opts.h linux-5.10-rc6.aufs/fs/aufs/opts.h ---- linux-5.10-rc6/fs/aufs/opts.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/opts.h 2020-12-02 21:19:51.883036833 +0200 -@@ -0,0 +1,212 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * mount options/flags -+ */ -+ -+#ifndef __AUFS_OPTS_H__ -+#define __AUFS_OPTS_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+ -+struct file; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* 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 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 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; -+ }; -+}; -+ -+/* 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 */ -+void au_optstr_br_perm(au_br_perm_str_t *str, int perm); -+const char *au_optstr_udba(int udba); -+const char *au_optstr_wbr_copyup(int wbr_copyup); -+const char *au_optstr_wbr_create(int wbr_create); -+ -+void au_opts_free(struct au_opts *opts); -+struct super_block; -+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts); -+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); -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_OPTS_H__ */ -diff -Nurp linux-5.10-rc6/fs/aufs/plink.c linux-5.10-rc6.aufs/fs/aufs/plink.c ---- linux-5.10-rc6/fs/aufs/plink.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/plink.c 2020-12-02 21:19:51.883036833 +0200 -@@ -0,0 +1,503 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 dentry *h_parent; -+ struct au_branch *br; -+}; -+ -+static struct dentry *au_do_plink_lkup(struct qstr *tgtname, -+ struct dentry *h_parent, -+ struct au_branch *br) -+{ -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ -+ h_inode = d_inode(h_parent); -+ inode_lock_shared_nested(h_inode, AuLsc_I_CHILD2); -+ h_dentry = vfsub_lkup_one(tgtname, h_parent); -+ 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_parent, a->br); -+} -+ -+/* 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, *h_parent; -+ struct au_branch *br; -+ 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_parent = br->br_wbr->wbr_plink; -+ 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_parent = h_parent, -+ .br = br -+ }; -+ -+ 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_parent, br); -+ -+ return h_dentry; -+} -+ -+/* create a pseudo-link */ -+static int do_whplink(struct qstr *tgt, struct dentry *h_parent, -+ struct dentry *h_dentry, struct au_branch *br) -+{ -+ int err; -+ struct path h_path = { -+ .mnt = au_br_mnt(br) -+ }; -+ struct inode *h_dir, *delegated; -+ -+ h_dir = d_inode(h_parent); -+ inode_lock_nested(h_dir, AuLsc_I_CHILD2); -+again: -+ h_path.dentry = vfsub_lkup_one(tgt, h_parent); -+ 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 dentry *h_parent; -+ struct dentry *h_dentry; -+ struct au_branch *br; -+}; -+ -+static void call_do_whplink(void *args) -+{ -+ struct do_whplink_args *a = args; -+ *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br); -+} -+ -+static int whplink(struct dentry *h_dentry, struct inode *inode, -+ aufs_bindex_t bindex, struct au_branch *br) -+{ -+ int err, wkq_err; -+ struct au_wbr *wbr; -+ struct dentry *h_parent; -+ char a[PLINK_NAME_LEN]; -+ struct qstr tgtname = QSTR_INIT(a, 0); -+ -+ wbr = au_sbr(inode->i_sb, bindex)->br_wbr; -+ h_parent = wbr->wbr_plink; -+ 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_parent = h_parent, -+ .h_dentry = h_dentry, -+ .br = br -+ }; -+ wkq_err = au_wkq_wait(call_do_whplink, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } else -+ err = do_whplink(&tgtname, h_parent, h_dentry, br); -+ -+ 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, au_sbr(sb, 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 -Nurp linux-5.10-rc6/fs/aufs/poll.c linux-5.10-rc6.aufs/fs/aufs/poll.c ---- linux-5.10-rc6/fs/aufs/poll.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/poll.c 2020-12-02 21:19:51.883036833 +0200 -@@ -0,0 +1,38 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.10-rc6/fs/aufs/posix_acl.c linux-5.10-rc6.aufs/fs/aufs/posix_acl.c ---- linux-5.10-rc6/fs/aufs/posix_acl.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/posix_acl.c 2020-12-02 21:19:51.883036833 +0200 -@@ -0,0 +1,92 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2014-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * posix acl operations -+ */ -+ -+#include -+#include "aufs.h" -+ -+struct posix_acl *aufs_get_acl(struct inode *inode, int type) -+{ -+ struct posix_acl *acl; -+ int err; -+ aufs_bindex_t bindex; -+ struct inode *h_inode; -+ struct super_block *sb; -+ -+ acl = NULL; -+ sb = inode->i_sb; -+ si_read_lock(sb, AuLock_FLUSH); -+ ii_read_lock_child(inode); -+ if (!(sb->s_flags & SB_POSIXACL)) -+ goto out; -+ -+ 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 out; -+ } -+ -+ /* always topmost only */ -+ acl = get_acl(h_inode, type); -+ if (IS_ERR(acl)) -+ forget_cached_acl(inode, type); -+ else -+ set_cached_acl(inode, type, acl); -+ -+out: -+ ii_read_unlock(inode); -+ si_read_unlock(sb); -+ -+ AuTraceErrPtr(acl); -+ return acl; -+} -+ -+int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type) -+{ -+ int err; -+ ssize_t ssz; -+ struct dentry *dentry; -+ struct au_sxattr arg = { -+ .type = AU_ACL_SET, -+ .u.acl_set = { -+ .acl = acl, -+ .type = type -+ }, -+ }; -+ -+ IMustLock(inode); -+ -+ if (inode->i_ino == AUFS_ROOT_INO) -+ dentry = dget(inode->i_sb->s_root); -+ else { -+ dentry = d_find_alias(inode); -+ if (!dentry) -+ dentry = d_find_any_alias(inode); -+ if (!dentry) { -+ pr_warn("cannot handle this inode, " -+ "please report to aufs-users ML\n"); -+ err = -ENOENT; -+ goto out; -+ } -+ } -+ -+ ssz = au_sxattr(dentry, inode, &arg); -+ /* forget even it if succeeds since the branch might set differently */ -+ forget_cached_acl(inode, type); -+ dput(dentry); -+ err = ssz; -+ if (ssz >= 0) -+ err = 0; -+ -+out: -+ return err; -+} -diff -Nurp linux-5.10-rc6/fs/aufs/procfs.c linux-5.10-rc6.aufs/fs/aufs/procfs.c ---- linux-5.10-rc6/fs/aufs/procfs.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/procfs.c 2020-12-02 21:19:51.883036833 +0200 -@@ -0,0 +1,157 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2010-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.10-rc6/fs/aufs/rdu.c linux-5.10-rc6.aufs/fs/aufs/rdu.c ---- linux-5.10-rc6/fs/aufs/rdu.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/rdu.c 2020-12-02 21:19:51.883036833 +0200 -@@ -0,0 +1,371 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 int 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 && !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 -Nurp linux-5.10-rc6/fs/aufs/rwsem.h linux-5.10-rc6.aufs/fs/aufs/rwsem.h ---- linux-5.10-rc6/fs/aufs/rwsem.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/rwsem.h 2020-12-02 21:19:51.883036833 +0200 -@@ -0,0 +1,60 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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)) -+/* rwsem_is_locked() is unusable */ -+#define AuRwMustReadLock(rw) AuDebugOn(!lockdep_recursing(current) \ -+ && debug_locks \ -+ && !lockdep_is_held_type(rw, 1)) -+#define AuRwMustWriteLock(rw) AuDebugOn(!lockdep_recursing(current) \ -+ && debug_locks \ -+ && !lockdep_is_held_type(rw, 0)) -+#define AuRwMustAnyLock(rw) AuDebugOn(!lockdep_recursing(current) \ -+ && debug_locks \ -+ && !lockdep_is_held(rw)) -+#define AuRwDestroy(rw) AuDebugOn(!lockdep_recursing(current) \ -+ && debug_locks \ -+ && lockdep_is_held(rw)) -+ -+#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 -Nurp linux-5.10-rc6/fs/aufs/sbinfo.c linux-5.10-rc6.aufs/fs/aufs/sbinfo.c ---- linux-5.10-rc6/fs/aufs/sbinfo.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/sbinfo.c 2020-12-02 21:19:51.883036833 +0200 -@@ -0,0 +1,301 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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); -+} -+ -+int au_si_alloc(struct super_block *sb) -+{ -+ int err, i; -+ struct au_sbinfo *sbinfo; -+ -+ 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; -+ sb->s_fs_info = sbinfo; -+ si_pid_set(sb); -+ return 0; /* success */ -+ -+out_br: -+ au_kfree_try_rcu(sbinfo->si_branch); -+out_sbinfo: -+ au_kfree_rcu(sbinfo); -+out: -+ return 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 -Nurp linux-5.10-rc6/fs/aufs/super.c linux-5.10-rc6.aufs/fs/aufs/super.c ---- linux-5.10-rc6/fs/aufs/super.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/super.c 2020-12-02 21:19:51.883036833 +0200 -@@ -0,0 +1,1034 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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(); -+ 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 __maybe_unused, const char *pat, -+ const char *append) -+{ -+ char *p; -+ -+ p = fmt; -+ while (*pat != ':') -+ *p++ = *pat++; -+ *p++ = *pat++; -+ strcpy(p, append); -+ 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, wait); -+ 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; -+} -+ -+static 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); -+} -+ -+/* 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 aufs_remount_fs(struct super_block *sb, int *flags, char *data) -+{ -+ int err, do_dx; -+ unsigned int mntflags; -+ struct au_opts opts = { -+ .opt = NULL -+ }; -+ struct dentry *root; -+ struct inode *inode; -+ struct au_sbinfo *sbinfo; -+ -+ err = 0; -+ root = sb->s_root; -+ if (!data || !*data) { -+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (!err) { -+ di_write_lock_child(root); -+ err = au_opts_verify(sb, *flags, /*pending*/0); -+ aufs_write_unlock(root); -+ } -+ goto out; -+ } -+ -+ err = -ENOMEM; -+ opts.opt = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!opts.opt)) -+ goto out; -+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt); -+ opts.flags = AuOpts_REMOUNT; -+ opts.sb_flags = *flags; -+ -+ /* parse it before aufs lock */ -+ err = au_opts_parse(sb, data, &opts); -+ if (unlikely(err)) -+ goto out_opts; -+ -+ sbinfo = au_sbi(sb); -+ inode = d_inode(root); -+ inode_lock(inode); -+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (unlikely(err)) -+ goto out_mtx; -+ di_write_lock_child(root); -+ -+ /* au_opts_remount() may return an error */ -+ err = au_opts_remount(sb, &opts); -+ au_opts_free(&opts); -+ -+ if (au_ftest_opts(opts.flags, REFRESH)) -+ au_remount_refresh(sb, au_ftest_opts(opts.flags, REFRESH_IDOP)); -+ -+ if (au_ftest_opts(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_mtx: -+ inode_unlock(inode); -+out_opts: -+ free_page((unsigned long)opts.opt); -+out: -+ err = cvt_err(err); -+ AuTraceErr(err); -+ return err; -+} -+ -+static 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, -+ .remount_fs = aufs_remount_fs -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int 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; -+ set_nlink(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 int aufs_fill_super(struct super_block *sb, void *raw_data, -+ int silent __maybe_unused) -+{ -+ int err; -+ struct au_opts opts = { -+ .opt = NULL -+ }; -+ struct au_sbinfo *sbinfo; -+ struct dentry *root; -+ struct inode *inode; -+ char *arg = raw_data; -+ -+ if (unlikely(!arg || !*arg)) { -+ err = -EINVAL; -+ pr_err("no arg\n"); -+ goto out; -+ } -+ -+ err = -ENOMEM; -+ opts.opt = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!opts.opt)) -+ goto out; -+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt); -+ opts.sb_flags = sb->s_flags; -+ -+ err = au_si_alloc(sb); -+ if (unlikely(err)) -+ goto out_opts; -+ sbinfo = au_sbi(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 = alloc_root(sb); -+ if (unlikely(err)) { -+ si_write_unlock(sb); -+ goto out_info; -+ } -+ root = sb->s_root; -+ inode = d_inode(root); -+ -+ /* -+ * actually we can parse options regardless aufs lock here. -+ * but at remount time, parsing must be done before aufs lock. -+ * so we follow the same rule. -+ */ -+ ii_write_lock_parent(inode); -+ aufs_write_unlock(root); -+ err = au_opts_parse(sb, arg, &opts); -+ if (unlikely(err)) -+ goto out_root; -+ -+ /* lock vfs_inode first, then aufs. */ -+ inode_lock(inode); -+ aufs_write_lock(root); -+ err = au_opts_mount(sb, &opts); -+ au_opts_free(&opts); -+ if (!err && au_ftest_si(sbinfo, NO_DREVAL)) { -+ sb->s_d_op = &aufs_dop_noreval; -+ 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_opts; /* success */ -+ -+out_root: -+ dput(root); -+ sb->s_root = NULL; -+out_info: -+ kobject_put(&sbinfo->si_kobj); -+ sb->s_fs_info = NULL; -+out_opts: -+ free_page((unsigned long)opts.opt); -+out: -+ AuTraceErr(err); -+ err = cvt_err(err); -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static struct dentry *aufs_mount(struct file_system_type *fs_type, int flags, -+ const char *dev_name __maybe_unused, -+ void *raw_data) -+{ -+ struct dentry *root; -+ -+ /* all timestamps always follow the ones on the branch */ -+ /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */ -+ root = mount_nodev(fs_type, flags, raw_data, aufs_fill_super); -+ if (IS_ERR(root)) -+ goto out; -+ -+ au_sbilist_add(root->d_sb); -+ -+out: -+ return root; -+} -+ -+static void aufs_kill_sb(struct super_block *sb) -+{ -+ struct au_sbinfo *sbinfo; -+ -+ sbinfo = au_sbi(sb); -+ if (sbinfo) { -+ au_sbilist_del(sb); -+ aufs_write_lock(sb->s_root); -+ 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); -+ au_dr_opt_flush(sb); -+ sbinfo->si_sb = NULL; -+ aufs_write_unlock(sb->s_root); -+ au_nwt_flush(&sbinfo->si_nowait); -+ } -+ 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, -+ .mount = aufs_mount, -+ .kill_sb = aufs_kill_sb, -+ /* no need to __module_get() and module_put(). */ -+ .owner = THIS_MODULE, -+}; -diff -Nurp linux-5.10-rc6/fs/aufs/super.h linux-5.10-rc6.aufs/fs/aufs/super.h ---- linux-5.10-rc6/fs/aufs/super.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/super.h 2020-12-02 21:19:51.883036833 +0200 -@@ -0,0 +1,576 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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) */ -+ vfs_readf_t si_xread; -+ vfs_writef_t si_xwrite; -+ 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 */ -+extern struct file_system_type aufs_fs_type; -+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); -+ -+/* sbinfo.c */ -+void au_si_free(struct kobject *kobj); -+int 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 -Nurp linux-5.10-rc6/fs/aufs/sysaufs.c linux-5.10-rc6.aufs/fs/aufs/sysaufs.c ---- linux-5.10-rc6/fs/aufs/sysaufs.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/sysaufs.c 2020-12-02 21:19:51.883036833 +0200 -@@ -0,0 +1,80 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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, -+}; -+ -+static const struct sysfs_ops au_sbi_ops = { -+ .show = sysaufs_si_show -+}; -+ -+static struct kobj_type au_sbi_ktype = { -+ .release = au_si_free, -+ .sysfs_ops = &au_sbi_ops, -+ .default_attrs = sysaufs_si_attrs -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+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 -Nurp linux-5.10-rc6/fs/aufs/sysaufs.h linux-5.10-rc6.aufs/fs/aufs/sysaufs.h ---- linux-5.10-rc6/fs/aufs/sysaufs.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/sysaufs.h 2020-12-02 21:19:51.883036833 +0200 -@@ -0,0 +1,89 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.10-rc6/fs/aufs/sysfs.c linux-5.10-rc6.aufs/fs/aufs/sysfs.c ---- linux-5.10-rc6/fs/aufs/sysfs.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/sysfs.c 2020-12-02 21:19:51.883036833 +0200 -@@ -0,0 +1,338 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * sysfs interface -+ */ -+ -+#include -+#include -+#include "aufs.h" -+ -+static struct attribute *au_attr[] = { -+ 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 -Nurp linux-5.10-rc6/fs/aufs/sysrq.c linux-5.10-rc6.aufs/fs/aufs/sysrq.c ---- linux-5.10-rc6/fs/aufs/sysrq.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/sysrq.c 2020-12-02 21:19:51.883036833 +0200 -@@ -0,0 +1,136 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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(int 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 -Nurp linux-5.10-rc6/fs/aufs/wbr_policy.c linux-5.10-rc6.aufs/fs/aufs/wbr_policy.c ---- linux-5.10-rc6/fs/aufs/wbr_policy.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/wbr_policy.c 2020-12-02 21:19:51.884036878 +0200 -@@ -0,0 +1,817 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.10-rc6/fs/aufs/vdir.c linux-5.10-rc6.aufs/fs/aufs/vdir.c ---- linux-5.10-rc6/fs/aufs/vdir.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/vdir.c 2020-12-02 21:19:51.884036878 +0200 -@@ -0,0 +1,883 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 int 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 -Nurp linux-5.10-rc6/fs/aufs/vfsub.c linux-5.10-rc6.aufs/fs/aufs/vfsub.c ---- linux-5.10-rc6/fs/aufs/vfsub.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/vfsub.c 2020-12-02 21:19:51.884036878 +0200 -@@ -0,0 +1,882 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * sub-routines for VFS -+ */ -+ -+#include -+#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 wait) -+{ -+ int err; -+ -+ lockdep_off(); -+ down_read(&h_sb->s_umount); -+ err = __sync_filesystem(h_sb, wait); -+ up_read(&h_sb->s_umount); -+ lockdep_on(); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int vfsub_update_h_iattr(struct path *h_path, int *did) -+{ -+ int err; -+ struct kstat st; -+ struct super_block *h_sb; -+ -+ /* 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 dentry *parent, int len) -+{ -+ struct path path = { -+ .mnt = NULL -+ }; -+ -+ path.dentry = lookup_one_len_unlocked(name, parent, len); -+ if (IS_ERR(path.dentry)) -+ goto out; -+ if (d_is_positive(path.dentry)) -+ 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 dentry *parent, -+ int len) -+{ -+ struct path path = { -+ .mnt = NULL -+ }; -+ -+ /* VFS checks it too, but by WARN_ON_ONCE() */ -+ IMustLock(d_inode(parent)); -+ -+ path.dentry = lookup_one_len(name, parent, len); -+ if (IS_ERR(path.dentry)) -+ goto out; -+ if (d_is_positive(path.dentry)) -+ 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->parent); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+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; -+ -+ 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; -+ -+ lockdep_off(); -+ err = vfs_create(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; -+ -+ 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; -+ -+ lockdep_off(); -+ err = vfs_symlink(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; -+ -+ 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; -+ -+ lockdep_off(); -+ err = vfs_mknod(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) -+ || inode->i_nlink < 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; -+ -+ 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; -+ -+ lockdep_off(); -+ err = vfs_link(src_dentry, 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 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; -+ -+ lockdep_off(); -+ err = vfs_rename(src_dir, src_dentry, dir, path->dentry, -+ delegated_inode, flags); -+ 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; -+ -+ 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; -+ -+ lockdep_off(); -+ err = vfs_mkdir(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; -+ -+ IMustLock(dir); -+ -+ d = path->dentry; -+ path->dentry = d->d_parent; -+ err = security_path_rmdir(path, d); -+ path->dentry = d; -+ if (unlikely(err)) -+ goto out; -+ -+ lockdep_off(); -+ err = vfs_rmdir(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; -+} -+ -+/* todo: kernel_read()? */ -+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count, -+ loff_t *ppos) -+{ -+ ssize_t err; -+ mm_segment_t oldfs; -+ union { -+ void *k; -+ char __user *u; -+ } buf; -+ -+ buf.k = kbuf; -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); -+ err = vfsub_read_u(file, buf.u, count, ppos); -+ set_fs(oldfs); -+ 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; -+ mm_segment_t oldfs; -+ union { -+ void *k; -+ const char __user *u; -+ } buf; -+ -+ buf.k = kbuf; -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); -+ err = vfsub_write_u(file, buf.u, count, ppos); -+ set_fs(oldfs); -+ 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_to(struct file *in, loff_t *ppos, -+ struct pipe_inode_info *pipe, size_t len, -+ unsigned int flags) -+{ -+ long err; -+ -+ lockdep_off(); -+ err = do_splice_to(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; -+ -+ 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 = locks_verify_truncate(h_inode, h_file, length); -+ if (!err) -+ err = security_path_truncate(h_path); -+ if (!err) { -+ lockdep_off(); -+ err = do_truncate(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; -+ -+ do_sio = au_test_h_perm_sio(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; -+ -+ do_sio = au_test_h_perm_sio(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; -+ -+ h_inode = d_inode(a->path->dentry); -+ IMustLock(h_inode); -+ -+ *a->errp = -EPERM; -+ if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) { -+ lockdep_off(); -+ *a->errp = notify_change(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; -+ 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); -+ } -+ -+ lockdep_off(); -+ *a->errp = vfs_unlink(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 -Nurp linux-5.10-rc6/fs/aufs/vfsub.h linux-5.10-rc6.aufs/fs/aufs/vfsub.h ---- linux-5.10-rc6/fs/aufs/vfsub.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/vfsub.h 2020-12-02 21:19:51.884036878 +0200 -@@ -0,0 +1,341 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * sub-routines for VFS -+ */ -+ -+#ifndef __AUFS_VFSUB_H__ -+#define __AUFS_VFSUB_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+#include -+#include -+#include "debug.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)) -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline void vfsub_drop_nlink(struct inode *inode) -+{ -+ AuDebugOn(!inode->i_nlink); -+ drop_nlink(inode); -+} -+ -+static inline void vfsub_dead_dir(struct inode *inode) -+{ -+ AuDebugOn(!S_ISDIR(inode->i_mode)); -+ inode->i_flags |= S_DEAD; -+ 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 wait); -+ -+/* ---------------------------------------------------------------------- */ -+ -+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 dentry *parent, int len); -+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent, -+ int len); -+ -+struct vfsub_lkup_one_args { -+ struct dentry **errp; -+ struct qstr *name; -+ struct dentry *parent; -+}; -+ -+static inline struct dentry *vfsub_lkup_one(struct qstr *name, -+ struct dentry *parent) -+{ -+ return vfsub_lookup_one_len(name->name, parent, 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 -+ -+/* ---------------------------------------------------------------------- */ -+ -+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, -+ struct timespec64 *ts, int flags) -+{ -+ return update_time(h_inode, ts, 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 inode *h_inode, umode_t h_mode) -+{ -+ int err; -+ -+ err = posix_acl_chmod(h_inode, h_mode); -+ if (err == -EOPNOTSUPP) -+ err = 0; -+ return err; -+} -+#else -+AuStubInt0(vfsub_acl_chmod, struct inode *h_inode, umode_t h_mode); -+#endif -+ -+long vfsub_splice_to(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 dentry *dentry, const char *name, -+ const void *value, size_t size, int flags) -+{ -+ int err; -+ -+ lockdep_off(); -+ err = vfs_setxattr(dentry, name, value, size, flags); -+ lockdep_on(); -+ -+ return err; -+} -+ -+static inline int vfsub_removexattr(struct dentry *dentry, const char *name) -+{ -+ int err; -+ -+ lockdep_off(); -+ err = vfs_removexattr(dentry, name); -+ lockdep_on(); -+ -+ return err; -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_VFSUB_H__ */ -diff -Nurp linux-5.10-rc6/fs/aufs/whout.c linux-5.10-rc6.aufs/fs/aufs/whout.c ---- linux-5.10-rc6/fs/aufs/whout.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/whout.c 2020-12-02 21:19:51.884036878 +0200 -@@ -0,0 +1,1049 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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_parent. -+ * @try_sio specifies the necessary of super-io. -+ */ -+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio) -+{ -+ int err; -+ struct dentry *wh_dentry; -+ -+ if (!try_sio) -+ wh_dentry = vfsub_lkup_one(wh_name, h_parent); -+ else -+ wh_dentry = au_sio_lkup_one(wh_name, h_parent); -+ 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_dentry sets opaque or not. -+ */ -+int au_diropq_test(struct dentry *h_dentry) -+{ -+ int err; -+ struct inode *h_dir; -+ -+ h_dir = d_inode(h_dentry); -+ err = au_wh_test(h_dentry, &diropq_name, -+ au_test_h_perm_sio(h_dir, MAY_EXEC)); -+ return err; -+} -+ -+/* -+ * 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; -+ -+ 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); -+ -+ qs.name = name; -+ for (i = 0; i < 3; i++) { -+ sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++); -+ dentry = au_sio_lkup_one(&qs, h_parent); -+ if (IS_ERR(dentry) || 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 dentry *h_parent, struct qstr *wh, -+ struct au_branch *br) -+{ -+ int err; -+ struct path h_path = { -+ .mnt = au_br_mnt(br) -+ }; -+ -+ err = 0; -+ h_path.dentry = vfsub_lkup_one(wh, h_parent); -+ if (IS_ERR(h_path.dentry)) -+ err = PTR_ERR(h_path.dentry); -+ else { -+ if (d_is_reg(h_path.dentry)) -+ err = do_unlink_wh(d_inode(h_parent), &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, *h_dentry; -+ struct super_block *sb; -+ struct au_branch *br; -+ int err; -+ -+ sb = dentry->d_sb; -+ br = au_sbr(sb, bindex); -+ h_dentry = au_h_dptr(dentry, bindex); -+ opq_dentry = vfsub_lkup_one(&diropq_name, h_dentry); -+ 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 { -+ struct path tmp = { -+ .dentry = opq_dentry, -+ .mnt = au_br_mnt(br) -+ }; -+ err = do_unlink_wh(au_h_iptr(d_inode(dentry), bindex), &tmp); -+ 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; -+ -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (!au_test_h_perm_sio(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; -+ -+ err = au_wh_name_alloc(&wh_name, base_name); -+ wh_dentry = ERR_PTR(err); -+ if (!err) { -+ wh_dentry = vfsub_lkup_one(&wh_name, h_parent); -+ 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 dentry *h_dentry, struct au_nhash *whlist, -+ aufs_bindex_t bindex, struct au_branch *br) -+{ -+ 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_dentry, &wh_name, br); -+ 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 dentry *h_dentry; -+ struct au_nhash *whlist; -+ aufs_bindex_t bindex; -+ struct au_branch *br; -+}; -+ -+static void call_del_wh_children(void *args) -+{ -+ struct del_wh_children_args *a = args; -+ *a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->br); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+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 h_tmp; -+ struct inode *wh_inode, *h_dir; -+ struct au_branch *br; -+ -+ h_dir = d_inode(wh_dentry->d_parent); /* dir inode is locked */ -+ IMustLock(h_dir); -+ -+ br = au_sbr(dir->i_sb, bindex); -+ 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(wh_inode, MAY_EXEC | MAY_WRITE)) -+ err = del_wh_children(wh_dentry, whlist, bindex, br); -+ else { -+ int wkq_err; -+ struct del_wh_children_args args = { -+ .errp = &err, -+ .h_dentry = wh_dentry, -+ .whlist = whlist, -+ .bindex = bindex, -+ .br = br -+ }; -+ -+ wkq_err = au_wkq_wait(call_del_wh_children, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } -+ inode_unlock(wh_inode); -+ -+ if (!err) { -+ h_tmp.dentry = wh_dentry; -+ h_tmp.mnt = au_br_mnt(br); -+ h_nlink = h_dir->i_nlink; -+ err = vfsub_rmdir(h_dir, &h_tmp); -+ /* some fs doesn't change the parent nlink in some cases */ -+ h_nlink -= h_dir->i_nlink; -+ } -+ -+ 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 -Nurp linux-5.10-rc6/fs/aufs/whout.h linux-5.10-rc6.aufs/fs/aufs/whout.h ---- linux-5.10-rc6/fs/aufs/whout.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/whout.h 2020-12-02 21:19:51.884036878 +0200 -@@ -0,0 +1,73 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 dentry *h_parent, struct qstr *wh_name, int try_sio); -+int au_diropq_test(struct dentry *h_dentry); -+struct au_branch; -+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br, -+ struct qstr *prefix); -+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br); -+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 -Nurp linux-5.10-rc6/fs/aufs/wkq.c linux-5.10-rc6.aufs/fs/aufs/wkq.c ---- linux-5.10-rc6/fs/aufs/wkq.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/wkq.c 2020-12-02 21:19:51.884036878 +0200 -@@ -0,0 +1,359 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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. -+ */ -+#define AuWkqCompDeclare(name) struct completion *comp = NULL -+ -+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; -+ AuWkqCompDeclare(comp); -+ 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 -Nurp linux-5.10-rc6/fs/aufs/wkq.h linux-5.10-rc6.aufs/fs/aufs/wkq.h ---- linux-5.10-rc6/fs/aufs/wkq.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/wkq.h 2020-12-02 21:19:51.884036878 +0200 -@@ -0,0 +1,76 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 -Nurp linux-5.10-rc6/fs/aufs/xattr.c linux-5.10-rc6.aufs/fs/aufs/xattr.c ---- linux-5.10-rc6/fs/aufs/xattr.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/xattr.c 2020-12-02 21:19:51.884036878 +0200 -@@ -0,0 +1,343 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2014-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * handling xattr functions -+ */ -+ -+#include -+#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 dentry *h_dst, struct dentry *h_src, -+ char *name, char **buf, unsigned int ignore_flags, -+ unsigned int verbose) -+{ -+ int err; -+ ssize_t ssz; -+ struct inode *h_idst; -+ -+ ssz = vfs_getxattr_alloc(h_src, name, buf, 0, GFP_NOFS); -+ err = ssz; -+ if (unlikely(err <= 0)) { -+ if (err == -ENODATA -+ || (err == -EOPNOTSUPP -+ && ((ignore_flags & au_xattr_out_of_list) -+ || (au_test_nfs_noacl(d_inode(h_src)) -+ && (!strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS) -+ || !strcmp(name, -+ XATTR_NAME_POSIX_ACL_DEFAULT)))) -+ )) -+ err = 0; -+ if (err && (verbose || au_debug_test())) -+ pr_err("%s, err %d\n", name, err); -+ goto out; -+ } -+ -+ /* unlock it temporary */ -+ h_idst = d_inode(h_dst); -+ inode_unlock(h_idst); -+ err = vfsub_setxattr(h_dst, 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 dentry *h_dst, struct dentry *h_src, int ignore_flags, -+ unsigned int verbose) -+{ -+ int err, unlocked, acl_access, acl_default; -+ ssize_t ssz; -+ 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_isrc = d_inode(h_src); -+ h_idst = d_inode(h_dst); -+ 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, 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, 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; -+ acl_access = 0; -+ acl_default = 0; -+ while (!err && p < e) { -+ acl_access |= !strncmp(p, XATTR_NAME_POSIX_ACL_ACCESS, -+ sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1); -+ acl_default |= !strncmp(p, XATTR_NAME_POSIX_ACL_DEFAULT, -+ sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) -+ - 1); -+ err = au_do_cpup_xattr(h_dst, h_src, p, &value, ignore_flags, -+ verbose); -+ p += strlen(p) + 1; -+ } -+ AuTraceErr(err); -+ ignore_flags |= au_xattr_out_of_list; -+ if (!err && !acl_access) { -+ err = au_do_cpup_xattr(h_dst, h_src, -+ XATTR_NAME_POSIX_ACL_ACCESS, &value, -+ ignore_flags, verbose); -+ AuTraceErr(err); -+ } -+ if (!err && !acl_default) { -+ err = au_do_cpup_xattr(h_dst, h_src, -+ XATTR_NAME_POSIX_ACL_DEFAULT, &value, -+ ignore_flags, verbose); -+ AuTraceErr(err); -+ } -+ -+ 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(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 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[] = { -+#ifdef CONFIG_FS_POSIX_ACL -+ &posix_acl_access_xattr_handler, -+ &posix_acl_default_xattr_handler, -+#endif -+ &au_xattr_handler, /* must be last */ -+ NULL -+}; -+ -+void au_xattr_init(struct super_block *sb) -+{ -+ sb->s_xattr = au_xattr_handlers; -+} -diff -Nurp linux-5.10-rc6/fs/aufs/xino.c linux-5.10-rc6.aufs/fs/aufs/xino.c ---- linux-5.10-rc6/fs/aufs/xino.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/fs/aufs/xino.c 2020-12-02 21:19:51.884036878 +0200 -@@ -0,0 +1,1953 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+/* -+ * 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 (inode->i_nlink) -+ 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 == 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, *parent; -+ struct inode *dir, *delegated; -+ struct qstr *name; -+ struct path path; -+ int err, do_unlock; -+ struct au_xino_lock_dir ldir; -+ -+ do_unlock = 1; -+ au_xino_lock_dir(sb, base, &ldir); -+ dentry = base->dentry; -+ parent = dentry->d_parent; /* dir inode is locked */ -+ dir = d_inode(parent); -+ IMustLock(dir); -+ -+ name = &dentry->d_name; -+ path.dentry = vfsub_lookup_one_len(name->name, parent, 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(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(vfs_writef_t 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(sbi->si_xwrite, 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(sbinfo->si_xread, 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(vfs_writef_t write, struct file *file, -+ struct au_xi_calc *calc, ino_t ino) -+{ -+ ssize_t sz; -+ -+ sz = xino_fwrite(write, 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(au_sbi(sb)->si_xwrite, 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(vfs_readf_t func, struct file *file, void *buf, -+ size_t size, loff_t *pos); -+ -+/* todo: unnecessary to support mmap_sem since kernel-space? */ -+ssize_t xino_fread(vfs_readf_t func, struct file *file, void *kbuf, size_t size, -+ loff_t *pos) -+{ -+ ssize_t err; -+ mm_segment_t oldfs; -+ union { -+ void *k; -+ char __user *u; -+ } buf; -+ int i; -+ const int prevent_endless = 10; -+ -+ i = 0; -+ buf.k = kbuf; -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); -+ do { -+ err = func(file, buf.u, size, pos); -+ if (err == -EINTR -+ && !au_wkq_test() -+ && fatal_signal_pending(current)) { -+ set_fs(oldfs); -+ err = xino_fread_wkq(func, file, kbuf, size, pos); -+ BUG_ON(err == -EINTR); -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); -+ } -+ } while (i++ < prevent_endless -+ && (err == -EAGAIN || err == -EINTR)); -+ set_fs(oldfs); -+ -+#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; -+ vfs_readf_t func; -+ 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->func, a->file, a->buf, a->size, a->pos); -+} -+ -+static ssize_t xino_fread_wkq(vfs_readf_t func, struct file *file, void *buf, -+ size_t size, loff_t *pos) -+{ -+ ssize_t err; -+ int wkq_err; -+ struct xino_fread_args args = { -+ .errp = &err, -+ .func = func, -+ .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(vfs_writef_t func, struct file *file, void *buf, -+ size_t size, loff_t *pos); -+ -+static ssize_t do_xino_fwrite(vfs_writef_t func, struct file *file, void *kbuf, -+ size_t size, loff_t *pos) -+{ -+ ssize_t err; -+ mm_segment_t oldfs; -+ union { -+ void *k; -+ const char __user *u; -+ } buf; -+ int i; -+ const int prevent_endless = 10; -+ -+ i = 0; -+ buf.k = kbuf; -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); -+ do { -+ err = func(file, buf.u, size, pos); -+ if (err == -EINTR -+ && !au_wkq_test() -+ && fatal_signal_pending(current)) { -+ set_fs(oldfs); -+ err = xino_fwrite_wkq(func, file, kbuf, size, pos); -+ BUG_ON(err == -EINTR); -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); -+ } -+ } while (i++ < prevent_endless -+ && (err == -EAGAIN || err == -EINTR)); -+ set_fs(oldfs); -+ -+#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; -+ vfs_writef_t func; -+ 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->func, a->file, a->buf, a->size, a->pos); -+} -+ -+static ssize_t xino_fwrite_wkq(vfs_writef_t func, 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, -+ .func = func, -+ .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(vfs_writef_t func, 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(func, file, buf, size, pos); -+ lockdep_on(); -+ } else { -+ lockdep_off(); -+ err = xino_fwrite_wkq(func, 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(sbinfo->si_xwrite, 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(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos); -+ else { -+ memset(p, 0, PAGE_SIZE); -+ sz = xino_fwrite(sbinfo->si_xwrite, 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(inode->i_nlink); -+ -+ 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; -+ vfs_readf_t func; -+ ino_t *ino; -+ unsigned long *p; -+ -+ err = 0; -+ sbinfo = au_sbi(sb); -+ MtxMustLock(&sbinfo->si_xib_mtx); -+ p = sbinfo->si_xib_buf; -+ func = sbinfo->si_xread; -+ pend = vfsub_f_size_read(file); -+ pos = 0; -+ while (pos < pend) { -+ sz = xino_fread(func, 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_xwrite, 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); -+ /* unnecessary to clear sbinfo->si_xread and ->si_xwrite */ -+ 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; -+ sbinfo->si_xread = vfs_readf(file); -+ sbinfo->si_xwrite = vfs_writef(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(sbinfo->si_xwrite, 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 { -+ vfs_writef_t writef; -+ 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(args->writef, 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); -+ args.writef = au_sbi(sb)->si_xwrite; -+ 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.writef = au_sbi(sb)->si_xwrite; -+ 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; -+ vfs_writef_t xwrite; -+ 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; -+ -+ xwrite = au_sbi(sb)->si_xwrite; -+ 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 && h_inode->i_nlink)) -+ 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(xwrite, 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 -Nurp linux-5.10-rc6/fs/dcache.c linux-5.10-rc6.aufs/fs/dcache.c ---- linux-5.10-rc6/fs/dcache.c 2020-10-12 00:15:50.000000000 +0300 -+++ linux-5.10-rc6.aufs/fs/dcache.c 2020-12-02 21:19:51.885036923 +0200 -@@ -1285,7 +1285,7 @@ enum d_walk_ret { - * - * The @enter() callbacks are called with d_lock held. - */ --static void d_walk(struct dentry *parent, void *data, -+void d_walk(struct dentry *parent, void *data, - enum d_walk_ret (*enter)(void *, struct dentry *)) - { - struct dentry *this_parent; -@@ -1390,6 +1390,7 @@ rename_retry: - seq = 1; - goto again; - } -+EXPORT_SYMBOL_GPL(d_walk); - - struct check_mount { - struct vfsmount *mnt; -@@ -2935,6 +2936,7 @@ void d_exchange(struct dentry *dentry1, - - write_sequnlock(&rename_lock); - } -+EXPORT_SYMBOL_GPL(d_exchange); - - /** - * d_ancestor - search for an ancestor -diff -Nurp linux-5.10-rc6/fs/exec.c linux-5.10-rc6.aufs/fs/exec.c ---- linux-5.10-rc6/fs/exec.c 2020-12-02 21:18:30.978421631 +0200 -+++ linux-5.10-rc6.aufs/fs/exec.c 2020-12-02 21:19:51.885036923 +0200 -@@ -113,6 +113,7 @@ bool path_noexec(const struct path *path - return (path->mnt->mnt_flags & MNT_NOEXEC) || - (path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC); - } -+EXPORT_SYMBOL_GPL(path_noexec); - - #ifdef CONFIG_USELIB - /* -diff -Nurp linux-5.10-rc6/fs/fcntl.c linux-5.10-rc6.aufs/fs/fcntl.c ---- linux-5.10-rc6/fs/fcntl.c 2020-10-12 00:15:50.000000000 +0300 -+++ linux-5.10-rc6.aufs/fs/fcntl.c 2020-12-02 21:19:51.885036923 +0200 -@@ -32,7 +32,7 @@ - - #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME) - --static int setfl(int fd, struct file * filp, unsigned long arg) -+int setfl(int fd, struct file *filp, unsigned long arg) - { - struct inode * inode = file_inode(filp); - int error = 0; -@@ -63,6 +63,8 @@ static int setfl(int fd, struct file * f - - if (filp->f_op->check_flags) - error = filp->f_op->check_flags(arg); -+ if (!error && filp->f_op->setfl) -+ error = filp->f_op->setfl(filp, arg); - if (error) - return error; - -@@ -83,6 +85,7 @@ static int setfl(int fd, struct file * f - out: - return error; - } -+EXPORT_SYMBOL_GPL(setfl); - - static void f_modown(struct file *filp, struct pid *pid, enum pid_type type, - int force) -diff -Nurp linux-5.10-rc6/fs/file_table.c linux-5.10-rc6.aufs/fs/file_table.c ---- linux-5.10-rc6/fs/file_table.c 2020-12-02 21:18:30.986421988 +0200 -+++ linux-5.10-rc6.aufs/fs/file_table.c 2020-12-02 21:19:51.885036923 +0200 -@@ -162,6 +162,7 @@ over: - } - return ERR_PTR(-ENFILE); - } -+EXPORT_SYMBOL_GPL(alloc_empty_file); - - /* - * Variant of alloc_empty_file() that doesn't check and modify nr_files. -@@ -376,6 +377,7 @@ void __fput_sync(struct file *file) - } - - EXPORT_SYMBOL(fput); -+EXPORT_SYMBOL_GPL(__fput_sync); - - void __init files_init(void) - { -diff -Nurp linux-5.10-rc6/fs/inode.c linux-5.10-rc6.aufs/fs/inode.c ---- linux-5.10-rc6/fs/inode.c 2020-12-02 21:18:30.990422167 +0200 -+++ linux-5.10-rc6.aufs/fs/inode.c 2020-12-02 21:19:51.885036923 +0200 -@@ -1770,12 +1770,13 @@ EXPORT_SYMBOL(generic_update_time); - * This does the actual work of updating an inodes time or version. Must have - * had called mnt_want_write() before calling this. - */ --static int update_time(struct inode *inode, struct timespec64 *time, int flags) -+int update_time(struct inode *inode, struct timespec64 *time, int flags) - { - if (inode->i_op->update_time) - return inode->i_op->update_time(inode, time, flags); - return generic_update_time(inode, time, flags); - } -+EXPORT_SYMBOL_GPL(update_time); - - /** - * touch_atime - update the access time -diff -Nurp linux-5.10-rc6/fs/Kconfig linux-5.10-rc6.aufs/fs/Kconfig ---- linux-5.10-rc6/fs/Kconfig 2020-10-12 00:15:50.000000000 +0300 -+++ linux-5.10-rc6.aufs/fs/Kconfig 2020-12-02 21:19:51.879036653 +0200 -@@ -288,6 +288,7 @@ source "fs/sysv/Kconfig" - source "fs/ufs/Kconfig" - source "fs/erofs/Kconfig" - source "fs/vboxsf/Kconfig" -+source "fs/aufs/Kconfig" - - endif # MISC_FILESYSTEMS - -diff -Nurp linux-5.10-rc6/fs/Makefile linux-5.10-rc6.aufs/fs/Makefile ---- linux-5.10-rc6/fs/Makefile 2020-12-02 21:18:30.963420960 +0200 -+++ linux-5.10-rc6.aufs/fs/Makefile 2020-12-02 21:19:51.879036653 +0200 -@@ -136,3 +136,4 @@ obj-$(CONFIG_EFIVAR_FS) += efivarfs/ - obj-$(CONFIG_EROFS_FS) += erofs/ - obj-$(CONFIG_VBOXSF_FS) += vboxsf/ - obj-$(CONFIG_ZONEFS_FS) += zonefs/ -+obj-$(CONFIG_AUFS_FS) += aufs/ -diff -Nurp linux-5.10-rc6/fs/namespace.c linux-5.10-rc6.aufs/fs/namespace.c ---- linux-5.10-rc6/fs/namespace.c 2020-12-02 21:18:30.993422301 +0200 -+++ linux-5.10-rc6.aufs/fs/namespace.c 2020-12-02 21:19:51.885036923 +0200 -@@ -431,6 +431,7 @@ void __mnt_drop_write(struct vfsmount *m - mnt_dec_writers(real_mount(mnt)); - preempt_enable(); - } -+EXPORT_SYMBOL_GPL(__mnt_drop_write); - - /** - * mnt_drop_write - give up write access to a mount -@@ -792,6 +793,13 @@ static inline int check_mnt(struct mount - return mnt->mnt_ns == current->nsproxy->mnt_ns; - } - -+/* for aufs, CONFIG_AUFS_BR_FUSE */ -+int is_current_mnt_ns(struct vfsmount *mnt) -+{ -+ return check_mnt(real_mount(mnt)); -+} -+EXPORT_SYMBOL_GPL(is_current_mnt_ns); -+ - /* - * vfsmount lock must be held for write - */ -@@ -1955,6 +1963,7 @@ int iterate_mounts(int (*f)(struct vfsmo - } - return 0; - } -+EXPORT_SYMBOL_GPL(iterate_mounts); - - static void lock_mnt_tree(struct mount *mnt) - { -diff -Nurp linux-5.10-rc6/fs/notify/group.c linux-5.10-rc6.aufs/fs/notify/group.c ---- linux-5.10-rc6/fs/notify/group.c 2020-10-12 00:15:50.000000000 +0300 -+++ linux-5.10-rc6.aufs/fs/notify/group.c 2020-12-02 21:19:51.885036923 +0200 -@@ -100,6 +100,7 @@ void fsnotify_get_group(struct fsnotify_ - { - refcount_inc(&group->refcnt); - } -+EXPORT_SYMBOL_GPL(fsnotify_get_group); - - /* - * Drop a reference to a group. Free it if it's through. -diff -Nurp linux-5.10-rc6/fs/open.c linux-5.10-rc6.aufs/fs/open.c ---- linux-5.10-rc6/fs/open.c 2020-10-12 00:15:50.000000000 +0300 -+++ linux-5.10-rc6.aufs/fs/open.c 2020-12-02 21:19:51.885036923 +0200 -@@ -65,6 +65,7 @@ int do_truncate(struct dentry *dentry, l - inode_unlock(dentry->d_inode); - return ret; - } -+EXPORT_SYMBOL_GPL(do_truncate); - - long vfs_truncate(const struct path *path, loff_t length) - { -diff -Nurp linux-5.10-rc6/fs/proc/base.c linux-5.10-rc6.aufs/fs/proc/base.c ---- linux-5.10-rc6/fs/proc/base.c 2020-12-02 21:18:31.000422613 +0200 -+++ linux-5.10-rc6.aufs/fs/proc/base.c 2020-12-02 21:19:51.885036923 +0200 -@@ -2184,7 +2184,7 @@ static int map_files_get_link(struct den - rc = -ENOENT; - vma = find_exact_vma(mm, vm_start, vm_end); - if (vma && vma->vm_file) { -- *path = vma->vm_file->f_path; -+ *path = vma_pr_or_file(vma)->f_path; - path_get(path); - rc = 0; - } -diff -Nurp linux-5.10-rc6/fs/proc/nommu.c linux-5.10-rc6.aufs/fs/proc/nommu.c ---- linux-5.10-rc6/fs/proc/nommu.c 2020-10-12 00:15:50.000000000 +0300 -+++ linux-5.10-rc6.aufs/fs/proc/nommu.c 2020-12-02 21:19:51.885036923 +0200 -@@ -40,7 +40,10 @@ static int nommu_region_show(struct seq_ - file = region->vm_file; - - if (file) { -- struct inode *inode = file_inode(region->vm_file); -+ struct inode *inode; -+ -+ file = vmr_pr_or_file(region); -+ inode = file_inode(file); - dev = inode->i_sb->s_dev; - ino = inode->i_ino; - } -diff -Nurp linux-5.10-rc6/fs/proc/task_mmu.c linux-5.10-rc6.aufs/fs/proc/task_mmu.c ---- linux-5.10-rc6/fs/proc/task_mmu.c 2020-12-02 21:18:31.000422613 +0200 -+++ linux-5.10-rc6.aufs/fs/proc/task_mmu.c 2020-12-02 21:19:51.885036923 +0200 -@@ -280,7 +280,10 @@ show_map_vma(struct seq_file *m, struct - const char *name = NULL; - - 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; -@@ -1851,7 +1854,7 @@ static int show_numa_map(struct seq_file - 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]; -diff -Nurp linux-5.10-rc6/fs/proc/task_nommu.c linux-5.10-rc6.aufs/fs/proc/task_nommu.c ---- linux-5.10-rc6/fs/proc/task_nommu.c 2020-10-12 00:15:50.000000000 +0300 -+++ linux-5.10-rc6.aufs/fs/proc/task_nommu.c 2020-12-02 21:19:51.885036923 +0200 -@@ -155,7 +155,10 @@ static int nommu_vma_show(struct seq_fil - file = vma->vm_file; - - 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; -diff -Nurp linux-5.10-rc6/fs/read_write.c linux-5.10-rc6.aufs/fs/read_write.c ---- linux-5.10-rc6/fs/read_write.c 2020-12-02 21:18:31.001422659 +0200 -+++ linux-5.10-rc6.aufs/fs/read_write.c 2020-12-02 21:19:51.886036968 +0200 -@@ -503,6 +503,7 @@ ssize_t vfs_read(struct file *file, char - inc_syscr(current); - return ret; - } -+EXPORT_SYMBOL_GPL(vfs_read); - - static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) - { -@@ -523,6 +524,30 @@ static ssize_t new_sync_write(struct fil - } - - /* caller is responsible for file_start_write/file_end_write */ -+vfs_readf_t vfs_readf(struct file *file) -+{ -+ const struct file_operations *fop = file->f_op; -+ -+ if (fop->read) -+ return fop->read; -+ if (fop->read_iter) -+ return new_sync_read; -+ return ERR_PTR(-ENOSYS); /* doesn't have ->read(|_iter)() op */ -+} -+EXPORT_SYMBOL_GPL(vfs_readf); -+ -+vfs_writef_t vfs_writef(struct file *file) -+{ -+ const struct file_operations *fop = file->f_op; -+ -+ if (fop->write) -+ return fop->write; -+ if (fop->write_iter) -+ return new_sync_write; -+ return ERR_PTR(-ENOSYS); /* doesn't have ->write(|_iter)() op */ -+} -+EXPORT_SYMBOL_GPL(vfs_writef); -+ - ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos) - { - struct kvec iov = { -@@ -613,6 +638,7 @@ ssize_t vfs_write(struct file *file, con - file_end_write(file); - return ret; - } -+EXPORT_SYMBOL_GPL(vfs_write); - - /* file_ppos returns &file->f_pos or NULL if file is stream */ - static inline loff_t *file_ppos(struct file *file) -diff -Nurp linux-5.10-rc6/fs/splice.c linux-5.10-rc6.aufs/fs/splice.c ---- linux-5.10-rc6/fs/splice.c 2020-12-02 21:18:31.002422703 +0200 -+++ linux-5.10-rc6.aufs/fs/splice.c 2020-12-02 21:19:51.886036968 +0200 -@@ -756,8 +756,8 @@ static int warn_unsupported(struct file - /* - * 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) - { - if (unlikely(!out->f_op->splice_write)) - return warn_unsupported(out, "write"); -@@ -767,9 +767,9 @@ static long do_splice_from(struct pipe_i - /* - * Attempt to initiate a splice from a file to a pipe. - */ --static long do_splice_to(struct file *in, loff_t *ppos, -- struct pipe_inode_info *pipe, size_t len, -- unsigned int flags) -+long do_splice_to(struct file *in, loff_t *ppos, -+ struct pipe_inode_info *pipe, size_t len, -+ unsigned int flags) - { - int ret; - -@@ -787,6 +787,7 @@ static long do_splice_to(struct file *in - return warn_unsupported(in, "read"); - return in->f_op->splice_read(in, ppos, pipe, len, flags); - } -+EXPORT_SYMBOL_GPL(do_splice_from); - - /** - * splice_direct_to_actor - splices data directly between two non-pipes -@@ -933,6 +934,7 @@ static int direct_splice_actor(struct pi - return do_splice_from(pipe, file, sd->opos, sd->total_len, - sd->flags); - } -+EXPORT_SYMBOL_GPL(do_splice_to); - - /** - * do_splice_direct - splices data directly between two files -diff -Nurp linux-5.10-rc6/fs/sync.c linux-5.10-rc6.aufs/fs/sync.c ---- linux-5.10-rc6/fs/sync.c 2020-10-12 00:15:50.000000000 +0300 -+++ linux-5.10-rc6.aufs/fs/sync.c 2020-12-02 21:19:51.886036968 +0200 -@@ -28,7 +28,7 @@ - * wait == 1 case since in that case write_inode() functions do - * sync_dirty_buffer() and thus effectively write one block at a time. - */ --static int __sync_filesystem(struct super_block *sb, int wait) -+int __sync_filesystem(struct super_block *sb, int wait) - { - if (wait) - sync_inodes_sb(sb); -@@ -39,6 +39,7 @@ static int __sync_filesystem(struct supe - sb->s_op->sync_fs(sb, wait); - return __sync_blockdev(sb->s_bdev, wait); - } -+EXPORT_SYMBOL_GPL(__sync_filesystem); - - /* - * Write out and wait upon all dirty data associated with this -diff -Nurp linux-5.10-rc6/fs/xattr.c linux-5.10-rc6.aufs/fs/xattr.c ---- linux-5.10-rc6/fs/xattr.c 2020-12-02 21:18:31.004422793 +0200 -+++ linux-5.10-rc6.aufs/fs/xattr.c 2020-12-02 21:19:51.886036968 +0200 -@@ -360,6 +360,7 @@ vfs_getxattr_alloc(struct dentry *dentry - *xattr_value = value; - return error; - } -+EXPORT_SYMBOL_GPL(vfs_getxattr_alloc); - - ssize_t - __vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name, -diff -Nurp linux-5.10-rc6/include/linux/fs.h linux-5.10-rc6.aufs/include/linux/fs.h ---- linux-5.10-rc6/include/linux/fs.h 2020-12-02 21:18:31.018423418 +0200 -+++ linux-5.10-rc6.aufs/include/linux/fs.h 2020-12-02 21:19:51.886036968 +0200 -@@ -1332,6 +1332,7 @@ extern void fasync_free(struct fasync_st - /* can be called from interrupts */ - extern void kill_fasync(struct fasync_struct **, int, int); - -+extern int setfl(int fd, struct file *filp, unsigned long arg); - extern void __f_setown(struct file *filp, struct pid *, enum pid_type, int force); - extern int f_setown(struct file *filp, unsigned long arg, int force); - extern void f_delown(struct file *filp); -@@ -1843,6 +1844,7 @@ struct file_operations { - ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); - unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); - int (*check_flags)(int); -+ int (*setfl)(struct file *, unsigned long); - int (*flock) (struct file *, int, struct file_lock *); - 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); -@@ -1908,6 +1910,12 @@ static inline int call_mmap(struct file - return file->f_op->mmap(file, vma); - } - -+typedef ssize_t (*vfs_readf_t)(struct file *, char __user *, size_t, loff_t *); -+typedef ssize_t (*vfs_writef_t)(struct file *, const char __user *, size_t, -+ loff_t *); -+vfs_readf_t vfs_readf(struct file *file); -+vfs_writef_t vfs_writef(struct file *file); -+ - extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *); - extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *); - extern ssize_t vfs_copy_file_range(struct file *, loff_t , struct file *, -@@ -2328,6 +2336,7 @@ extern int current_umask(void); - extern void ihold(struct inode * inode); - extern void iput(struct inode *); - extern int generic_update_time(struct inode *, struct timespec64 *, int); -+extern int update_time(struct inode *, struct timespec64 *, int); - - /* /sys/fs */ - extern struct kobject *fs_kobj; -@@ -2564,6 +2573,7 @@ static inline bool sb_is_blkdev_sb(struc - } - - void emergency_thaw_all(void); -+extern int __sync_filesystem(struct super_block *, int); - extern int sync_filesystem(struct super_block *); - extern const struct file_operations def_blk_fops; - extern const struct file_operations def_chr_fops; -diff -Nurp linux-5.10-rc6/include/linux/lockdep.h linux-5.10-rc6.aufs/include/linux/lockdep.h ---- linux-5.10-rc6/include/linux/lockdep.h 2020-12-02 21:18:31.021423552 +0200 -+++ linux-5.10-rc6.aufs/include/linux/lockdep.h 2020-12-02 21:19:51.886036968 +0200 -@@ -241,6 +241,8 @@ static inline int lockdep_match_key(stru - return lock->key == key; - } - -+struct lock_class *lockdep_hlock_class(struct held_lock *hlock); -+ - /* - * Acquire a lock. - * -@@ -375,6 +377,7 @@ static inline void lockdep_unregister_ke - - #define lockdep_depth(tsk) (0) - -+#define lockdep_is_held(lock) (1) - #define lockdep_is_held_type(l, r) (1) - - #define lockdep_assert_held(l) do { (void)(l); } while (0) -diff -Nurp linux-5.10-rc6/include/linux/mm.h linux-5.10-rc6.aufs/include/linux/mm.h ---- linux-5.10-rc6/include/linux/mm.h 2020-12-02 21:18:31.023423642 +0200 -+++ linux-5.10-rc6.aufs/include/linux/mm.h 2020-12-02 21:19:51.886036968 +0200 -@@ -1712,6 +1712,28 @@ static inline void unmap_shared_mapping_ - unmap_mapping_range(mapping, holebegin, holelen, 0); - } - -+extern void vma_do_file_update_time(struct vm_area_struct *, const char[], int); -+extern struct file *vma_do_pr_or_file(struct vm_area_struct *, const char[], -+ int); -+extern void vma_do_get_file(struct vm_area_struct *, const char[], int); -+extern void vma_do_fput(struct vm_area_struct *, const char[], int); -+ -+#define vma_file_update_time(vma) vma_do_file_update_time(vma, __func__, \ -+ __LINE__) -+#define vma_pr_or_file(vma) vma_do_pr_or_file(vma, __func__, \ -+ __LINE__) -+#define vma_get_file(vma) vma_do_get_file(vma, __func__, __LINE__) -+#define vma_fput(vma) vma_do_fput(vma, __func__, __LINE__) -+ -+#ifndef CONFIG_MMU -+extern struct file *vmr_do_pr_or_file(struct vm_region *, const char[], int); -+extern void vmr_do_fput(struct vm_region *, const char[], int); -+ -+#define vmr_pr_or_file(region) vmr_do_pr_or_file(region, __func__, \ -+ __LINE__) -+#define vmr_fput(region) vmr_do_fput(region, __func__, __LINE__) -+#endif /* !CONFIG_MMU */ -+ - extern int access_process_vm(struct task_struct *tsk, unsigned long addr, - void *buf, int len, unsigned int gup_flags); - extern int access_remote_vm(struct mm_struct *mm, unsigned long addr, -diff -Nurp linux-5.10-rc6/include/linux/mm_types.h linux-5.10-rc6.aufs/include/linux/mm_types.h ---- linux-5.10-rc6/include/linux/mm_types.h 2020-12-02 21:18:31.023423642 +0200 -+++ linux-5.10-rc6.aufs/include/linux/mm_types.h 2020-12-02 21:19:51.886036968 +0200 -@@ -280,6 +280,7 @@ struct vm_region { - unsigned long vm_top; /* region allocated to here */ - unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */ - struct file *vm_file; /* the backing file or NULL */ -+ struct file *vm_prfile; /* the virtual backing file or NULL */ - - int vm_usage; /* region usage count (access under nommu_region_sem) */ - bool vm_icache_flushed : 1; /* true if the icache has been flushed for -@@ -359,6 +360,7 @@ 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). */ -+ struct file *vm_prfile; /* shadow of vm_file */ - void * vm_private_data; /* was vm_pte (shared mem) */ - - #ifdef CONFIG_SWAP -diff -Nurp linux-5.10-rc6/include/linux/mnt_namespace.h linux-5.10-rc6.aufs/include/linux/mnt_namespace.h ---- linux-5.10-rc6/include/linux/mnt_namespace.h 2020-10-12 00:15:50.000000000 +0300 -+++ linux-5.10-rc6.aufs/include/linux/mnt_namespace.h 2020-12-02 21:19:51.886036968 +0200 -@@ -7,12 +7,15 @@ struct mnt_namespace; - struct fs_struct; - struct user_namespace; - struct ns_common; -+struct vfsmount; - - 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); - extern struct ns_common *from_mnt_ns(struct mnt_namespace *); - -+extern int is_current_mnt_ns(struct vfsmount *mnt); -+ - extern const struct file_operations proc_mounts_operations; - extern const struct file_operations proc_mountinfo_operations; - extern const struct file_operations proc_mountstats_operations; -diff -Nurp linux-5.10-rc6/include/linux/splice.h linux-5.10-rc6.aufs/include/linux/splice.h ---- linux-5.10-rc6/include/linux/splice.h 2020-12-02 21:18:31.030423955 +0200 -+++ linux-5.10-rc6.aufs/include/linux/splice.h 2020-12-02 21:19:51.886036968 +0200 -@@ -93,4 +93,10 @@ extern void splice_shrink_spd(struct spl - - 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 long do_splice_to(struct file *in, loff_t *ppos, -+ struct pipe_inode_info *pipe, size_t len, -+ unsigned int flags); - #endif -diff -Nurp linux-5.10-rc6/include/uapi/linux/aufs_type.h linux-5.10-rc6.aufs/include/uapi/linux/aufs_type.h ---- linux-5.10-rc6/include/uapi/linux/aufs_type.h 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/include/uapi/linux/aufs_type.h 2020-12-02 21:19:51.886036968 +0200 -@@ -0,0 +1,439 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -+/* -+ * Copyright (C) 2005-2020 Junjiro R. Okajima -+ */ -+ -+#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 "5.7" -+ -+/* 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 -Nurp linux-5.10-rc6/kernel/fork.c linux-5.10-rc6.aufs/kernel/fork.c ---- linux-5.10-rc6/kernel/fork.c 2020-12-02 21:18:31.051424893 +0200 -+++ linux-5.10-rc6.aufs/kernel/fork.c 2020-12-02 21:19:51.887037013 +0200 -@@ -554,7 +554,7 @@ static __latent_entropy int dup_mmap(str - struct inode *inode = file_inode(file); - struct address_space *mapping = file->f_mapping; - -- get_file(file); -+ vma_get_file(tmp); - if (tmp->vm_flags & VM_DENYWRITE) - put_write_access(inode); - i_mmap_lock_write(mapping); -diff -Nurp linux-5.10-rc6/kernel/locking/lockdep.c linux-5.10-rc6.aufs/kernel/locking/lockdep.c ---- linux-5.10-rc6/kernel/locking/lockdep.c 2020-12-02 21:18:31.053424982 +0200 -+++ linux-5.10-rc6.aufs/kernel/locking/lockdep.c 2020-12-02 21:19:51.887037013 +0200 -@@ -188,7 +188,7 @@ static - struct lock_class lock_classes[MAX_LOCKDEP_KEYS]; - static DECLARE_BITMAP(lock_classes_in_use, MAX_LOCKDEP_KEYS); - --static inline struct lock_class *hlock_class(struct held_lock *hlock) -+inline struct lock_class *lockdep_hlock_class(struct held_lock *hlock) - { - unsigned int class_idx = hlock->class_idx; - -@@ -209,6 +209,8 @@ static inline struct lock_class *hlock_c - */ - return lock_classes + class_idx; - } -+EXPORT_SYMBOL_GPL(lockdep_hlock_class); -+#define hlock_class(hlock) lockdep_hlock_class(hlock) - - #ifdef CONFIG_LOCK_STAT - static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], cpu_lock_stats); -diff -Nurp linux-5.10-rc6/kernel/task_work.c linux-5.10-rc6.aufs/kernel/task_work.c ---- linux-5.10-rc6/kernel/task_work.c 2020-12-02 21:18:31.060425295 +0200 -+++ linux-5.10-rc6.aufs/kernel/task_work.c 2020-12-02 21:19:51.887037013 +0200 -@@ -154,3 +154,4 @@ void task_work_run(void) - } while (work); - } - } -+EXPORT_SYMBOL_GPL(task_work_run); -diff -Nurp linux-5.10-rc6/MAINTAINERS linux-5.10-rc6.aufs/MAINTAINERS ---- linux-5.10-rc6/MAINTAINERS 2020-12-02 21:18:30.241388699 +0200 -+++ linux-5.10-rc6.aufs/MAINTAINERS 2020-12-02 21:19:51.879036653 +0200 -@@ -3001,6 +3001,19 @@ F: include/linux/audit.h - F: include/uapi/linux/audit.h - F: kernel/audit* - -+AUFS (advanced multi layered unification filesystem) FILESYSTEM -+M: "J. R. Okajima" -+L: aufs-users@lists.sourceforge.net (members only) -+L: linux-unionfs@vger.kernel.org -+W: http://aufs.sourceforge.net -+T: git://github.com/sfjro/aufs4-linux.git -+S: Supported -+F: Documentation/filesystems/aufs/ -+F: Documentation/ABI/testing/debugfs-aufs -+F: Documentation/ABI/testing/sysfs-aufs -+F: fs/aufs/ -+F: include/uapi/linux/aufs_type.h -+ - AUXILIARY DISPLAY DRIVERS - M: Miguel Ojeda Sandonis - S: Maintained -diff -Nurp linux-5.10-rc6/mm/filemap.c linux-5.10-rc6.aufs/mm/filemap.c ---- linux-5.10-rc6/mm/filemap.c 2020-12-02 21:18:31.071425787 +0200 -+++ linux-5.10-rc6.aufs/mm/filemap.c 2020-12-02 21:19:51.887037013 +0200 -@@ -2909,7 +2909,7 @@ vm_fault_t filemap_page_mkwrite(struct v - vm_fault_t ret = VM_FAULT_LOCKED; - - sb_start_pagefault(inode->i_sb); -- file_update_time(vmf->vma->vm_file); -+ vma_file_update_time(vmf->vma); - lock_page(page); - if (page->mapping != inode->i_mapping) { - unlock_page(page); -diff -Nurp linux-5.10-rc6/mm/Makefile linux-5.10-rc6.aufs/mm/Makefile ---- linux-5.10-rc6/mm/Makefile 2020-12-02 21:18:31.070425741 +0200 -+++ linux-5.10-rc6.aufs/mm/Makefile 2020-12-02 21:19:51.887037013 +0200 -@@ -52,7 +52,7 @@ obj-y := filemap.o mempool.o oom_kill. - mm_init.o percpu.o slab_common.o \ - compaction.o vmacache.o \ - interval_tree.o list_lru.o workingset.o \ -- debug.o gup.o $(mmu-y) -+ prfile.o debug.o gup.o $(mmu-y) - - # Give 'page_alloc' its own module-parameter namespace - page-alloc-y := page_alloc.o -diff -Nurp linux-5.10-rc6/mm/mmap.c linux-5.10-rc6.aufs/mm/mmap.c ---- linux-5.10-rc6/mm/mmap.c 2020-12-02 21:18:31.074425920 +0200 -+++ linux-5.10-rc6.aufs/mm/mmap.c 2020-12-02 21:19:51.887037013 +0200 -@@ -179,7 +179,7 @@ static struct vm_area_struct *remove_vma - if (vma->vm_ops && vma->vm_ops->close) - vma->vm_ops->close(vma); - if (vma->vm_file) -- fput(vma->vm_file); -+ vma_fput(vma); - mpol_put(vma_policy(vma)); - vm_area_free(vma); - return next; -@@ -951,7 +951,7 @@ again: - if (remove_next) { - if (file) { - uprobe_munmap(next, next->vm_start, next->vm_end); -- fput(file); -+ vma_fput(vma); - } - if (next->anon_vma) - anon_vma_merge(vma, next); -@@ -1899,8 +1899,8 @@ out: - return addr; - - unmap_and_free_vma: -+ vma_fput(vma); - vma->vm_file = NULL; -- fput(file); - - /* Undo any partial mapping done by a device driver. */ - unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end); -@@ -2759,7 +2759,7 @@ int __split_vma(struct mm_struct *mm, st - 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); -@@ -2778,7 +2778,7 @@ int __split_vma(struct mm_struct *mm, st - if (new->vm_ops && new->vm_ops->close) - new->vm_ops->close(new); - if (new->vm_file) -- fput(new->vm_file); -+ vma_fput(new); - unlink_anon_vmas(new); - out_free_mpol: - mpol_put(vma_policy(new)); -@@ -2971,7 +2971,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsign - struct vm_area_struct *vma; - unsigned long populate = 0; - unsigned long ret = -EINVAL; -- struct file *file; -+ struct file *file, *prfile; - - pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. See Documentation/vm/remap_file_pages.rst.\n", - current->comm, current->pid); -@@ -3046,10 +3046,27 @@ SYSCALL_DEFINE5(remap_file_pages, unsign - } - } - -- file = get_file(vma->vm_file); -+ vma_get_file(vma); -+ file = vma->vm_file; -+ prfile = vma->vm_prfile; - ret = do_mmap(vma->vm_file, start, size, - prot, flags, pgoff, &populate, NULL); -+ if (!IS_ERR_VALUE(ret) && file && prfile) { -+ struct vm_area_struct *new_vma; -+ -+ new_vma = find_vma(mm, ret); -+ if (!new_vma->vm_prfile) -+ new_vma->vm_prfile = prfile; -+ if (new_vma != vma) -+ get_file(prfile); -+ } -+ /* -+ * two fput()s instead of vma_fput(vma), -+ * coz vma may not be available anymore. -+ */ - fput(file); -+ if (prfile) -+ fput(prfile); - out: - mmap_write_unlock(mm); - if (populate) -@@ -3336,7 +3353,7 @@ struct vm_area_struct *copy_vma(struct v - 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); - vma_link(mm, new_vma, prev, rb_link, rb_parent); -diff -Nurp linux-5.10-rc6/mm/nommu.c linux-5.10-rc6.aufs/mm/nommu.c ---- linux-5.10-rc6/mm/nommu.c 2020-12-02 21:18:31.074425920 +0200 -+++ linux-5.10-rc6.aufs/mm/nommu.c 2020-12-02 21:19:51.888037058 +0200 -@@ -533,7 +533,7 @@ static void __put_nommu_region(struct vm - up_write(&nommu_region_sem); - - if (region->vm_file) -- fput(region->vm_file); -+ vmr_fput(region); - - /* IO memory and memory shared directly out of the pagecache - * from ramfs/tmpfs mustn't be released here */ -@@ -665,7 +665,7 @@ static void delete_vma(struct mm_struct - if (vma->vm_ops && vma->vm_ops->close) - vma->vm_ops->close(vma); - if (vma->vm_file) -- fput(vma->vm_file); -+ vma_fput(vma); - put_nommu_region(vma->vm_region); - vm_area_free(vma); - } -@@ -1188,7 +1188,7 @@ unsigned long do_mmap(struct file *file, - goto error_just_free; - } - } -- fput(region->vm_file); -+ vmr_fput(region); - kmem_cache_free(vm_region_jar, region); - region = pregion; - result = start; -@@ -1265,10 +1265,10 @@ error_just_free: - up_write(&nommu_region_sem); - error: - if (region->vm_file) -- fput(region->vm_file); -+ vmr_fput(region); - kmem_cache_free(vm_region_jar, region); - if (vma->vm_file) -- fput(vma->vm_file); -+ vma_fput(vma); - vm_area_free(vma); - return ret; - -diff -Nurp linux-5.10-rc6/mm/prfile.c linux-5.10-rc6.aufs/mm/prfile.c ---- linux-5.10-rc6/mm/prfile.c 1970-01-01 02:00:00.000000000 +0200 -+++ linux-5.10-rc6.aufs/mm/prfile.c 2020-12-02 21:19:51.888037058 +0200 -@@ -0,0 +1,86 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Mainly for aufs which mmap(2) different file and wants to print different -+ * path in /proc/PID/maps. -+ * Call these functions via macros defined in linux/mm.h. -+ * -+ * See Documentation/filesystems/aufs/design/06mmap.txt -+ * -+ * Copyright (c) 2014-2020 Junjro R. Okajima -+ * Copyright (c) 2014 Ian Campbell -+ */ -+ -+#include -+#include -+#include -+ -+/* #define PRFILE_TRACE */ -+static inline void prfile_trace(struct file *f, struct file *pr, -+ const char func[], int line, const char func2[]) -+{ -+#ifdef PRFILE_TRACE -+ if (pr) -+ pr_info("%s:%d: %s, %pD2\n", func, line, func2, f); -+#endif -+} -+ -+void vma_do_file_update_time(struct vm_area_struct *vma, const char func[], -+ int line) -+{ -+ struct file *f = vma->vm_file, *pr = vma->vm_prfile; -+ -+ prfile_trace(f, pr, func, line, __func__); -+ file_update_time(f); -+ if (f && pr) -+ file_update_time(pr); -+} -+ -+struct file *vma_do_pr_or_file(struct vm_area_struct *vma, const char func[], -+ int line) -+{ -+ struct file *f = vma->vm_file, *pr = vma->vm_prfile; -+ -+ prfile_trace(f, pr, func, line, __func__); -+ return (f && pr) ? pr : f; -+} -+ -+void vma_do_get_file(struct vm_area_struct *vma, const char func[], int line) -+{ -+ struct file *f = vma->vm_file, *pr = vma->vm_prfile; -+ -+ prfile_trace(f, pr, func, line, __func__); -+ get_file(f); -+ if (f && pr) -+ get_file(pr); -+} -+ -+void vma_do_fput(struct vm_area_struct *vma, const char func[], int line) -+{ -+ struct file *f = vma->vm_file, *pr = vma->vm_prfile; -+ -+ prfile_trace(f, pr, func, line, __func__); -+ fput(f); -+ if (f && pr) -+ fput(pr); -+} -+ -+#ifndef CONFIG_MMU -+struct file *vmr_do_pr_or_file(struct vm_region *region, const char func[], -+ int line) -+{ -+ struct file *f = region->vm_file, *pr = region->vm_prfile; -+ -+ prfile_trace(f, pr, func, line, __func__); -+ return (f && pr) ? pr : f; -+} -+ -+void vmr_do_fput(struct vm_region *region, const char func[], int line) -+{ -+ struct file *f = region->vm_file, *pr = region->vm_prfile; -+ -+ prfile_trace(f, pr, func, line, __func__); -+ fput(f); -+ if (f && pr) -+ fput(pr); -+} -+#endif /* !CONFIG_MMU */ -diff -Nurp linux-5.10-rc6/security/security.c linux-5.10-rc6.aufs/security/security.c ---- linux-5.10-rc6/security/security.c 2020-12-02 21:18:31.125428199 +0200 -+++ linux-5.10-rc6.aufs/security/security.c 2020-12-02 21:19:51.888037058 +0200 -@@ -1093,6 +1093,7 @@ int security_path_rmdir(const struct pat - return 0; - return call_int_hook(path_rmdir, 0, dir, dentry); - } -+EXPORT_SYMBOL_GPL(security_path_rmdir); - - int security_path_unlink(const struct path *dir, struct dentry *dentry) - { -@@ -1109,6 +1110,7 @@ int security_path_symlink(const struct p - return 0; - return call_int_hook(path_symlink, 0, dir, dentry, old_name); - } -+EXPORT_SYMBOL_GPL(security_path_symlink); - - int security_path_link(struct dentry *old_dentry, const struct path *new_dir, - struct dentry *new_dentry) -@@ -1117,6 +1119,7 @@ int security_path_link(struct dentry *ol - return 0; - return call_int_hook(path_link, 0, old_dentry, new_dir, new_dentry); - } -+EXPORT_SYMBOL_GPL(security_path_link); - - int security_path_rename(const struct path *old_dir, struct dentry *old_dentry, - const struct path *new_dir, struct dentry *new_dentry, -@@ -1144,6 +1147,7 @@ int security_path_truncate(const struct - return 0; - return call_int_hook(path_truncate, 0, path); - } -+EXPORT_SYMBOL_GPL(security_path_truncate); - - int security_path_chmod(const struct path *path, umode_t mode) - { -@@ -1151,6 +1155,7 @@ int security_path_chmod(const struct pat - return 0; - return call_int_hook(path_chmod, 0, path, mode); - } -+EXPORT_SYMBOL_GPL(security_path_chmod); - - int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid) - { -@@ -1158,6 +1163,7 @@ int security_path_chown(const struct pat - return 0; - return call_int_hook(path_chown, 0, path, uid, gid); - } -+EXPORT_SYMBOL_GPL(security_path_chown); - - int security_path_chroot(const struct path *path) - { -@@ -1258,6 +1264,7 @@ int security_inode_permission(struct ino - return 0; - return call_int_hook(inode_permission, 0, inode, mask); - } -+EXPORT_SYMBOL_GPL(security_inode_permission); - - int security_inode_setattr(struct dentry *dentry, struct iattr *attr) - { -@@ -1450,6 +1457,7 @@ int security_file_permission(struct file - - return fsnotify_perm(file, mask); - } -+EXPORT_SYMBOL_GPL(security_file_permission); - - int security_file_alloc(struct file *file) - { diff --git a/kernel/tools/perf/pspec.xml b/kernel/tools/perf/pspec.xml index d734b45ff3..cc8f8d5d6f 100644 --- a/kernel/tools/perf/pspec.xml +++ b/kernel/tools/perf/pspec.xml @@ -42,10 +42,13 @@ - patches/linux/patch-5.10.3.xz + patches/linux/patch-5.10.19.xz - patches/mageia/fs-aufs5.patch + patches/mageia/fs-aufs5.10.patch + patches/mageia/fs-aufs5.10-symbol-exports.patch + patches/mageia/fs-aufs5.10-tristate.patch patches/mageia/CVE-2019-12379.patch + patches/mageia/CVE-2020-16119-DCCP-CCID-structure-use-after-free.patch patches/mageia/3rd-3rdparty-tree.patch patches/mageia/3rd-3rdparty-merge.patch @@ -77,6 +80,7 @@ patches/mageia/3rd-rtl8821ce.patch patches/mageia/3rd-rtl8821ce-Kconfig-Makefile.patch patches/mageia/3rd-rtl8821ce-5.8-fix.patch + patches/mageia/3rd-rtl8821ce-kernel-5.10.patch patches/mageia/3rd-fix-kconfig.patch @@ -112,7 +116,14 @@ - + + 2020-12-27 + 5.10.19 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + + 2020-12-27 5.10.3 Version bump.

    ^)!|TjuJH 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%0AbY{6$Gmku{&K7#Gvh% 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%0DAF9HI4M#8kR%=?rsFOBV^l=8A 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ˊ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