Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/external/cddl/osnet/dist/uts/common/fs/zfs Cannot use ZFS_EN...
details: https://anonhg.NetBSD.org/src/rev/7aa943294a35
branches: trunk
changeset: 995683:7aa943294a35
user: hannken <hannken%NetBSD.org@localhost>
date: Tue Jan 01 10:09:26 2019 +0000
description:
Cannot use ZFS_ENTER() / ZFS_EXIT() as zfs_netbsd_putpages() is used
during vnode reclaim.
Add missing protection with fstrans.
diffstat:
external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c | 41 +++++++++++------
1 files changed, 26 insertions(+), 15 deletions(-)
diffs (72 lines):
diff -r f417ec11473e -r 7aa943294a35 external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c
--- a/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c Tue Jan 01 10:08:42 2019 +0000
+++ b/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c Tue Jan 01 10:09:26 2019 +0000
@@ -84,6 +84,7 @@
#include <miscfs/genfs/genfs.h>
#include <miscfs/genfs/genfs_node.h>
#include <uvm/uvm_extern.h>
+#include <sys/fstrans.h>
uint_t zfs_putpage_key;
#endif
@@ -5972,9 +5973,6 @@
bool async = (flags & PGO_SYNCIO) == 0;
bool cleaning = (flags & PGO_CLEANIT) != 0;
- ZFS_ENTER(zfsvfs);
- ZFS_VERIFY_ZP(zp);
-
if (cleaning) {
ASSERT((offlo & PAGE_MASK) == 0 && (offhi & PAGE_MASK) == 0);
ASSERT(offlo < offhi || offhi == 0);
@@ -5983,25 +5981,38 @@
else
len = offhi - offlo;
mutex_exit(vp->v_interlock);
+ if (curlwp == uvm.pagedaemon_lwp) {
+ error = fstrans_start_nowait(vp->v_mount);
+ if (error)
+ return error;
+ } else {
+ vfs_t *mp = vp->v_mount;
+ fstrans_start(mp);
+ if (vp->v_mount != mp) {
+ fstrans_done(mp);
+ ASSERT(!vn_has_cached_data(vp));
+ return 0;
+ }
+ }
rl = zfs_range_lock(zp, offlo, len, RL_WRITER);
mutex_enter(vp->v_interlock);
tsd_set(zfs_putpage_key, &cleaned);
}
error = genfs_putpages(v);
- if (rl) {
+ if (cleaning) {
tsd_set(zfs_putpage_key, NULL);
zfs_range_unlock(rl);
- }
-
- /*
- * Only zil_commit() if we cleaned something.
- * This avoids deadlock if we're called from zfs_netbsd_setsize().
- */
-
- if (cleaned)
- if (!async || zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
- zil_commit(zfsvfs->z_log, zp->z_id);
- ZFS_EXIT(zfsvfs);
+
+ /*
+ * Only zil_commit() if we cleaned something. This avoids
+ * deadlock if we're called from zfs_netbsd_setsize().
+ */
+
+ if (cleaned)
+ if (!async || zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
+ zil_commit(zfsvfs->z_log, zp->z_id);
+ fstrans_done(vp->v_mount);
+ }
return error;
}
Home |
Main Index |
Thread Index |
Old Index