Index: lib/libperfuse/ops.c =================================================================== RCS file: /cvsroot/src/lib/libperfuse/ops.c,v retrieving revision 1.50.2.6 diff -U 4 -r1.50.2.6 ops.c --- lib/libperfuse/ops.c 12 Aug 2012 13:13:20 -0000 1.50.2.6 +++ lib/libperfuse/ops.c 13 Aug 2014 03:37:05 -0000 @@ -1317,8 +1317,15 @@ int perfuse_node_open(struct puffs_usermount *pu, puffs_cookie_t opc, int mode, const struct puffs_cred *pcr) { + return perfuse_node_open2(pu, opc, mode, pcr, NULL); +} + +int +perfuse_node_open2(struct puffs_usermount *pu, puffs_cookie_t opc, int mode, + const struct puffs_cred *pcr, int *oflags) +{ struct perfuse_state *ps; struct perfuse_node_data *pnd; perfuse_msg_t *pm; mode_t fmode; @@ -1395,8 +1425,15 @@ * so that we can reuse it later */ perfuse_new_fh(opc, foo->fh, mode); + /* + * Set direct I/O if the filesystems forces it + */ + if (foo->open_flags & FUSE_FOPEN_DIRECT_IO && oflags) + *oflags |= PUFFS_OPEN_IO_DIRECT; + + #ifdef PERFUSE_DEBUG if (perfuse_diagflags & (PDF_FH|PDF_FILENAME)) DPRINTF("%s: opc = %p, file = \"%s\", " "nodeid = 0x%"PRIx64", %s%sfh = 0x%"PRIx64"\n", @@ -2028,16 +2065,8 @@ node_rele(opc); return error; } -/* ARGSUSED0 */ -int -perfuse_node_seek(struct puffs_usermount *pu, puffs_cookie_t opc, - off_t oldoff, off_t newoff, const struct puffs_cred *pcr) -{ - return 0; -} - int perfuse_node_remove(struct puffs_usermount *pu, puffs_cookie_t opc, puffs_cookie_t targ, const struct puffs_cn *pcn) { @@ -2987,13 +3016,8 @@ */ if (vap->va_type == VDIR) return EISDIR; - if ((u_quad_t)offset + *resid > vap->va_size) - DWARNX("%s %p read %lld@%zu beyond EOF %" PRIu64 "\n", - __func__, (void *)opc, (long long)offset, - *resid, vap->va_size); - do { size_t max_read; max_read = ps->ps_max_readahead - sizeof(*foh); Index: lib/libperfuse/perfuse.c =================================================================== RCS file: /cvsroot/src/lib/libperfuse/perfuse.c,v retrieving revision 1.25.2.3 diff -U 4 -r1.25.2.3 perfuse.c --- lib/libperfuse/perfuse.c 13 Sep 2012 22:31:03 -0000 1.25.2.3 +++ lib/libperfuse/perfuse.c 13 Aug 2014 03:37:05 -0000 @@ -474,9 +474,8 @@ #if 0 PUFFSOP_SET(pops, perfuse, node, mmap); #endif PUFFSOP_SET(pops, perfuse, node, fsync); - PUFFSOP_SET(pops, perfuse, node, seek); PUFFSOP_SET(pops, perfuse, node, remove); PUFFSOP_SET(pops, perfuse, node, link); PUFFSOP_SET(pops, perfuse, node, rename); PUFFSOP_SET(pops, perfuse, node, mkdir); @@ -502,8 +501,11 @@ #endif /* PUFFS_KFLAG_CACHE_FS_TTL */ #ifdef PUFFS_SETATTR_FAF PUFFSOP_SET(pops, perfuse, node, write2); #endif /* PUFFS_SETATTR_FAF */ +#ifdef PUFFS_OPEN_IO_DIRECT + PUFFSOP_SET(pops, perfuse, node, open2); +#endif /* PUFFS_OPEN_IO_DIRECT */ /* * PUFFS_KFLAG_NOCACHE_NAME is required so that we can see changes * done by other machines in networked filesystems. In later Index: lib/libperfuse/perfuse_priv.h =================================================================== RCS file: /cvsroot/src/lib/libperfuse/perfuse_priv.h,v retrieving revision 1.25.2.4 diff -U 4 -r1.25.2.4 perfuse_priv.h --- lib/libperfuse/perfuse_priv.h 12 Aug 2012 13:13:20 -0000 1.25.2.4 +++ lib/libperfuse/perfuse_priv.h 13 Aug 2014 03:37:05 -0000 @@ -225,10 +226,8 @@ int perfuse_node_mmap(struct puffs_usermount *, puffs_cookie_t, vm_prot_t, const struct puffs_cred *); int perfuse_node_fsync(struct puffs_usermount *, puffs_cookie_t, const struct puffs_cred *, int, off_t, off_t); -int perfuse_node_seek(struct puffs_usermount *, - puffs_cookie_t, off_t, off_t, const struct puffs_cred *); int perfuse_node_remove(struct puffs_usermount *, puffs_cookie_t, puffs_cookie_t, const struct puffs_cn *); int perfuse_node_link(struct puffs_usermount *, puffs_cookie_t, puffs_cookie_t, const struct puffs_cn *); @@ -260,8 +259,10 @@ int perfuse_node_write(struct puffs_usermount *, puffs_cookie_t, uint8_t *, off_t, size_t *, const struct puffs_cred *, int); int perfuse_node_write2(struct puffs_usermount *, puffs_cookie_t, uint8_t *, off_t, size_t *, const struct puffs_cred *, int, int); +int perfuse_node_open2(struct puffs_usermount *, + puffs_cookie_t, int, const struct puffs_cred *, int *); void perfuse_cache_write(struct puffs_usermount *, puffs_cookie_t, size_t, struct puffs_cacherun *); int perfuse_node_getextattr(struct puffs_usermount *, puffs_cookie_t, int, const char *, size_t *, uint8_t *, size_t *, Index: lib/libpuffs/dispatcher.c =================================================================== RCS file: /cvsroot/src/lib/libpuffs/dispatcher.c,v retrieving revision 1.38.2.4 diff -U 4 -r1.38.2.4 dispatcher.c --- lib/libpuffs/dispatcher.c 13 Sep 2012 20:20:15 -0000 1.38.2.4 +++ lib/libpuffs/dispatcher.c 13 Aug 2014 03:37:05 -0000 @@ -411,8 +411,15 @@ { struct puffs_vnmsg_open *auxt = auxbuf; PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); + if (pops->puffs_node_open2 != NULL) { + error = pops->puffs_node_open2(pu, + opcookie, auxt->pvnr_mode, pcr, + &auxt->pvnr_oflags); + break; + } + if (pops->puffs_node_open == NULL) { error = 0; break; } Index: lib/libpuffs/puffs.h =================================================================== RCS file: /cvsroot/src/lib/libpuffs/puffs.h,v retrieving revision 1.119.4.4 diff -U 4 -r1.119.4.4 puffs.h --- lib/libpuffs/puffs.h 13 Sep 2012 20:20:16 -0000 1.119.4.4 +++ lib/libpuffs/puffs.h 13 Aug 2014 03:37:05 -0000 @@ -249,8 +250,10 @@ int (*puffs_node_write2)(struct puffs_usermount *, puffs_cookie_t, uint8_t *, off_t, size_t *, const struct puffs_cred *, int, int); int (*puffs_node_reclaim2)(struct puffs_usermount *, puffs_cookie_t, int); + int (*puffs_node_open2)(struct puffs_usermount *, + puffs_cookie_t, int, const struct puffs_cred *, int *); void *puffs_ops_spare[28]; }; @@ -409,9 +412,11 @@ int fsname##_node_write2(struct puffs_usermount *, \ puffs_cookie_t, uint8_t *, off_t, size_t *, \ const struct puffs_cred *, int, int); \ int fsname##_node_reclaim2(struct puffs_usermount *, \ - puffs_cookie_t, int); + puffs_cookie_t, int); \ + int fsname##_node_open2(struct puffs_usermount *, \ + puffs_cookie_t, int, const struct puffs_cred *, int *); #define PUFFSOP_INIT(ops) \ ops = malloc(sizeof(struct puffs_ops)); \ Index: lib/libpuffs/puffs_ops.3 =================================================================== RCS file: /cvsroot/src/lib/libpuffs/puffs_ops.3,v retrieving revision 1.29.4.4 diff -U 4 -r1.29.4.4 puffs_ops.3 --- lib/libpuffs/puffs_ops.3 13 Sep 2012 20:20:15 -0000 1.29.4.4 +++ lib/libpuffs/puffs_ops.3 13 Aug 2014 03:37:05 -0000 @@ -82,8 +82,13 @@ .Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int mode" .Fa "const struct puffs_cred *pcr" .Fc .Ft int +.Fo puffs_node_open2 +.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int mode" +.Fa "const struct puffs_cred *pcr" "int *oflags" +.Fc +.Ft int .Fo puffs_node_close .Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int flags" .Fa "const struct puffs_cred *pcr" .Fc @@ -481,8 +486,9 @@ .Pp In case of mknod, the device identifier can be found in .Fa va-\*[Gt]va_rdev . .It Fn puffs_node_open "pu" "opc" "mode" "pcr" +.It Fn puffs_node_open2 "pu" "opc" "mode" "pcr" "oflags" Open the node denoted by the cookie .Fa opc . The parameter .Fa mode @@ -491,8 +497,16 @@ was called with, e.g. .Dv O_APPEND and .Dv O_NONBLOCK . +.Fn puffs_node_open2 +lets the file system return flags in +.Fa oflags . +The only currently supported value is +.Dv PUFFS_OPEN_IO_DIRECT , +which will force +.Dv O_DIRECT +access-mdode for the node. .It Fn puffs_node_close "pu" "opc" "flags" "pcr" Close a node. The parameter .Fa flags Index: sys/fs/puffs/puffs_msgif.h =================================================================== RCS file: /cvsroot/src/sys/fs/puffs/puffs_msgif.h,v retrieving revision 1.77.8.2 diff -U 4 -r1.77.8.2 puffs_msgif.h --- sys/fs/puffs/puffs_msgif.h 12 Aug 2012 13:13:20 -0000 1.77.8.2 +++ sys/fs/puffs/puffs_msgif.h 13 Aug 2014 03:37:04 -0000 @@ -338,8 +338,11 @@ #define PUFFS_SUSPEND_ERROR 3 #define PUFFS_EXTATTRCTL_HASNODE 0x01 #define PUFFS_EXTATTRCTL_HASATTRNAME 0x02 + +#define PUFFS_OPEN_IO_DIRECT 0x01 + struct puffs_vfsmsg_extattrctl { struct puffs_req pvfsr_pr; int pvfsr_cmd; /* OUT */ @@ -398,8 +401,9 @@ struct puffs_req pvn_pr; struct puffs_kcred pvnr_cred; /* OUT */ int pvnr_mode; /* OUT */ + int pvnr_oflags; /* IN */ }; struct puffs_vnmsg_close { struct puffs_req pvn_pr; Index: sys/fs/puffs/puffs_sys.h =================================================================== RCS file: /cvsroot/src/sys/fs/puffs/puffs_sys.h,v retrieving revision 1.78.8.2 diff -U 4 -r1.78.8.2 puffs_sys.h --- sys/fs/puffs/puffs_sys.h 12 Aug 2012 13:13:20 -0000 1.78.8.2 +++ sys/fs/puffs/puffs_sys.h 13 Aug 2014 03:37:04 -0000 @@ -192,8 +192,9 @@ #define PNODE_DYING 0x002 /* NOREFS + inactive */ #define PNODE_FAF 0x004 /* issue all operations as FAF */ #define PNODE_DOINACT 0x008 /* if inactive-on-demand, call inactive */ #define PNODE_SOPEXP 0x100 /* Node reclaim postponed in sop thread */ +#define PNODE_IO_DIRECT 0x200 /* bypass page cache on read/write */ #define PNODE_METACACHE_ATIME 0x10 /* cache atime metadata */ #define PNODE_METACACHE_CTIME 0x20 /* cache atime metadata */ #define PNODE_METACACHE_MTIME 0x40 /* cache atime metadata */ Index: sys/fs/puffs/puffs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/fs/puffs/puffs_vnops.c,v retrieving revision 1.163.2.4 diff -U 4 -r1.163.2.4 puffs_vnops.c --- sys/fs/puffs/puffs_vnops.c 12 Aug 2012 13:13:20 -0000 1.163.2.4 +++ sys/fs/puffs/puffs_vnops.c 13 Aug 2014 03:37:05 -0000 @@ -870,8 +870,9 @@ } */ *ap = v; PUFFS_MSG_VARS(vn, open); struct vnode *vp = ap->a_vp; struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount); + struct puffs_node *pn = VPTOPP(vp); int mode = ap->a_mode; int error; DPRINTF(("puffs_open: vp %p, mode 0x%x\n", vp, mode)); @@ -890,8 +891,10 @@ PUFFS_MSG_ENQUEUEWAIT2(pmp, park_open, vp->v_data, NULL, error); error = checkerr(pmp, error, __func__); + if (open_msg->pvnr_oflags & PUFFS_OPEN_IO_DIRECT) + pn->pn_stat |= PNODE_IO_DIRECT; out: DPRINTF(("puffs_open: returning %d\n", error)); PUFFS_MSG_RELEASE(open); return error; @@ -2164,8 +2167,9 @@ kauth_cred_t a_cred; } */ *ap = v; PUFFS_MSG_VARS(vn, read); struct vnode *vp = ap->a_vp; + struct puffs_node *pn = VPTOPP(vp); struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount); struct uio *uio = ap->a_uio; size_t tomove, argsize; vsize_t bytelen; @@ -2179,9 +2183,11 @@ return 0; if (uio->uio_offset < 0) return EINVAL; - if (vp->v_type == VREG && PUFFS_USE_PAGECACHE(pmp)) { + if (vp->v_type == VREG && + PUFFS_USE_PAGECACHE(pmp) && + !(pn->pn_stat & PNODE_IO_DIRECT)) { const int advice = IO_ADV_DECODE(ap->a_ioflag); while (uio->uio_resid > 0) { if (vp->v_size <= uio->uio_offset) { @@ -2284,9 +2290,11 @@ write_msg = NULL; mutex_enter(&pn->pn_sizemtx); - if (vp->v_type == VREG && PUFFS_USE_PAGECACHE(pmp)) { + if (vp->v_type == VREG && + PUFFS_USE_PAGECACHE(pmp) && + !(pn->pn_stat & PNODE_IO_DIRECT)) { ubcflags = UBC_WRITE | UBC_PARTIALOK | UBC_UNMAP_FLAG(vp); /* * userspace *should* be allowed to control this,