@@ -4088,8 +4088,9 @@ sr_raid_start_stop(struct sr_workunit *wu)
40884088int
40894089sr_raid_sync (struct sr_workunit * wu )
40904090{
4091+ struct sr_workunit * wup ;
40914092 struct sr_discipline * sd = wu -> swu_dis ;
4092- int ios = 0 , rv = 0 , retries = 15 ;
4093+ int ios = 0 , rv = ETIMEDOUT , retries = 15 ;
40934094
40944095 if (!(wu -> swu_flags & SR_WUF_FAKE )) {
40954096 /* When we are not a fake sync we must not acount the sync
@@ -4100,41 +4101,59 @@ sr_raid_sync(struct sr_workunit *wu)
41004101 ios = 1 ;
41014102 }
41024103
4103- mtx_enter (& sd -> sd_wu_mtx );
4104-
41054104 DNPRINTF (SR_D_DIS , "%s: sr_raid_sync %d fake %d\n" ,
41064105 DEVNAME (sd -> sd_sc ),
41074106 sd -> sd_wu_pending ,
41084107 wu -> swu_flags & SR_WUF_FAKE );
41094108
4110- /* diagnostic */
41114109 if (sd -> sd_sync != 0 ) {
4112- printf ("sd->sd_sync != 0, called reentrant\n" );
4110+ /* Sync in progress. Wait and return. */
4111+ return tsleep (& sd -> sd_sync , PRIBIO | PCATCH , "sr_sync1" , 0 );
4112+ }
4113+
4114+ /*
4115+ * Mark the WUs we need to dispose of.
4116+ */
4117+ mtx_enter (& sd -> sd_wu_mtx );
4118+ TAILQ_FOREACH (wup , & sd -> sd_wu_pendq , swu_link ) {
4119+ KASSERT ((wup -> swu_flags & SR_WUF_SEEN ) == 0 );
4120+ wup -> swu_flags |= SR_WUF_SEEN ;
41134121 }
41144122
41154123 sd -> sd_sync = 1 ;
4116- for (;;) {
4124+
4125+ while (retries -- > 0 ) {
4126+ /* Wait a bit for I/O to drain. */
4127+ msleep (sd , & sd -> sd_wu_mtx , PWAIT , "sr_sync2" , 1 * hz );
41174128 if (sd -> sd_wu_pending <= ios ) {
4129+ /* We can be sure all of the marked WUs are gone. */
4130+ rv = 0 ;
41184131 break ;
41194132 }
4120-
4121- /* wait a bit for io to drain */
4122- if (msleep (sd , & sd -> sd_wu_mtx , PWAIT , "sr_sync" , 1 * hz ) ==
4123- EWOULDBLOCK ) {
4124- if (retries -- > 0 ) {
4133+ TAILQ_FOREACH (wup , & sd -> sd_wu_pendq , swu_link ) {
4134+ if (wup -> swu_flags & SR_WUF_SEEN ) {
4135+ /*
4136+ * One of the observed WUs is still around.
4137+ * Try again.
4138+ */
41254139 continue ;
41264140 }
4141+ }
4142+ rv = 0 ;
4143+ break ;
4144+ }
41274145
4128- /* print timeout for now */
4129- printf ("%s: sr_raid_sync timeout\n" ,
4130- DEVNAME (sd -> sd_sc ));
4146+ if (rv != 0 ) {
4147+ /* print timeout for now */
4148+ printf ("%s: sr_raid_sync timeout\n" ,
4149+ DEVNAME (sd -> sd_sc ));
41314150
4132- DNPRINTF (SR_D_DIS , "%s: sr_raid_sync timeout\n" ,
4133- DEVNAME (sd -> sd_sc ));
4134- rv = 1 ;
4135- break ;
4136- }
4151+ DNPRINTF (SR_D_DIS , "%s: sr_raid_sync timeout\n" ,
4152+ DEVNAME (sd -> sd_sc ));
41374153 }
4154+
4155+ /* XXX TODO: DIOCCACHESYNC on the real disk(s) */
4156+
41384157 sd -> sd_sync = 0 ;
41394158 mtx_leave (& sd -> sd_wu_mtx );
41404159
0 commit comments