Thu Apr 18 18:24:31 2024 UTC (21d)
Pull up following revision(s) (requested by hannken in ticket #669):

	sys/dev/ccd.c: revision 1.190

Using a ccd(4) with GPT (dk* at ccd*) the disk framework will call
ccdstrategy() -> ccdstart() -> ccdbuffer()  from softint context.

Allocating the buffer with PR_WAITOK here is forbidden.

Change ccdstart() / ccdbuffer() to report failure back to caller and
pass PR_WAITOK / PR_NOWAIT as an additional argument.

Call ccdstart() with PR_NOPWAIT from ccdstrategy() and on error defer
to the kthread.  Call ccdstart() with PR_WAITOK from kthread so requests
from kthread always succeed to allocate the buffers.

Remove the (non working) throttling on low memory as it is no longer needed.

Fixes PR kern/58043 "kernel crash in assert_sleepable() in -current,
dk(4) driver?"


(martin)
diff -r1.189 -r1.189.4.1 src/sys/dev/ccd.c

cvs diff -r1.189 -r1.189.4.1 src/sys/dev/ccd.c (expand / switch to unified diff)

--- src/sys/dev/ccd.c 2022/03/28 12:48:35 1.189
+++ src/sys/dev/ccd.c 2024/04/18 18:24:31 1.189.4.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ccd.c,v 1.189 2022/03/28 12:48:35 riastradh Exp $ */ 1/* $NetBSD: ccd.c,v 1.189.4.1 2024/04/18 18:24:31 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1996, 1997, 1998, 1999, 2007, 2009 The NetBSD Foundation, Inc. 4 * Copyright (c) 1996, 1997, 1998, 1999, 2007, 2009 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 Jason R. Thorpe, and by Andrew Doran. 8 * by Jason R. Thorpe, and by Andrew Doran.
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.
@@ -78,27 +78,27 @@ @@ -78,27 +78,27 @@
78 * sc_stop, sc_bufq and b_resid from master buffers. 78 * sc_stop, sc_bufq and b_resid from master buffers.
79 * 79 *
80 * => a combination of CCDF_INITED, sc_inflight, and sc_iolock is used to 80 * => a combination of CCDF_INITED, sc_inflight, and sc_iolock is used to
81 * serialize I/O and configuration changes. 81 * serialize I/O and configuration changes.
82 * 82 *
83 * => the in-core disk label does not change while the device is open. 83 * => the in-core disk label does not change while the device is open.
84 * 84 *
85 * On memory consumption: ccd fans out I/O requests and so needs to 85 * On memory consumption: ccd fans out I/O requests and so needs to
86 * allocate memory. If the system is desperately low on memory, we 86 * allocate memory. If the system is desperately low on memory, we
87 * single thread I/O. 87 * single thread I/O.
88 */ 88 */
89 89
90#include <sys/cdefs.h> 90#include <sys/cdefs.h>
91__KERNEL_RCSID(0, "$NetBSD: ccd.c,v 1.189 2022/03/28 12:48:35 riastradh Exp $"); 91__KERNEL_RCSID(0, "$NetBSD: ccd.c,v 1.189.4.1 2024/04/18 18:24:31 martin Exp $");
92 92
93#include <sys/param.h> 93#include <sys/param.h>
94#include <sys/systm.h> 94#include <sys/systm.h>
95#include <sys/kernel.h> 95#include <sys/kernel.h>
96#include <sys/proc.h> 96#include <sys/proc.h>
97#include <sys/errno.h> 97#include <sys/errno.h>
98#include <sys/buf.h> 98#include <sys/buf.h>
99#include <sys/kmem.h> 99#include <sys/kmem.h>
100#include <sys/pool.h> 100#include <sys/pool.h>
101#include <sys/module.h> 101#include <sys/module.h>
102#include <sys/namei.h> 102#include <sys/namei.h>
103#include <sys/stat.h> 103#include <sys/stat.h>
104#include <sys/ioctl.h> 104#include <sys/ioctl.h>
@@ -142,47 +142,47 @@ int ccddebug = 0x00; @@ -142,47 +142,47 @@ int ccddebug = 0x00;
142#define ccdunit(x) DISKUNIT(x) 142#define ccdunit(x) DISKUNIT(x)
143 143
144struct ccdbuf { 144struct ccdbuf {
145 struct buf cb_buf; /* new I/O buf */ 145 struct buf cb_buf; /* new I/O buf */
146 struct buf *cb_obp; /* ptr. to original I/O buf */ 146 struct buf *cb_obp; /* ptr. to original I/O buf */
147 struct ccd_softc *cb_sc; /* pointer to ccd softc */ 147 struct ccd_softc *cb_sc; /* pointer to ccd softc */
148 int cb_comp; /* target component */ 148 int cb_comp; /* target component */
149 SIMPLEQ_ENTRY(ccdbuf) cb_q; /* fifo of component buffers */ 149 SIMPLEQ_ENTRY(ccdbuf) cb_q; /* fifo of component buffers */
150}; 150};
151 151
152/* component buffer pool */ 152/* component buffer pool */
153static pool_cache_t ccd_cache; 153static pool_cache_t ccd_cache;
154 154
155#define CCD_GETBUF() pool_cache_get(ccd_cache, PR_WAITOK) 155#define CCD_GETBUF(wait) pool_cache_get(ccd_cache, wait)
156#define CCD_PUTBUF(cbp) pool_cache_put(ccd_cache, cbp) 156#define CCD_PUTBUF(cbp) pool_cache_put(ccd_cache, cbp)
157 157
158#define CCDLABELDEV(dev) \ 158#define CCDLABELDEV(dev) \
159 (MAKEDISKDEV(major((dev)), ccdunit((dev)), RAW_PART)) 159 (MAKEDISKDEV(major((dev)), ccdunit((dev)), RAW_PART))
160 160
161/* called by main() at boot time */ 161/* called by main() at boot time */
162void ccddetach(void); 162void ccddetach(void);
163 163
164/* called by biodone() at interrupt time */ 164/* called by biodone() at interrupt time */
165static void ccdiodone(struct buf *); 165static void ccdiodone(struct buf *);
166 166
167static void ccdinterleave(struct ccd_softc *); 167static void ccdinterleave(struct ccd_softc *);
168static int ccdinit(struct ccd_softc *, char **, struct vnode **, 168static int ccdinit(struct ccd_softc *, char **, struct vnode **,
169 struct lwp *); 169 struct lwp *);
170static struct ccdbuf *ccdbuffer(struct ccd_softc *, struct buf *, 170static struct ccdbuf *ccdbuffer(struct ccd_softc *, struct buf *,
171 daddr_t, void *, long); 171 daddr_t, void *, long, int);
172static void ccdgetdefaultlabel(struct ccd_softc *, struct disklabel *); 172static void ccdgetdefaultlabel(struct ccd_softc *, struct disklabel *);
173static void ccdgetdisklabel(dev_t); 173static void ccdgetdisklabel(dev_t);
174static void ccdmakedisklabel(struct ccd_softc *); 174static void ccdmakedisklabel(struct ccd_softc *);
175static void ccdstart(struct ccd_softc *); 175static int ccdstart(struct ccd_softc *, struct buf *, int);
176static void ccdthread(void *); 176static void ccdthread(void *);
177 177
178static dev_type_open(ccdopen); 178static dev_type_open(ccdopen);
179static dev_type_close(ccdclose); 179static dev_type_close(ccdclose);
180static dev_type_read(ccdread); 180static dev_type_read(ccdread);
181static dev_type_write(ccdwrite); 181static dev_type_write(ccdwrite);
182static dev_type_ioctl(ccdioctl); 182static dev_type_ioctl(ccdioctl);
183static dev_type_strategy(ccdstrategy); 183static dev_type_strategy(ccdstrategy);
184static dev_type_size(ccdsize); 184static dev_type_size(ccdsize);
185 185
186const struct bdevsw ccd_bdevsw = { 186const struct bdevsw ccd_bdevsw = {
187 .d_open = ccdopen, 187 .d_open = ccdopen,
188 .d_close = ccdclose, 188 .d_close = ccdclose,
@@ -692,64 +692,54 @@ ccdclose(dev_t dev, int flags, int fmt,  @@ -692,64 +692,54 @@ ccdclose(dev_t dev, int flags, int fmt,
692 } 692 }
693 cs->sc_dkdev.dk_openmask = 693 cs->sc_dkdev.dk_openmask =
694 cs->sc_dkdev.dk_copenmask | cs->sc_dkdev.dk_bopenmask; 694 cs->sc_dkdev.dk_copenmask | cs->sc_dkdev.dk_bopenmask;
695 695
696 if (cs->sc_dkdev.dk_openmask == 0) { 696 if (cs->sc_dkdev.dk_openmask == 0) {
697 if ((cs->sc_flags & CCDF_KLABEL) == 0) 697 if ((cs->sc_flags & CCDF_KLABEL) == 0)
698 cs->sc_flags &= ~CCDF_VLABEL; 698 cs->sc_flags &= ~CCDF_VLABEL;
699 } 699 }
700 700
701 mutex_exit(&cs->sc_dvlock); 701 mutex_exit(&cs->sc_dvlock);
702 return (0); 702 return (0);
703} 703}
704 704
705static bool 
706ccdbackoff(struct ccd_softc *cs) 
707{ 
708 
709 /* XXX Arbitrary, should be a uvm call. */ 
710 return uvm_availmem(true) < (uvmexp.freemin >> 1) && 
711 disk_isbusy(&cs->sc_dkdev); 
712} 
713 
714static void 705static void
715ccdthread(void *cookie) 706ccdthread(void *cookie)
716{ 707{
 708 int error;
717 struct ccd_softc *cs; 709 struct ccd_softc *cs;
 710 struct buf *bp;
718 711
719 cs = cookie; 712 cs = cookie;
720 713
721#ifdef DEBUG 714#ifdef DEBUG
722 if (ccddebug & CCDB_FOLLOW) 715 if (ccddebug & CCDB_FOLLOW)
723 printf("ccdthread: hello\n"); 716 printf("ccdthread: hello\n");
724#endif 717#endif
725 718
726 mutex_enter(cs->sc_iolock); 719 mutex_enter(cs->sc_iolock);
727 while (__predict_true(!cs->sc_zap)) { 720 while (__predict_true(!cs->sc_zap)) {
728 if (bufq_peek(cs->sc_bufq) == NULL) { 721 bp = bufq_get(cs->sc_bufq);
 722 if (bp == NULL) {
729 /* Nothing to do. */ 723 /* Nothing to do. */
730 cv_wait(&cs->sc_push, cs->sc_iolock); 724 cv_wait(&cs->sc_push, cs->sc_iolock);
731 continue; 725 continue;
732 } 726 }
733 if (ccdbackoff(cs)) { 
734 /* Wait for memory to become available. */ 
735 (void)cv_timedwait(&cs->sc_push, cs->sc_iolock, 1); 
736 continue; 
737 } 
738#ifdef DEBUG 727#ifdef DEBUG
739 if (ccddebug & CCDB_FOLLOW) 728 if (ccddebug & CCDB_FOLLOW)
740 printf("ccdthread: dispatching I/O\n"); 729 printf("ccdthread: dispatching I/O\n");
741#endif 730#endif
742 ccdstart(cs); 731 error = ccdstart(cs, bp, PR_WAITOK);
 732 KASSERT(error == 0);
743 mutex_enter(cs->sc_iolock); 733 mutex_enter(cs->sc_iolock);
744 } 734 }
745 cs->sc_thread = NULL; 735 cs->sc_thread = NULL;
746 mutex_exit(cs->sc_iolock); 736 mutex_exit(cs->sc_iolock);
747#ifdef DEBUG 737#ifdef DEBUG
748 if (ccddebug & CCDB_FOLLOW) 738 if (ccddebug & CCDB_FOLLOW)
749 printf("ccdthread: goodbye\n"); 739 printf("ccdthread: goodbye\n");
750#endif 740#endif
751 kthread_exit(0); 741 kthread_exit(0);
752} 742}
753 743
754static void 744static void
755ccdstrategy(struct buf *bp) 745ccdstrategy(struct buf *bp)
@@ -767,55 +757,48 @@ ccdstrategy(struct buf *bp) @@ -767,55 +757,48 @@ ccdstrategy(struct buf *bp)
767 /* Synchronize with device init/uninit. */ 757 /* Synchronize with device init/uninit. */
768 if (__predict_false((cs->sc_flags & CCDF_INITED) == 0)) { 758 if (__predict_false((cs->sc_flags & CCDF_INITED) == 0)) {
769 mutex_exit(cs->sc_iolock); 759 mutex_exit(cs->sc_iolock);
770#ifdef DEBUG 760#ifdef DEBUG
771 if (ccddebug & CCDB_FOLLOW) 761 if (ccddebug & CCDB_FOLLOW)
772 printf("ccdstrategy: unit %d: not inited\n", unit); 762 printf("ccdstrategy: unit %d: not inited\n", unit);
773#endif 763#endif
774 bp->b_error = ENXIO; 764 bp->b_error = ENXIO;
775 bp->b_resid = bp->b_bcount; 765 bp->b_resid = bp->b_bcount;
776 biodone(bp); 766 biodone(bp);
777 return; 767 return;
778 } 768 }
779 769
780 /* Defer to thread if system is low on memory. */ 770 if (ccdstart(cs, bp, PR_NOWAIT) != 0) {
781 bufq_put(cs->sc_bufq, bp); 771 /* Defer to thread if system is low on memory. */
782 if (__predict_false(ccdbackoff(cs))) { 772 bufq_put(cs->sc_bufq, bp);
 773 cv_broadcast(&cs->sc_push);
783 mutex_exit(cs->sc_iolock); 774 mutex_exit(cs->sc_iolock);
784#ifdef DEBUG 
785 if (ccddebug & CCDB_FOLLOW) 
786 printf("ccdstrategy: holding off on I/O\n"); 
787#endif 
788 return; 
789 } 775 }
790 ccdstart(cs); 
791} 776}
792 777
793static void 778static int
794ccdstart(struct ccd_softc *cs) 779ccdstart(struct ccd_softc *cs, struct buf *bp, int wait)
795{ 780{
796 daddr_t blkno; 781 daddr_t blkno;
797 int wlabel; 782 int wlabel;
798 struct disklabel *lp; 783 struct disklabel *lp;
799 long bcount, rcount; 784 long bcount, rcount;
800 struct ccdbuf *cbp; 785 struct ccdbuf *cbp;
801 char *addr; 786 char *addr;
802 daddr_t bn; 787 daddr_t bn;
803 vnode_t *vp; 788 vnode_t *vp;
804 buf_t *bp; 789 SIMPLEQ_HEAD(, ccdbuf) cbufq;
805 790
806 KASSERT(mutex_owned(cs->sc_iolock)); 791 KASSERT(mutex_owned(cs->sc_iolock));
807 
808 bp = bufq_get(cs->sc_bufq); 
809 KASSERT(bp != NULL); 792 KASSERT(bp != NULL);
810 793
811 disk_busy(&cs->sc_dkdev); 794 disk_busy(&cs->sc_dkdev);
812 795
813#ifdef DEBUG 796#ifdef DEBUG
814 if (ccddebug & CCDB_FOLLOW) 797 if (ccddebug & CCDB_FOLLOW)
815 printf("ccdstart(%s, %p)\n", cs->sc_xname, bp); 798 printf("ccdstart(%s, %p)\n", cs->sc_xname, bp);
816#endif 799#endif
817 800
818 /* If it's a nil transfer, wake up the top half now. */ 801 /* If it's a nil transfer, wake up the top half now. */
819 if (bp->b_bcount == 0) 802 if (bp->b_bcount == 0)
820 goto done; 803 goto done;
821 804
@@ -826,60 +809,78 @@ ccdstart(struct ccd_softc *cs) @@ -826,60 +809,78 @@ ccdstart(struct ccd_softc *cs)
826 * error, the bounds check will flag that for us. Convert 809 * error, the bounds check will flag that for us. Convert
827 * the partition relative block number to an absolute. 810 * the partition relative block number to an absolute.
828 */ 811 */
829 blkno = bp->b_blkno; 812 blkno = bp->b_blkno;
830 wlabel = cs->sc_flags & (CCDF_WLABEL|CCDF_LABELLING); 813 wlabel = cs->sc_flags & (CCDF_WLABEL|CCDF_LABELLING);
831 if (DISKPART(bp->b_dev) != RAW_PART) { 814 if (DISKPART(bp->b_dev) != RAW_PART) {
832 if (bounds_check_with_label(&cs->sc_dkdev, bp, wlabel) <= 0) 815 if (bounds_check_with_label(&cs->sc_dkdev, bp, wlabel) <= 0)
833 goto done; 816 goto done;
834 blkno += lp->d_partitions[DISKPART(bp->b_dev)].p_offset; 817 blkno += lp->d_partitions[DISKPART(bp->b_dev)].p_offset;
835 } 818 }
836 mutex_exit(cs->sc_iolock); 819 mutex_exit(cs->sc_iolock);
837 bp->b_rawblkno = blkno; 820 bp->b_rawblkno = blkno;
838 821
839 /* Allocate the component buffers and start I/O! */ 822 /* Allocate the component buffers. */
 823 SIMPLEQ_INIT(&cbufq);
840 bp->b_resid = bp->b_bcount; 824 bp->b_resid = bp->b_bcount;
841 bn = bp->b_rawblkno; 825 bn = bp->b_rawblkno;
842 addr = bp->b_data; 826 addr = bp->b_data;
843 for (bcount = bp->b_bcount; bcount > 0; bcount -= rcount) { 827 for (bcount = bp->b_bcount; bcount > 0; bcount -= rcount) {
844 cbp = ccdbuffer(cs, bp, bn, addr, bcount); 828 cbp = ccdbuffer(cs, bp, bn, addr, bcount, wait);
 829 KASSERT(cbp != NULL || wait == PR_NOWAIT);
 830 if (cbp == NULL) {
 831 while ((cbp = SIMPLEQ_FIRST(&cbufq)) != NULL) {
 832 SIMPLEQ_REMOVE_HEAD(&cbufq, cb_q);
 833 CCD_PUTBUF(cbp);
 834 }
 835 mutex_enter(cs->sc_iolock);
 836 disk_unbusy(&cs->sc_dkdev, 0, 0);
 837 return ENOMEM;
 838 }
 839 SIMPLEQ_INSERT_TAIL(&cbufq, cbp, cb_q);
845 rcount = cbp->cb_buf.b_bcount; 840 rcount = cbp->cb_buf.b_bcount;
846 bn += btodb(rcount); 841 bn += btodb(rcount);
847 addr += rcount; 842 addr += rcount;
 843 }
 844
 845 /* All buffers set up, now fire off the requests. */
 846 while ((cbp = SIMPLEQ_FIRST(&cbufq)) != NULL) {
 847 SIMPLEQ_REMOVE_HEAD(&cbufq, cb_q);
848 vp = cbp->cb_buf.b_vp; 848 vp = cbp->cb_buf.b_vp;
849 if ((cbp->cb_buf.b_flags & B_READ) == 0) { 849 if ((cbp->cb_buf.b_flags & B_READ) == 0) {
850 mutex_enter(vp->v_interlock); 850 mutex_enter(vp->v_interlock);
851 vp->v_numoutput++; 851 vp->v_numoutput++;
852 mutex_exit(vp->v_interlock); 852 mutex_exit(vp->v_interlock);
853 } 853 }
854 (void)VOP_STRATEGY(vp, &cbp->cb_buf); 854 (void)VOP_STRATEGY(vp, &cbp->cb_buf);
855 } 855 }
856 return; 856 return 0;
857 857
858 done: 858 done:
859 disk_unbusy(&cs->sc_dkdev, 0, 0); 859 disk_unbusy(&cs->sc_dkdev, 0, 0);
860 cv_broadcast(&cs->sc_stop); 860 cv_broadcast(&cs->sc_stop);
861 cv_broadcast(&cs->sc_push); 861 cv_broadcast(&cs->sc_push);
862 mutex_exit(cs->sc_iolock); 862 mutex_exit(cs->sc_iolock);
863 bp->b_resid = bp->b_bcount; 863 bp->b_resid = bp->b_bcount;
864 biodone(bp); 864 biodone(bp);
 865 return 0;
865} 866}
866 867
867/* 868/*
868 * Build a component buffer header. 869 * Build a component buffer header.
869 */ 870 */
870static struct ccdbuf * 871static struct ccdbuf *
871ccdbuffer(struct ccd_softc *cs, struct buf *bp, daddr_t bn, void *addr, 872ccdbuffer(struct ccd_softc *cs, struct buf *bp, daddr_t bn, void *addr,
872 long bcount) 873 long bcount, int wait)
873{ 874{
874 struct ccdcinfo *ci; 875 struct ccdcinfo *ci;
875 struct ccdbuf *cbp; 876 struct ccdbuf *cbp;
876 daddr_t cbn, cboff; 877 daddr_t cbn, cboff;
877 u_int64_t cbc; 878 u_int64_t cbc;
878 int ccdisk; 879 int ccdisk;
879 880
880#ifdef DEBUG 881#ifdef DEBUG
881 if (ccddebug & CCDB_IO) 882 if (ccddebug & CCDB_IO)
882 printf("ccdbuffer(%p, %p, %" PRId64 ", %p, %ld)\n", 883 printf("ccdbuffer(%p, %p, %" PRId64 ", %p, %ld)\n",
883 cs, bp, bn, addr, bcount); 884 cs, bp, bn, addr, bcount);
884#endif 885#endif
885 /* 886 /*
@@ -919,28 +920,29 @@ ccdbuffer(struct ccd_softc *cs, struct b @@ -919,28 +920,29 @@ ccdbuffer(struct ccd_softc *cs, struct b
919 ccdisk = ii->ii_index[0]; 920 ccdisk = ii->ii_index[0];
920 cbn = ii->ii_startoff + off; 921 cbn = ii->ii_startoff + off;
921 } else { 922 } else {
922 ccdisk = ii->ii_index[off % ii->ii_ndisk]; 923 ccdisk = ii->ii_index[off % ii->ii_ndisk];
923 cbn = ii->ii_startoff + off / ii->ii_ndisk; 924 cbn = ii->ii_startoff + off / ii->ii_ndisk;
924 } 925 }
925 cbn *= cs->sc_ileave; 926 cbn *= cs->sc_ileave;
926 ci = &cs->sc_cinfo[ccdisk]; 927 ci = &cs->sc_cinfo[ccdisk];
927 } 928 }
928 929
929 /* 930 /*
930 * Fill in the component buf structure. 931 * Fill in the component buf structure.
931 */ 932 */
932 cbp = CCD_GETBUF(); 933 cbp = CCD_GETBUF(wait);
933 KASSERT(cbp != NULL); 934 if (cbp == NULL)
 935 return NULL;
934 buf_init(&cbp->cb_buf); 936 buf_init(&cbp->cb_buf);
935 cbp->cb_buf.b_flags = bp->b_flags; 937 cbp->cb_buf.b_flags = bp->b_flags;
936 cbp->cb_buf.b_oflags = bp->b_oflags; 938 cbp->cb_buf.b_oflags = bp->b_oflags;
937 cbp->cb_buf.b_cflags = bp->b_cflags; 939 cbp->cb_buf.b_cflags = bp->b_cflags;
938 cbp->cb_buf.b_iodone = ccdiodone; 940 cbp->cb_buf.b_iodone = ccdiodone;
939 cbp->cb_buf.b_proc = bp->b_proc; 941 cbp->cb_buf.b_proc = bp->b_proc;
940 cbp->cb_buf.b_dev = ci->ci_dev; 942 cbp->cb_buf.b_dev = ci->ci_dev;
941 cbp->cb_buf.b_blkno = cbn + cboff; 943 cbp->cb_buf.b_blkno = cbn + cboff;
942 cbp->cb_buf.b_data = addr; 944 cbp->cb_buf.b_data = addr;
943 cbp->cb_buf.b_vp = ci->ci_vp; 945 cbp->cb_buf.b_vp = ci->ci_vp;
944 cbp->cb_buf.b_objlock = ci->ci_vp->v_interlock; 946 cbp->cb_buf.b_objlock = ci->ci_vp->v_interlock;
945 if (cs->sc_ileave == 0) 947 if (cs->sc_ileave == 0)
946 cbc = dbtob((u_int64_t)(ci->ci_size - cbn)); 948 cbc = dbtob((u_int64_t)(ci->ci_size - cbn));