svn commit: r271540 - in head/sys: fs/ext2fs ufs/ffs
Alan Cox
alc at FreeBSD.org
Sat Sep 13 18:26:14 UTC 2014
Author: alc
Date: Sat Sep 13 18:26:13 2014
New Revision: 271540
URL: http://svnweb.freebsd.org/changeset/base/271540
Log:
We don't need an exclusive object lock on the expected execution path
through {ext2,ffs}_getpages().
Reviewed by: kib, pfg
MFC after: 6 weeks
Sponsored by: EMC / Isilon Storage Division
Modified:
head/sys/fs/ext2fs/ext2_vnops.c
head/sys/ufs/ffs/ffs_vnops.c
Modified: head/sys/fs/ext2fs/ext2_vnops.c
==============================================================================
--- head/sys/fs/ext2fs/ext2_vnops.c Sat Sep 13 18:24:54 2014 (r271539)
+++ head/sys/fs/ext2fs/ext2_vnops.c Sat Sep 13 18:26:13 2014 (r271540)
@@ -2074,19 +2074,25 @@ ext2_getpages(struct vop_getpages_args *
vm_page_t mreq;
int pcount;
- pcount = round_page(ap->a_count) / PAGE_SIZE;
mreq = ap->a_m[ap->a_reqpage];
/*
+ * Since the caller has busied the requested page, that page's valid
+ * field will not be changed by other threads.
+ */
+ vm_page_assert_xbusied(mreq);
+
+ /*
* if ANY DEV_BSIZE blocks are valid on a large filesystem block,
* then the entire page is valid. Since the page may be mapped,
* user programs might reference data beyond the actual end of file
* occuring within the page. We have to zero that data.
*/
- VM_OBJECT_WLOCK(mreq->object);
if (mreq->valid) {
+ VM_OBJECT_WLOCK(mreq->object);
if (mreq->valid != VM_PAGE_BITS_ALL)
vm_page_zero_invalid(mreq, TRUE);
+ pcount = round_page(ap->a_count) / PAGE_SIZE;
for (i = 0; i < pcount; i++) {
if (i != ap->a_reqpage) {
vm_page_lock(ap->a_m[i]);
@@ -2097,7 +2103,6 @@ ext2_getpages(struct vop_getpages_args *
VM_OBJECT_WUNLOCK(mreq->object);
return VM_PAGER_OK;
}
- VM_OBJECT_WUNLOCK(mreq->object);
return vnode_pager_generic_getpages(ap->a_vp, ap->a_m,
ap->a_count,
Modified: head/sys/ufs/ffs/ffs_vnops.c
==============================================================================
--- head/sys/ufs/ffs/ffs_vnops.c Sat Sep 13 18:24:54 2014 (r271539)
+++ head/sys/ufs/ffs/ffs_vnops.c Sat Sep 13 18:26:13 2014 (r271540)
@@ -857,19 +857,25 @@ ffs_getpages(ap)
vm_page_t mreq;
int pcount;
- pcount = round_page(ap->a_count) / PAGE_SIZE;
mreq = ap->a_m[ap->a_reqpage];
/*
+ * Since the caller has busied the requested page, that page's valid
+ * field will not be changed by other threads.
+ */
+ vm_page_assert_xbusied(mreq);
+
+ /*
* if ANY DEV_BSIZE blocks are valid on a large filesystem block,
* then the entire page is valid. Since the page may be mapped,
* user programs might reference data beyond the actual end of file
* occuring within the page. We have to zero that data.
*/
- VM_OBJECT_WLOCK(mreq->object);
if (mreq->valid) {
+ VM_OBJECT_WLOCK(mreq->object);
if (mreq->valid != VM_PAGE_BITS_ALL)
vm_page_zero_invalid(mreq, TRUE);
+ pcount = round_page(ap->a_count) / PAGE_SIZE;
for (i = 0; i < pcount; i++) {
if (i != ap->a_reqpage) {
vm_page_lock(ap->a_m[i]);
@@ -880,7 +886,6 @@ ffs_getpages(ap)
VM_OBJECT_WUNLOCK(mreq->object);
return VM_PAGER_OK;
}
- VM_OBJECT_WUNLOCK(mreq->object);
return vnode_pager_generic_getpages(ap->a_vp, ap->a_m,
ap->a_count,
More information about the svn-src-head
mailing list