linux-unionfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: Kernel warnings in fs/inode.c:302 drop_nlink+0x28/0x40
       [not found] <CAFkON1U3cXdXFQYdkoQ3OQU+14GX7C88U6qre58vyfhrrFgKXw@mail.gmail.com>
@ 2020-03-23 12:52 ` Miklos Szeredi
  2020-03-23 13:23   ` Amir Goldstein
  2020-03-23 14:27 ` Miklos Szeredi
  1 sibling, 1 reply; 8+ messages in thread
From: Miklos Szeredi @ 2020-03-23 12:52 UTC (permalink / raw)
  To: Phasip; +Cc: overlayfs

[-- Attachment #1: Type: text/plain, Size: 1025 bytes --]

On Mon, Mar 23, 2020 at 9:50 AM Phasip <phasip@gmail.com> wrote:
>
> Hello!
>
> I have stumbled upon two ways of producing kernel warnings when using the overlayfs, both seem to be results of the same issue.
>
> The issue seems to be related to handling of hard links that are created directly in the upperdir.
> Below is my system details and then two samples with a list of commands to reproduce and the corresponding kernel warning

Hi,

Thanks for the report.

The problem is that i_nlink is not kept in sync with changes to
underlying layers.   That would not in itself be an issue, since
modification of the underlying layers may result in
undefined/unexpected behavior.  The problem is that this manifests
itself as a kernel warning.

Since unlink/rename is synchronized on the victim inode (the one that
is getting removed) it is possible to detect this condition and
prevent drop_nlink() from being called.

Attached patch fixes both of your testcases.

We'll need an xfstests case for this as well.

Thanks,
Miklos

[-- Attachment #2: ovl-prevent-negative-nlink.patch --]
[-- Type: text/x-patch, Size: 1162 bytes --]

---
 fs/overlayfs/dir.c |   18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

--- a/fs/overlayfs/dir.c
+++ b/fs/overlayfs/dir.c
@@ -819,6 +819,20 @@ static bool ovl_pure_upper(struct dentry
 	       !ovl_test_flag(OVL_WHITEOUTS, d_inode(dentry));
 }
 
+static void ovl_drop_nlink(struct inode *inode)
+{
+	struct dentry *alias = d_find_alias(inode);
+
+	dput(alias);
+	/*
+	 * Changes to underlying layers may cause i_nlink to lose sync with
+	 * reality.  In this case prevent the link count from going to zero
+	 * prematurely.
+	 */
+	if (inode->i_nlink > !!alias)
+		drop_nlink(inode);
+}
+
 static int ovl_do_remove(struct dentry *dentry, bool is_dir)
 {
 	int err;
@@ -856,7 +870,7 @@ static int ovl_do_remove(struct dentry *
 		if (is_dir)
 			clear_nlink(dentry->d_inode);
 		else
-			drop_nlink(dentry->d_inode);
+			ovl_drop_nlink(dentry->d_inode);
 	}
 	ovl_nlink_end(dentry);
 
@@ -1201,7 +1215,7 @@ static int ovl_rename(struct inode *oldd
 		if (new_is_dir)
 			clear_nlink(d_inode(new));
 		else
-			drop_nlink(d_inode(new));
+			ovl_drop_nlink(d_inode(new));
 	}
 
 	ovl_dir_modified(old->d_parent, ovl_type_origin(old) ||

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Kernel warnings in fs/inode.c:302 drop_nlink+0x28/0x40
  2020-03-23 12:52 ` Kernel warnings in fs/inode.c:302 drop_nlink+0x28/0x40 Miklos Szeredi
@ 2020-03-23 13:23   ` Amir Goldstein
  2020-03-23 14:21     ` Miklos Szeredi
  0 siblings, 1 reply; 8+ messages in thread
From: Amir Goldstein @ 2020-03-23 13:23 UTC (permalink / raw)
  To: Miklos Szeredi; +Cc: Phasip, overlayfs

On Mon, Mar 23, 2020 at 2:53 PM Miklos Szeredi <miklos@szeredi.hu> wrote:
>
> On Mon, Mar 23, 2020 at 9:50 AM Phasip <phasip@gmail.com> wrote:
> >
> > Hello!
> >
> > I have stumbled upon two ways of producing kernel warnings when using the overlayfs, both seem to be results of the same issue.
> >
> > The issue seems to be related to handling of hard links that are created directly in the upperdir.
> > Below is my system details and then two samples with a list of commands to reproduce and the corresponding kernel warning
>
> Hi,
>
> Thanks for the report.
>
> The problem is that i_nlink is not kept in sync with changes to
> underlying layers.   That would not in itself be an issue, since
> modification of the underlying layers may result in
> undefined/unexpected behavior.  The problem is that this manifests
> itself as a kernel warning.
>
> Since unlink/rename is synchronized on the victim inode (the one that
> is getting removed) it is possible to detect this condition and
> prevent drop_nlink() from being called.
>
> Attached patch fixes both of your testcases.

