Changeset View
Changeset View
Standalone View
Standalone View
sys/ufs/ffs/ffs_rawread.c
Show First 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | static int ffs_rawread_main(struct vnode *vp, | ||||
struct uio *uio); | struct uio *uio); | ||||
static int ffs_rawread_sync(struct vnode *vp); | static int ffs_rawread_sync(struct vnode *vp); | ||||
int ffs_rawread(struct vnode *vp, struct uio *uio, int *workdone); | int ffs_rawread(struct vnode *vp, struct uio *uio, int *workdone); | ||||
SYSCTL_DECL(_vfs_ffs); | SYSCTL_DECL(_vfs_ffs); | ||||
static int ffsrawbufcnt = 4; | static uma_zone_t ffsraw_pbuf_zone; | ||||
SYSCTL_INT(_vfs_ffs, OID_AUTO, ffsrawbufcnt, CTLFLAG_RD, &ffsrawbufcnt, 0, | |||||
"Buffers available for raw reads"); | |||||
static int allowrawread = 1; | static int allowrawread = 1; | ||||
SYSCTL_INT(_vfs_ffs, OID_AUTO, allowrawread, CTLFLAG_RW, &allowrawread, 0, | SYSCTL_INT(_vfs_ffs, OID_AUTO, allowrawread, CTLFLAG_RW, &allowrawread, 0, | ||||
"Flag to enable raw reads"); | "Flag to enable raw reads"); | ||||
static int rawreadahead = 1; | static int rawreadahead = 1; | ||||
SYSCTL_INT(_vfs_ffs, OID_AUTO, rawreadahead, CTLFLAG_RW, &rawreadahead, 0, | SYSCTL_INT(_vfs_ffs, OID_AUTO, rawreadahead, CTLFLAG_RW, &rawreadahead, 0, | ||||
"Flag to enable readahead for long raw reads"); | "Flag to enable readahead for long raw reads"); | ||||
static void | static void | ||||
ffs_rawread_setup(void *arg __unused) | ffs_rawread_setup(void *arg __unused) | ||||
{ | { | ||||
ffsrawbufcnt = (nswbuf > 100 ) ? (nswbuf - (nswbuf >> 4)) : nswbuf - 8; | ffsraw_pbuf_zone = uma_zsecond_create("ffsrawpbuf", pbuf_ctor, | ||||
pbuf_dtor, pbuf_init, NULL, pbuf_zone); | |||||
uma_zone_set_max(ffsraw_pbuf_zone, (nswbuf > 100 ) ? | |||||
(nswbuf - (nswbuf >> 4)) : nswbuf - 8); | |||||
} | } | ||||
SYSINIT(ffs_raw, SI_SUB_VM_CONF, SI_ORDER_ANY, ffs_rawread_setup, NULL); | SYSINIT(ffs_raw, SI_SUB_VM_CONF, SI_ORDER_ANY, ffs_rawread_setup, NULL); | ||||
static int | static int | ||||
ffs_rawread_sync(struct vnode *vp) | ffs_rawread_sync(struct vnode *vp) | ||||
{ | { | ||||
int error; | int error; | ||||
int upgraded; | int upgraded; | ||||
▲ Show 20 Lines • Show All 189 Lines • ▼ Show 20 Lines | ffs_rawread_main(struct vnode *vp, | ||||
nerror = 0; | nerror = 0; | ||||
bp = NULL; | bp = NULL; | ||||
nbp = NULL; | nbp = NULL; | ||||
while (resid > 0) { | while (resid > 0) { | ||||
if (bp == NULL) { /* Setup first read */ | if (bp == NULL) { /* Setup first read */ | ||||
/* XXX: Leave some bufs for swap */ | bp = uma_zalloc(ffsraw_pbuf_zone, M_WAITOK); | ||||
bp = getpbuf(&ffsrawbufcnt); | |||||
pbgetvp(vp, bp); | pbgetvp(vp, bp); | ||||
error = ffs_rawread_readahead(vp, udata, offset, | error = ffs_rawread_readahead(vp, udata, offset, | ||||
resid, td, bp); | resid, td, bp); | ||||
if (error != 0) | if (error != 0) | ||||
break; | break; | ||||
if (resid > bp->b_bufsize) { /* Setup fist readahead */ | if (resid > bp->b_bufsize) { /* Setup fist readahead */ | ||||
/* XXX: Leave bufs for swap */ | |||||
if (rawreadahead != 0) | if (rawreadahead != 0) | ||||
nbp = trypbuf(&ffsrawbufcnt); | nbp = uma_zalloc(ffsraw_pbuf_zone, | ||||
M_NOWAIT); | |||||
else | else | ||||
nbp = NULL; | nbp = NULL; | ||||
if (nbp != NULL) { | if (nbp != NULL) { | ||||
pbgetvp(vp, nbp); | pbgetvp(vp, nbp); | ||||
nerror = ffs_rawread_readahead(vp, | nerror = ffs_rawread_readahead(vp, | ||||
udata + | udata + | ||||
bp->b_bufsize, | bp->b_bufsize, | ||||
offset + | offset + | ||||
bp->b_bufsize, | bp->b_bufsize, | ||||
resid - | resid - | ||||
bp->b_bufsize, | bp->b_bufsize, | ||||
td, | td, | ||||
nbp); | nbp); | ||||
if (nerror) { | if (nerror) { | ||||
pbrelvp(nbp); | pbrelvp(nbp); | ||||
relpbuf(nbp, &ffsrawbufcnt); | uma_zfree(ffsraw_pbuf_zone, | ||||
nbp); | |||||
nbp = NULL; | nbp = NULL; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
bwait(bp, PRIBIO, "rawrd"); | bwait(bp, PRIBIO, "rawrd"); | ||||
vunmapbuf(bp); | vunmapbuf(bp); | ||||
Show All 24 Lines | while (resid > 0) { | ||||
} else if (nbp != NULL) { /* Complete read with readahead */ | } else if (nbp != NULL) { /* Complete read with readahead */ | ||||
tbp = bp; | tbp = bp; | ||||
bp = nbp; | bp = nbp; | ||||
nbp = tbp; | nbp = tbp; | ||||
if (resid <= bp->b_bufsize) { /* No more readaheads */ | if (resid <= bp->b_bufsize) { /* No more readaheads */ | ||||
pbrelvp(nbp); | pbrelvp(nbp); | ||||
relpbuf(nbp, &ffsrawbufcnt); | uma_zfree(ffsraw_pbuf_zone, nbp); | ||||
nbp = NULL; | nbp = NULL; | ||||
} else { /* Setup next readahead */ | } else { /* Setup next readahead */ | ||||
nerror = ffs_rawread_readahead(vp, | nerror = ffs_rawread_readahead(vp, | ||||
udata + | udata + | ||||
bp->b_bufsize, | bp->b_bufsize, | ||||
offset + | offset + | ||||
bp->b_bufsize, | bp->b_bufsize, | ||||
resid - | resid - | ||||
bp->b_bufsize, | bp->b_bufsize, | ||||
td, | td, | ||||
nbp); | nbp); | ||||
if (nerror != 0) { | if (nerror != 0) { | ||||
pbrelvp(nbp); | pbrelvp(nbp); | ||||
relpbuf(nbp, &ffsrawbufcnt); | uma_zfree(ffsraw_pbuf_zone, nbp); | ||||
nbp = NULL; | nbp = NULL; | ||||
} | } | ||||
} | } | ||||
} else if (nerror != 0) {/* Deferred Readahead error */ | } else if (nerror != 0) {/* Deferred Readahead error */ | ||||
break; | break; | ||||
} else if (resid > 0) { /* More to read, no readahead */ | } else if (resid > 0) { /* More to read, no readahead */ | ||||
error = ffs_rawread_readahead(vp, udata, offset, | error = ffs_rawread_readahead(vp, udata, offset, | ||||
resid, td, bp); | resid, td, bp); | ||||
if (error != 0) | if (error != 0) | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
if (bp != NULL) { | if (bp != NULL) { | ||||
pbrelvp(bp); | pbrelvp(bp); | ||||
relpbuf(bp, &ffsrawbufcnt); | uma_zfree(ffsraw_pbuf_zone, bp); | ||||
} | } | ||||
if (nbp != NULL) { /* Run down readahead buffer */ | if (nbp != NULL) { /* Run down readahead buffer */ | ||||
bwait(nbp, PRIBIO, "rawrd"); | bwait(nbp, PRIBIO, "rawrd"); | ||||
vunmapbuf(nbp); | vunmapbuf(nbp); | ||||
pbrelvp(nbp); | pbrelvp(nbp); | ||||
relpbuf(nbp, &ffsrawbufcnt); | uma_zfree(ffsraw_pbuf_zone, nbp); | ||||
} | } | ||||
if (error == 0) | if (error == 0) | ||||
error = nerror; | error = nerror; | ||||
PRELE(td->td_proc); | PRELE(td->td_proc); | ||||
uio->uio_iov->iov_base = udata; | uio->uio_iov->iov_base = udata; | ||||
uio->uio_resid = resid; | uio->uio_resid = resid; | ||||
uio->uio_offset = offset; | uio->uio_offset = offset; | ||||
▲ Show 20 Lines • Show All 64 Lines • Show Last 20 Lines |