diff options
author | alc <alc@FreeBSD.org> | 2003-10-20 05:57:55 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2003-10-20 05:57:55 +0000 |
commit | ba669f61995f85d29944a6d89b25a6fc37c8e77a (patch) | |
tree | bcd1ab6a87da801363799a59ea89f8f9510ad48e | |
parent | 87282b0dcb5127d039a406b2578faafbc83d0703 (diff) | |
download | FreeBSD-src-ba669f61995f85d29944a6d89b25a6fc37c8e77a.zip FreeBSD-src-ba669f61995f85d29944a6d89b25a6fc37c8e77a.tar.gz |
- Synchronize access to a vm page's valid field using the containing
vm object's lock.
-rw-r--r-- | sys/kern/vfs_cluster.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/sys/kern/vfs_cluster.c b/sys/kern/vfs_cluster.c index d46ae86..11964ac 100644 --- a/sys/kern/vfs_cluster.c +++ b/sys/kern/vfs_cluster.c @@ -373,6 +373,7 @@ cluster_rbuild(vp, filesize, lbn, blkno, size, run, fbp) bp->b_offset = tbp->b_offset; KASSERT(bp->b_offset != NOOFFSET, ("cluster_rbuild: no buffer offset")); pbgetvp(vp, bp); + bp->b_object = tbp->b_object; TAILQ_INIT(&bp->b_cluster.cluster_head); @@ -416,10 +417,14 @@ cluster_rbuild(vp, filesize, lbn, blkno, size, run, fbp) * take part in the cluster. If it is partially valid * then we stop. */ + VM_OBJECT_LOCK(tbp->b_object); for (j = 0;j < tbp->b_npages; j++) { + VM_OBJECT_LOCK_ASSERT(tbp->b_pages[j]->object, + MA_OWNED); if (tbp->b_pages[j]->valid) break; } + VM_OBJECT_UNLOCK(tbp->b_object); if (j != tbp->b_npages) { bqrelse(tbp); break; @@ -454,8 +459,7 @@ cluster_rbuild(vp, filesize, lbn, blkno, size, run, fbp) BUF_KERNPROC(tbp); TAILQ_INSERT_TAIL(&bp->b_cluster.cluster_head, tbp, b_cluster.cluster_entry); - if (tbp->b_object != NULL) - VM_OBJECT_LOCK(tbp->b_object); + VM_OBJECT_LOCK(tbp->b_object); vm_page_lock_queues(); for (j = 0; j < tbp->b_npages; j += 1) { vm_page_t m; @@ -471,8 +475,7 @@ cluster_rbuild(vp, filesize, lbn, blkno, size, run, fbp) tbp->b_pages[j] = bogus_page; } vm_page_unlock_queues(); - if (tbp->b_object != NULL) - VM_OBJECT_UNLOCK(tbp->b_object); + VM_OBJECT_UNLOCK(tbp->b_object); /* * XXX shouldn't this be += size for both, like in * cluster_wbuild()? @@ -493,12 +496,15 @@ cluster_rbuild(vp, filesize, lbn, blkno, size, run, fbp) * Fully valid pages in the cluster are already good and do not need * to be re-read from disk. Replace the page with bogus_page */ + VM_OBJECT_LOCK(bp->b_object); for (j = 0; j < bp->b_npages; j++) { + VM_OBJECT_LOCK_ASSERT(bp->b_pages[j]->object, MA_OWNED); if ((bp->b_pages[j]->valid & VM_PAGE_BITS_ALL) == VM_PAGE_BITS_ALL) { bp->b_pages[j] = bogus_page; } } + VM_OBJECT_UNLOCK(bp->b_object); if (bp->b_bufsize > bp->b_kvasize) panic("cluster_rbuild: b_bufsize(%ld) > b_kvasize(%d)\n", bp->b_bufsize, bp->b_kvasize); |