IDGI. coming from vfs_unlink() and vfs_rename() it doesn't look like
it is possible for victim inode not to have a hashed alias, so the
alias test seems futile.

We better replace the WARN_ON() with pr_warn_ratelimited().

>
> We'll need an xfstests case for this as well.
>

Please forward the part of the email with the test case to the list.

Thanks,
Amir.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Kernel warnings in fs/inode.c:302 drop_nlink+0x28/0x40
  2020-03-23 13:23   ` Amir Goldstein
@ 2020-03-23 14:21     ` Miklos Szeredi
  2020-03-23 14:53       ` Miklos Szeredi
  0 siblings, 1 reply; 8+ messages in thread
From: Miklos Szeredi @ 2020-03-23 14:21 UTC (permalink / raw)
  To: Amir Goldstein; +Cc: Phasip, overlayfs

On Mon, Mar 23, 2020 at 2:24 PM Amir Goldstein <amir73il@gmail.com> wrote:
>
> On Mon, Mar 23, 2020 at 2:53 PM Miklos Szeredi <miklos@szeredi.hu> wrote:
> >
> > On Mon, Mar 23, 2020 at 9:50 AM Phasip <phasip@gmail.com> wrote:
> > >
> > > Hello!
> > >
> > > I have stumbled upon two ways of producing kernel warnings when using the overlayfs, both seem to be results of the same issue.
> > >
> > > The issue seems to be related to handling of hard links that are created directly in the upperdir.
> > > Below is my system details and then two samples with a list of commands to reproduce and the corresponding kernel warning
> >
> > Hi,
> >
> > Thanks for the report.
> >
> > The problem is that i_nlink is not kept in sync with changes to
> > underlying layers.   That would not in itself be an issue, since
> > modification of the underlying layers may result in
> > undefined/unexpected behavior.  The problem is that this manifests
> > itself as a kernel warning.
> >
> > Since unlink/rename is synchronized on the victim inode (the one that
> > is getting removed) it is possible to detect this condition and
> > prevent drop_nlink() from being called.
> >
> > Attached patch fixes both of your testcases.
>
> IDGI. coming from vfs_unlink() and vfs_rename() it doesn't look like
> it is possible for victim inode not to have a hashed alias, so the
> alias test seems futile.

Yeah, needs a comment: both ovl_remove_upper() and
ovl_remove_and_whiteout() unhash the dentry before returning, so
d_find_alias() will find another hashed dentry or none.

> We better replace the WARN_ON() with pr_warn_ratelimited().
>
> >
> > We'll need an xfstests case for this as well.
> >
>
> Please forward the part of the email with the test case to the list.

Okay.

Thanks,
Miklos

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Kernel warnings in fs/inode.c:302 drop_nlink+0x28/0x40
       [not found] <CAFkON1U3cXdXFQYdkoQ3OQU+14GX7C88U6qre58vyfhrrFgKXw@mail.gmail.com>
  2020-03-23 12:52 ` Kernel warnings in fs/inode.c:302 drop_nlink+0x28/0x40 Miklos Szeredi
