15812c3ccSTomohiro Kusumi /*- 25812c3ccSTomohiro Kusumi * Copyright (c) 2019 Tomohiro Kusumi <tkusumi@netbsd.org> 35812c3ccSTomohiro Kusumi * Copyright (c) 2019 The DragonFly Project 45812c3ccSTomohiro Kusumi * All rights reserved. 55812c3ccSTomohiro Kusumi * 65812c3ccSTomohiro Kusumi * Redistribution and use in source and binary forms, with or without 75812c3ccSTomohiro Kusumi * modification, are permitted provided that the following conditions 85812c3ccSTomohiro Kusumi * are met: 95812c3ccSTomohiro Kusumi * 1. Redistributions of source code must retain the above copyright 105812c3ccSTomohiro Kusumi * notice, this list of conditions and the following disclaimer. 115812c3ccSTomohiro Kusumi * 2. Redistributions in binary form must reproduce the above copyright 125812c3ccSTomohiro Kusumi * notice, this list of conditions and the following disclaimer in the 135812c3ccSTomohiro Kusumi * documentation and/or other materials provided with the distribution. 145812c3ccSTomohiro Kusumi * 155812c3ccSTomohiro Kusumi * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 165812c3ccSTomohiro Kusumi * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 175812c3ccSTomohiro Kusumi * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 185812c3ccSTomohiro Kusumi * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 195812c3ccSTomohiro Kusumi * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 205812c3ccSTomohiro Kusumi * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 215812c3ccSTomohiro Kusumi * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 225812c3ccSTomohiro Kusumi * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 235812c3ccSTomohiro Kusumi * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 245812c3ccSTomohiro Kusumi * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 255812c3ccSTomohiro Kusumi * SUCH DAMAGE. 265812c3ccSTomohiro Kusumi */ 275812c3ccSTomohiro Kusumi 285812c3ccSTomohiro Kusumi #include "fuse.h" 295812c3ccSTomohiro Kusumi 305812c3ccSTomohiro Kusumi #include <sys/uio.h> 315812c3ccSTomohiro Kusumi #include <sys/buf2.h> 325812c3ccSTomohiro Kusumi 33*5d0d0bafSMatthew Dillon #if 0 345812c3ccSTomohiro Kusumi static void 355812c3ccSTomohiro Kusumi fuse_fix_size(struct fuse_node *fnp, bool fixsize, size_t oldsize) 365812c3ccSTomohiro Kusumi { 375812c3ccSTomohiro Kusumi if (fixsize) 385812c3ccSTomohiro Kusumi fuse_node_truncate(fnp, fnp->size, oldsize); 395812c3ccSTomohiro Kusumi } 40*5d0d0bafSMatthew Dillon #endif 415812c3ccSTomohiro Kusumi 42*5d0d0bafSMatthew Dillon #if 0 435812c3ccSTomohiro Kusumi int 445812c3ccSTomohiro Kusumi fuse_read(struct vop_read_args *ap) 455812c3ccSTomohiro Kusumi { 465812c3ccSTomohiro Kusumi struct vnode *vp = ap->a_vp; 475812c3ccSTomohiro Kusumi struct uio *uio = ap->a_uio; 485812c3ccSTomohiro Kusumi struct fuse_mount *fmp = VFSTOFUSE(vp->v_mount); 495812c3ccSTomohiro Kusumi struct fuse_node *fnp = VTOI(vp); 505812c3ccSTomohiro Kusumi bool need_reopen = !curproc || fnp->closed; /* XXX */ 515812c3ccSTomohiro Kusumi int error = 0; 525812c3ccSTomohiro Kusumi 535812c3ccSTomohiro Kusumi while (uio->uio_resid > 0 && uio->uio_offset < fnp->size) { 545812c3ccSTomohiro Kusumi struct file *fp; 555812c3ccSTomohiro Kusumi struct buf *bp; 565812c3ccSTomohiro Kusumi struct fuse_ipc *fip; 575812c3ccSTomohiro Kusumi struct fuse_read_in *fri; 585812c3ccSTomohiro Kusumi off_t base_offset, buf_offset; 595812c3ccSTomohiro Kusumi size_t len; 605812c3ccSTomohiro Kusumi uint64_t fh; 615812c3ccSTomohiro Kusumi 625812c3ccSTomohiro Kusumi fh = fuse_nfh(VTOI(vp)); 635812c3ccSTomohiro Kusumi if (ap->a_fp) 645812c3ccSTomohiro Kusumi fh = fuse_fh(ap->a_fp); 655812c3ccSTomohiro Kusumi 665812c3ccSTomohiro Kusumi buf_offset = (off_t)uio->uio_offset & FUSE_BLKMASK64; 675812c3ccSTomohiro Kusumi base_offset = (off_t)uio->uio_offset - buf_offset; 685812c3ccSTomohiro Kusumi 695812c3ccSTomohiro Kusumi fuse_dbg("uio_offset=%ju uio_resid=%ju base_offset=%ju " 705812c3ccSTomohiro Kusumi "buf_offset=%ju\n", 715812c3ccSTomohiro Kusumi uio->uio_offset, uio->uio_resid, base_offset, buf_offset); 725812c3ccSTomohiro Kusumi 735812c3ccSTomohiro Kusumi bp = getblk(vp, base_offset, FUSE_BLKSIZE, 0, 0); 745812c3ccSTomohiro Kusumi KKASSERT(bp); 755812c3ccSTomohiro Kusumi if ((bp->b_flags & (B_INVAL | B_CACHE | B_RAM)) == B_CACHE) { 765812c3ccSTomohiro Kusumi bp->b_flags &= ~B_AGE; 775812c3ccSTomohiro Kusumi goto skip; 785812c3ccSTomohiro Kusumi } 795812c3ccSTomohiro Kusumi if (ap->a_ioflag & IO_NRDELAY) { 805812c3ccSTomohiro Kusumi bqrelse(bp); 815812c3ccSTomohiro Kusumi return EWOULDBLOCK; 825812c3ccSTomohiro Kusumi } 835812c3ccSTomohiro Kusumi 845812c3ccSTomohiro Kusumi error = breadnx(vp, base_offset, FUSE_BLKSIZE, B_NOTMETA, NULL, 855812c3ccSTomohiro Kusumi NULL, 0, &bp); 865812c3ccSTomohiro Kusumi KKASSERT(!error); 875812c3ccSTomohiro Kusumi 885812c3ccSTomohiro Kusumi fuse_dbg("b_loffset=%ju b_bcount=%d b_flags=%x\n", 895812c3ccSTomohiro Kusumi bp->b_loffset, bp->b_bcount, bp->b_flags); 905812c3ccSTomohiro Kusumi 915812c3ccSTomohiro Kusumi if (need_reopen) { 925812c3ccSTomohiro Kusumi error = falloc(NULL, &fp, NULL); 935812c3ccSTomohiro Kusumi if (error) { 945812c3ccSTomohiro Kusumi fuse_brelse(bp); 955812c3ccSTomohiro Kusumi break; 965812c3ccSTomohiro Kusumi } 975bd45597SMatthew Dillon error = VOP_OPEN(vp, FREAD | FWRITE, ap->a_cred, &fp); 985812c3ccSTomohiro Kusumi if (error) { 995812c3ccSTomohiro Kusumi fuse_brelse(bp); 1005812c3ccSTomohiro Kusumi break; 1015812c3ccSTomohiro Kusumi } 1025812c3ccSTomohiro Kusumi } 1035812c3ccSTomohiro Kusumi 1045812c3ccSTomohiro Kusumi fip = fuse_ipc_get(fmp, sizeof(*fri)); 1055812c3ccSTomohiro Kusumi fri = fuse_ipc_fill(fip, FUSE_READ, fnp->ino, ap->a_cred); 1065812c3ccSTomohiro Kusumi fri->offset = bp->b_loffset; 1075812c3ccSTomohiro Kusumi fri->size = bp->b_bcount; 1085812c3ccSTomohiro Kusumi if (need_reopen) 1095812c3ccSTomohiro Kusumi fri->fh = fuse_nfh(VTOI(vp)); 1105812c3ccSTomohiro Kusumi else 1115812c3ccSTomohiro Kusumi fri->fh = fh; 1125812c3ccSTomohiro Kusumi 1135812c3ccSTomohiro Kusumi fuse_dbg("fuse_read_in offset=%ju size=%u fh=%jx\n", 1145812c3ccSTomohiro Kusumi fri->offset, fri->size, fri->fh); 1155812c3ccSTomohiro Kusumi 1165812c3ccSTomohiro Kusumi error = fuse_ipc_tx(fip); 1175812c3ccSTomohiro Kusumi if (error) { 1185812c3ccSTomohiro Kusumi fuse_brelse(bp); 1195812c3ccSTomohiro Kusumi break; 1205812c3ccSTomohiro Kusumi } 1215812c3ccSTomohiro Kusumi memcpy(bp->b_data, fuse_out_data(fip), fuse_out_data_size(fip)); 1225812c3ccSTomohiro Kusumi fuse_ipc_put(fip); 1235812c3ccSTomohiro Kusumi 1245812c3ccSTomohiro Kusumi if (need_reopen) { 1255812c3ccSTomohiro Kusumi error = fdrop(fp); /* calls VOP_CLOSE() */ 1265812c3ccSTomohiro Kusumi if (error) { 1275812c3ccSTomohiro Kusumi fuse_brelse(bp); 1285812c3ccSTomohiro Kusumi break; 1295812c3ccSTomohiro Kusumi } 1305812c3ccSTomohiro Kusumi } 1315812c3ccSTomohiro Kusumi skip: 1325812c3ccSTomohiro Kusumi len = FUSE_BLKSIZE - buf_offset; 1335812c3ccSTomohiro Kusumi if (len > uio->uio_resid) 1345812c3ccSTomohiro Kusumi len = uio->uio_resid; 1355812c3ccSTomohiro Kusumi if (uio->uio_offset + len > fnp->size) 1365812c3ccSTomohiro Kusumi len = (size_t)(fnp->size - uio->uio_offset); 1375812c3ccSTomohiro Kusumi fuse_dbg("size=%ju len=%ju\n", fnp->size, len); 1385812c3ccSTomohiro Kusumi 1395812c3ccSTomohiro Kusumi error = uiomovebp(bp, bp->b_data + buf_offset, len, uio); 1405812c3ccSTomohiro Kusumi bqrelse(bp); 1415812c3ccSTomohiro Kusumi if (error) 1425812c3ccSTomohiro Kusumi break; 1435812c3ccSTomohiro Kusumi } 1445812c3ccSTomohiro Kusumi 1455812c3ccSTomohiro Kusumi fuse_dbg("uio_offset=%ju uio_resid=%ju error=%d done\n", 1465812c3ccSTomohiro Kusumi uio->uio_offset, uio->uio_resid, error); 1475812c3ccSTomohiro Kusumi 1485812c3ccSTomohiro Kusumi return error; 1495812c3ccSTomohiro Kusumi } 1505812c3ccSTomohiro Kusumi 1515812c3ccSTomohiro Kusumi int 1525812c3ccSTomohiro Kusumi fuse_write(struct vop_write_args *ap) 1535812c3ccSTomohiro Kusumi { 1545812c3ccSTomohiro Kusumi return fuse_dio_write(ap); 1555812c3ccSTomohiro Kusumi } 1565812c3ccSTomohiro Kusumi 1575812c3ccSTomohiro Kusumi int 1585812c3ccSTomohiro Kusumi fuse_dio_write(struct vop_write_args *ap) 1595812c3ccSTomohiro Kusumi { 1605812c3ccSTomohiro Kusumi struct vnode *vp = ap->a_vp; 1615812c3ccSTomohiro Kusumi struct uio *uio = ap->a_uio; 1625812c3ccSTomohiro Kusumi struct fuse_mount *fmp = VFSTOFUSE(vp->v_mount); 1635812c3ccSTomohiro Kusumi struct fuse_node *fnp = VTOI(vp); 1645812c3ccSTomohiro Kusumi bool need_reopen = !curproc || fnp->closed; /* XXX */ 1655812c3ccSTomohiro Kusumi int kflags = 0; 1665812c3ccSTomohiro Kusumi int error = 0; 1675812c3ccSTomohiro Kusumi 1685812c3ccSTomohiro Kusumi if (ap->a_ioflag & IO_APPEND) 1695812c3ccSTomohiro Kusumi uio->uio_offset = fnp->size; 1705812c3ccSTomohiro Kusumi 1715812c3ccSTomohiro Kusumi while (uio->uio_resid > 0) { 1725812c3ccSTomohiro Kusumi struct file *fp; 1735812c3ccSTomohiro Kusumi struct buf *bp; 1745812c3ccSTomohiro Kusumi struct fuse_ipc *fip; 1755812c3ccSTomohiro Kusumi struct fuse_read_in *fri; 1765812c3ccSTomohiro Kusumi struct fuse_write_in *fwi; 1775812c3ccSTomohiro Kusumi struct fuse_write_out *fwo; 1785812c3ccSTomohiro Kusumi off_t base_offset, buf_offset; 1795812c3ccSTomohiro Kusumi size_t len, oldsize; 1805812c3ccSTomohiro Kusumi uint64_t fh; 1815812c3ccSTomohiro Kusumi bool fixsize = false; 1825812c3ccSTomohiro Kusumi bool need_read = false; 1835812c3ccSTomohiro Kusumi 1845812c3ccSTomohiro Kusumi fh = fuse_nfh(VTOI(vp)); 1855812c3ccSTomohiro Kusumi if (ap->a_fp) 1865812c3ccSTomohiro Kusumi fh = fuse_fh(ap->a_fp); 1875812c3ccSTomohiro Kusumi 1885812c3ccSTomohiro Kusumi buf_offset = (off_t)uio->uio_offset & FUSE_BLKMASK64; 1895812c3ccSTomohiro Kusumi base_offset = (off_t)uio->uio_offset - buf_offset; 1905812c3ccSTomohiro Kusumi 1915812c3ccSTomohiro Kusumi fuse_dbg("uio_offset=%ju uio_resid=%ju base_offset=%ju " 1925812c3ccSTomohiro Kusumi "buf_offset=%ju\n", 1935812c3ccSTomohiro Kusumi uio->uio_offset, uio->uio_resid, base_offset, buf_offset); 1945812c3ccSTomohiro Kusumi 1955812c3ccSTomohiro Kusumi oldsize = fnp->size; 1965812c3ccSTomohiro Kusumi len = FUSE_BLKSIZE - buf_offset; 1975812c3ccSTomohiro Kusumi if (len > uio->uio_resid) 1985812c3ccSTomohiro Kusumi len = uio->uio_resid; 1995812c3ccSTomohiro Kusumi if (uio->uio_offset + len > fnp->size) { 2005812c3ccSTomohiro Kusumi /* XXX trivial flag */ 2015812c3ccSTomohiro Kusumi error = fuse_node_truncate(fnp, fnp->size, 2025812c3ccSTomohiro Kusumi uio->uio_offset + len); 2035812c3ccSTomohiro Kusumi if (error) 2045812c3ccSTomohiro Kusumi break; 2055812c3ccSTomohiro Kusumi fixsize = true; 2065812c3ccSTomohiro Kusumi kflags |= NOTE_EXTEND; 2075812c3ccSTomohiro Kusumi } 2085812c3ccSTomohiro Kusumi fuse_dbg("size=%ju len=%ju\n", fnp->size, len); 2095812c3ccSTomohiro Kusumi 2105812c3ccSTomohiro Kusumi bp = NULL; 2115812c3ccSTomohiro Kusumi if (uio->uio_segflg == UIO_NOCOPY) { 2125812c3ccSTomohiro Kusumi bp = getblk(ap->a_vp, base_offset, FUSE_BLKSIZE, 2135812c3ccSTomohiro Kusumi GETBLK_BHEAVY, 0); 2145812c3ccSTomohiro Kusumi if (!(bp->b_flags & B_CACHE)) { 2155812c3ccSTomohiro Kusumi bqrelse(bp); 2165812c3ccSTomohiro Kusumi need_read = true; 2175812c3ccSTomohiro Kusumi } 2185812c3ccSTomohiro Kusumi } else if (!buf_offset && uio->uio_resid >= FUSE_BLKSIZE) { 2195812c3ccSTomohiro Kusumi bp = getblk(ap->a_vp, base_offset, FUSE_BLKSIZE, 2205812c3ccSTomohiro Kusumi GETBLK_BHEAVY, 0); 2215812c3ccSTomohiro Kusumi if (!(bp->b_flags & B_CACHE)) 2225812c3ccSTomohiro Kusumi vfs_bio_clrbuf(bp); 2235812c3ccSTomohiro Kusumi } else if (base_offset >= fnp->size) { 2245812c3ccSTomohiro Kusumi bp = getblk(ap->a_vp, base_offset, FUSE_BLKSIZE, 2255812c3ccSTomohiro Kusumi GETBLK_BHEAVY, 0); 2265812c3ccSTomohiro Kusumi vfs_bio_clrbuf(bp); 2275812c3ccSTomohiro Kusumi } else { 2285812c3ccSTomohiro Kusumi need_read = true; 2295812c3ccSTomohiro Kusumi } 2305812c3ccSTomohiro Kusumi 2315812c3ccSTomohiro Kusumi if (bp) 2325812c3ccSTomohiro Kusumi fuse_dbg("b_loffset=%ju b_bcount=%d b_flags=%x\n", 2335812c3ccSTomohiro Kusumi bp->b_loffset, bp->b_bcount, bp->b_flags); 2345812c3ccSTomohiro Kusumi 2355812c3ccSTomohiro Kusumi if (need_reopen) { 2365812c3ccSTomohiro Kusumi error = falloc(NULL, &fp, NULL); 2375812c3ccSTomohiro Kusumi if (error) { 2385812c3ccSTomohiro Kusumi fuse_brelse(bp); 2395812c3ccSTomohiro Kusumi fuse_fix_size(fnp, fixsize, oldsize); 2405812c3ccSTomohiro Kusumi break; 2415812c3ccSTomohiro Kusumi } 2425812c3ccSTomohiro Kusumi /* XXX can panic at vref() in vop_stdopen() */ 2435bd45597SMatthew Dillon error = VOP_OPEN(vp, FREAD | FWRITE, ap->a_cred, &fp); 2445812c3ccSTomohiro Kusumi if (error) { 2455812c3ccSTomohiro Kusumi fuse_brelse(bp); 2465812c3ccSTomohiro Kusumi fuse_fix_size(fnp, fixsize, oldsize); 2475812c3ccSTomohiro Kusumi break; 2485812c3ccSTomohiro Kusumi } 2495812c3ccSTomohiro Kusumi } 2505812c3ccSTomohiro Kusumi 2515812c3ccSTomohiro Kusumi if (need_read) { 2525812c3ccSTomohiro Kusumi error = bread(ap->a_vp, base_offset, FUSE_BLKSIZE, &bp); 2535812c3ccSTomohiro Kusumi KKASSERT(!error); 2545812c3ccSTomohiro Kusumi 2555812c3ccSTomohiro Kusumi fuse_dbg("b_loffset=%ju b_bcount=%d b_flags=%x\n", 2565812c3ccSTomohiro Kusumi bp->b_loffset, bp->b_bcount, bp->b_flags); 2575812c3ccSTomohiro Kusumi 2585812c3ccSTomohiro Kusumi if (bp->b_loffset + (buf_offset + len) > oldsize) { 2595812c3ccSTomohiro Kusumi memset(bp->b_data, 0, FUSE_BLKSIZE); /* XXX */ 2605812c3ccSTomohiro Kusumi goto skip; /* prevent EBADF */ 2615812c3ccSTomohiro Kusumi } 2625812c3ccSTomohiro Kusumi 2635812c3ccSTomohiro Kusumi fip = fuse_ipc_get(fmp, sizeof(*fri)); 2645812c3ccSTomohiro Kusumi fri = fuse_ipc_fill(fip, FUSE_READ, fnp->ino, 2655812c3ccSTomohiro Kusumi ap->a_cred); 2665812c3ccSTomohiro Kusumi fri->offset = bp->b_loffset; 2675812c3ccSTomohiro Kusumi fri->size = buf_offset + len; 2685812c3ccSTomohiro Kusumi if (need_reopen) 2695812c3ccSTomohiro Kusumi fri->fh = fuse_nfh(VTOI(vp)); 2705812c3ccSTomohiro Kusumi else 2715812c3ccSTomohiro Kusumi fri->fh = fh; 2725812c3ccSTomohiro Kusumi 2735812c3ccSTomohiro Kusumi fuse_dbg("fuse_read_in offset=%ju size=%u fh=%jx\n", 2745812c3ccSTomohiro Kusumi fri->offset, fri->size, fri->fh); 2755812c3ccSTomohiro Kusumi 2765812c3ccSTomohiro Kusumi error = fuse_ipc_tx(fip); 2775812c3ccSTomohiro Kusumi if (error) { 2785812c3ccSTomohiro Kusumi fuse_brelse(bp); 2795812c3ccSTomohiro Kusumi fuse_fix_size(fnp, fixsize, oldsize); 2805812c3ccSTomohiro Kusumi break; 2815812c3ccSTomohiro Kusumi } 2825812c3ccSTomohiro Kusumi memcpy(bp->b_data, fuse_out_data(fip), 2835812c3ccSTomohiro Kusumi fuse_out_data_size(fip)); 2845812c3ccSTomohiro Kusumi fuse_ipc_put(fip); 2855812c3ccSTomohiro Kusumi } 2865812c3ccSTomohiro Kusumi skip: 2875812c3ccSTomohiro Kusumi error = uiomovebp(bp, bp->b_data + buf_offset, len, uio); 2885812c3ccSTomohiro Kusumi if (error) { 2895812c3ccSTomohiro Kusumi bqrelse(bp); 2905812c3ccSTomohiro Kusumi fuse_fix_size(fnp, fixsize, oldsize); 2915812c3ccSTomohiro Kusumi break; 2925812c3ccSTomohiro Kusumi } 2935812c3ccSTomohiro Kusumi kflags |= NOTE_WRITE; 2945812c3ccSTomohiro Kusumi 2955812c3ccSTomohiro Kusumi fip = fuse_ipc_get(fmp, sizeof(*fwi) + len); 2965812c3ccSTomohiro Kusumi fwi = fuse_ipc_fill(fip, FUSE_WRITE, fnp->ino, ap->a_cred); 2975812c3ccSTomohiro Kusumi fwi->offset = bp->b_loffset + buf_offset; 2985812c3ccSTomohiro Kusumi fwi->size = len; 2995812c3ccSTomohiro Kusumi if (need_reopen) 3005812c3ccSTomohiro Kusumi fwi->fh = fuse_nfh(VTOI(vp)); 3015812c3ccSTomohiro Kusumi else 3025812c3ccSTomohiro Kusumi fwi->fh = fh; 3035812c3ccSTomohiro Kusumi memcpy((void*)(fwi + 1), bp->b_data + buf_offset, len); 3045812c3ccSTomohiro Kusumi 3055812c3ccSTomohiro Kusumi fuse_dbg("fuse_write_in offset=%ju size=%u fh=%jx\n", 3065812c3ccSTomohiro Kusumi fwi->offset, fwi->size, fwi->fh); 3075812c3ccSTomohiro Kusumi 3085812c3ccSTomohiro Kusumi error = fuse_ipc_tx(fip); 3095812c3ccSTomohiro Kusumi if (error) { 3105812c3ccSTomohiro Kusumi fuse_brelse(bp); 3115812c3ccSTomohiro Kusumi fuse_fix_size(fnp, fixsize, oldsize); 3125812c3ccSTomohiro Kusumi break; 3135812c3ccSTomohiro Kusumi } 3145812c3ccSTomohiro Kusumi fwo = fuse_out_data(fip); 3155812c3ccSTomohiro Kusumi if (fwo->size != len) { 3165812c3ccSTomohiro Kusumi fuse_ipc_put(fip); 3175812c3ccSTomohiro Kusumi fuse_brelse(bp); 3185812c3ccSTomohiro Kusumi fuse_fix_size(fnp, fixsize, oldsize); 3195812c3ccSTomohiro Kusumi break; 3205812c3ccSTomohiro Kusumi } 3215812c3ccSTomohiro Kusumi fuse_ipc_put(fip); 3225812c3ccSTomohiro Kusumi 3235812c3ccSTomohiro Kusumi if (need_reopen) { 3245812c3ccSTomohiro Kusumi error = fdrop(fp); /* calls VOP_CLOSE() */ 3255812c3ccSTomohiro Kusumi if (error) { 3265812c3ccSTomohiro Kusumi fuse_brelse(bp); 3275812c3ccSTomohiro Kusumi fuse_fix_size(fnp, fixsize, oldsize); 3285812c3ccSTomohiro Kusumi break; 3295812c3ccSTomohiro Kusumi } 3305812c3ccSTomohiro Kusumi } 3315812c3ccSTomohiro Kusumi 3325812c3ccSTomohiro Kusumi error = bwrite(bp); 3335812c3ccSTomohiro Kusumi KKASSERT(!error); 3345812c3ccSTomohiro Kusumi } 3355812c3ccSTomohiro Kusumi 3365812c3ccSTomohiro Kusumi fuse_knote(ap->a_vp, kflags); 3375812c3ccSTomohiro Kusumi 3385812c3ccSTomohiro Kusumi fuse_dbg("uio_offset=%ju uio_resid=%ju error=%d done\n", 3395812c3ccSTomohiro Kusumi uio->uio_offset, uio->uio_resid, error); 3405812c3ccSTomohiro Kusumi 3415812c3ccSTomohiro Kusumi return error; 3425812c3ccSTomohiro Kusumi } 343*5d0d0bafSMatthew Dillon #endif 344