diff --git a/include/sys/vnode.h b/include/sys/vnode.h index 09d843366..104e65d15 100644 --- a/include/sys/vnode.h +++ b/include/sys/vnode.h @@ -180,6 +180,7 @@ typedef struct vnode { struct stdata *v_stream; /* associated stream */ enum vtype v_type; /* vnode type */ dev_t v_rdev; /* device (VCHR, VBLK) */ + gfp_t v_gfp_mask; /* original mapping gfp mask */ } vnode_t; typedef struct vn_file { diff --git a/module/spl/spl-vnode.c b/module/spl/spl-vnode.c index dd759bf7f..29028c3c0 100644 --- a/module/spl/spl-vnode.c +++ b/module/spl/spl-vnode.c @@ -104,6 +104,7 @@ vn_open(const char *path, uio_seg_t seg, int flags, int mode, struct file *fp; struct kstat stat; int rc, saved_umask = 0; + gfp_t saved_gfp; vnode_t *vp; SENTRY; @@ -145,9 +146,13 @@ vn_open(const char *path, uio_seg_t seg, int flags, int mode, SRETURN(ENOMEM); } + saved_gfp = mapping_gfp_mask(fp->f_mapping); + mapping_set_gfp_mask(fp->f_mapping, saved_gfp & ~(__GFP_IO|__GFP_FS)); + mutex_enter(&vp->v_lock); vp->v_type = vn_get_sol_type(stat.mode); vp->v_file = fp; + vp->v_gfp_mask = saved_gfp; *vpp = vp; mutex_exit(&vp->v_lock); @@ -237,6 +242,7 @@ vn_close(vnode_t *vp, int flags, int x1, int x2, void *x3, void *x4) ASSERT(vp); ASSERT(vp->v_file); + mapping_set_gfp_mask(vp->v_file->f_mapping, vp->v_gfp_mask); rc = filp_close(vp->v_file, 0); vn_free(vp);