Refine the implementation of POSIX_FADV_NOREUSE for the read(2) case such

that instead of using direct I/O it allows read-ahead similar to
POSIX_FADV_NORMAL, but invokes VOP_ADVISE(POSIX_FADV_DONTNEED) after the
read(2) has completed to purge just-read data.  The write(2) path continues
to use direct I/O for POSIX_FADV_NOREUSE for now.  Note that NOREUSE works
optimally if an application reads and writes full fs blocks.
This commit is contained in:
John Baldwin 2012-01-30 19:35:15 +00:00
parent 75ce221fa1
commit 2bd3e4c2c2

View File

@ -519,6 +519,7 @@ vn_read(fp, uio, active_cred, flags, td)
int error, ioflag;
struct mtx *mtxp;
int advice, vfslocked;
off_t offset;
KASSERT(uio->uio_td == td, ("uio_td %p is not td %p",
uio->uio_td, td));
@ -558,19 +559,14 @@ vn_read(fp, uio, active_cred, flags, td)
switch (advice) {
case POSIX_FADV_NORMAL:
case POSIX_FADV_SEQUENTIAL:
case POSIX_FADV_NOREUSE:
ioflag |= sequential_heuristic(uio, fp);
break;
case POSIX_FADV_RANDOM:
/* Disable read-ahead for random I/O. */
break;
case POSIX_FADV_NOREUSE:
/*
* Request the underlying FS to discard the buffers
* and pages after the I/O is complete.
*/
ioflag |= IO_DIRECT;
break;
}
offset = uio->uio_offset;
#ifdef MAC
error = mac_vnode_check_read(active_cred, fp->f_cred, vp);
@ -587,6 +583,10 @@ vn_read(fp, uio, active_cred, flags, td)
}
fp->f_nextoff = uio->uio_offset;
VOP_UNLOCK(vp, 0);
if (error == 0 && advice == POSIX_FADV_NOREUSE &&
offset != uio->uio_offset)
error = VOP_ADVISE(vp, offset, uio->uio_offset - 1,
POSIX_FADV_DONTNEED);
VFS_UNLOCK_GIANT(vfslocked);
return (error);
}