From b0c1faefddc8e9564347eed879ea0ae17ff4a960 Mon Sep 17 00:00:00 2001 From: Semen Ustimenko Date: Wed, 31 Jul 2002 00:42:57 +0000 Subject: [PATCH] Fix a problem with sendfile() syscall by always doing I/O via bread() in ntfs_read(). This guarantee that requested cache pages will be valid if UIO_NOCOPY specifed. PR: bin/34072, bin/36189 MFC after: 1 week --- sys/fs/ntfs/ntfs_vnops.c | 43 +++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/sys/fs/ntfs/ntfs_vnops.c b/sys/fs/ntfs/ntfs_vnops.c index 52e24c693ce..dbb559383d9 100644 --- a/sys/fs/ntfs/ntfs_vnops.c +++ b/sys/fs/ntfs/ntfs_vnops.c @@ -101,7 +101,9 @@ ntfs_read(ap) register struct ntnode *ip = FTONT(fp); struct uio *uio = ap->a_uio; struct ntfsmount *ntmp = ip->i_mp; - u_int64_t toread; + struct buf *bp; + daddr_t cn; + int resid, off, toread; int error; dprintf(("ntfs_read: ino: %d, off: %d resid: %d, segflg: %d\n",ip->i_number,(u_int32_t)uio->uio_offset,uio->uio_resid,uio->uio_segflg)); @@ -110,23 +112,36 @@ ntfs_read(ap) /* don't allow reading after end of file */ if (uio->uio_offset > fp->f_size) - toread = 0; - else - toread = min( uio->uio_resid, fp->f_size - uio->uio_offset ); - - dprintf((", toread: %d\n",(u_int32_t)toread)); - - if (toread == 0) return (0); - error = ntfs_readattr(ntmp, ip, fp->f_attrtype, - fp->f_attrname, uio->uio_offset, toread, NULL, uio); - if (error) { - printf("ntfs_read: ntfs_readattr failed: %d\n",error); - return (error); + resid = min(uio->uio_resid, fp->f_size - uio->uio_offset); + + dprintf((", resid: %d\n", resid)); + + error = 0; + while (resid) { + cn = ntfs_btocn(uio->uio_offset); + off = ntfs_btocnoff(uio->uio_offset); + + toread = min(off + resid, ntfs_cntob(1)); + + error = bread(vp, cn, ntfs_cntob(1), NOCRED, &bp); + if (error) { + brelse(bp); + break; + } + + error = uiomove(bp->b_data + off, toread - off, uio); + if(error) { + brelse(bp); + break; + } + brelse(bp); + + resid -= toread - off; } - return (0); + return (error); } static int