diff --git a/include/sys/kmem.h b/include/sys/kmem.h
index d4b3bf680a..d6b428551f 100644
--- a/include/sys/kmem.h
+++ b/include/sys/kmem.h
@@ -46,6 +46,8 @@ extern void strfree(char *str);
 
 #define	KM_PUBLIC_MASK	(KM_SLEEP | KM_NOSLEEP | KM_PUSHPAGE)
 
+static int spl_fstrans_check(void);
+
 /*
  * Convert a KM_* flags mask to its Linux GFP_* counterpart.  The conversion
  * function is context aware which means that KM_SLEEP allocations can be
@@ -60,7 +62,7 @@ kmem_flags_convert(int flags)
 		lflags |= GFP_ATOMIC | __GFP_NORETRY;
 	} else {
 		lflags |= GFP_KERNEL;
-		if ((current->flags & PF_FSTRANS))
+		if (spl_fstrans_check())
 			lflags &= ~(__GFP_IO|__GFP_FS);
 	}
 
@@ -78,17 +80,34 @@ typedef struct {
 	unsigned int saved_flags;
 } fstrans_cookie_t;
 
+/*
+ * Introduced in Linux 3.9, however this cannot be solely relied on before
+ * Linux 3.18 as it doesn't turn off __GFP_FS as it should.
+ */
 #ifdef PF_MEMALLOC_NOIO
-#define	SPL_FSTRANS (PF_FSTRANS|PF_MEMALLOC_NOIO)
+#define	__SPL_PF_MEMALLOC_NOIO (PF_MEMALLOC_NOIO)
 #else
-#define	SPL_FSTRANS (PF_FSTRANS)
+#define	__SPL_PF_MEMALLOC_NOIO (0)
 #endif
 
+/*
+ * PF_FSTRANS is removed from Linux 4.12
+ */
+#ifdef PF_FSTRANS
+#define	__SPL_PF_FSTRANS (PF_FSTRANS)
+#else
+#define	__SPL_PF_FSTRANS (0)
+#endif
+
+#define	SPL_FSTRANS (__SPL_PF_FSTRANS|__SPL_PF_MEMALLOC_NOIO)
+
 static inline fstrans_cookie_t
 spl_fstrans_mark(void)
 {
 	fstrans_cookie_t cookie;
 
+	BUILD_BUG_ON(SPL_FSTRANS == 0);
+
 	cookie.fstrans_thread = current;
 	cookie.saved_flags = current->flags & SPL_FSTRANS;
 	current->flags |= SPL_FSTRANS;
@@ -109,7 +128,17 @@ spl_fstrans_unmark(fstrans_cookie_t cookie)
 static inline int
 spl_fstrans_check(void)
 {
-	return (current->flags & PF_FSTRANS);
+	return (current->flags & SPL_FSTRANS);
+}
+
+/*
+ * specifically used to check PF_FSTRANS flag, cannot be relied on for
+ * checking spl_fstrans_mark().
+ */
+static inline int
+__spl_pf_fstrans_check(void)
+{
+	return (current->flags & __SPL_PF_FSTRANS);
 }
 
 #ifdef HAVE_ATOMIC64_T
diff --git a/module/spl/spl-vnode.c b/module/spl/spl-vnode.c
index 0902e11618..346e63c0f1 100644
--- a/module/spl/spl-vnode.c
+++ b/module/spl/spl-vnode.c
@@ -558,13 +558,13 @@ int vn_fsync(vnode_t *vp, int flags, void *x3, void *x4)
 	 * May enter XFS which generates a warning when PF_FSTRANS is set.
 	 * To avoid this the flag is cleared over vfs_sync() and then reset.
 	 */
-	fstrans = spl_fstrans_check();
+	fstrans = __spl_pf_fstrans_check();
 	if (fstrans)
-		current->flags &= ~(PF_FSTRANS);
+		current->flags &= ~(__SPL_PF_FSTRANS);
 
 	error = -spl_filp_fsync(vp->v_file, datasync);
 	if (fstrans)
-		current->flags |= PF_FSTRANS;
+		current->flags |= __SPL_PF_FSTRANS;
 
 	return (error);
 } /* vn_fsync() */
@@ -590,9 +590,9 @@ int vn_space(vnode_t *vp, int cmd, struct flock *bfp, int flag,
 	 * May enter XFS which generates a warning when PF_FSTRANS is set.
 	 * To avoid this the flag is cleared over vfs_sync() and then reset.
 	 */
-	fstrans = spl_fstrans_check();
+	fstrans = __spl_pf_fstrans_check();
 	if (fstrans)
-		current->flags &= ~(PF_FSTRANS);
+		current->flags &= ~(__SPL_PF_FSTRANS);
 
 	/*
 	 * When supported by the underlying file system preferentially
@@ -603,7 +603,7 @@ int vn_space(vnode_t *vp, int cmd, struct flock *bfp, int flag,
 	    bfp->l_start, bfp->l_len);
 
 	if (fstrans)
-		current->flags |= PF_FSTRANS;
+		current->flags |= __SPL_PF_FSTRANS;
 
 	if (error == 0)
 		return (0);