7301 zpool export -f should be able to interrupt file freeing
Reviewed by: Matthew Ahrens <mahrens@delphix.com> Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com> Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com> Reviewed by: John Kennedy <john.kennedy@delphix.com> Author: Alek Pinchuk <alek@nexenta.com> Closes #175
This commit is contained in:
parent
d503f63e1b
commit
760c70cd25
@ -24,7 +24,7 @@
|
||||
*/
|
||||
/* Copyright (c) 2013 by Saso Kiselkov. All rights reserved. */
|
||||
/* Copyright (c) 2013, Joyent, Inc. All rights reserved. */
|
||||
/* Copyright (c) 2014, Nexenta Systems, Inc. All rights reserved. */
|
||||
/* Copyright 2016 Nexenta Systems, Inc. All rights reserved. */
|
||||
|
||||
#include <sys/dmu.h>
|
||||
#include <sys/dmu_impl.h>
|
||||
@ -695,6 +695,22 @@ get_next_chunk(dnode_t *dn, uint64_t *start, uint64_t minimum)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* If this objset is of type OST_ZFS return true if vfs's unmounted flag is set,
|
||||
* otherwise return false.
|
||||
* Used below in dmu_free_long_range_impl() to enable abort when unmounting
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static boolean_t
|
||||
dmu_objset_zfs_unmounting(objset_t *os)
|
||||
{
|
||||
#ifdef _KERNEL
|
||||
if (dmu_objset_type(os) == DMU_OST_ZFS)
|
||||
return (zfs_get_vfs_flag_unmounted(os));
|
||||
#endif
|
||||
return (B_FALSE);
|
||||
}
|
||||
|
||||
static int
|
||||
dmu_free_long_range_impl(objset_t *os, dnode_t *dn, uint64_t offset,
|
||||
uint64_t length)
|
||||
@ -711,6 +727,9 @@ dmu_free_long_range_impl(objset_t *os, dnode_t *dn, uint64_t offset,
|
||||
while (length != 0) {
|
||||
uint64_t chunk_end, chunk_begin;
|
||||
|
||||
if (dmu_objset_zfs_unmounting(dn->dn_objset))
|
||||
return (SET_ERROR(EINTR));
|
||||
|
||||
chunk_end = chunk_begin = offset + length;
|
||||
|
||||
/* move chunk_begin backwards to the beginning of this chunk */
|
||||
|
@ -22,6 +22,7 @@
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2015 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2014 Integros [integros.com]
|
||||
* Copyright 2016 Nexenta Systems, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_FS_ZFS_ZNODE_H
|
||||
@ -302,6 +303,7 @@ extern int zfs_sync(vfs_t *vfsp, short flag, cred_t *cr);
|
||||
extern dev_t zfs_cmpldev(uint64_t);
|
||||
extern int zfs_get_zplprop(objset_t *os, zfs_prop_t prop, uint64_t *value);
|
||||
extern int zfs_get_stats(objset_t *os, nvlist_t *nv);
|
||||
extern boolean_t zfs_get_vfs_flag_unmounted(objset_t *os);
|
||||
extern void zfs_znode_dmu_fini(znode_t *);
|
||||
|
||||
extern void zfs_log_create(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
|
||||
|
@ -618,8 +618,8 @@ zfs_rmnode(znode_t *zp)
|
||||
error = dmu_free_long_range(os, zp->z_id, 0, DMU_OBJECT_END);
|
||||
if (error) {
|
||||
/*
|
||||
* Not enough space. Leave the file in the unlinked
|
||||
* set.
|
||||
* Not enough space or we were interrupted by unmount.
|
||||
* Leave the file in the unlinked set.
|
||||
*/
|
||||
zfs_znode_dmu_fini(zp);
|
||||
zfs_znode_free(zp);
|
||||
|
@ -22,6 +22,7 @@
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2015 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2014 Integros [integros.com]
|
||||
* Copyright 2016 Nexenta Systems, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
/* Portions Copyright 2010 Robert Milkowski */
|
||||
@ -1728,7 +1729,7 @@ zfs_root(vfs_t *vfsp, vnode_t **vpp)
|
||||
/*
|
||||
* Teardown the zfsvfs::z_os.
|
||||
*
|
||||
* Note, if 'unmounting' if FALSE, we return with the 'z_teardown_lock'
|
||||
* Note, if 'unmounting' is FALSE, we return with the 'z_teardown_lock'
|
||||
* and 'z_teardown_inactive_lock' held.
|
||||
*/
|
||||
static int
|
||||
@ -1793,8 +1794,8 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting)
|
||||
*/
|
||||
if (unmounting) {
|
||||
zfsvfs->z_unmounted = B_TRUE;
|
||||
rrm_exit(&zfsvfs->z_teardown_lock, FTAG);
|
||||
rw_exit(&zfsvfs->z_teardown_inactive_lock);
|
||||
rrm_exit(&zfsvfs->z_teardown_lock, FTAG);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2272,6 +2273,29 @@ zfs_get_zplprop(objset_t *os, zfs_prop_t prop, uint64_t *value)
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if the coresponding vfs's unmounted flag is set.
|
||||
* Otherwise return false.
|
||||
* If this function returns true we know VFS unmount has been initiated.
|
||||
*/
|
||||
boolean_t
|
||||
zfs_get_vfs_flag_unmounted(objset_t *os)
|
||||
{
|
||||
zfsvfs_t *zfvp;
|
||||
boolean_t unmounted = B_FALSE;
|
||||
|
||||
ASSERT(dmu_objset_type(os) == DMU_OST_ZFS);
|
||||
|
||||
mutex_enter(&os->os_user_ptr_lock);
|
||||
zfvp = dmu_objset_get_user(os);
|
||||
if (zfvp != NULL && zfvp->z_vfs != NULL &&
|
||||
(zfvp->z_vfs->vfs_flag & VFS_UNMOUNTED))
|
||||
unmounted = B_TRUE;
|
||||
mutex_exit(&os->os_user_ptr_lock);
|
||||
|
||||
return (unmounted);
|
||||
}
|
||||
|
||||
static vfsdef_t vfw = {
|
||||
VFSDEF_VERSION,
|
||||
MNTTYPE_ZFS,
|
||||
|
Loading…
Reference in New Issue
Block a user