FreeBSD/sys/kern/vfs_bio.c
/*
 * Shutdown the system cleanly to prepare for reboot, halt, or power off.
 */
Shutdown the system cleanly to prepare for reboot, halt, or power off.
Shutdown the system cleanly to prepare for reboot halt or power off .
void
bufshutdown(int show_busybufs)
{
	static int first_buf_printf = 1;
	struct buf *bp;
	int iter, nbusy, pbusy;
#ifndef PREEMPTION
	int subiter;
#endif
	wdog_kern_pat(WD_LASTVAL);
	sys_sync(curthread, NULL);
	for (iter = pbusy = 0; iter < 20; iter++) {
		nbusy = 0;
		for (bp = &buf[nbuf]; --bp >= buf; )
			if (isbufbusy(bp))
				nbusy++;
		if (nbusy == 0) {
			if (first_buf_printf)
				printf("All buffers synced.");
			break;
		}
		if (first_buf_printf) {
			printf("Syncing disks, buffers remaining... ");
			first_buf_printf = 0;
		}
		printf("%d ", nbusy);
		if (nbusy < pbusy)
			iter = 0;
		pbusy = nbusy;
		wdog_kern_pat(WD_LASTVAL);
		sys_sync(curthread, NULL);
#ifdef PREEMPTION
		DROP_GIANT();
		DELAY(50000 * iter);
		PICKUP_GIANT();
#else
		DROP_GIANT();
		for (subiter = 0; subiter < 50 * iter; subiter++) {
			thread_lock(curthread);
			mi_switch(SW_VOL, NULL);
			thread_unlock(curthread);
			DELAY(1000);
		}
		PICKUP_GIANT();
#endif
	}
	printf("\n");
	nbusy = 0;
	for (bp = &buf[nbuf]; --bp >= buf; ) {
		if (isbufbusy(bp)) {
#if 0
			if (bp->b_dev == NULL) {
				TAILQ_REMOVE(&mountlist,
				    bp->b_vp->v_mount, mnt_list);
				continue;
			}
#endif
			nbusy++;
			if (show_busybufs > 0) {
				printf(
	    "%d: buf:%p, vnode:%p, flags:%0x, blkno:%jd, lblkno:%jd, buflock:",
				    nbusy, bp, bp->b_vp, bp->b_flags,
				    (intmax_t)bp->b_blkno,
				    (intmax_t)bp->b_lblkno);
				BUF_LOCKPRINTINFO(bp);
				if (show_busybufs > 1)
					vn_printf(bp->b_vp,
					    "vnode content: ");
			}
		}
	}
	if (nbusy) {
		printf("Giving up on %d buffers\n", nbusy);
		DELAY(5000000);	
	} else {
		if (!first_buf_printf)
			printf("Final sync complete\n");
		if (panicstr == NULL)
			vfs_unmountall();
	}
	swapoff_all();
	DELAY(100000);		
}
void bufshutdown ( int show_busybufs ) { static int first_buf_printf = 1 ; struct buf * bp ; int iter , nbusy , pbusy ; #ifndef PREEMPTION int subiter ; #endif wdog_kern_pat ( WD_LASTVAL ) ; sys_sync ( curthread , NULL ) ; for ( iter = pbusy = 0 ; iter < 20 ; iter ++ ) { nbusy = 0 ; for ( bp = & buf [ nbuf ] ; -- bp >= buf ; ) if ( isbufbusy ( bp ) ) nbusy ++ ; if ( nbusy == 0 ) { if ( first_buf_printf ) printf ( " " ) ; break ; } if ( first_buf_printf ) { printf ( " " ) ; first_buf_printf = 0 ; } printf ( " " , nbusy ) ; if ( nbusy < pbusy ) iter = 0 ; pbusy = nbusy ; wdog_kern_pat ( WD_LASTVAL ) ; sys_sync ( curthread , NULL ) ; #ifdef PREEMPTION DROP_GIANT ( ) ; DELAY ( 50000 * iter ) ; PICKUP_GIANT ( ) ; #else DROP_GIANT ( ) ; for ( subiter = 0 ; subiter < 50 * iter ; subiter ++ ) { thread_lock ( curthread ) ; mi_switch ( SW_VOL , NULL ) ; thread_unlock ( curthread ) ; DELAY ( 1000 ) ; } PICKUP_GIANT ( ) ; #endif } printf ( " \n " ) ; nbusy = 0 ; for ( bp = & buf [ nbuf ] ; -- bp >= buf ; ) { if ( isbufbusy ( bp ) ) { #if 0 if ( bp -> b_dev == NULL ) { TAILQ_REMOVE ( & mountlist , bp -> b_vp -> v_mount , mnt_list ) ; continue ; } #endif nbusy ++ ; if ( show_busybufs > 0 ) { printf ( " " , nbusy , bp , bp -> b_vp , bp -> b_flags , ( intmax_t ) bp -> b_blkno , ( intmax_t ) bp -> b_lblkno ) ; BUF_LOCKPRINTINFO ( bp ) ; if ( show_busybufs > 1 ) vn_printf ( bp -> b_vp , " " ) ; } } } if ( nbusy ) { printf ( " \n " , nbusy ) ; DELAY ( 5000000 ) ; } else { if ( ! first_buf_printf ) printf ( " \n " ) ; if ( panicstr == NULL ) vfs_unmountall ( ) ; } swapoff_all ( ) ; DELAY ( 100000 ) ; }
Shutdown the system cleanly to prepare for reboot, halt, or power off.
Shutdown the system cleanly to prepare for reboot halt or power off .
/* 
	 * Sync filesystems for shutdown
	 */ /*
	 * With soft updates, some buffers that are
	 * written will be remarked as dirty until other
	 * buffers are written.
	 */ /*
		 * Drop Giant and spin for a while to allow
		 * interrupt threads to run.
		 */ /*
		 * Drop Giant and context switch several times to
		 * allow interrupt threads to run.
		 */ /*
	 * Count only busy local buffers to prevent forcing 
	 * a fsck if we're just a client of a wedged NFS server
	 */ /* XXX: This is bogus.  We should probably have a BO_REMOTE flag instead */ /*
		 * Failed to sync all blocks. Indicate this and don't
		 * unmount filesystems (thus forcing an fsck on reboot).
		 */ /* 5 seconds */ /*
		 * Unmount filesystems
		 */ /* wait for console output to finish */