@ 2020-03-23 14:27 ` Miklos Szeredi
  1 sibling, 0 replies; 8+ messages in thread
From: Miklos Szeredi @ 2020-03-23 14:27 UTC (permalink / raw)
  To: fstests; +Cc: overlayfs, Phasip, Amir Goldstein

[forwarding test case to fstests@vger]

On Mon, Mar 23, 2020 at 9:50 AM Phasip <phasip@gmail.com> wrote:
>
> Hello!
>
> I have stumbled upon two ways of producing kernel warnings when using the overlayfs, both seem to be results of the same issue.
>
> The issue seems to be related to handling of hard links that are created directly in the upperdir.
> Below is my system details and then two samples with a list of commands to reproduce and the corresponding kernel warning
>
> System details
> -------------------
> My kernel version: Linux ubuntu 5.6.0-050600rc5-generic #202003082130 SMP Mon Mar 9 01:33:48 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
>
> # modinfo overlay
> filename:       /lib/modules/5.6.0-050600rc5-generic/kernel/fs/overlayfs/overlay.ko
> alias:          fs-overlay
> license:        GPL
> description:    Overlay filesystem
> author:         Miklos Szeredi <miklos@szeredi.hu>
> srcversion:     DF053786AE7737625051D8F
> depends:
> retpoline:      Y
> intree:         Y
> name:           overlay
> vermagic:       5.6.0-050600rc5-generic SMP mod_unload
> parm:           check_copy_up:Obsolete; does nothing
> parm:           redirect_max:Maximum length of absolute redirect xattr value (ushort)
> parm:           redirect_dir:Default to on or off for the redirect_dir feature (bool)
> parm:           redirect_always_follow:Follow redirects even if redirect_dir feature is turned off (bool)
> parm:           index:Default to on or off for the inodes index feature (bool)
> parm:           nfs_export:Default to on or off for the NFS export feature (bool)
> parm:           xino_auto:Auto enable xino feature (bool)
> parm:           metacopy:Default to on or off for the metadata only copy up feature (bool)
>
>
> Sample 1
> -------------
> mkdir work lower upper final
> sudo mount -t overlay -o workdir=work,lowerdir=lower,upperdir=upper,metacopy=on overlay final
> touch final/h
> ln upper/h upper/k
> rm -rf final/k
> rm -rf final/h
> dmesg
>
> [ 5771.305217] ------------[ cut here ]------------
> [ 5771.305227] WARNING: CPU: 1 PID: 116244 at fs/inode.c:302 drop_nlink+0x28/0x40
> [ 5771.305228] Modules linked in: overlay intel_rapl_msr intel_rapl_common crct10dif_pclmul crc32_pclmul ghash_clmulni_intel vmw_balloon aesni_intel crypto_simd cryptd glue_helper intel_rapl_perf joydev input_leds serio_raw i2c_piix4 mac_hid vsock_loopback vmw_vsock_virtio_transport_common vmw_vsock_vmci_transport vsock vmw_vmci parport_pc ppdev lp parport autofs4 vmw_pvscsi vmxnet3 hid_generic vmwgfx psmouse usbhid hid ttm drm_kms_helper ahci libahci e1000 mptspi syscopyarea mptscsih sysfillrect sysimgblt mptbase fb_sys_fops cec rc_core scsi_transport_spi drm pata_acpi [last unloaded: overlay]
> [ 5771.305255] CPU: 1 PID: 116244 Comm: rm Tainted: G        W         5.6.0-050600rc5-generic #202003082130
> [ 5771.305256] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 07/29/2019
> [ 5771.305258] RIP: 0010:drop_nlink+0x28/0x40
> [ 5771.305260] Code: 66 90 0f 1f 44 00 00 55 8b 47 48 48 89 e5 85 c0 74 18 8d 50 ff 89 57 48 85 d2 75 0c 48 8b 47 28 f0 48 ff 80 98 04 00 00 5d c3 <0f> 0b c7 47 48 ff ff ff ff 5d c3 66 66 2e 0f 1f 84 00 00 00 00 00
> [ 5771.305261] RSP: 0018:ffffb7c042bdbdd8 EFLAGS: 00010246
> [ 5771.305262] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000200000000
> [ 5771.305263] RDX: ffffa0ec6f512f80 RSI: 0000000100000000 RDI: ffffa0ec726a22a8
> [ 5771.305263] RBP: ffffb7c042bdbdd8 R08: 0000000000000002 R09: 0000000000000064
> [ 5771.305264] R10: ffffa0ec7271b300 R11: ffffa0eaf2158668 R12: ffffa0eaf400a480
> [ 5771.305264] R13: ffffb7c042bdbe08 R14: 0000000000000000 R15: 0000000000000000
> [ 5771.305266] FS:  00007f81856ac700(0000) GS:ffffa0ec75e40000(0000) knlGS:0000000000000000
> [ 5771.305266] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [ 5771.305267] CR2: 0000000001a2e000 CR3: 000000003466c004 CR4: 00000000003606e0
> [ 5771.305273] Call Trace:
> [ 5771.305283]  ovl_do_remove+0x348/0x4c0 [overlay]
> [ 5771.305287]  ovl_unlink+0x13/0x20 [overlay]
> [ 5771.305289]  vfs_unlink+0x114/0x200
> [ 5771.305290]  do_unlinkat+0x19a/0x2d0
> [ 5771.305292]  __x64_sys_unlinkat+0x38/0x60
> [ 5771.305318]  do_syscall_64+0x57/0x1b0
> [ 5771.305322]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
> [ 5771.305323] RIP: 0033:0x7f81851cfac7
> [ 5771.305325] Code: 73 01 c3 48 8b 0d d1 b3 2c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 b8 07 01 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d a1 b3 2c 00 f7 d8 64 89 01 48
> [ 5771.305325] RSP: 002b:00007ffdfc056c58 EFLAGS: 00000202 ORIG_RAX: 0000000000000107
> [ 5771.305327] RAX: ffffffffffffffda RBX: 0000000001a2f230 RCX: 00007f81851cfac7
> [ 5771.305327] RDX: 0000000000000000 RSI: 0000000001a2e000 RDI: 00000000ffffff9c
> [ 5771.305328] RBP: 0000000000000000 R08: 0000000000000003 R09: 0000000000000000
> [ 5771.305328] R10: 000000000000015e R11: 0000000000000202 R12: 0000000001a2df70
> [ 5771.305329] R13: 00007ffdfc056d80 R14: 0000000000000000 R15: 0000000000000000
> [ 5771.305331] ---[ end trace 67e413528020d510 ]---
>
>
> Sample 2
> -------------
> mkdir work lower upper final
> sudo mount -t overlay -o workdir=work,lowerdir=lower,upperdir=upper,metacopy=on overlay final
> touch final/h
> ln upper/h upper/k
> rm -rf final/k
> touch final/z
> mv final/z final/h
> dmesg
>
> [ 6633.944688] ------------[ cut here ]------------
> [ 6633.944700] WARNING: CPU: 0 PID: 47279 at fs/inode.c:302 drop_nlink+0x28/0x40
> [ 6633.944701] Modules linked in: overlay intel_rapl_msr intel_rapl_common crct10dif_pclmul crc32_pclmul ghash_clmulni_intel vmw_balloon aesni_intel crypto_simd cryptd glue_helper intel_rapl_perf joydev input_leds serio_raw i2c_piix4 mac_hid vsock_loopback vmw_vsock_virtio_transport_common vmw_vsock_vmci_transport vsock vmw_vmci parport_pc ppdev lp parport autofs4 vmw_pvscsi vmxnet3 hid_generic vmwgfx psmouse usbhid hid ttm drm_kms_helper ahci libahci e1000 mptspi syscopyarea mptscsih sysfillrect sysimgblt mptbase fb_sys_fops cec rc_core scsi_transport_spi drm pata_acpi [last unloaded: overlay]
> [ 6633.944732] CPU: 0 PID: 47279 Comm: mv Tainted: G        W         5.6.0-050600rc5-generic #202003082130
> [ 6633.944733] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 07/29/2019
> [ 6633.944735] RIP: 0010:drop_nlink+0x28/0x40
> [ 6633.944736] Code: 66 90 0f 1f 44 00 00 55 8b 47 48 48 89 e5 85 c0 74 18 8d 50 ff 89 57 48 85 d2 75 0c 48 8b 47 28 f0 48 ff 80 98 04 00 00 5d c3 <0f> 0b c7 47 48 ff ff ff ff 5d c3 66 66 2e 0f 1f 84 00 00 00 00 00
> [ 6633.944737] RSP: 0018:ffffb7c045163cc8 EFLAGS: 00010246
> [ 6633.944738] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000002
> [ 6633.944739] RDX: 0000000000000000 RSI: 0000000000000800 RDI: ffffa0ec726a0020
> [ 6633.944739] RBP: ffffb7c045163cc8 R08: 0000000000000000 R09: 0000000000000000
> [ 6633.944740] R10: ffffa0eaf22cb500 R11: ffffa0eb93e20540 R12: ffffa0eaf22cb080
> [ 6633.944740] R13: ffffa0eb93e21440 R14: ffffb7c045163d40 R15: 0000000000000000
> [ 6633.944741] FS:  00007f866894e800(0000) GS:ffffa0ec75e00000(0000) knlGS:0000000000000000
> [ 6633.944742] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [ 6633.944743] CR2: 0000000001ba9808 CR3: 00000000af75c005 CR4: 00000000003606f0
> [ 6633.944753] Call Trace:
> [ 6633.944767]  ovl_rename+0x92f/0x940 [overlay]
> [ 6633.944770]  vfs_rename+0x3df/0x9b0
> [ 6633.944775]  ? _cond_resched+0x19/0x30
> [ 6633.944779]  ? security_path_rename+0x88/0xb0
> [ 6633.944780]  do_renameat2+0x507/0x570
> [ 6633.944782]  __x64_sys_rename+0x23/0x30
> [ 6633.944786]  do_syscall_64+0x57/0x1b0
> [ 6633.944787]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
> [ 6633.944789] RIP: 0033:0x7f8667db9367
> [ 6633.944790] Code: 75 12 48 89 df e8 a9 d7 08 00 85 c0 0f 95 c0 0f b6 c0 f7 d8 5b c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 b8 52 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 01 8b 35 00 f7 d8 64 89 01 48
> [ 6633.944790] RSP: 002b:00007ffc331da4a8 EFLAGS: 00000202 ORIG_RAX: 0000000000000052
> [ 6633.944792] RAX: ffffffffffffffda RBX: 0000000000008000 RCX: 00007f8667db9367
> [ 6633.944792] RDX: 0000000000000000 RSI: 00007ffc331dc517 RDI: 00007ffc331dc50f
> [ 6633.944793] RBP: 00007ffc331da870 R08: 0000000000000000 R09: 0000000000000000
> [ 6633.944793] R10: 0000000000000640 R11: 0000000000000202 R12: 00007ffc331da601
> [ 6633.944794] R13: 00007ffc331da960 R14: 00007ffc331dc50f R15: 0000000000000000
> [ 6633.944795] ---[ end trace 67e413528020d64a ]---
>
>
> Best Wishes
> Pasi Saarinen
>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Kernel warnings in fs/inode.c:302 drop_nlink+0x28/0x40
  2020-03-23 14:21     ` Miklos Szeredi
