summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortruckman <truckman@FreeBSD.org>2005-09-30 18:07:41 +0000
committertruckman <truckman@FreeBSD.org>2005-09-30 18:07:41 +0000
commit7dfe92499b7e0ea087caa4e1dbc1079abe841768 (patch)
tree9e904b90d9d95a774677892619bde564e956a568
parentdbcc5e2770c9a125a38072056024bbb2164fe5fc (diff)
downloadFreeBSD-src-7dfe92499b7e0ea087caa4e1dbc1079abe841768.zip
FreeBSD-src-7dfe92499b7e0ea087caa4e1dbc1079abe841768.tar.gz
Un-staticize waitrunningbufspace() and call it before returning from
ffs_copyonwrite() if any async writes were launched. Restore the threads previous TDP_NORUNNINGBUF state before returning from ffs_copyonwrite().
-rw-r--r--sys/kern/vfs_bio.c2
-rw-r--r--sys/sys/buf.h1
-rw-r--r--sys/ufs/ffs/ffs_snapshot.c14
3 files changed, 15 insertions, 2 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index 945d95d..dd11298 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -373,7 +373,7 @@ bufcountwakeup(void)
* for earlier writes to complete and generally returns before the
* caller's write has reached the device.
*/
-static __inline void
+void
waitrunningbufspace(void)
{
diff --git a/sys/sys/buf.h b/sys/sys/buf.h
index 6ef4f0f..a3dde53 100644
--- a/sys/sys/buf.h
+++ b/sys/sys/buf.h
@@ -478,6 +478,7 @@ extern int cluster_pbuf_freecnt; /* Number of pbufs for clusters */
extern int vnode_pbuf_freecnt; /* Number of pbufs for vnode pager */
void runningbufwakeup(struct buf *);
+void waitrunningbufspace(void);
caddr_t kern_vfs_bio_buffer_alloc(caddr_t v, long physmem_est);
void bufinit(void);
void bwillwrite(void);
diff --git a/sys/ufs/ffs/ffs_snapshot.c b/sys/ufs/ffs/ffs_snapshot.c
index 3e7e231..5c62d02 100644
--- a/sys/ufs/ffs/ffs_snapshot.c
+++ b/sys/ufs/ffs/ffs_snapshot.c
@@ -1969,6 +1969,7 @@ ffs_copyonwrite(devvp, bp)
struct vnode *vp = 0;
ufs2_daddr_t lbn, blkno, *snapblklist;
int lower, upper, mid, indiroff, snapshot_locked = 0, error = 0;
+ int launched_async_io, prev_norunningbuf;
if (td->td_pflags & TDP_COWINPROGRESS)
panic("ffs_copyonwrite: recursive call");
@@ -1997,6 +1998,8 @@ ffs_copyonwrite(devvp, bp)
VI_UNLOCK(devvp);
return (0);
}
+ launched_async_io = 0;
+ prev_norunningbuf = td->td_pflags & TDP_NORUNNINGBUF;
/*
* Since I/O on bp isn't yet in progress and it may be blocked
* for a long time waiting on snaplk, back it out of
@@ -2101,6 +2104,8 @@ retry:
bawrite(cbp);
if (dopersistence && ip->i_effnlink > 0)
(void) ffs_syncvnode(vp, MNT_WAIT);
+ else
+ launched_async_io = 1;
continue;
}
/*
@@ -2111,6 +2116,8 @@ retry:
bawrite(cbp);
if (dopersistence && ip->i_effnlink > 0)
(void) ffs_syncvnode(vp, MNT_WAIT);
+ else
+ launched_async_io = 1;
break;
}
savedcbp = cbp;
@@ -2125,12 +2132,17 @@ retry:
bawrite(savedcbp);
if (dopersistence && VTOI(vp)->i_effnlink > 0)
(void) ffs_syncvnode(vp, MNT_WAIT);
+ else
+ launched_async_io = 1;
}
if (snapshot_locked) {
lockmgr(vp->v_vnlock, LK_RELEASE, NULL, td);
- td->td_pflags &= ~TDP_NORUNNINGBUF;
+ td->td_pflags = (td->td_pflags & ~TDP_NORUNNINGBUF) |
+ prev_norunningbuf;
} else
VI_UNLOCK(devvp);
+ if (launched_async_io && (td->td_pflags & TDP_NORUNNINGBUF))
+ waitrunningbufspace();
/*
* I/O on bp will now be started, so count it in runningbufspace.
*/
OpenPOWER on IntegriCloud