summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChunwei Chen <[email protected]>2017-05-09 10:36:54 -0700
committerBrian Behlendorf <[email protected]>2017-05-09 10:36:54 -0700
commit8f87971e1fd11e3bca034dff2cbc0e884381c350 (patch)
treea05d3e63a971c03259233973b742804817d9e55a
parent3665037f301b83144d198676f06a782f3273676f (diff)
Linux 4.12 compat: PF_FSTRANS was removed
Change SPL_FSTRANS to optionally contains PF_FSTRANS. Also, add __spl_pf_fstrans_check for the checks specifically for PF_FSTRANS. Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Chunwei Chen <[email protected]> Closes #614
-rw-r--r--include/sys/kmem.h37
-rw-r--r--module/spl/spl-vnode.c12
2 files changed, 39 insertions, 10 deletions
diff --git a/include/sys/kmem.h b/include/sys/kmem.h
index d4b3bf680..d6b428551 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_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_FSTRANS (PF_FSTRANS)
+#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 0902e1161..346e63c0f 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);