New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix remounting snapshots read-write #6515
Conversation
module/zfs/zfs_vfsops.c
Outdated
| ASSERT(vfsp->vfs_do_readonly); | ||
| *flags |= MS_RDONLY; | ||
| return (EROFS); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The readonly flags is always exists in flags as MS_RDONLY. We cannot rely on the option string for common mount flags.
Also, we should do the same thing for reaonly import.
module/zfs/zfs_vfsops.c
Outdated
| @@ -1769,6 +1769,13 @@ zfs_remount(struct super_block *sb, int *flags, zfs_mnt_t *zm) | |||
| if (error) | |||
| return (error); | |||
|
|
|||
| if ((dmu_objset_is_snapshot(zfsvfs->z_os) || | |||
| !spa_writeable(dmu_objset_spa(zfsvfs->z_os))) && | |||
| (!vfsp->vfs_readonly || !(*flags & MS_RDONLY))) { | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to remove the check on vfsp. As I said, we cannot rely on option string as MS_RDONLY is the only authoritative flag for readonly. It's perfectly normal to have MS_RDONLY and emtpy option string, and we need to treat that as readonly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that MS_RDONLY is the only authoritative flag for readonly to the VFS, but what happens if we have flags=MS_RDONLY and data="rw")?
I think we should stop processing is this other case too, otherwise we will execute a lot of code (zfs_register_callbacks/zfs_unregister_callbacks/zfsvfs_vfs_free) that is useless and potentially dangerous: for instance the panic in list_destroy() seems to be caused by unregistered callbacks.
module/zfs/zfs_vfsops.c
Outdated
| *flags |= MS_RDONLY; | ||
| return (EROFS); | ||
| } | ||
|
|
||
| zfs_unregister_callbacks(zfsvfs); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[16498.559788] VERIFY(list_is_empty(list)) failed
[16498.560525] PANIC at list.h:88:list_destroy()
[16498.561242] Showing stack for process 908
[16498.561967] CPU: 0 PID: 908 Comm: dbu_evict Tainted: P OE 4.9.0 #4
[16498.564434] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
[16498.566161] 0000000000000000 ffffffff88129055 ffffffffc0a4e081 ffffbf2040e73e10
[16498.569740] ffffffffc07eb03f ffffa08c4a3586c0 ffffffff00000028 ffffbf2040e73e20
[16498.573670] ffffbf2040e73dc0 6c28594649524556 655f73695f747369 73696c287974706d
[16498.575983] Call Trace:
[16498.576456] [<ffffffff88129055>] ? dump_stack+0x5c/0x77
[16498.578307] [<ffffffffc07eb03f>] ? spl_panic+0xbf/0xf0 [spl]
[16498.580339] [<ffffffff883f8dce>] ? mutex_lock+0xe/0x30
[16498.582178] [<ffffffff883f8dce>] ? mutex_lock+0xe/0x30
[16498.584078] [<ffffffffc0986fb9>] ? refcount_remove_many+0x179/0x280 [zfs]
[16498.585849] [<ffffffffc0930935>] ? dbuf_rele_and_unlock+0x1e5/0x450 [zfs]
[16498.586479] [<ffffffffc0930b65>] ? dbuf_rele_and_unlock+0x415/0x450 [zfs]
[16498.588155] [<ffffffffc098525a>] ? multilist_insert+0xca/0x1a0 [zfs]
[16498.590031] [<ffffffffc091cd0a>] ? remove_reference+0x8a/0x180 [zfs]
[16498.591858] [<ffffffff883f8dce>] ? mutex_lock+0xe/0x30
[16498.592541] [<ffffffffc0986fb9>] ? refcount_remove_many+0x179/0x280 [zfs]
[16498.594420] [<ffffffffc096bffe>] ? dsl_dir_evict+0x1ae/0x1e0 [zfs]
[16498.596174] [<ffffffffc07e8eb9>] ? taskq_thread+0x269/0x520 [spl]
[16498.597929] [<ffffffff87ea9170>] ? wake_up_q+0x60/0x60
[16498.599595] [<ffffffffc07e8c50>] ? taskq_thread_spawn+0x50/0x50 [spl]
[16498.600174] [<ffffffff87e9dc10>] ? kthread+0xe0/0x100
[16498.601646] [<ffffffff87e2b76b>] ? __switch_to+0x2bb/0x700
[16498.602361] [<ffffffff87e9db30>] ? kthread_park+0x60/0x60
[16498.604091] [<ffffffff883fbaf5>] ? ret_from_fork+0x25/0x3
The issue here is that zfs_unregister_callbacks() does not execute dsl_prop_unregister_all() if dmu_objset_is_snapshot(os), so we leave a dirtry/non-empty ds->ds_prop_cbs list when we remount successfully a snapshot (-o remount,noxattr).
Maybe we should skip callback registration in zfs_remount() when we are processing a snapshot.
|
Yeah, the snapshot didn't register the callback in the first place as it can't change properties anyway. And yes, most of the callback should be removed since they are all MS_* flags and handle by the kernel. But we can do the cleanup later. Last bit,
Otherwise LGTM. |
|
@tuxoko the reason i choose
I will force-push an updated version with |
Actually I think you're right. Since this is specific for snapshot and readonly import, not a fs independent error, we can leave it as EROFS. |
module/zfs/zfs_vfsops.c
Outdated
| zfsvfs_vfs_free(zfsvfs->z_vfs); | ||
|
|
||
| vfsp->vfs_data = zfsvfs; | ||
| zfsvfs->z_vfs = vfsp; | ||
| (void) zfs_register_callbacks(vfsp); | ||
| if (issnap) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check and the one above look inverted to me. We should only be registering and unregistering callbacks when it's not a snapshot.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, the check is inverted. But we should be hitting VERIFY(list_is_empty(list)) failed from the dbu_evict thread in this case, so this means the test script is not covering every possible case.
I'll update this in a bit, thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As you pointed out earlier zfs_unregister_callbacks() already does this check internally so no need to do it twice. I think we only need to check such that callbacks are registered for non-snapshots. And to fix the test case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can still trigger the failure in dbu_evict with a successfull mount -t zfs -o remount,ro $MNTPSNAP: i'm adding this to the test case.
|
@behlendorf |
|
Good question. The readonly property on a dataset was historically intended to be overridden as described in the "Temporary Mount Point Properties" section of |
|
Oh, I see that now, then we're good since it's documented that way. |
ed59dda
to
a2d4865
Compare
|
This is not quite ready yet, sorry: some distro (CentOS 6, Ubuntu 14) don't handle http://build.zfsonlinux.org/builders/CentOS%206%20x86_64%20%28TEST%29/builds/7/steps/shell_8/logs/log Also CentOS 7 x86_64 is failing every combination of Finally, the following kmemleak warnings still need to be investigated: http://build.zfsonlinux.org/builders/Ubuntu%2016.04%20x86_64%20Kmemleak%20%28TEST%29/builds/2986/steps/shell_8/logs/kmemleak I'm in the process of building a box with kmemleak enabled, i hope to push an update later today: sorry about the noise. |
8ea558d
to
05049dc
Compare
It's not enough to preserve/restore MS_RDONLY on the superblock flags to avoid remounting a snapshot read-write: be explicit about our intentions to the VFS layer so the readonly bit is updated correctly in do_remount_sb(). Signed-off-by: loli10K <ezomori.nozomu@gmail.com>
|
@loli10K were you able to identify the kmem leak? The source code changes look the same as in the last version. Thanks for sorting out the test case failure. |
|
@behlendorf |
|
Got it. Then this looks good. |
|
Yes, sorry, forgot to update: @tuxoko is exactly right. |
It's not enough to preserve/restore MS_RDONLY on the superblock flags to avoid remounting a snapshot read-write: be explicit about our intentions to the VFS layer so the readonly bit is updated correctly in do_remount_sb(). Reviewed-by: Chunwei Chen <tuxoko@gmail.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: loli10K <ezomori.nozomu@gmail.com> Closes #6510 Closes #6515
It's not enough to preserve/restore MS_RDONLY on the superblock flags to avoid remounting a snapshot read-write: be explicit about our intentions to the VFS layer so the readonly bit is updated correctly in do_remount_sb(). Reviewed-by: Chunwei Chen <tuxoko@gmail.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: loli10K <ezomori.nozomu@gmail.com> Closes openzfs#6510 Closes openzfs#6515
It's not enough to preserve/restore MS_RDONLY on the superblock flags to avoid remounting a snapshot read-write: be explicit about our intentions to the VFS layer so the readonly bit is updated correctly in do_remount_sb(). Reviewed-by: Chunwei Chen <tuxoko@gmail.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: loli10K <ezomori.nozomu@gmail.com> Closes openzfs#6510 Closes openzfs#6515
Description
Apparently it's not enough to preserve/restore MS_RDONLY on the superblock flags to avoid remounting a snapshot read-write: be explicit about our intentions to the VFS layer so the readonly bit is updated correctly in
do_remount_sb().This is still causing another issue different from the one reported in #6510, i'm still investigating this:
Motivation and Context
Fix #6510
How Has This Been Tested?
Types of changes
Checklist:
Signed-off-by.