@ 2020-03-23 14:53       ` Miklos Szeredi
  2020-03-23 17:27         ` Amir Goldstein
  0 siblings, 1 reply; 8+ messages in thread
From: Miklos Szeredi @ 2020-03-23 14:53 UTC (permalink / raw)
  To: Amir Goldstein; +Cc: Phasip, overlayfs

[-- Attachment #1: Type: text/plain, Size: 633 bytes --]

On Mon, Mar 23, 2020 at 3:21 PM Miklos Szeredi <miklos@szeredi.hu> wrote:
>
> On Mon, Mar 23, 2020 at 2:24 PM Amir Goldstein <amir73il@gmail.com> wrote:

> > IDGI. coming from vfs_unlink() and vfs_rename() it doesn't look like
> > it is possible for victim inode not to have a hashed alias, so the
> > alias test seems futile.
>
> Yeah, needs a comment: both ovl_remove_upper() and
> ovl_remove_and_whiteout() unhash the dentry before returning, so
> d_find_alias() will find another hashed dentry or none.

Except that doesn't seem to be true for the overwriting rename case...

Attached patch should work for both.

Thanks,
Miklos

[-- Attachment #2: ovl-prevent-negative-nlink-v2.patch --]
[-- Type: text/x-patch, Size: 1344 bytes --]

---
 fs/overlayfs/dir.c |   25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

--- a/fs/overlayfs/dir.c
+++ b/fs/overlayfs/dir.c
@@ -819,6 +819,27 @@ static bool ovl_pure_upper(struct dentry
 	       !ovl_test_flag(OVL_WHITEOUTS, d_inode(dentry));
 }
 
+static void ovl_drop_nlink(struct dentry *dentry)
+{
+	struct inode *inode = d_inode(dentry);
+	struct dentry *alias;
+
+	spin_lock(&inode->i_lock);
+	hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) {
+ 		if (alias != dentry && !d_unhashed(alias))
+			break;
+	}
+	spin_unlock(&inode->i_lock);
+
+	/*
+	 * Changes to underlying layers may cause i_nlink to lose sync with
+	 * reality.  In this case prevent the link count from going to zero
+	 * prematurely.
+	 */
+	if (inode->i_nlink > !!alias)
+		drop_nlink(inode);
+}
+
 static int ovl_do_remove(struct dentry *dentry, bool is_dir)
 {
 	int err;
@@ -856,7 +877,7 @@ static int ovl_do_remove(struct dentry *
 		if (is_dir)
 			clear_nlink(dentry->d_inode);
 		else
-			drop_nlink(dentry->d_inode);
+			ovl_drop_nlink(dentry);
 	}
 	ovl_nlink_end(dentry);
 
@@ -1201,7 +1222,7 @@ static int ovl_rename(struct inode *oldd
 		if (new_is_dir)
 			clear_nlink(d_inode(new));
 		else
-			drop_nlink(d_inode(new));
+			ovl_drop_nlink(new);
 	}
 
 	ovl_dir_modified(old->d_parent, ovl_type_origin(old) ||

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Kernel warnings in fs/inode.c:302 drop_nlink+0x28/0x40
  2020-03-23 14:53       ` Miklos Szeredi
@ 2020-03-23 17:27         ` Amir Goldstein
  2020-03-23 19:15           ` Amir Goldstein
  0 siblings, 1 reply; 8+ messages in thread
From: Amir Goldstein @ 2020-03-23 17:27 UTC (permalink / raw)
  To: Miklos Szeredi; +Cc: Phasip, overlayfs

On Mon, Mar 23, 2020 at 4:53 PM Miklos Szeredi <miklos@szeredi.hu> wrote:
>
> On Mon, Mar 23, 2020 at 3:21 PM Miklos Szeredi <miklos@szeredi.hu> wrote:
> >
> > On Mon, Mar 23, 2020 at 2:24 PM Amir Goldstein <amir73il@gmail.com> wrote:
>
> > > IDGI. coming from vfs_unlink() and vfs_rename() it doesn't look like
> > > it is possible for victim inode not to have a hashed alias, so the
> > > alias test seems futile.
> >
> > Yeah, needs a comment: both ovl_remove_upper() and
> > ovl_remove_and_whiteout() unhash the dentry before returning, so
> > d_find_alias() will find another hashed dentry or none.
>
> Except that doesn't seem to be true for the overwriting rename case...
>
> Attached patch should work for both.
>

It still looks quite hacky.
Why do we not look at upper->i_nlink in order to fix the situation?

For index=on, there is already code to handle lower hardlink skew case,
including pr_warn and several xfstests (overlay/034 for example).
The check is buried in ovl_nlink_end() => ovl_cleanup_index().
It's keeping overlay i_nlink above upper i_nlink.

In fact, if you change one line in overlay/034 it triggers the reported
bug, so we can just fork this test.

-lowerdir=$OVL_BASE_SCRATCH_MNT/$OVL_LOWER
+lowerdir=$OVL_BASE_SCRATCH_MNT/$OVL_UPPER
 workdir=$OVL_BASE_SCRATCH_MNT/$OVL_WORK

How about adding a check in ovl_nlink_start() to fix overlay i_nlink
below upper i_link?
It would be a valid check for both index=off and on.
I will try to write it up later.

Thanks,
Amir.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Kernel warnings in fs/inode.c:302 drop_nlink+0x28/0x40
  2020-03-23 17:27         ` Amir Goldstein
@ 2020-03-23 19:15           ` Amir Goldstein
  2020-03-24  6:27             ` Amir Goldstein
  0 siblings, 1 reply; 8+ messages in thread
From: Amir Goldstein @ 2020-03-23 19:15 UTC (permalink / raw)
  To: Miklos Szeredi; +Cc: Phasip, overlayfs

On Mon, Mar 23, 2020 at 7:27 PM Amir Goldstein <amir73il@gmail.com> wrote:
>
> On Mon, Mar 23, 2020 at 4:53 PM Miklos Szeredi <miklos@szeredi.hu> wrote:
> >
> > On Mon, Mar 23, 2020 at 3:21 PM Miklos Szeredi <miklos@szeredi.hu> wrote:
> > >
> > > On Mon, Mar 23, 2020 at 2:24 PM Amir Goldstein <amir73il@gmail.com> wrote:
> >
> > > > IDGI. coming from vfs_unlink() and vfs_rename() it doesn't look like
> > > > it is possible for victim inode not to have a hashed alias, so the
> > > > alias test seems futile.
> > >
> > > Yeah, needs a comment: both ovl_remove_upper() and
> > > ovl_remove_and_whiteout() unhash the dentry before returning, so
> > > d_find_alias() will find another hashed dentry or none.
> >
> > Except that doesn't seem to be true for the overwriting rename case...
> >
> > Attached patch should work for both.
> >
>
> It still looks quite hacky.
> Why do we not look at upper->i_nlink in order to fix the situation?
>
> For index=on, there is already code to handle lower hardlink skew case,
> including pr_warn and several xfstests (overlay/034 for example).
> The check is buried in ovl_nlink_end() => ovl_cleanup_index().
> It's keeping overlay i_nlink above upper i_nlink.
>
> In fact, if you change one line in overlay/034 it triggers the reported
> bug, so we can just fork this test.
>
> -lowerdir=$OVL_BASE_SCRATCH_MNT/$OVL_LOWER
> +lowerdir=$OVL_BASE_SCRATCH_MNT/$OVL_UPPER
>  workdir=$OVL_BASE_SCRATCH_MNT/$OVL_WORK
>
> How about adding a check in ovl_nlink_start() to fix overlay i_nlink
> below upper i_link?
> It would be a valid check for both index=off and on.
> I will try to write it up later.
>

https://lore.kernel.org/linux-unionfs/20200323190850.3091-1-amir73il@gmail.com/T/#u

Sorry, Phasip, forgot to CC you.

Thanks,
Amir.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Kernel warnings in fs/inode.c:302 drop_nlink+0x28/0x40
  2020-03-23 19:15           ` Amir Goldstein
@ 2020-03-24  6:27             ` Amir Goldstein
  0 siblings, 0 replies; 8+ messages in thread
From: Amir Goldstein @ 2020-03-24  6:27 UTC (permalink / raw)
  To: Miklos Szeredi; +Cc: Phasip, overlayfs

[-- Attachment #1: Type: text/plain, Size: 1973 bytes --]

On Mon, Mar 23, 2020 at 9:15 PM Amir Goldstein <amir73il@gmail.com> wrote:
>
> On Mon, Mar 23, 2020 at 7:27 PM Amir Goldstein <amir73il@gmail.com> wrote:
> >
> > On Mon, Mar 23, 2020 at 4:53 PM Miklos Szeredi <miklos@szeredi.hu> wrote:
> > >
> > > On Mon, Mar 23, 2020 at 3:21 PM Miklos Szeredi <miklos@szeredi.hu> wrote:
> > > >
> > > > On Mon, Mar 23, 2020 at 2:24 PM Amir Goldstein <amir73il@gmail.com> wrote:
> > >
> > > > > IDGI. coming from vfs_unlink() and vfs_rename() it doesn't look like
> > > > > it is possible for victim inode not to have a hashed alias, so the
> > > > > alias test seems futile.
> > > >
> > > > Yeah, needs a comment: both ovl_remove_upper() and
> > > > ovl_remove_and_whiteout() unhash the dentry before returning, so
> > > > d_find_alias() will find another hashed dentry or none.
> > >
> > > Except that doesn't seem to be true for the overwriting rename case...
> > >
> > > Attached patch should work for both.
> > >
> >
> > It still looks quite hacky.
> > Why do we not look at upper->i_nlink in order to fix the situation?
> >
> > For index=on, there is already code to handle lower hardlink skew case,
> > including pr_warn and several xfstests (overlay/034 for example).
> > The check is buried in ovl_nlink_end() => ovl_cleanup_index().
> > It's keeping overlay i_nlink above upper i_nlink.
> >
> > In fact, if you change one line in overlay/034 it triggers the reported
> > bug, so we can just fork this test.
> >
> > -lowerdir=$OVL_BASE_SCRATCH_MNT/$OVL_LOWER
> > +lowerdir=$OVL_BASE_SCRATCH_MNT/$OVL_UPPER
> >  workdir=$OVL_BASE_SCRATCH_MNT/$OVL_WORK
> >
> > How about adding a check in ovl_nlink_start() to fix overlay i_nlink
> > below upper i_link?
> > It would be a valid check for both index=off and on.
> > I will try to write it up later.
> >
>
> https://lore.kernel.org/linux-unionfs/20200323190850.3091-1-amir73il@gmail.com/T/#u
>

Attached xfstest. I will post it once the kernel fix commit is finalized.

Thanks,
Amir.

[-- Attachment #2: 0001-overlay-another-test-for-dropping-nlink-below-zero.patch --]
[-- Type: text/x-patch, Size: 3633 bytes --]

From 37c9f71f3dacd2fe0811e7278f13775c55e3e854 Mon Sep 17 00:00:00 2001
From: Amir Goldstein <amir73il@gmail.com>
Date: Tue, 24 Mar 2020 08:12:42 +0200
Subject: [PATCH] overlay: another test for dropping nlink below zero

This is a variant on test overlay/034.

This variant is mangling upper hardlinks instead of lower hardlinks
and does not require the inodes index feature.

This is a regression test for kernel commit:
("ovl: fix WARN_ON nlink drop to zero")

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 tests/overlay/072     | 85 +++++++++++++++++++++++++++++++++++++++++++
 tests/overlay/072.out |  2 +
 tests/overlay/group   |  1 +
 3 files changed, 88 insertions(+)
 create mode 100755 tests/overlay/072
 create mode 100644 tests/overlay/072.out

diff --git a/tests/overlay/072 b/tests/overlay/072
new file mode 100755
index 00000000..e8a378e4
--- /dev/null
+++ b/tests/overlay/072
@@ -0,0 +1,85 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (C) 2020 CTERA Networks. All Rights Reserved.
+#
+# FS QA Test 072
+#
+# Test overlay nlink when adding upper hardlinks.
+#
+# nlink of overlay inode could be dropped indefinitely by adding
+# unaccounted upper hardlinks underneath a mounted overlay and
+# trying to remove them.
+#
+# This is a variant of test overlay/034 with mangling of upper instead
+# of lower hardlinks. Unlike overlay/034, this test does not require the
+# inode index feature and will pass whether is it enabled or disabled
+# by default.
+#
+# This is a regression test for kernel commit:
+# ("ovl: fix WARN_ON nlink drop to zero").
+# Without the fix, the test triggers
+# WARN_ON(inode->i_nlink == 0) in drop_link().
+#
+seq=`basename $0`
+seqres=$RESULT_DIR/$seq
+echo "QA output created by $seq"
+
+tmp=/tmp/$$
+status=1	# failure is the default!
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+_cleanup()
+{
+	cd /
+	rm -f $tmp.*
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+
+# remove previous $seqres.full before test
+rm -f $seqres.full
+
+# real QA test starts here
+_supported_fs overlay
+_supported_os Linux
+_require_scratch
+
+upperdir=$OVL_BASE_SCRATCH_MNT/$OVL_UPPER
+
+# Remove all files from previous tests
+_scratch_mkfs
+
+# Create lower hardlink
+mkdir -p $upperdir
+touch $upperdir/0
+ln $upperdir/0 $upperdir/1
+
+_scratch_mount
+
+# Copy up lower hardlink - overlay inode nlink 2 is copied from lower
+touch $SCRATCH_MNT/0
+
+# Add lower hardlinks while overlay is mounted - overlay inode nlink
+# is not being updated
+ln $upperdir/0 $upperdir/2
+ln $upperdir/0 $upperdir/3
+
+# Unlink the 2 un-accounted lower hardlinks - overlay inode nlinks
+# drops 2 and may reach 0 if the situation is not detected
+rm $SCRATCH_MNT/2
+rm $SCRATCH_MNT/3
+
+# Check if getting ENOENT when trying to link !I_LINKABLE with nlink 0
+ln $SCRATCH_MNT/0 $SCRATCH_MNT/4
+
+# Unlink all hardlinks - if overlay inode nlink is 0, this will trigger
+# WARN_ON() in drop_nlink()
+rm $SCRATCH_MNT/0
+rm $SCRATCH_MNT/1
+rm $SCRATCH_MNT/4
+
+echo "Silence is golden"
+status=0
+exit
diff --git a/tests/overlay/072.out b/tests/overlay/072.out
new file mode 100644
index 00000000..590bbc6c
--- /dev/null
+++ b/tests/overlay/072.out
@@ -0,0 +1,2 @@
+QA output created by 072
+Silence is golden
diff --git a/tests/overlay/group b/tests/overlay/group
index 43ad8a52..82876d09 100644
--- a/tests/overlay/group
+++ b/tests/overlay/group
@@ -74,3 +74,4 @@
 069 auto quick copyup hardlink exportfs nested nonsamefs
 070 auto quick copyup redirect nested
 071 auto quick copyup redirect nested nonsamefs
+072 auto quick copyup hardlink
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2020-03-24  6:27 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CAFkON1U3cXdXFQYdkoQ3OQU+14GX7C88U6qre58vyfhrrFgKXw@mail.gmail.com>
2020-03-23 12:52 ` Kernel warnings in fs/inode.c:302 drop_nlink+0x28/0x40 Miklos Szeredi
2020-03-23 13:23   ` Amir Goldstein
2020-03-23 14:21     ` Miklos Szeredi
2020-03-23 14:53       ` Miklos Szeredi
2020-03-23 17:27         ` Amir Goldstein
2020-03-23 19:15           ` Amir Goldstein
2020-03-24  6:27             ` Amir Goldstein
2020-03-23 14:27 ` Miklos Szeredi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).