Correct a long-standing performance bug in cluster_rbuild(). Specifically,
in the case of a file system with a block size that is less than the page size, cluster_rbuild() looks at too many of the page's valid bits. Consequently, it may terminate prematurely, resulting in poor performance. Reported by: bde Reviewed by: tegge Approved by: re (kib)
This commit is contained in:
parent
29bd7d7e9a
commit
de0c3e0895
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=195122
@ -310,7 +310,9 @@ cluster_rbuild(vp, filesize, lbn, blkno, size, run, fbp)
|
||||
struct bufobj *bo;
|
||||
struct buf *bp, *tbp;
|
||||
daddr_t bn;
|
||||
int i, inc, j;
|
||||
off_t off;
|
||||
long tinc, tsize;
|
||||
int i, inc, j, toff;
|
||||
|
||||
KASSERT(size == vp->v_mount->mnt_stat.f_iosize,
|
||||
("cluster_rbuild: size %ld != filesize %jd\n",
|
||||
@ -402,15 +404,24 @@ cluster_rbuild(vp, filesize, lbn, blkno, size, run, fbp)
|
||||
* take part in the cluster. If it is partially valid
|
||||
* then we stop.
|
||||
*/
|
||||
off = tbp->b_offset;
|
||||
tsize = size;
|
||||
VM_OBJECT_LOCK(tbp->b_bufobj->bo_object);
|
||||
for (j = 0;j < tbp->b_npages; j++) {
|
||||
for (j = 0; tsize > 0; j++) {
|
||||
toff = off & PAGE_MASK;
|
||||
tinc = tsize;
|
||||
if (toff + tinc > PAGE_SIZE)
|
||||
tinc = PAGE_SIZE - toff;
|
||||
VM_OBJECT_LOCK_ASSERT(tbp->b_pages[j]->object,
|
||||
MA_OWNED);
|
||||
if (tbp->b_pages[j]->valid)
|
||||
if ((tbp->b_pages[j]->valid &
|
||||
vm_page_bits(toff, tinc)) != 0)
|
||||
break;
|
||||
off += tinc;
|
||||
tsize -= tinc;
|
||||
}
|
||||
VM_OBJECT_UNLOCK(tbp->b_bufobj->bo_object);
|
||||
if (j != tbp->b_npages) {
|
||||
if (tsize > 0) {
|
||||
bqrelse(tbp);
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user