version 1.86.4.2, 2007/03/21 20:11:58 |
version 1.86.4.3, 2007/05/13 17:36:43 |
Line 246 ffs_fsync(void *v) |
|
Line 246 ffs_fsync(void *v) |
|
struct lwp *a_l; |
struct lwp *a_l; |
} */ *ap = v; |
} */ *ap = v; |
struct buf *bp; |
struct buf *bp; |
int s, num, error, i; |
int num, error, i; |
struct indir ia[NIADDR + 1]; |
struct indir ia[NIADDR + 1]; |
int bsize; |
int bsize; |
daddr_t blk_high; |
daddr_t blk_high; |
Line 286 ffs_fsync(void *v) |
|
Line 286 ffs_fsync(void *v) |
|
* Then, flush indirect blocks. |
* Then, flush indirect blocks. |
*/ |
*/ |
|
|
s = splbio(); |
|
if (blk_high >= NDADDR) { |
if (blk_high >= NDADDR) { |
error = ufs_getlbns(vp, blk_high, ia, &num); |
error = ufs_getlbns(vp, blk_high, ia, &num); |
if (error) { |
if (error) |
splx(s); |
|
goto out; |
goto out; |
} |
|
|
mutex_enter(&bqueue_lock); |
for (i = 0; i < num; i++) { |
for (i = 0; i < num; i++) { |
bp = incore(vp, ia[i].in_lbn); |
if ((bp = incore(vp, ia[i].in_lbn)) == NULL) |
if (bp != NULL) { |
continue; |
mutex_enter(&bp->b_interlock); |
mutex_enter(&bp->b_interlock); |
if (!(bp->b_flags & B_BUSY) && (bp->b_flags & B_DELWRI)) { |
if ((bp->b_flags & (B_BUSY | B_DELWRI)) != B_DELWRI) { |
bp->b_flags |= B_BUSY | B_VFLUSH; |
mutex_exit(&bp->b_interlock); |
mutex_exit(&bp->b_interlock); |
continue; |
splx(s); |
|
bawrite(bp); |
|
s = splbio(); |
|
} else { |
|
mutex_exit(&bp->b_interlock); |
|
} |
|
} |
} |
|
bp->b_flags |= B_BUSY | B_VFLUSH; |
|
mutex_exit(&bp->b_interlock); |
|
mutex_exit(&bqueue_lock); |
|
bawrite(bp); |
|
mutex_enter(&bqueue_lock); |
} |
} |
|
mutex_exit(&bqueue_lock); |
} |
} |
|
|
if (ap->a_flags & FSYNC_WAIT) { |
if (ap->a_flags & FSYNC_WAIT) { |
Line 316 ffs_fsync(void *v) |
|
Line 315 ffs_fsync(void *v) |
|
cv_wait(&vp->v_outputcv, &global_v_numoutput_lock); |
cv_wait(&vp->v_outputcv, &global_v_numoutput_lock); |
mutex_exit(&global_v_numoutput_lock); |
mutex_exit(&global_v_numoutput_lock); |
} |
} |
splx(s); |
|
|
|
error = ffs_update(vp, NULL, NULL, |
error = ffs_update(vp, NULL, NULL, |
((ap->a_flags & (FSYNC_WAIT | FSYNC_DATAONLY)) == FSYNC_WAIT) |
((ap->a_flags & (FSYNC_WAIT | FSYNC_DATAONLY)) == FSYNC_WAIT) |
Line 350 ffs_full_fsync(void *v) |
|
Line 348 ffs_full_fsync(void *v) |
|
} */ *ap = v; |
} */ *ap = v; |
struct vnode *vp = ap->a_vp; |
struct vnode *vp = ap->a_vp; |
struct buf *bp, *nbp; |
struct buf *bp, *nbp; |
int s, error, passes, skipmeta, inodedeps_only, waitfor; |
int error, passes, skipmeta, inodedeps_only, waitfor; |
|
|
if (vp->v_type == VBLK && |
if (vp->v_type == VBLK && |
vp->v_specmountpoint != NULL && |
vp->v_specmountpoint != NULL && |
Line 379 ffs_full_fsync(void *v) |
|
Line 377 ffs_full_fsync(void *v) |
|
skipmeta = 0; |
skipmeta = 0; |
if (ap->a_flags & FSYNC_WAIT) |
if (ap->a_flags & FSYNC_WAIT) |
skipmeta = 1; |
skipmeta = 1; |
s = splbio(); |
|
|
|
loop: |
loop: |
LIST_FOREACH(bp, &vp->v_dirtyblkhd, b_vnbufs) |
LIST_FOREACH(bp, &vp->v_dirtyblkhd, b_vnbufs) { |
|
mutex_enter(&bp->b_interlock); |
bp->b_flags &= ~B_SCANNED; |
bp->b_flags &= ~B_SCANNED; |
|
mutex_exit(&bp->b_interlock); |
|
} |
for (bp = LIST_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { |
for (bp = LIST_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { |
nbp = LIST_NEXT(bp, b_vnbufs); |
nbp = LIST_NEXT(bp, b_vnbufs); |
mutex_enter(&bp->b_interlock); |
mutex_enter(&bp->b_interlock); |
|
|
mutex_exit(&bp->b_interlock); |
mutex_exit(&bp->b_interlock); |
continue; |
continue; |
} |
} |
mutex_exit(&bp->b_interlock); |
|
bp->b_flags |= B_BUSY | B_VFLUSH | B_SCANNED; |
bp->b_flags |= B_BUSY | B_VFLUSH | B_SCANNED; |
splx(s); |
mutex_exit(&bp->b_interlock); |
/* |
/* |
* On our final pass through, do all I/O synchronously |
* On our final pass through, do all I/O synchronously |
* so that we can find out if our flush is failing |
* so that we can find out if our flush is failing |
|
|
(void) bawrite(bp); |
(void) bawrite(bp); |
else if ((error = bwrite(bp)) != 0) |
else if ((error = bwrite(bp)) != 0) |
return (error); |
return (error); |
s = splbio(); |
|
/* |
/* |
* Since we may have slept during the I/O, we need |
* Since we may have slept during the I/O, we need |
* to start from a known point. |
* to start from a known point. |
|
|
cv_wait(&vp->v_outputcv, &global_v_numoutput_lock); |
cv_wait(&vp->v_outputcv, &global_v_numoutput_lock); |
} |
} |
mutex_exit(&global_v_numoutput_lock); |
mutex_exit(&global_v_numoutput_lock); |
splx(s); |
|
|
|
/* |
/* |
* Ensure that any filesystem metadata associated |
* Ensure that any filesystem metadata associated |
|
|
if ((error = softdep_sync_metadata(ap)) != 0) |
if ((error = softdep_sync_metadata(ap)) != 0) |
return (error); |
return (error); |
|
|
s = splbio(); |
|
if (!LIST_EMPTY(&vp->v_dirtyblkhd)) { |
if (!LIST_EMPTY(&vp->v_dirtyblkhd)) { |
/* |
/* |
* Block devices associated with filesystems may |
* Block devices associated with filesystems may |
|
|
#endif |
#endif |
} |
} |
} |
} |
splx(s); |
|
|
|
if (inodedeps_only) |
if (inodedeps_only) |
waitfor = 0; |
waitfor = 0; |