Thu Jul 23 21:38:33 2009 UTC ()
Extract ldlastclose() and use it in ldclose().  At the top of
ldbegindetach(), call disk_begindetach(..., ldlastclose, ...).

Compiles.  Not tested.


(dyoung)
diff -r1.65 -r1.66 src/sys/dev/ld.c

cvs diff -r1.65 -r1.66 src/sys/dev/ld.c (expand / switch to unified diff)

--- src/sys/dev/ld.c 2009/05/07 09:11:42 1.65
+++ src/sys/dev/ld.c 2009/07/23 21:38:33 1.66
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ld.c,v 1.65 2009/05/07 09:11:42 cegger Exp $ */ 1/* $NetBSD: ld.c,v 1.66 2009/07/23 21:38:33 dyoung Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran and Charles M. Hannum. 8 * by Andrew Doran and Charles M. Hannum.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -24,27 +24,27 @@ @@ -24,27 +24,27 @@
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * Disk driver for use by RAID controllers. 33 * Disk driver for use by RAID controllers.
34 */ 34 */
35 35
36#include <sys/cdefs.h> 36#include <sys/cdefs.h>
37__KERNEL_RCSID(0, "$NetBSD: ld.c,v 1.65 2009/05/07 09:11:42 cegger Exp $"); 37__KERNEL_RCSID(0, "$NetBSD: ld.c,v 1.66 2009/07/23 21:38:33 dyoung Exp $");
38 38
39#include "rnd.h" 39#include "rnd.h"
40 40
41#include <sys/param.h> 41#include <sys/param.h>
42#include <sys/systm.h> 42#include <sys/systm.h>
43#include <sys/kernel.h> 43#include <sys/kernel.h>
44#include <sys/device.h> 44#include <sys/device.h>
45#include <sys/queue.h> 45#include <sys/queue.h>
46#include <sys/proc.h> 46#include <sys/proc.h>
47#include <sys/buf.h> 47#include <sys/buf.h>
48#include <sys/bufq.h> 48#include <sys/bufq.h>
49#include <sys/endian.h> 49#include <sys/endian.h>
50#include <sys/disklabel.h> 50#include <sys/disklabel.h>
@@ -61,26 +61,27 @@ __KERNEL_RCSID(0, "$NetBSD: ld.c,v 1.65  @@ -61,26 +61,27 @@ __KERNEL_RCSID(0, "$NetBSD: ld.c,v 1.65
61#endif 61#endif
62 62
63#include <dev/ldvar.h> 63#include <dev/ldvar.h>
64 64
65#include <prop/proplib.h> 65#include <prop/proplib.h>
66 66
67static void ldgetdefaultlabel(struct ld_softc *, struct disklabel *); 67static void ldgetdefaultlabel(struct ld_softc *, struct disklabel *);
68static void ldgetdisklabel(struct ld_softc *); 68static void ldgetdisklabel(struct ld_softc *);
69static void ldminphys(struct buf *bp); 69static void ldminphys(struct buf *bp);
70static bool ld_shutdown(device_t, int); 70static bool ld_shutdown(device_t, int);
71static void ldstart(struct ld_softc *, struct buf *); 71static void ldstart(struct ld_softc *, struct buf *);
72static void ld_set_properties(struct ld_softc *); 72static void ld_set_properties(struct ld_softc *);
73static void ld_config_interrupts (device_t); 73static void ld_config_interrupts (device_t);
 74static int ldlastclose(device_t);
74 75
75extern struct cfdriver ld_cd; 76extern struct cfdriver ld_cd;
76 77
77static dev_type_open(ldopen); 78static dev_type_open(ldopen);
78static dev_type_close(ldclose); 79static dev_type_close(ldclose);
79static dev_type_read(ldread); 80static dev_type_read(ldread);
80static dev_type_write(ldwrite); 81static dev_type_write(ldwrite);
81static dev_type_ioctl(ldioctl); 82static dev_type_ioctl(ldioctl);
82static dev_type_strategy(ldstrategy); 83static dev_type_strategy(ldstrategy);
83static dev_type_dump(lddump); 84static dev_type_dump(lddump);
84static dev_type_size(ldsize); 85static dev_type_size(ldsize);
85 86
86const struct bdevsw ld_bdevsw = { 87const struct bdevsw ld_bdevsw = {
@@ -173,28 +174,30 @@ ldadjqparam(struct ld_softc *sc, int xma @@ -173,28 +174,30 @@ ldadjqparam(struct ld_softc *sc, int xma
173 splx(s); 174 splx(s);
174 175
175 return (0); 176 return (0);
176} 177}
177 178
178int 179int
179ldbegindetach(struct ld_softc *sc, int flags) 180ldbegindetach(struct ld_softc *sc, int flags)
180{ 181{
181 int s, rv = 0; 182 int s, rv = 0;
182 183
183 if ((sc->sc_flags & LDF_ENABLED) == 0) 184 if ((sc->sc_flags & LDF_ENABLED) == 0)
184 return (0); 185 return (0);
185 186
186 if ((flags & DETACH_FORCE) == 0 && sc->sc_dk.dk_openmask != 0) 187 rv = disk_begindetach(&sc->sc_dk, ldlastclose, sc->sc_dv, flags);
187 return (EBUSY); 188
 189 if (rv != 0)
 190 return rv;
188 191
189 s = splbio(); 192 s = splbio();
190 sc->sc_maxqueuecnt = 0; 193 sc->sc_maxqueuecnt = 0;
191 sc->sc_flags |= LDF_DETACH; 194 sc->sc_flags |= LDF_DETACH;
192 while (sc->sc_queuecnt > 0) { 195 while (sc->sc_queuecnt > 0) {
193 sc->sc_flags |= LDF_DRAIN; 196 sc->sc_flags |= LDF_DRAIN;
194 rv = tsleep(&sc->sc_queuecnt, PRIBIO, "lddrn", 0); 197 rv = tsleep(&sc->sc_queuecnt, PRIBIO, "lddrn", 0);
195 if (rv) 198 if (rv)
196 break; 199 break;
197 } 200 }
198 splx(s); 201 splx(s);
199 202
200 return (rv); 203 return (rv);
@@ -311,56 +314,65 @@ ldopen(dev_t dev, int flags, int fmt, st @@ -311,56 +314,65 @@ ldopen(dev_t dev, int flags, int fmt, st
311 case S_IFBLK: 314 case S_IFBLK:
312 sc->sc_dk.dk_bopenmask |= (1 << part); 315 sc->sc_dk.dk_bopenmask |= (1 << part);
313 break; 316 break;
314 } 317 }
315 sc->sc_dk.dk_openmask = 318 sc->sc_dk.dk_openmask =
316 sc->sc_dk.dk_copenmask | sc->sc_dk.dk_bopenmask; 319 sc->sc_dk.dk_copenmask | sc->sc_dk.dk_bopenmask;
317 320
318 error = 0; 321 error = 0;
319 bad1: 322 bad1:
320 mutex_exit(&sc->sc_dk.dk_openlock); 323 mutex_exit(&sc->sc_dk.dk_openlock);
321 return (error); 324 return (error);
322} 325}
323 326
 327static int
 328ldlastclose(device_t self)
 329{
 330 struct ld_softc *sc = device_private(self);
 331
 332 if (sc->sc_flush != NULL && (*sc->sc_flush)(sc, 0) != 0)
 333 aprint_error_dev(self, "unable to flush cache\n");
 334 if ((sc->sc_flags & LDF_KLABEL) == 0)
 335 sc->sc_flags &= ~LDF_VLABEL;
 336
 337 return 0;
 338}
 339
324/* ARGSUSED */ 340/* ARGSUSED */
325static int 341static int
326ldclose(dev_t dev, int flags, int fmt, struct lwp *l) 342ldclose(dev_t dev, int flags, int fmt, struct lwp *l)
327{ 343{
328 struct ld_softc *sc; 344 struct ld_softc *sc;
329 int part, unit; 345 int part, unit;
330 346
331 unit = DISKUNIT(dev); 347 unit = DISKUNIT(dev);
332 part = DISKPART(dev); 348 part = DISKPART(dev);
333 sc = device_lookup_private(&ld_cd, unit); 349 sc = device_lookup_private(&ld_cd, unit);
334 350
335 mutex_enter(&sc->sc_dk.dk_openlock); 351 mutex_enter(&sc->sc_dk.dk_openlock);
336 352
337 switch (fmt) { 353 switch (fmt) {
338 case S_IFCHR: 354 case S_IFCHR:
339 sc->sc_dk.dk_copenmask &= ~(1 << part); 355 sc->sc_dk.dk_copenmask &= ~(1 << part);
340 break; 356 break;
341 case S_IFBLK: 357 case S_IFBLK:
342 sc->sc_dk.dk_bopenmask &= ~(1 << part); 358 sc->sc_dk.dk_bopenmask &= ~(1 << part);
343 break; 359 break;
344 } 360 }
345 sc->sc_dk.dk_openmask = 361 sc->sc_dk.dk_openmask =
346 sc->sc_dk.dk_copenmask | sc->sc_dk.dk_bopenmask; 362 sc->sc_dk.dk_copenmask | sc->sc_dk.dk_bopenmask;
347 363
348 if (sc->sc_dk.dk_openmask == 0) { 364 if (sc->sc_dk.dk_openmask == 0)
349 if (sc->sc_flush != NULL && (*sc->sc_flush)(sc, 0) != 0) 365 ldlastclose(sc->sc_dv);
350 aprint_error_dev(sc->sc_dv, "unable to flush cache\n"); 
351 if ((sc->sc_flags & LDF_KLABEL) == 0) 
352 sc->sc_flags &= ~LDF_VLABEL; 
353 } 
354 366
355 mutex_exit(&sc->sc_dk.dk_openlock); 367 mutex_exit(&sc->sc_dk.dk_openlock);
356 return (0); 368 return (0);
357} 369}
358 370
359/* ARGSUSED */ 371/* ARGSUSED */
360static int 372static int
361ldread(dev_t dev, struct uio *uio, int ioflag) 373ldread(dev_t dev, struct uio *uio, int ioflag)
362{ 374{
363 375
364 return (physio(ldstrategy, NULL, dev, B_READ, ldminphys, uio)); 376 return (physio(ldstrategy, NULL, dev, B_READ, ldminphys, uio));
365} 377}
366 378