]>
git.saurik.com Git - apple/xnu.git/blob - bsd/vfs/vfs_cluster.c
5756a104a3cd8316d1916f92ad14535616670498
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
22 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
25 * The Regents of the University of California. All rights reserved.
27 * Redistribution and use in source and binary forms, with or without
28 * modification, are permitted provided that the following conditions
30 * 1. Redistributions of source code must retain the above copyright
31 * notice, this list of conditions and the following disclaimer.
32 * 2. Redistributions in binary form must reproduce the above copyright
33 * notice, this list of conditions and the following disclaimer in the
34 * documentation and/or other materials provided with the distribution.
35 * 3. All advertising materials mentioning features or use of this software
36 * must display the following acknowledgement:
37 * This product includes software developed by the University of
38 * California, Berkeley and its contributors.
39 * 4. Neither the name of the University nor the names of its contributors
40 * may be used to endorse or promote products derived from this software
41 * without specific prior written permission.
43 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
44 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
47 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55 * @(#)vfs_cluster.c 8.10 (Berkeley) 3/28/95
58 #include <sys/param.h>
61 #include <sys/vnode.h>
62 #include <sys/mount.h>
63 #include <sys/trace.h>
64 #include <sys/malloc.h>
65 #include <sys/resourcevar.h>
66 #include <libkern/libkern.h>
69 #include <vm/vm_pageout.h>
71 #include <sys/kdebug.h>
75 #define CL_COMMIT 0x04
77 #define CL_PAGEOUT 0x10
80 #define CL_NOZERO 0x80
81 #define CL_PAGEIN 0x100
82 #define CL_DEV_MEMORY 0x200
85 * throttle the number of async writes that
86 * can be outstanding on a single vnode
87 * before we issue a synchronous write
89 #define ASYNC_THROTTLE 6
102 struct buf
*cbp_head
;
103 struct buf
*cbp_next
;
110 cbp_head
= (struct buf
*)(bp
->b_trans_head
);
112 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 20)) | DBG_FUNC_START
,
113 cbp_head
, bp
->b_lblkno
, bp
->b_bcount
, bp
->b_flags
, 0);
115 for (cbp
= cbp_head
; cbp
; cbp
= cbp
->b_trans_next
) {
117 * all I/O requests that are part of this transaction
118 * have to complete before we can process it
120 if ( !(cbp
->b_flags
& B_DONE
)) {
122 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 20)) | DBG_FUNC_END
,
123 cbp_head
, cbp
, cbp
->b_bcount
, cbp
->b_flags
, 0);
133 upl_offset
= cbp
->b_uploffset
;
134 upl
= cbp
->b_pagelist
;
135 b_flags
= cbp
->b_flags
;
136 real_bp
= cbp
->b_real_bp
;
140 if (cbp
->b_vectorcount
> 1)
141 _FREE(cbp
->b_vectorlist
, M_SEGMENT
);
143 if ((cbp
->b_flags
& B_ERROR
) && error
== 0)
144 error
= cbp
->b_error
;
146 total_resid
+= cbp
->b_resid
;
147 total_size
+= cbp
->b_bcount
;
149 cbp_next
= cbp
->b_trans_next
;
155 if ((vp
->v_flag
& VTHROTTLED
) && (vp
->v_numoutput
<= (ASYNC_THROTTLE
/ 3))) {
156 vp
->v_flag
&= ~VTHROTTLED
;
157 wakeup((caddr_t
)&vp
->v_numoutput
);
159 if ((b_flags
& B_NEED_IODONE
) && real_bp
) {
161 real_bp
->b_flags
|= B_ERROR
;
162 real_bp
->b_error
= error
;
164 real_bp
->b_resid
= total_resid
;
168 if (error
== 0 && total_resid
)
171 if (b_flags
& B_COMMIT_UPL
) {
172 pg_offset
= upl_offset
& PAGE_MASK
;
173 commit_size
= (((pg_offset
+ total_size
) + (PAGE_SIZE
- 1)) / PAGE_SIZE
) * PAGE_SIZE
;
175 if (error
|| (b_flags
& B_NOCACHE
)) {
178 if (b_flags
& B_PAGEOUT
)
179 upl_abort_code
= UPL_ABORT_FREE_ON_EMPTY
;
180 else if (b_flags
& B_PGIN
)
181 upl_abort_code
= UPL_ABORT_FREE_ON_EMPTY
| UPL_ABORT_ERROR
;
183 upl_abort_code
= UPL_ABORT_FREE_ON_EMPTY
| UPL_ABORT_DUMP_PAGES
;
185 ubc_upl_abort_range(upl
, upl_offset
- pg_offset
, commit_size
,
188 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 20)) | DBG_FUNC_END
,
189 upl
, upl_offset
- pg_offset
, commit_size
,
190 0x80000000|upl_abort_code
, 0);
193 int upl_commit_flags
= UPL_COMMIT_FREE_ON_EMPTY
;
195 if ( !(b_flags
& B_PAGEOUT
))
196 upl_commit_flags
|= UPL_COMMIT_CLEAR_DIRTY
;
198 upl_commit_flags
|= UPL_COMMIT_INACTIVATE
;
200 ubc_upl_commit_range(upl
, upl_offset
- pg_offset
, commit_size
,
203 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 20)) | DBG_FUNC_END
,
204 upl
, upl_offset
- pg_offset
, commit_size
,
205 upl_commit_flags
, 0);
208 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 20)) | DBG_FUNC_END
,
209 upl
, upl_offset
, 0, error
, 0);
216 cluster_zero(upl
, upl_offset
, size
, flags
, bp
)
218 vm_offset_t upl_offset
;
223 vm_offset_t io_addr
= 0;
226 if ( !(flags
& CL_NOMAP
)) {
227 kret
= ubc_upl_map(upl
, &io_addr
);
229 if (kret
!= KERN_SUCCESS
)
230 panic("cluster_zero: ubc_upl_map() failed with (%d)", kret
);
232 panic("cluster_zero: ubc_upl_map() mapped 0");
234 io_addr
= (vm_offset_t
)bp
->b_data
;
235 bzero((caddr_t
)(io_addr
+ upl_offset
), size
);
237 if ( !(flags
& CL_NOMAP
)) {
238 kret
= ubc_upl_unmap(upl
);
240 if (kret
!= KERN_SUCCESS
)
241 panic("cluster_zero: kernel_upl_unmap failed");
246 cluster_io(vp
, upl
, upl_offset
, f_offset
, size
, flags
, real_bp
)
249 vm_offset_t upl_offset
;
260 struct buf
*cbp_head
= 0;
261 struct buf
*cbp_tail
= 0;
269 if (flags
& CL_READ
) {
270 io_flags
= (B_VECTORLIST
| B_READ
);
272 vfs_io_attributes(vp
, B_READ
, &max_iosize
, &max_vectors
);
274 io_flags
= (B_VECTORLIST
| B_WRITEINPROG
);
276 vfs_io_attributes(vp
, B_WRITE
, &max_iosize
, &max_vectors
);
278 pl
= ubc_upl_pageinfo(upl
);
280 if (flags
& CL_ASYNC
)
281 io_flags
|= (B_CALL
| B_ASYNC
);
285 io_flags
|= B_NOCACHE
;
286 if (flags
& CL_PAGEIN
)
290 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 22)) | DBG_FUNC_START
,
291 (int)f_offset
, size
, upl_offset
, flags
, 0);
293 if ((flags
& CL_READ
) && ((upl_offset
+ size
) & PAGE_MASK
) && (!(flags
& CL_NOZERO
))) {
295 * then we are going to end up
296 * with a page that we can't complete (the file size wasn't a multiple
297 * of PAGE_SIZE and we're trying to read to the end of the file
298 * so we'll go ahead and zero out the portion of the page we can't
299 * read in from the file
301 cluster_zero(upl
, upl_offset
+ size
, PAGE_SIZE
- ((upl_offset
+ size
) & PAGE_MASK
), flags
, real_bp
);
303 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 23)) | DBG_FUNC_NONE
,
304 upl_offset
+ size
, PAGE_SIZE
- ((upl_offset
+ size
) & PAGE_MASK
),
317 if (size
> max_iosize
)
318 io_size
= max_iosize
;
322 if (error
= VOP_CMAP(vp
, f_offset
, io_size
, &blkno
, &io_size
, NULL
)) {
323 if (error
== EOPNOTSUPP
)
324 panic("VOP_CMAP Unimplemented");
328 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 24)) | DBG_FUNC_NONE
,
329 (int)f_offset
, (int)blkno
, io_size
, 0, 0);
331 if ( (!(flags
& CL_READ
) && (long)blkno
== -1) || io_size
== 0) {
332 if (flags
& CL_PAGEOUT
) {
337 /* Try paging out the page individually before
338 giving up entirely and dumping it (it could
339 be mapped in a "hole" and require allocation
342 ubc_upl_abort_range(upl
, upl_offset
, PAGE_SIZE_64
, UPL_ABORT_FREE_ON_EMPTY
);
343 if (ubc_pushdirty_range(vp
, f_offset
, PAGE_SIZE_64
) == 0) {
348 upl_offset
+= PAGE_SIZE_64
;
349 f_offset
+= PAGE_SIZE_64
;
350 size
-= PAGE_SIZE_64
;
353 lblkno
= (daddr_t
)(f_offset
/ PAGE_SIZE_64
);
355 * we have now figured out how much I/O we can do - this is in 'io_size'
356 * pl_index represents the first page in the 'upl' that the I/O will occur for
357 * pg_offset is the starting point in the first page for the I/O
358 * pg_count is the number of full and partial pages that 'io_size' encompasses
360 pl_index
= upl_offset
/ PAGE_SIZE
;
361 pg_offset
= upl_offset
& PAGE_MASK
;
362 pg_count
= (io_size
+ pg_offset
+ (PAGE_SIZE
- 1)) / PAGE_SIZE
;
364 if (flags
& CL_DEV_MEMORY
) {
366 * currently, can't deal with reading 'holes' in file
368 if ((long)blkno
== -1) {
373 * treat physical requests as one 'giant' page
377 if ((flags
& CL_READ
) && (long)blkno
== -1) {
379 * if we're reading and blkno == -1, then we've got a
380 * 'hole' in the file that we need to deal with by zeroing
381 * out the affected area in the upl
383 cluster_zero(upl
, upl_offset
, io_size
, flags
, real_bp
);
385 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 23)) | DBG_FUNC_NONE
,
386 upl_offset
, io_size
, flags
, real_bp
, 0);
388 pg_count
= (io_size
- pg_offset
) / PAGE_SIZE
;
390 if (io_size
== size
&& ((upl_offset
+ io_size
) & PAGE_MASK
))
395 pg_resid
= PAGE_SIZE
- pg_offset
;
398 if (flags
& CL_COMMIT
)
399 ubc_upl_commit_range(upl
,
400 upl_offset
+ pg_resid
,
401 pg_count
* PAGE_SIZE
,
402 UPL_COMMIT_CLEAR_DIRTY
| UPL_COMMIT_FREE_ON_EMPTY
);
404 upl_offset
+= io_size
;
408 if (cbp_head
&& pg_count
)
411 } else if (real_bp
&& (real_bp
->b_blkno
== real_bp
->b_lblkno
)) {
412 real_bp
->b_blkno
= blkno
;
416 if (pg_count
> max_vectors
) {
417 io_size
-= (pg_count
- max_vectors
) * PAGE_SIZE
;
420 io_size
= PAGE_SIZE
- pg_offset
;
423 pg_count
= max_vectors
;
426 * we need to allocate space for the vector list
429 iovp
= (struct iovec
*)_MALLOC(sizeof(struct iovec
) * pg_count
,
430 M_SEGMENT
, M_NOWAIT
);
432 if (iovp
== (struct iovec
*) 0) {
434 * if the allocation fails, then throttle down to a single page
436 io_size
= PAGE_SIZE
- pg_offset
;
442 /* Throttle the speculative IO */
443 if ((flags
& CL_ASYNC
) && !(flags
& CL_PAGEOUT
))
448 cbp
= alloc_io_buf(vp
, priv
);
452 * we use the io vector that's reserved in the buffer header
453 * this insures we can always issue an I/O even in a low memory
454 * condition that prevents the _MALLOC from succeeding... this
455 * is necessary to prevent deadlocks with the pager
457 iovp
= (struct iovec
*)(&cbp
->b_vects
[0]);
459 cbp
->b_vectorlist
= (void *)iovp
;
460 cbp
->b_vectorcount
= pg_count
;
462 if (flags
& CL_DEV_MEMORY
) {
464 iovp
->iov_len
= io_size
;
465 iovp
->iov_base
= (caddr_t
)upl_phys_page(pl
, 0);
467 if (iovp
->iov_base
== (caddr_t
) 0) {
471 iovp
->iov_base
+= upl_offset
;
474 for (i
= 0, vsize
= io_size
; i
< pg_count
; i
++, iovp
++) {
477 psize
= PAGE_SIZE
- pg_offset
;
482 iovp
->iov_len
= psize
;
483 iovp
->iov_base
= (caddr_t
)upl_phys_page(pl
, pl_index
+ i
);
485 if (iovp
->iov_base
== (caddr_t
) 0) {
487 _FREE(cbp
->b_vectorlist
, M_SEGMENT
);
493 iovp
->iov_base
+= pg_offset
;
496 if (flags
& CL_PAGEOUT
) {
501 if (bp
= incore(vp
, lblkno
+ i
)) {
502 if (!ISSET(bp
->b_flags
, B_BUSY
)) {
504 SET(bp
->b_flags
, (B_BUSY
| B_INVAL
));
508 panic("BUSY bp found in cluster_io");
518 if (flags
& CL_ASYNC
)
519 cbp
->b_iodone
= (void *)cluster_iodone
;
520 cbp
->b_flags
|= io_flags
;
522 cbp
->b_lblkno
= lblkno
;
523 cbp
->b_blkno
= blkno
;
524 cbp
->b_bcount
= io_size
;
525 cbp
->b_pagelist
= upl
;
526 cbp
->b_uploffset
= upl_offset
;
527 cbp
->b_trans_next
= (struct buf
*)0;
530 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 26)) | DBG_FUNC_NONE
,
531 cbp
->b_lblkno
, cbp
->b_blkno
, upl_offset
, io_size
, 0);
533 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 27)) | DBG_FUNC_NONE
,
534 cbp
->b_lblkno
, cbp
->b_blkno
, upl_offset
, io_size
, 0);
537 cbp_tail
->b_trans_next
= cbp
;
543 (struct buf
*)(cbp
->b_trans_head
) = cbp_head
;
545 upl_offset
+= io_size
;
549 if ( (!(upl_offset
& PAGE_MASK
) && !(flags
& CL_DEV_MEMORY
)) || size
== 0) {
551 * if we have no more I/O to issue or
552 * the current I/O we've prepared fully
553 * completes the last page in this request
554 * or it's been completed via a zero-fill
555 * due to a 'hole' in the file
556 * then go ahead and issue the I/O
559 if (flags
& CL_COMMIT
)
560 cbp_head
->b_flags
|= B_COMMIT_UPL
;
561 if (flags
& CL_PAGEOUT
)
562 cbp_head
->b_flags
|= B_PAGEOUT
;
563 if (flags
& CL_PAGEIN
)
564 cbp_head
->b_flags
|= B_PGIN
;
567 cbp_head
->b_flags
|= B_NEED_IODONE
;
568 cbp_head
->b_real_bp
= real_bp
;
571 for (cbp
= cbp_head
; cbp
;) {
572 struct buf
* cbp_next
;
574 if (io_flags
& B_WRITEINPROG
)
575 cbp
->b_vp
->v_numoutput
++;
577 cbp_next
= cbp
->b_trans_next
;
579 (void) VOP_STRATEGY(cbp
);
582 if ( !(flags
& CL_ASYNC
)) {
583 for (cbp
= cbp_head
; cbp
; cbp
= cbp
->b_trans_next
)
586 if (error
= cluster_iodone(cbp_head
)) {
591 cbp_head
= (struct buf
*)0;
592 cbp_tail
= (struct buf
*)0;
598 for (cbp
= cbp_head
; cbp
;) {
599 struct buf
* cbp_next
;
601 if (cbp
->b_vectorcount
> 1)
602 _FREE(cbp
->b_vectorlist
, M_SEGMENT
);
603 upl_offset
-= cbp
->b_bcount
;
604 size
+= cbp
->b_bcount
;
606 cbp_next
= cbp
->b_trans_next
;
610 pg_offset
= upl_offset
& PAGE_MASK
;
611 abort_size
= ((size
+ pg_offset
+ (PAGE_SIZE
- 1)) / PAGE_SIZE
) * PAGE_SIZE
;
613 if (flags
& CL_COMMIT
) {
616 if (flags
& CL_PAGEOUT
)
617 upl_abort_code
= UPL_ABORT_FREE_ON_EMPTY
;
618 else if (flags
& CL_PAGEIN
)
619 upl_abort_code
= UPL_ABORT_FREE_ON_EMPTY
| UPL_ABORT_ERROR
;
621 upl_abort_code
= UPL_ABORT_FREE_ON_EMPTY
| UPL_ABORT_DUMP_PAGES
;
623 ubc_upl_abort_range(upl
, upl_offset
- pg_offset
, abort_size
,
626 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 28)) | DBG_FUNC_NONE
,
627 upl
, upl_offset
- pg_offset
, abort_size
, error
, 0);
630 real_bp
->b_flags
|= B_ERROR
;
631 real_bp
->b_error
= error
;
638 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 22)) | DBG_FUNC_END
,
639 (int)f_offset
, size
, upl_offset
, retval
, 0);
646 cluster_rd_prefetch(vp
, f_offset
, size
, filesize
, devblocksize
)
662 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 49)) | DBG_FUNC_START
,
663 (int)f_offset
, size
, (int)filesize
, 0, 0);
665 if (f_offset
>= filesize
) {
666 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 49)) | DBG_FUNC_END
,
667 (int)f_offset
, 0, 0, 0, 0);
670 if (ubc_page_op(vp
, f_offset
, 0, 0, 0) == KERN_SUCCESS
) {
671 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 49)) | DBG_FUNC_END
,
672 (int)f_offset
, 0, 0, 0, 0);
675 if (size
> (MAX_UPL_TRANSFER
* PAGE_SIZE
))
676 size
= MAX_UPL_TRANSFER
* PAGE_SIZE
;
678 size
= (size
+ (PAGE_SIZE
- 1)) & ~(PAGE_SIZE
- 1);
680 if ((off_t
)size
> (filesize
- f_offset
))
681 size
= ((filesize
- f_offset
) + (devblocksize
- 1)) & ~(devblocksize
- 1);
683 pages_in_upl
= (size
+ (PAGE_SIZE
- 1)) / PAGE_SIZE
;
687 pages_in_upl
* PAGE_SIZE
,
692 if (upl
== (upl_t
) 0)
696 * scan from the beginning of the upl looking for the first
697 * non-valid page.... this will become the first page in
698 * the request we're going to make to 'cluster_io'... if all
699 * of the pages are valid, we won't call through to 'cluster_io'
701 for (start_pg
= 0; start_pg
< pages_in_upl
; start_pg
++) {
702 if (!upl_valid_page(pl
, start_pg
))
707 * scan from the starting invalid page looking for a valid
708 * page before the end of the upl is reached, if we
709 * find one, then it will be the last page of the request to
712 for (last_pg
= start_pg
; last_pg
< pages_in_upl
; last_pg
++) {
713 if (upl_valid_page(pl
, last_pg
))
718 * if we find any more free valid pages at the tail of the upl
719 * than update maxra accordingly....
721 for (last_valid
= last_pg
; last_valid
< pages_in_upl
; last_valid
++) {
722 if (!upl_valid_page(pl
, last_valid
))
725 if (start_pg
< last_pg
) {
726 vm_offset_t upl_offset
;
729 * we found a range of 'invalid' pages that must be filled
730 * 'size' has already been clipped to the LEOF
731 * make sure it's at least a multiple of the device block size
733 upl_offset
= start_pg
* PAGE_SIZE
;
734 io_size
= (last_pg
- start_pg
) * PAGE_SIZE
;
736 if ((upl_offset
+ io_size
) > size
) {
737 io_size
= size
- upl_offset
;
739 KERNEL_DEBUG(0xd001000, upl_offset
, size
, io_size
, 0, 0);
741 cluster_io(vp
, upl
, upl_offset
, f_offset
+ upl_offset
, io_size
,
742 CL_READ
| CL_COMMIT
| CL_ASYNC
| CL_AGE
, (struct buf
*)0);
746 * start_pg of non-zero indicates we found some already valid pages
747 * at the beginning of the upl.... we need to release these without
748 * modifying there state
750 ubc_upl_abort_range(upl
, 0, start_pg
* PAGE_SIZE
, UPL_ABORT_FREE_ON_EMPTY
);
752 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 50)) | DBG_FUNC_NONE
,
753 upl
, 0, start_pg
* PAGE_SIZE
, 0, 0);
755 if (last_pg
< pages_in_upl
) {
757 * the set of pages that we issued an I/O for did not extend all the
758 * way to the end of the upl... so just release them without modifying
761 ubc_upl_abort_range(upl
, last_pg
* PAGE_SIZE
, (pages_in_upl
- last_pg
) * PAGE_SIZE
,
762 UPL_ABORT_FREE_ON_EMPTY
);
764 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 50)) | DBG_FUNC_NONE
,
765 upl
, last_pg
* PAGE_SIZE
, (pages_in_upl
- last_pg
) * PAGE_SIZE
, 0, 0);
768 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 49)) | DBG_FUNC_END
,
769 (int)f_offset
+ (last_valid
* PAGE_SIZE
), 0, 0, 0, 0);
777 cluster_rd_ahead(vp
, b_lblkno
, e_lblkno
, filesize
, devblocksize
)
786 int size_of_prefetch
;
790 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 48)) | DBG_FUNC_START
,
791 b_lblkno
, e_lblkno
, vp
->v_lastr
, 0, 0);
793 if (b_lblkno
== vp
->v_lastr
&& b_lblkno
== e_lblkno
) {
794 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 48)) | DBG_FUNC_END
,
795 vp
->v_ralen
, vp
->v_maxra
, vp
->v_lastr
, 0, 0);
799 if (vp
->v_lastr
== -1 || (b_lblkno
!= vp
->v_lastr
&& b_lblkno
!= (vp
->v_lastr
+ 1) && b_lblkno
!= (vp
->v_maxra
+ 1))) {
803 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 48)) | DBG_FUNC_END
,
804 vp
->v_ralen
, vp
->v_maxra
, vp
->v_lastr
, 1, 0);
808 vfs_io_attributes(vp
, B_READ
, &max_iosize
, &max_pages
);
810 if ((max_iosize
/ PAGE_SIZE
) < max_pages
)
811 max_pages
= max_iosize
/ PAGE_SIZE
;
812 if (max_pages
> MAX_UPL_TRANSFER
)
813 max_pages
= MAX_UPL_TRANSFER
;
815 vp
->v_ralen
= vp
->v_ralen
? min(max_pages
, vp
->v_ralen
<< 1) : 1;
817 if (((e_lblkno
+ 1) - b_lblkno
) > vp
->v_ralen
)
818 vp
->v_ralen
= min(max_pages
, (e_lblkno
+ 1) - b_lblkno
);
820 if (e_lblkno
< vp
->v_maxra
) {
821 if ((vp
->v_maxra
- e_lblkno
) > (max_pages
/ 4)) {
823 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 48)) | DBG_FUNC_END
,
824 vp
->v_ralen
, vp
->v_maxra
, vp
->v_lastr
, 2, 0);
828 r_lblkno
= max(e_lblkno
, vp
->v_maxra
) + 1;
829 f_offset
= (off_t
)r_lblkno
* PAGE_SIZE_64
;
831 size_of_prefetch
= cluster_rd_prefetch(vp
, f_offset
, vp
->v_ralen
* PAGE_SIZE
, filesize
, devblocksize
);
833 if (size_of_prefetch
)
834 vp
->v_maxra
= r_lblkno
+ (size_of_prefetch
- 1);
836 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 48)) | DBG_FUNC_END
,
837 vp
->v_ralen
, vp
->v_maxra
, vp
->v_lastr
, 3, 0);
841 cluster_pageout(vp
, upl
, upl_offset
, f_offset
, size
, filesize
, devblocksize
, flags
)
844 vm_offset_t upl_offset
;
854 int local_flags
= CL_PAGEOUT
;
856 if ((flags
& UPL_IOSYNC
) == 0)
857 local_flags
|= CL_ASYNC
;
858 if ((flags
& UPL_NOCOMMIT
) == 0)
859 local_flags
|= CL_COMMIT
;
861 if (upl
== (upl_t
) 0)
862 panic("cluster_pageout: can't handle NULL upl yet\n");
865 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 52)) | DBG_FUNC_NONE
,
866 (int)f_offset
, size
, (int)filesize
, local_flags
, 0);
869 * If they didn't specify any I/O, then we are done...
870 * we can't issue an abort because we don't know how
871 * big the upl really is
876 if (vp
->v_mount
->mnt_flag
& MNT_RDONLY
) {
877 if (local_flags
& CL_COMMIT
)
878 ubc_upl_abort_range(upl
, upl_offset
, size
,
879 UPL_ABORT_FREE_ON_EMPTY
);
883 * can't page-in from a negative offset
884 * or if we're starting beyond the EOF
885 * or if the file offset isn't page aligned
886 * or the size requested isn't a multiple of PAGE_SIZE
888 if (f_offset
< 0 || f_offset
>= filesize
||
889 (f_offset
& PAGE_MASK_64
) || (size
& PAGE_MASK
)) {
890 if (local_flags
& CL_COMMIT
)
891 ubc_upl_abort_range(upl
, upl_offset
, size
, UPL_ABORT_FREE_ON_EMPTY
);
894 max_size
= filesize
- f_offset
;
899 io_size
= (max_size
+ (devblocksize
- 1)) & ~(devblocksize
- 1);
901 pg_size
= (io_size
+ (PAGE_SIZE
- 1)) & ~PAGE_MASK
;
903 if (size
> pg_size
) {
904 if (local_flags
& CL_COMMIT
)
905 ubc_upl_abort_range(upl
, upl_offset
+ pg_size
, size
- pg_size
,
906 UPL_ABORT_FREE_ON_EMPTY
);
908 while (vp
->v_numoutput
>= ASYNC_THROTTLE
) {
909 vp
->v_flag
|= VTHROTTLED
;
910 tsleep((caddr_t
)&vp
->v_numoutput
, PRIBIO
+ 1, "cluster_pageout", 0);
913 return (cluster_io(vp
, upl
, upl_offset
, f_offset
, io_size
,
914 local_flags
, (struct buf
*)0));
918 cluster_pagein(vp
, upl
, upl_offset
, f_offset
, size
, filesize
, devblocksize
, flags
)
921 vm_offset_t upl_offset
;
936 * If they didn't ask for any data, then we are done...
937 * we can't issue an abort because we don't know how
938 * big the upl really is
943 if ((flags
& UPL_NOCOMMIT
) == 0)
944 local_flags
= CL_COMMIT
;
946 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 56)) | DBG_FUNC_NONE
,
947 (int)f_offset
, size
, (int)filesize
, local_flags
, 0);
950 * can't page-in from a negative offset
951 * or if we're starting beyond the EOF
952 * or if the file offset isn't page aligned
953 * or the size requested isn't a multiple of PAGE_SIZE
955 if (f_offset
< 0 || f_offset
>= filesize
||
956 (f_offset
& PAGE_MASK_64
) || (size
& PAGE_MASK
)) {
957 if (local_flags
& CL_COMMIT
)
958 ubc_upl_abort_range(upl
, upl_offset
, size
,
959 UPL_ABORT_ERROR
| UPL_ABORT_FREE_ON_EMPTY
);
962 max_size
= filesize
- f_offset
;
967 io_size
= (max_size
+ (devblocksize
- 1)) & ~(devblocksize
- 1);
969 pg_size
= (io_size
+ (PAGE_SIZE
- 1)) & ~PAGE_MASK
;
971 if (upl
== (upl_t
) 0) {
979 if (upl
== (upl_t
) 0)
982 upl_offset
= (vm_offset_t
)0;
985 if (size
> pg_size
) {
986 if (local_flags
& CL_COMMIT
)
987 ubc_upl_abort_range(upl
, upl_offset
+ pg_size
, size
- pg_size
,
988 UPL_ABORT_FREE_ON_EMPTY
);
991 retval
= cluster_io(vp
, upl
, upl_offset
, f_offset
, io_size
,
992 local_flags
| CL_READ
| CL_PAGEIN
, (struct buf
*)0);
998 b_lblkno
= (int)(f_offset
/ PAGE_SIZE_64
);
1000 ((f_offset
+ ((off_t
)io_size
- 1)) / PAGE_SIZE_64
);
1002 if (!(flags
& UPL_NORDAHEAD
) && !(vp
->v_flag
& VRAOFF
)) {
1004 * we haven't read the last page in of the file yet
1005 * so let's try to read ahead if we're in
1006 * a sequential access pattern
1008 cluster_rd_ahead(vp
, b_lblkno
, e_lblkno
, filesize
, devblocksize
);
1010 vp
->v_lastr
= e_lblkno
;
1022 if (bp
->b_pagelist
== (upl_t
) 0)
1023 panic("cluster_bp: can't handle NULL upl yet\n");
1024 if (bp
->b_flags
& B_READ
)
1025 flags
= CL_ASYNC
| CL_NOMAP
| CL_READ
;
1027 flags
= CL_ASYNC
| CL_NOMAP
;
1029 f_offset
= ubc_blktooff(bp
->b_vp
, bp
->b_lblkno
);
1031 return (cluster_io(bp
->b_vp
, bp
->b_pagelist
, 0, f_offset
, bp
->b_bcount
, flags
, bp
));
1035 cluster_write(vp
, uio
, oldEOF
, newEOF
, headOff
, tailOff
, devblocksize
, flags
)
1049 vm_offset_t upl_offset
;
1052 upl_page_info_t
*pl
;
1058 if ((!uio
) || (uio
->uio_segflg
!= UIO_USERSPACE
) || (!(vp
->v_flag
& VNOCACHE_DATA
)))
1060 retval
= cluster_write_x(vp
, uio
, oldEOF
, newEOF
, headOff
, tailOff
, devblocksize
, flags
);
1064 while (uio
->uio_resid
&& uio
->uio_offset
< newEOF
&& retval
== 0)
1066 /* we know we have a resid, so this is safe */
1068 while (iov
->iov_len
== 0) {
1075 * We check every vector target and if it is physically
1076 * contiguous space, we skip the sanity checks.
1079 upl_offset
= (vm_offset_t
)iov
->iov_base
& ~PAGE_MASK
;
1080 upl_size
= (upl_offset
+ PAGE_SIZE
+(PAGE_SIZE
-1)) & ~PAGE_MASK
;
1082 upl_flags
= UPL_QUERY_OBJECT_TYPE
;
1083 if ((vm_map_get_upl(current_map(),
1084 (vm_offset_t
)iov
->iov_base
& ~PAGE_MASK
,
1085 &upl_size
, &upl
, NULL
, &pages_in_pl
, &upl_flags
, 0)) != KERN_SUCCESS
)
1088 * the user app must have passed in an invalid address
1093 if (upl_flags
& UPL_PHYS_CONTIG
)
1096 * since the interface to the IOKit below us uses physical block #'s and
1097 * block counts to specify the I/O, we can't handle anything that isn't
1098 * devblocksize aligned
1100 if ((uio
->uio_offset
& (devblocksize
- 1)) || (uio
->uio_resid
& (devblocksize
- 1)))
1103 if (flags
& IO_HEADZEROFILL
)
1105 flags
&= ~IO_HEADZEROFILL
;
1107 if (retval
= cluster_write_x(vp
, (struct uio
*)0, 0, uio
->uio_offset
, headOff
, 0, devblocksize
, IO_HEADZEROFILL
))
1111 retval
= cluster_phys_write(vp
, uio
);
1113 if (uio
->uio_resid
== 0 && (flags
& IO_TAILZEROFILL
))
1115 retval
= cluster_write_x(vp
, (struct uio
*)0, 0, tailOff
, uio
->uio_offset
, 0, devblocksize
, IO_HEADZEROFILL
);
1119 else if ((uio
->uio_resid
< 4 * PAGE_SIZE
) || (flags
& (IO_TAILZEROFILL
| IO_HEADZEROFILL
)))
1122 * We set a threshhold of 4 pages to decide if the nocopy
1123 * write loop is worth the trouble...
1124 * we also come here if we're trying to zero the head and/or tail
1125 * of a partially written page, and the user source is not a physically contiguous region
1127 retval
= cluster_write_x(vp
, uio
, oldEOF
, newEOF
, headOff
, tailOff
, devblocksize
, flags
);
1130 else if (uio
->uio_offset
& PAGE_MASK_64
)
1132 /* Bring the file offset write up to a pagesize boundary */
1133 clip_size
= (PAGE_SIZE
- (uio
->uio_offset
& PAGE_MASK_64
));
1134 if (uio
->uio_resid
< clip_size
)
1135 clip_size
= uio
->uio_resid
;
1137 * Fake the resid going into the cluster_write_x call
1138 * and restore it on the way out.
1140 prev_resid
= uio
->uio_resid
;
1141 uio
->uio_resid
= clip_size
;
1142 retval
= cluster_write_x(vp
, uio
, oldEOF
, newEOF
, headOff
, tailOff
, devblocksize
, flags
);
1143 uio
->uio_resid
= prev_resid
- (clip_size
- uio
->uio_resid
);
1145 else if ((int)iov
->iov_base
& PAGE_MASK_64
)
1147 clip_size
= iov
->iov_len
;
1148 prev_resid
= uio
->uio_resid
;
1149 uio
->uio_resid
= clip_size
;
1150 retval
= cluster_write_x(vp
, uio
, oldEOF
, newEOF
, headOff
, tailOff
, devblocksize
, flags
);
1151 uio
->uio_resid
= prev_resid
- (clip_size
- uio
->uio_resid
);
1156 * If we come in here, we know the offset into
1157 * the file is on a pagesize boundary
1160 max_io_size
= newEOF
- uio
->uio_offset
;
1161 clip_size
= uio
->uio_resid
;
1162 if (iov
->iov_len
< clip_size
)
1163 clip_size
= iov
->iov_len
;
1164 if (max_io_size
< clip_size
)
1165 clip_size
= max_io_size
;
1167 if (clip_size
< PAGE_SIZE
)
1170 * Take care of tail end of write in this vector
1172 prev_resid
= uio
->uio_resid
;
1173 uio
->uio_resid
= clip_size
;
1174 retval
= cluster_write_x(vp
, uio
, oldEOF
, newEOF
, headOff
, tailOff
, devblocksize
, flags
);
1175 uio
->uio_resid
= prev_resid
- (clip_size
- uio
->uio_resid
);
1179 /* round clip_size down to a multiple of pagesize */
1180 clip_size
= clip_size
& ~(PAGE_MASK
);
1181 prev_resid
= uio
->uio_resid
;
1182 uio
->uio_resid
= clip_size
;
1183 retval
= cluster_nocopy_write(vp
, uio
, newEOF
, devblocksize
, flags
);
1184 if ((retval
== 0) && uio
->uio_resid
)
1185 retval
= cluster_write_x(vp
, uio
, oldEOF
, newEOF
, headOff
, tailOff
, devblocksize
, flags
);
1186 uio
->uio_resid
= prev_resid
- (clip_size
- uio
->uio_resid
);
1194 cluster_nocopy_write(vp
, uio
, newEOF
, devblocksize
, flags
)
1202 upl_page_info_t
*pl
;
1204 vm_offset_t upl_offset
;
1208 int upl_needed_size
;
1214 int force_data_sync
;
1217 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 75)) | DBG_FUNC_START
,
1218 (int)uio
->uio_offset
, (int)uio
->uio_resid
,
1219 (int)newEOF
, devblocksize
, 0);
1222 * When we enter this routine, we know
1223 * -- the offset into the file is on a pagesize boundary
1224 * -- the resid is a page multiple
1225 * -- the resid will not exceed iov_len
1230 while (uio
->uio_resid
&& uio
->uio_offset
< newEOF
&& error
== 0) {
1231 io_size
= uio
->uio_resid
;
1233 if (io_size
> (MAX_UPL_TRANSFER
* PAGE_SIZE
))
1234 io_size
= MAX_UPL_TRANSFER
* PAGE_SIZE
;
1236 upl_offset
= (vm_offset_t
)iov
->iov_base
& PAGE_MASK_64
;
1237 upl_needed_size
= (upl_offset
+ io_size
+ (PAGE_SIZE
-1)) & ~PAGE_MASK
;
1239 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 76)) | DBG_FUNC_START
,
1240 (int)upl_offset
, upl_needed_size
, iov
->iov_base
, io_size
, 0);
1242 for (force_data_sync
= 0; force_data_sync
< 3; force_data_sync
++)
1245 upl_size
= upl_needed_size
;
1246 upl_flags
= UPL_COPYOUT_FROM
| UPL_NO_SYNC
| UPL_CLEAN_IN_PLACE
| UPL_SET_INTERNAL
;
1248 kret
= vm_map_get_upl(current_map(),
1249 (vm_offset_t
)iov
->iov_base
& ~PAGE_MASK
,
1257 if (kret
!= KERN_SUCCESS
)
1259 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 76)) | DBG_FUNC_END
,
1262 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 75)) | DBG_FUNC_END
,
1263 (int)uio
->uio_offset
, (int)uio
->uio_resid
, kret
, 1, 0);
1265 /* cluster_nocopy_write: failed to get pagelist */
1266 /* do not return kret here */
1270 pl
= UPL_GET_INTERNAL_PAGE_LIST(upl
);
1271 pages_in_pl
= upl_size
/ PAGE_SIZE
;
1273 for(i
=0; i
< pages_in_pl
; i
++)
1275 if (!upl_valid_page(pl
, i
))
1279 if (i
== pages_in_pl
)
1282 ubc_upl_abort_range(upl
, (upl_offset
& ~PAGE_MASK
), upl_size
,
1283 UPL_ABORT_FREE_ON_EMPTY
);
1286 if (force_data_sync
>= 3)
1288 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 76)) | DBG_FUNC_END
,
1289 i
, pages_in_pl
, upl_size
, kret
, 0);
1291 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 75)) | DBG_FUNC_END
,
1292 (int)uio
->uio_offset
, (int)uio
->uio_resid
, kret
, 2, 0);
1297 * Consider the possibility that upl_size wasn't satisfied.
1299 if (upl_size
!= upl_needed_size
)
1300 io_size
= (upl_size
- (int)upl_offset
) & ~PAGE_MASK
;
1302 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 76)) | DBG_FUNC_END
,
1303 (int)upl_offset
, upl_size
, iov
->iov_base
, io_size
, 0);
1307 ubc_upl_abort_range(upl
, (upl_offset
& ~PAGE_MASK
), upl_size
,
1308 UPL_ABORT_FREE_ON_EMPTY
);
1309 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 75)) | DBG_FUNC_END
,
1310 (int)uio
->uio_offset
, uio
->uio_resid
, 0, 3, 0);
1316 * Now look for pages already in the cache
1317 * and throw them away.
1320 upl_f_offset
= uio
->uio_offset
; /* this is page aligned in the file */
1321 max_io_size
= io_size
;
1323 while (max_io_size
) {
1326 * Flag UPL_POP_DUMP says if the page is found
1327 * in the page cache it must be thrown away.
1331 UPL_POP_SET
| UPL_POP_BUSY
| UPL_POP_DUMP
,
1333 max_io_size
-= PAGE_SIZE
;
1334 upl_f_offset
+= PAGE_SIZE
;
1338 * issue a synchronous write to cluster_io
1341 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 77)) | DBG_FUNC_START
,
1342 (int)upl_offset
, (int)uio
->uio_offset
, io_size
, 0, 0);
1344 error
= cluster_io(vp
, upl
, upl_offset
, uio
->uio_offset
,
1345 io_size
, 0, (struct buf
*)0);
1349 * The cluster_io write completed successfully,
1350 * update the uio structure.
1352 iov
->iov_base
+= io_size
;
1353 iov
->iov_len
-= io_size
;
1354 uio
->uio_resid
-= io_size
;
1355 uio
->uio_offset
+= io_size
;
1358 * always 'commit' the I/O via the abort primitive whether the I/O
1359 * succeeded cleanly or not... this is necessary to insure that
1360 * we preserve the state of the DIRTY flag on the pages used to
1361 * provide the data for the I/O... the state of this flag SHOULD
1362 * NOT be changed by a write
1364 ubc_upl_abort_range(upl
, (upl_offset
& ~PAGE_MASK
), upl_size
,
1365 UPL_ABORT_FREE_ON_EMPTY
);
1368 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 77)) | DBG_FUNC_END
,
1369 (int)upl_offset
, (int)uio
->uio_offset
, (int)uio
->uio_resid
, error
, 0);
1374 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 75)) | DBG_FUNC_END
,
1375 (int)uio
->uio_offset
, (int)uio
->uio_resid
, error
, 4, 0);
1381 cluster_phys_write(vp
, uio
)
1386 vm_offset_t upl_offset
;
1389 int upl_needed_size
;
1397 * When we enter this routine, we know
1398 * -- the resid will not exceed iov_len
1399 * -- the vector target address is physcially contiguous
1403 io_size
= iov
->iov_len
;
1404 upl_offset
= (vm_offset_t
)iov
->iov_base
& PAGE_MASK_64
;
1405 upl_needed_size
= upl_offset
+ io_size
;
1408 upl_size
= upl_needed_size
;
1409 upl_flags
= UPL_COPYOUT_FROM
| UPL_NO_SYNC
| UPL_CLEAN_IN_PLACE
| UPL_SET_INTERNAL
;
1411 kret
= vm_map_get_upl(current_map(),
1412 (vm_offset_t
)iov
->iov_base
& ~PAGE_MASK
,
1413 &upl_size
, &upl
, NULL
, &pages_in_pl
, &upl_flags
, 0);
1415 if (kret
!= KERN_SUCCESS
)
1417 /* cluster_phys_write: failed to get pagelist */
1418 /* note: return kret here */
1423 * Consider the possibility that upl_size wasn't satisfied.
1424 * This is a failure in the physical memory case.
1426 if (upl_size
< upl_needed_size
)
1428 kernel_upl_abort_range(upl
, 0, upl_size
, UPL_ABORT_FREE_ON_EMPTY
);
1433 * issue a synchronous write to cluster_io
1436 error
= cluster_io(vp
, upl
, upl_offset
, uio
->uio_offset
,
1437 io_size
, CL_DEV_MEMORY
, (struct buf
*)0);
1441 * The cluster_io write completed successfully,
1442 * update the uio structure and commit.
1445 ubc_upl_commit_range(upl
, 0, upl_size
, UPL_COMMIT_FREE_ON_EMPTY
);
1447 iov
->iov_base
+= io_size
;
1448 iov
->iov_len
-= io_size
;
1449 uio
->uio_resid
-= io_size
;
1450 uio
->uio_offset
+= io_size
;
1453 ubc_upl_abort_range(upl
, 0, upl_size
, UPL_ABORT_FREE_ON_EMPTY
);
1459 cluster_write_x(vp
, uio
, oldEOF
, newEOF
, headOff
, tailOff
, devblocksize
, flags
)
1469 upl_page_info_t
*pl
;
1471 vm_offset_t upl_offset
;
1478 int io_size_before_rounding
;
1480 vm_offset_t io_address
;
1487 long long total_size
;
1490 long long zero_cnt1
;
1492 daddr_t start_blkno
;
1496 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 40)) | DBG_FUNC_START
,
1497 (int)uio
->uio_offset
, uio
->uio_resid
, (int)oldEOF
, (int)newEOF
, 0);
1499 uio_resid
= uio
->uio_resid
;
1501 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 40)) | DBG_FUNC_START
,
1502 0, 0, (int)oldEOF
, (int)newEOF
, 0);
1509 if (flags
& IO_HEADZEROFILL
) {
1511 * some filesystems (HFS is one) don't support unallocated holes within a file...
1512 * so we zero fill the intervening space between the old EOF and the offset
1513 * where the next chunk of real data begins.... ftruncate will also use this
1514 * routine to zero fill to the new EOF when growing a file... in this case, the
1515 * uio structure will not be provided
1518 if (headOff
< uio
->uio_offset
) {
1519 zero_cnt
= uio
->uio_offset
- headOff
;
1522 } else if (headOff
< newEOF
) {
1523 zero_cnt
= newEOF
- headOff
;
1527 if (flags
& IO_TAILZEROFILL
) {
1529 zero_off1
= uio
->uio_offset
+ uio
->uio_resid
;
1531 if (zero_off1
< tailOff
)
1532 zero_cnt1
= tailOff
- zero_off1
;
1535 if (zero_cnt
== 0 && uio
== (struct uio
*) 0)
1537 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 40)) | DBG_FUNC_END
,
1538 retval
, 0, 0, 0, 0);
1542 while ((total_size
= (uio_resid
+ zero_cnt
+ zero_cnt1
)) && retval
== 0) {
1544 * for this iteration of the loop, figure out where our starting point is
1547 start_offset
= (int)(zero_off
& PAGE_MASK_64
);
1548 upl_f_offset
= zero_off
- start_offset
;
1549 } else if (uio_resid
) {
1550 start_offset
= (int)(uio
->uio_offset
& PAGE_MASK_64
);
1551 upl_f_offset
= uio
->uio_offset
- start_offset
;
1553 start_offset
= (int)(zero_off1
& PAGE_MASK_64
);
1554 upl_f_offset
= zero_off1
- start_offset
;
1556 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 46)) | DBG_FUNC_NONE
,
1557 (int)zero_off
, (int)zero_cnt
, (int)zero_off1
, (int)zero_cnt1
, 0);
1559 if (total_size
> (MAX_UPL_TRANSFER
* PAGE_SIZE
))
1560 total_size
= MAX_UPL_TRANSFER
* PAGE_SIZE
;
1563 * compute the size of the upl needed to encompass
1564 * the requested write... limit each call to cluster_io
1565 * to the maximum UPL size... cluster_io will clip if
1566 * this exceeds the maximum io_size for the device,
1567 * make sure to account for
1568 * a starting offset that's not page aligned
1570 upl_size
= (start_offset
+ total_size
+ (PAGE_SIZE
- 1)) & ~PAGE_MASK
;
1572 if (upl_size
> (MAX_UPL_TRANSFER
* PAGE_SIZE
))
1573 upl_size
= MAX_UPL_TRANSFER
* PAGE_SIZE
;
1575 pages_in_upl
= upl_size
/ PAGE_SIZE
;
1576 io_size
= upl_size
- start_offset
;
1578 if ((long long)io_size
> total_size
)
1579 io_size
= total_size
;
1581 start_blkno
= (daddr_t
)(upl_f_offset
/ PAGE_SIZE_64
);
1582 last_blkno
= start_blkno
+ pages_in_upl
;
1584 kret
= ubc_create_upl(vp
,
1590 if (kret
!= KERN_SUCCESS
)
1591 panic("cluster_write: failed to get pagelist");
1593 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 41)) | DBG_FUNC_NONE
,
1594 upl
, (int)upl_f_offset
, upl_size
, start_offset
, 0);
1596 if (start_offset
&& !upl_valid_page(pl
, 0)) {
1600 * we're starting in the middle of the first page of the upl
1601 * and the page isn't currently valid, so we're going to have
1602 * to read it in first... this is a synchronous operation
1604 read_size
= PAGE_SIZE
;
1606 if ((upl_f_offset
+ read_size
) > newEOF
) {
1607 read_size
= newEOF
- upl_f_offset
;
1608 read_size
= (read_size
+ (devblocksize
- 1)) & ~(devblocksize
- 1);
1610 retval
= cluster_io(vp
, upl
, 0, upl_f_offset
, read_size
,
1611 CL_READ
, (struct buf
*)0);
1614 * we had an error during the read which causes us to abort
1615 * the current cluster_write request... before we do, we need
1616 * to release the rest of the pages in the upl without modifying
1617 * there state and mark the failed page in error
1619 ubc_upl_abort_range(upl
, 0, PAGE_SIZE
, UPL_ABORT_DUMP_PAGES
);
1620 ubc_upl_abort(upl
, 0);
1622 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 45)) | DBG_FUNC_NONE
,
1623 upl
, 0, 0, retval
, 0);
1627 if ((start_offset
== 0 || upl_size
> PAGE_SIZE
) && ((start_offset
+ io_size
) & PAGE_MASK
)) {
1629 * the last offset we're writing to in this upl does not end on a page
1630 * boundary... if it's not beyond the old EOF, then we'll also need to
1631 * pre-read this page in if it isn't already valid
1633 upl_offset
= upl_size
- PAGE_SIZE
;
1635 if ((upl_f_offset
+ start_offset
+ io_size
) < oldEOF
&&
1636 !upl_valid_page(pl
, upl_offset
/ PAGE_SIZE
)) {
1639 read_size
= PAGE_SIZE
;
1641 if ((upl_f_offset
+ upl_offset
+ read_size
) > newEOF
) {
1642 read_size
= newEOF
- (upl_f_offset
+ upl_offset
);
1643 read_size
= (read_size
+ (devblocksize
- 1)) & ~(devblocksize
- 1);
1645 retval
= cluster_io(vp
, upl
, upl_offset
, upl_f_offset
+ upl_offset
, read_size
,
1646 CL_READ
, (struct buf
*)0);
1649 * we had an error during the read which causes us to abort
1650 * the current cluster_write request... before we do, we
1651 * need to release the rest of the pages in the upl without
1652 * modifying there state and mark the failed page in error
1654 ubc_upl_abort_range(upl
, upl_offset
, PAGE_SIZE
,
1655 UPL_ABORT_DUMP_PAGES
);
1656 ubc_upl_abort(upl
, 0);
1658 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 45)) | DBG_FUNC_NONE
,
1659 upl
, 0, 0, retval
, 0);
1664 if ((kret
= ubc_upl_map(upl
, &io_address
)) != KERN_SUCCESS
)
1665 panic("cluster_write: ubc_upl_map failed\n");
1666 xfer_resid
= io_size
;
1667 io_offset
= start_offset
;
1669 while (zero_cnt
&& xfer_resid
) {
1671 if (zero_cnt
< (long long)xfer_resid
)
1672 bytes_to_zero
= zero_cnt
;
1674 bytes_to_zero
= xfer_resid
;
1676 if ( !(flags
& IO_NOZEROVALID
)) {
1677 bzero((caddr_t
)(io_address
+ io_offset
), bytes_to_zero
);
1679 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 43)) | DBG_FUNC_NONE
,
1680 (int)upl_f_offset
+ io_offset
, bytes_to_zero
,
1681 (int)zero_cnt
, xfer_resid
, 0);
1683 bytes_to_zero
= min(bytes_to_zero
, PAGE_SIZE
- (int)(zero_off
& PAGE_MASK_64
));
1685 if ( !upl_valid_page(pl
, (int)(zero_off
/ PAGE_SIZE_64
))) {
1686 bzero((caddr_t
)(io_address
+ io_offset
), bytes_to_zero
);
1688 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 43)) | DBG_FUNC_NONE
,
1689 (int)upl_f_offset
+ io_offset
, bytes_to_zero
,
1690 (int)zero_cnt
, xfer_resid
, 0);
1693 xfer_resid
-= bytes_to_zero
;
1694 zero_cnt
-= bytes_to_zero
;
1695 zero_off
+= bytes_to_zero
;
1696 io_offset
+= bytes_to_zero
;
1698 if (xfer_resid
&& uio_resid
) {
1699 bytes_to_move
= min(uio_resid
, xfer_resid
);
1701 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 42)) | DBG_FUNC_NONE
,
1702 (int)uio
->uio_offset
, bytes_to_move
, uio_resid
, xfer_resid
, 0);
1704 retval
= uiomove((caddr_t
)(io_address
+ io_offset
), bytes_to_move
, uio
);
1707 if ((kret
= ubc_upl_unmap(upl
)) != KERN_SUCCESS
)
1708 panic("cluster_write: kernel_upl_unmap failed\n");
1709 ubc_upl_abort(upl
, UPL_ABORT_DUMP_PAGES
);
1711 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 45)) | DBG_FUNC_NONE
,
1712 upl
, 0, 0, retval
, 0);
1714 uio_resid
-= bytes_to_move
;
1715 xfer_resid
-= bytes_to_move
;
1716 io_offset
+= bytes_to_move
;
1719 while (xfer_resid
&& zero_cnt1
&& retval
== 0) {
1721 if (zero_cnt1
< (long long)xfer_resid
)
1722 bytes_to_zero
= zero_cnt1
;
1724 bytes_to_zero
= xfer_resid
;
1726 if ( !(flags
& IO_NOZEROVALID
)) {
1727 bzero((caddr_t
)(io_address
+ io_offset
), bytes_to_zero
);
1729 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 43)) | DBG_FUNC_NONE
,
1730 (int)upl_f_offset
+ io_offset
,
1731 bytes_to_zero
, (int)zero_cnt1
, xfer_resid
, 0);
1733 bytes_to_zero
= min(bytes_to_zero
, PAGE_SIZE
- (int)(zero_off1
& PAGE_MASK_64
));
1734 if ( !upl_valid_page(pl
, (int)(zero_off1
/ PAGE_SIZE_64
))) {
1735 bzero((caddr_t
)(io_address
+ io_offset
), bytes_to_zero
);
1737 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 43)) | DBG_FUNC_NONE
,
1738 (int)upl_f_offset
+ io_offset
,
1739 bytes_to_zero
, (int)zero_cnt1
, xfer_resid
, 0);
1742 xfer_resid
-= bytes_to_zero
;
1743 zero_cnt1
-= bytes_to_zero
;
1744 zero_off1
+= bytes_to_zero
;
1745 io_offset
+= bytes_to_zero
;
1752 io_size
+= start_offset
;
1754 if ((upl_f_offset
+ io_size
) == newEOF
&& io_size
< upl_size
) {
1756 * if we're extending the file with this write
1757 * we'll zero fill the rest of the page so that
1758 * if the file gets extended again in such a way as to leave a
1759 * hole starting at this EOF, we'll have zero's in the correct spot
1761 bzero((caddr_t
)(io_address
+ io_size
), upl_size
- io_size
);
1763 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 43)) | DBG_FUNC_NONE
,
1764 (int)upl_f_offset
+ io_size
,
1765 upl_size
- io_size
, 0, 0, 0);
1767 if ((kret
= ubc_upl_unmap(upl
)) != KERN_SUCCESS
)
1768 panic("cluster_write: kernel_upl_unmap failed\n");
1770 io_size_before_rounding
= io_size
;
1772 if (io_size
& (devblocksize
- 1))
1773 io_size
= (io_size
+ (devblocksize
- 1)) & ~(devblocksize
- 1);
1782 * we have an existing cluster... see if this write will extend it nicely
1784 if (start_blkno
>= vp
->v_cstart
) {
1785 if (last_blkno
<= (vp
->v_cstart
+ vp
->v_clen
)) {
1787 * we have a write that fits entirely
1788 * within the existing cluster limits
1790 if (last_blkno
>= vp
->v_lastw
) {
1792 * if we're extending the dirty region within the cluster
1793 * we need to update the cluster info... we check for blkno
1794 * equality because we may be extending the file with a
1795 * partial write.... this in turn changes our idea of how
1796 * much data to write out (v_ciosiz) for the last page
1798 vp
->v_lastw
= last_blkno
;
1799 newsize
= io_size
+ ((start_blkno
- vp
->v_cstart
) * PAGE_SIZE
);
1801 if (newsize
> vp
->v_ciosiz
)
1802 vp
->v_ciosiz
= newsize
;
1807 if (start_blkno
< (vp
->v_cstart
+ vp
->v_clen
)) {
1809 * we have a write that starts in the middle of the current cluster
1810 * but extends beyond the cluster's limit
1811 * we'll clip the current cluster if we actually
1812 * overlap with the new write and then push it out
1813 * and start a new cluster with the current write
1815 if (vp
->v_lastw
> start_blkno
) {
1816 vp
->v_lastw
= start_blkno
;
1817 vp
->v_ciosiz
= (vp
->v_lastw
- vp
->v_cstart
) * PAGE_SIZE
;
1821 * we also get here for the case where the current write starts
1822 * beyond the limit of the existing cluster
1828 * the current write starts in front of the current cluster
1830 if (last_blkno
> vp
->v_cstart
) {
1832 * the current write extends into the existing cluster
1834 if ((vp
->v_lastw
- start_blkno
) > vp
->v_clen
) {
1836 * if we were to combine this write with the current cluster
1837 * we would exceed the cluster size limit....
1838 * clip the current cluster by moving the start position
1839 * to where the current write ends, and then push it
1841 vp
->v_ciosiz
-= (last_blkno
- vp
->v_cstart
) * PAGE_SIZE
;
1842 vp
->v_cstart
= last_blkno
;
1845 * round up the io_size to the nearest page size
1846 * since we've coalesced with at least 1 pre-existing
1847 * page in the current cluster... this write may have ended in the
1848 * middle of the page which would cause io_size to give us an
1849 * inaccurate view of how much I/O we actually need to do
1851 io_size
= (io_size
+ (PAGE_SIZE
- 1)) & ~PAGE_MASK
;
1857 * we can coalesce the current write with the existing cluster
1858 * adjust the cluster info to reflect this
1860 if (last_blkno
> vp
->v_lastw
) {
1862 * the current write completey overlaps
1863 * the existing cluster
1865 vp
->v_lastw
= last_blkno
;
1866 vp
->v_ciosiz
= io_size
;
1868 vp
->v_ciosiz
+= (vp
->v_cstart
- start_blkno
) * PAGE_SIZE
;
1870 if (io_size
> vp
->v_ciosiz
)
1871 vp
->v_ciosiz
= io_size
;
1873 vp
->v_cstart
= start_blkno
;
1878 * this I/O range is entirely in front of the current cluster
1879 * so we need to push the current cluster out before beginning
1888 if (io_size_before_rounding
< (MAX_UPL_TRANSFER
* PAGE_SIZE
) && !(flags
& IO_SYNC
)) {
1889 vp
->v_clen
= MAX_UPL_TRANSFER
;
1890 vp
->v_cstart
= start_blkno
;
1891 vp
->v_lastw
= last_blkno
;
1892 vp
->v_ciosiz
= io_size
;
1898 ubc_upl_commit_range(upl
, 0, upl_size
,
1899 UPL_COMMIT_SET_DIRTY
| UPL_COMMIT_FREE_ON_EMPTY
);
1902 if (flags
& IO_SYNC
)
1903 io_flags
= CL_COMMIT
| CL_AGE
;
1905 io_flags
= CL_COMMIT
| CL_AGE
| CL_ASYNC
;
1907 if (vp
->v_flag
& VNOCACHE_DATA
)
1908 io_flags
|= CL_DUMP
;
1910 while (vp
->v_numoutput
>= ASYNC_THROTTLE
) {
1911 vp
->v_flag
|= VTHROTTLED
;
1912 tsleep((caddr_t
)&vp
->v_numoutput
, PRIBIO
+ 1, "cluster_write", 0);
1914 retval
= cluster_io(vp
, upl
, 0, upl_f_offset
, io_size
,
1915 io_flags
, (struct buf
*)0);
1918 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 40)) | DBG_FUNC_END
,
1919 retval
, 0, 0, 0, 0);
1924 cluster_read(vp
, uio
, filesize
, devblocksize
, flags
)
1935 vm_offset_t upl_offset
;
1938 upl_page_info_t
*pl
;
1943 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 32)) | DBG_FUNC_START
,
1944 (int)uio
->uio_offset
, uio
->uio_resid
, (int)filesize
, devblocksize
, 0);
1947 * We set a threshhold of 4 pages to decide if the nocopy
1948 * read loop is worth the trouble...
1951 if (!((vp
->v_flag
& VNOCACHE_DATA
) && (uio
->uio_segflg
== UIO_USERSPACE
)))
1953 retval
= cluster_read_x(vp
, uio
, filesize
, devblocksize
, flags
);
1954 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 32)) | DBG_FUNC_END
,
1955 (int)uio
->uio_offset
, uio
->uio_resid
, vp
->v_lastr
, retval
, 0);
1959 while (uio
->uio_resid
&& uio
->uio_offset
< filesize
&& retval
== 0)
1961 /* we know we have a resid, so this is safe */
1963 while (iov
->iov_len
== 0) {
1970 * We check every vector target and if it is physically
1971 * contiguous space, we skip the sanity checks.
1974 upl_offset
= (vm_offset_t
)iov
->iov_base
& ~PAGE_MASK
;
1975 upl_size
= (upl_offset
+ PAGE_SIZE
+(PAGE_SIZE
-1)) & ~PAGE_MASK
;
1977 upl_flags
= UPL_QUERY_OBJECT_TYPE
;
1978 if((vm_map_get_upl(current_map(),
1979 (vm_offset_t
)iov
->iov_base
& ~PAGE_MASK
,
1980 &upl_size
, &upl
, NULL
, &pages_in_pl
, &upl_flags
, 0)) != KERN_SUCCESS
)
1983 * the user app must have passed in an invalid address
1988 if (upl_flags
& UPL_PHYS_CONTIG
)
1990 retval
= cluster_phys_read(vp
, uio
, filesize
);
1992 else if (uio
->uio_resid
< 4 * PAGE_SIZE
)
1995 * We set a threshhold of 4 pages to decide if the nocopy
1996 * read loop is worth the trouble...
1998 retval
= cluster_read_x(vp
, uio
, filesize
, devblocksize
, flags
);
1999 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 32)) | DBG_FUNC_END
,
2000 (int)uio
->uio_offset
, uio
->uio_resid
, vp
->v_lastr
, retval
, 0);
2003 else if (uio
->uio_offset
& PAGE_MASK_64
)
2005 /* Bring the file offset read up to a pagesize boundary */
2006 clip_size
= (PAGE_SIZE
- (int)(uio
->uio_offset
& PAGE_MASK_64
));
2007 if (uio
->uio_resid
< clip_size
)
2008 clip_size
= uio
->uio_resid
;
2010 * Fake the resid going into the cluster_read_x call
2011 * and restore it on the way out.
2013 prev_resid
= uio
->uio_resid
;
2014 uio
->uio_resid
= clip_size
;
2015 retval
= cluster_read_x(vp
, uio
, filesize
, devblocksize
, flags
);
2016 uio
->uio_resid
= prev_resid
- (clip_size
- uio
->uio_resid
);
2018 else if ((int)iov
->iov_base
& PAGE_MASK_64
)
2020 clip_size
= iov
->iov_len
;
2021 prev_resid
= uio
->uio_resid
;
2022 uio
->uio_resid
= clip_size
;
2023 retval
= cluster_read_x(vp
, uio
, filesize
, devblocksize
, flags
);
2024 uio
->uio_resid
= prev_resid
- (clip_size
- uio
->uio_resid
);
2029 * If we come in here, we know the offset into
2030 * the file is on a pagesize boundary
2033 max_io_size
= filesize
- uio
->uio_offset
;
2034 clip_size
= uio
->uio_resid
;
2035 if (iov
->iov_len
< clip_size
)
2036 clip_size
= iov
->iov_len
;
2037 if (max_io_size
< clip_size
)
2038 clip_size
= (int)max_io_size
;
2040 if (clip_size
< PAGE_SIZE
)
2043 * Take care of the tail end of the read in this vector.
2045 prev_resid
= uio
->uio_resid
;
2046 uio
->uio_resid
= clip_size
;
2047 retval
= cluster_read_x(vp
, uio
, filesize
, devblocksize
, flags
);
2048 uio
->uio_resid
= prev_resid
- (clip_size
- uio
->uio_resid
);
2052 /* round clip_size down to a multiple of pagesize */
2053 clip_size
= clip_size
& ~(PAGE_MASK
);
2054 prev_resid
= uio
->uio_resid
;
2055 uio
->uio_resid
= clip_size
;
2056 retval
= cluster_nocopy_read(vp
, uio
, filesize
, devblocksize
, flags
);
2057 if ((retval
==0) && uio
->uio_resid
)
2058 retval
= cluster_read_x(vp
, uio
, filesize
, devblocksize
, flags
);
2059 uio
->uio_resid
= prev_resid
- (clip_size
- uio
->uio_resid
);
2064 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 32)) | DBG_FUNC_END
,
2065 (int)uio
->uio_offset
, uio
->uio_resid
, vp
->v_lastr
, retval
, 0);
2071 cluster_read_x(vp
, uio
, filesize
, devblocksize
, flags
)
2078 upl_page_info_t
*pl
;
2080 vm_offset_t upl_offset
;
2090 vm_offset_t io_address
;
2098 b_lblkno
= (int)(uio
->uio_offset
/ PAGE_SIZE_64
);
2100 while (uio
->uio_resid
&& uio
->uio_offset
< filesize
&& retval
== 0) {
2102 * compute the size of the upl needed to encompass
2103 * the requested read... limit each call to cluster_io
2104 * to the maximum UPL size... cluster_io will clip if
2105 * this exceeds the maximum io_size for the device,
2106 * make sure to account for
2107 * a starting offset that's not page aligned
2109 start_offset
= (int)(uio
->uio_offset
& PAGE_MASK_64
);
2110 upl_f_offset
= uio
->uio_offset
- (off_t
)start_offset
;
2111 max_size
= filesize
- uio
->uio_offset
;
2113 if ((off_t
)((unsigned int)uio
->uio_resid
) < max_size
)
2114 io_size
= uio
->uio_resid
;
2118 if (uio
->uio_segflg
== UIO_USERSPACE
&& !(vp
->v_flag
& VNOCACHE_DATA
)) {
2119 segflg
= uio
->uio_segflg
;
2121 uio
->uio_segflg
= UIO_PHYS_USERSPACE
;
2123 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 34)) | DBG_FUNC_START
,
2124 (int)uio
->uio_offset
, io_size
, uio
->uio_resid
, 0, 0);
2126 while (io_size
&& retval
== 0) {
2132 UPL_POP_SET
| UPL_POP_BUSY
,
2133 &paddr
, 0) != KERN_SUCCESS
)
2136 xsize
= PAGE_SIZE
- start_offset
;
2138 if (xsize
> io_size
)
2141 retval
= uiomove((caddr_t
)(paddr
+ start_offset
), xsize
, uio
);
2143 ubc_page_op(vp
, upl_f_offset
,
2144 UPL_POP_CLR
| UPL_POP_BUSY
, 0, 0);
2147 start_offset
= (int)
2148 (uio
->uio_offset
& PAGE_MASK_64
);
2149 upl_f_offset
= uio
->uio_offset
- start_offset
;
2151 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 34)) | DBG_FUNC_END
,
2152 (int)uio
->uio_offset
, io_size
, uio
->uio_resid
, 0, 0);
2154 uio
->uio_segflg
= segflg
;
2161 * we're already finished with this read request
2162 * let's see if we should do a read-ahead
2165 ((uio
->uio_offset
- 1) / PAGE_SIZE_64
);
2167 if (!(vp
->v_flag
& VRAOFF
))
2169 * let's try to read ahead if we're in
2170 * a sequential access pattern
2172 cluster_rd_ahead(vp
, b_lblkno
, e_lblkno
, filesize
, devblocksize
);
2173 vp
->v_lastr
= e_lblkno
;
2177 max_size
= filesize
- uio
->uio_offset
;
2180 upl_size
= (start_offset
+ io_size
+ (PAGE_SIZE
- 1)) & ~PAGE_MASK
;
2181 if (upl_size
> (MAX_UPL_TRANSFER
* PAGE_SIZE
))
2182 upl_size
= MAX_UPL_TRANSFER
* PAGE_SIZE
;
2183 pages_in_upl
= upl_size
/ PAGE_SIZE
;
2185 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 33)) | DBG_FUNC_START
,
2186 upl
, (int)upl_f_offset
, upl_size
, start_offset
, 0);
2188 kret
= ubc_create_upl(vp
,
2194 if (kret
!= KERN_SUCCESS
)
2195 panic("cluster_read: failed to get pagelist");
2197 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 33)) | DBG_FUNC_END
,
2198 upl
, (int)upl_f_offset
, upl_size
, start_offset
, 0);
2201 * scan from the beginning of the upl looking for the first
2202 * non-valid page.... this will become the first page in
2203 * the request we're going to make to 'cluster_io'... if all
2204 * of the pages are valid, we won't call through to 'cluster_io'
2206 for (start_pg
= 0; start_pg
< pages_in_upl
; start_pg
++) {
2207 if (!upl_valid_page(pl
, start_pg
))
2212 * scan from the starting invalid page looking for a valid
2213 * page before the end of the upl is reached, if we
2214 * find one, then it will be the last page of the request to
2217 for (last_pg
= start_pg
; last_pg
< pages_in_upl
; last_pg
++) {
2218 if (upl_valid_page(pl
, last_pg
))
2222 if (start_pg
< last_pg
) {
2224 * we found a range of 'invalid' pages that must be filled
2225 * if the last page in this range is the last page of the file
2226 * we may have to clip the size of it to keep from reading past
2227 * the end of the last physical block associated with the file
2229 upl_offset
= start_pg
* PAGE_SIZE
;
2230 io_size
= (last_pg
- start_pg
) * PAGE_SIZE
;
2232 if ((upl_f_offset
+ upl_offset
+ io_size
) > filesize
) {
2233 io_size
= filesize
- (upl_f_offset
+ upl_offset
);
2234 io_size
= (io_size
+ (devblocksize
- 1)) & ~(devblocksize
- 1);
2237 * issue a synchronous read to cluster_io
2240 error
= cluster_io(vp
, upl
, upl_offset
, upl_f_offset
+ upl_offset
,
2241 io_size
, CL_READ
, (struct buf
*)0);
2245 * if the read completed successfully, or there was no I/O request
2246 * issued, than map the upl into kernel address space and
2247 * move the data into user land.... we'll first add on any 'valid'
2248 * pages that were present in the upl when we acquired it.
2251 u_int size_of_prefetch
;
2253 for (uio_last
= last_pg
; uio_last
< pages_in_upl
; uio_last
++) {
2254 if (!upl_valid_page(pl
, uio_last
))
2258 * compute size to transfer this round, if uio->uio_resid is
2259 * still non-zero after this uiomove, we'll loop around and
2260 * set up for another I/O.
2262 val_size
= (uio_last
* PAGE_SIZE
) - start_offset
;
2264 if (max_size
< val_size
)
2265 val_size
= max_size
;
2267 if (uio
->uio_resid
< val_size
)
2268 val_size
= uio
->uio_resid
;
2270 e_lblkno
= (int)((uio
->uio_offset
+ ((off_t
)val_size
- 1)) / PAGE_SIZE_64
);
2272 if (size_of_prefetch
= (uio
->uio_resid
- val_size
)) {
2274 * if there's still I/O left to do for this request, then issue a
2275 * pre-fetch I/O... the I/O wait time will overlap
2276 * with the copying of the data
2278 cluster_rd_prefetch(vp
, uio
->uio_offset
+ val_size
, size_of_prefetch
, filesize
, devblocksize
);
2280 if (!(vp
->v_flag
& VRAOFF
) && !(vp
->v_flag
& VNOCACHE_DATA
))
2282 * let's try to read ahead if we're in
2283 * a sequential access pattern
2285 cluster_rd_ahead(vp
, b_lblkno
, e_lblkno
, filesize
, devblocksize
);
2286 vp
->v_lastr
= e_lblkno
;
2289 if (uio
->uio_segflg
== UIO_USERSPACE
) {
2292 segflg
= uio
->uio_segflg
;
2294 uio
->uio_segflg
= UIO_PHYS_USERSPACE
;
2297 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 34)) | DBG_FUNC_START
,
2298 (int)uio
->uio_offset
, val_size
, uio
->uio_resid
, 0, 0);
2300 offset
= start_offset
;
2302 while (val_size
&& retval
== 0) {
2307 i
= offset
/ PAGE_SIZE
;
2308 csize
= min(PAGE_SIZE
- start_offset
, val_size
);
2310 paddr
= (caddr_t
)upl_phys_page(pl
, i
) + start_offset
;
2312 retval
= uiomove(paddr
, csize
, uio
);
2316 start_offset
= offset
& PAGE_MASK
;
2318 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 34)) | DBG_FUNC_END
,
2319 (int)uio
->uio_offset
, val_size
, uio
->uio_resid
, 0, 0);
2321 uio
->uio_segflg
= segflg
;
2325 if ((kret
= ubc_upl_map(upl
, &io_address
)) != KERN_SUCCESS
)
2326 panic("cluster_read: ubc_upl_map() failed\n");
2328 retval
= uiomove((caddr_t
)(io_address
+ start_offset
), val_size
, uio
);
2330 if ((kret
= ubc_upl_unmap(upl
)) != KERN_SUCCESS
)
2331 panic("cluster_read: ubc_upl_unmap() failed\n");
2334 if (start_pg
< last_pg
) {
2336 * compute the range of pages that we actually issued an I/O for
2337 * and either commit them as valid if the I/O succeeded
2338 * or abort them if the I/O failed
2340 io_size
= (last_pg
- start_pg
) * PAGE_SIZE
;
2342 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 35)) | DBG_FUNC_START
,
2343 upl
, start_pg
* PAGE_SIZE
, io_size
, error
, 0);
2345 if (error
|| (vp
->v_flag
& VNOCACHE_DATA
))
2346 ubc_upl_abort_range(upl
, start_pg
* PAGE_SIZE
, io_size
,
2347 UPL_ABORT_DUMP_PAGES
| UPL_ABORT_FREE_ON_EMPTY
);
2349 ubc_upl_commit_range(upl
, start_pg
* PAGE_SIZE
, io_size
,
2350 UPL_COMMIT_CLEAR_DIRTY
2351 | UPL_COMMIT_FREE_ON_EMPTY
2352 | UPL_COMMIT_INACTIVATE
);
2354 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 35)) | DBG_FUNC_END
,
2355 upl
, start_pg
* PAGE_SIZE
, io_size
, error
, 0);
2357 if ((last_pg
- start_pg
) < pages_in_upl
) {
2362 * the set of pages that we issued an I/O for did not encompass
2363 * the entire upl... so just release these without modifying
2367 ubc_upl_abort(upl
, 0);
2369 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 35)) | DBG_FUNC_START
,
2370 upl
, -1, pages_in_upl
- (last_pg
- start_pg
), 0, 0);
2374 * we found some already valid pages at the beginning of
2375 * the upl commit these back to the inactive list with
2378 for (cur_pg
= 0; cur_pg
< start_pg
; cur_pg
++) {
2379 commit_flags
= UPL_COMMIT_FREE_ON_EMPTY
2380 | UPL_COMMIT_INACTIVATE
;
2382 if (upl_dirty_page(pl
, cur_pg
))
2383 commit_flags
|= UPL_COMMIT_SET_DIRTY
;
2385 if ( !(commit_flags
& UPL_COMMIT_SET_DIRTY
) && (vp
->v_flag
& VNOCACHE_DATA
))
2386 ubc_upl_abort_range(upl
, cur_pg
* PAGE_SIZE
, PAGE_SIZE
,
2387 UPL_ABORT_DUMP_PAGES
| UPL_ABORT_FREE_ON_EMPTY
);
2389 ubc_upl_commit_range(upl
, cur_pg
* PAGE_SIZE
,
2390 PAGE_SIZE
, commit_flags
);
2393 if (last_pg
< uio_last
) {
2395 * we found some already valid pages immediately after the
2396 * pages we issued I/O for, commit these back to the
2397 * inactive list with reference cleared
2399 for (cur_pg
= last_pg
; cur_pg
< uio_last
; cur_pg
++) {
2400 commit_flags
= UPL_COMMIT_FREE_ON_EMPTY
2401 | UPL_COMMIT_INACTIVATE
;
2403 if (upl_dirty_page(pl
, cur_pg
))
2404 commit_flags
|= UPL_COMMIT_SET_DIRTY
;
2406 if ( !(commit_flags
& UPL_COMMIT_SET_DIRTY
) && (vp
->v_flag
& VNOCACHE_DATA
))
2407 ubc_upl_abort_range(upl
, cur_pg
* PAGE_SIZE
, PAGE_SIZE
,
2408 UPL_ABORT_DUMP_PAGES
| UPL_ABORT_FREE_ON_EMPTY
);
2410 ubc_upl_commit_range(upl
, cur_pg
* PAGE_SIZE
,
2411 PAGE_SIZE
, commit_flags
);
2414 if (uio_last
< pages_in_upl
) {
2416 * there were some invalid pages beyond the valid pages
2417 * that we didn't issue an I/O for, just release them
2420 ubc_upl_abort(upl
, 0);
2423 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 35)) | DBG_FUNC_END
,
2435 cluster_nocopy_read(vp
, uio
, filesize
, devblocksize
, flags
)
2443 upl_page_info_t
*pl
;
2445 vm_offset_t upl_offset
;
2446 off_t start_upl_f_offset
;
2450 int upl_needed_size
;
2458 int force_data_sync
;
2462 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 70)) | DBG_FUNC_START
,
2463 (int)uio
->uio_offset
, uio
->uio_resid
, (int)filesize
, devblocksize
, 0);
2466 * When we enter this routine, we know
2467 * -- the offset into the file is on a pagesize boundary
2468 * -- the resid is a page multiple
2469 * -- the resid will not exceed iov_len
2473 while (uio
->uio_resid
&& uio
->uio_offset
< filesize
&& retval
== 0) {
2475 max_io_size
= filesize
- uio
->uio_offset
;
2477 if (max_io_size
< (off_t
)((unsigned int)uio
->uio_resid
))
2478 io_size
= max_io_size
;
2480 io_size
= uio
->uio_resid
;
2483 * We don't come into this routine unless
2484 * UIO_USERSPACE is set.
2486 segflg
= uio
->uio_segflg
;
2488 uio
->uio_segflg
= UIO_PHYS_USERSPACE
;
2491 * First look for pages already in the cache
2492 * and move them to user space.
2494 while (io_size
&& (retval
== 0)) {
2495 upl_f_offset
= uio
->uio_offset
;
2498 * If this call fails, it means the page is not
2499 * in the page cache.
2501 if (ubc_page_op(vp
, upl_f_offset
,
2502 UPL_POP_SET
| UPL_POP_BUSY
, &paddr
, 0) != KERN_SUCCESS
)
2505 retval
= uiomove((caddr_t
)(paddr
), PAGE_SIZE
, uio
);
2507 ubc_page_op(vp
, upl_f_offset
,
2508 UPL_POP_CLR
| UPL_POP_BUSY
, 0, 0);
2510 io_size
-= PAGE_SIZE
;
2511 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 71)) | DBG_FUNC_NONE
,
2512 (int)uio
->uio_offset
, io_size
, uio
->uio_resid
, 0, 0);
2515 uio
->uio_segflg
= segflg
;
2519 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 70)) | DBG_FUNC_END
,
2520 (int)uio
->uio_offset
, uio
->uio_resid
, 2, retval
, 0);
2524 /* If we are already finished with this read, then return */
2528 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 70)) | DBG_FUNC_END
,
2529 (int)uio
->uio_offset
, uio
->uio_resid
, 3, io_size
, 0);
2533 max_io_size
= io_size
;
2534 if (max_io_size
> (MAX_UPL_TRANSFER
* PAGE_SIZE
))
2535 max_io_size
= MAX_UPL_TRANSFER
* PAGE_SIZE
;
2537 start_upl_f_offset
= uio
->uio_offset
; /* this is page aligned in the file */
2538 upl_f_offset
= start_upl_f_offset
;
2541 while(io_size
< max_io_size
)
2544 if(ubc_page_op(vp
, upl_f_offset
,
2545 UPL_POP_SET
| UPL_POP_BUSY
, &paddr
, 0) == KERN_SUCCESS
)
2547 ubc_page_op(vp
, upl_f_offset
,
2548 UPL_POP_CLR
| UPL_POP_BUSY
, 0, 0);
2553 * Build up the io request parameters.
2556 io_size
+= PAGE_SIZE
;
2557 upl_f_offset
+= PAGE_SIZE
;
2563 upl_offset
= (vm_offset_t
)iov
->iov_base
& PAGE_MASK_64
;
2564 upl_needed_size
= (upl_offset
+ io_size
+ (PAGE_SIZE
-1)) & ~PAGE_MASK
;
2566 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 72)) | DBG_FUNC_START
,
2567 (int)upl_offset
, upl_needed_size
, iov
->iov_base
, io_size
, 0);
2569 for (force_data_sync
= 0; force_data_sync
< 3; force_data_sync
++)
2572 upl_size
= upl_needed_size
;
2573 upl_flags
= UPL_NO_SYNC
| UPL_CLEAN_IN_PLACE
| UPL_SET_INTERNAL
;
2575 kret
= vm_map_get_upl(current_map(),
2576 (vm_offset_t
)iov
->iov_base
& ~PAGE_MASK
,
2577 &upl_size
, &upl
, NULL
, &pages_in_pl
, &upl_flags
, force_data_sync
);
2579 if (kret
!= KERN_SUCCESS
)
2581 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 72)) | DBG_FUNC_END
,
2582 (int)upl_offset
, upl_size
, io_size
, kret
, 0);
2584 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 70)) | DBG_FUNC_END
,
2585 (int)uio
->uio_offset
, uio
->uio_resid
, 4, retval
, 0);
2587 /* cluster_nocopy_read: failed to get pagelist */
2588 /* do not return kret here */
2592 pages_in_pl
= upl_size
/ PAGE_SIZE
;
2593 pl
= UPL_GET_INTERNAL_PAGE_LIST(upl
);
2595 for(i
=0; i
< pages_in_pl
; i
++)
2597 if (!upl_valid_page(pl
, i
))
2600 if (i
== pages_in_pl
)
2603 ubc_upl_abort_range(upl
, (upl_offset
& ~PAGE_MASK
), upl_size
,
2604 UPL_ABORT_FREE_ON_EMPTY
);
2607 if (force_data_sync
>= 3)
2609 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 72)) | DBG_FUNC_END
,
2610 (int)upl_offset
, upl_size
, io_size
, kret
, 0);
2612 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 70)) | DBG_FUNC_END
,
2613 (int)uio
->uio_offset
, uio
->uio_resid
, 5, retval
, 0);
2617 * Consider the possibility that upl_size wasn't satisfied.
2619 if (upl_size
!= upl_needed_size
)
2620 io_size
= (upl_size
- (int)upl_offset
) & ~PAGE_MASK
;
2624 ubc_upl_abort_range(upl
, (upl_offset
& ~PAGE_MASK
), upl_size
,
2625 UPL_ABORT_FREE_ON_EMPTY
);
2629 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 72)) | DBG_FUNC_END
,
2630 (int)upl_offset
, upl_size
, io_size
, kret
, 0);
2633 * issue a synchronous read to cluster_io
2636 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 73)) | DBG_FUNC_START
,
2637 upl
, (int)upl_offset
, (int)start_upl_f_offset
, io_size
, 0);
2639 error
= cluster_io(vp
, upl
, upl_offset
, start_upl_f_offset
,
2640 io_size
, CL_READ
| CL_NOZERO
, (struct buf
*)0);
2644 * The cluster_io read completed successfully,
2645 * update the uio structure and commit.
2648 ubc_upl_commit_range(upl
, (upl_offset
& ~PAGE_MASK
), upl_size
,
2649 UPL_COMMIT_SET_DIRTY
| UPL_COMMIT_FREE_ON_EMPTY
);
2651 iov
->iov_base
+= io_size
;
2652 iov
->iov_len
-= io_size
;
2653 uio
->uio_resid
-= io_size
;
2654 uio
->uio_offset
+= io_size
;
2657 ubc_upl_abort_range(upl
, (upl_offset
& ~PAGE_MASK
), upl_size
,
2658 UPL_ABORT_FREE_ON_EMPTY
);
2661 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 73)) | DBG_FUNC_END
,
2662 upl
, (int)uio
->uio_offset
, (int)uio
->uio_resid
, error
, 0);
2670 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 70)) | DBG_FUNC_END
,
2671 (int)uio
->uio_offset
, (int)uio
->uio_resid
, 6, retval
, 0);
2678 cluster_phys_read(vp
, uio
, filesize
)
2684 vm_offset_t upl_offset
;
2688 int upl_needed_size
;
2696 * When we enter this routine, we know
2697 * -- the resid will not exceed iov_len
2698 * -- the target address is physically contiguous
2703 max_size
= filesize
- uio
->uio_offset
;
2705 if (max_size
< (off_t
)((unsigned int)iov
->iov_len
))
2708 io_size
= iov
->iov_len
;
2710 upl_offset
= (vm_offset_t
)iov
->iov_base
& PAGE_MASK_64
;
2711 upl_needed_size
= upl_offset
+ io_size
;
2714 upl_size
= upl_needed_size
;
2715 upl_flags
= UPL_NO_SYNC
| UPL_CLEAN_IN_PLACE
| UPL_SET_INTERNAL
;
2717 kret
= vm_map_get_upl(current_map(),
2718 (vm_offset_t
)iov
->iov_base
& ~PAGE_MASK
,
2719 &upl_size
, &upl
, NULL
, &pages_in_pl
, &upl_flags
, 0);
2721 if (kret
!= KERN_SUCCESS
)
2723 /* cluster_phys_read: failed to get pagelist */
2728 * Consider the possibility that upl_size wasn't satisfied.
2730 if (upl_size
< upl_needed_size
)
2732 ubc_upl_abort_range(upl
, 0, upl_size
, UPL_ABORT_FREE_ON_EMPTY
);
2737 * issue a synchronous read to cluster_io
2740 error
= cluster_io(vp
, upl
, upl_offset
, uio
->uio_offset
,
2741 io_size
, CL_READ
| CL_NOZERO
| CL_DEV_MEMORY
, (struct buf
*)0);
2746 * The cluster_io read completed successfully,
2747 * update the uio structure and commit.
2750 ubc_upl_commit_range(upl
, 0, upl_size
, UPL_COMMIT_FREE_ON_EMPTY
);
2752 iov
->iov_base
+= io_size
;
2753 iov
->iov_len
-= io_size
;
2754 uio
->uio_resid
-= io_size
;
2755 uio
->uio_offset
+= io_size
;
2758 ubc_upl_abort_range(upl
, 0, upl_size
, UPL_ABORT_FREE_ON_EMPTY
);
2764 * generate advisory I/O's in the largest chunks possible
2765 * the completed pages will be released into the VM cache
2767 advisory_read(vp
, filesize
, f_offset
, resid
, devblocksize
)
2774 upl_page_info_t
*pl
;
2776 vm_offset_t upl_offset
;
2789 if (!UBCINFOEXISTS(vp
))
2792 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 60)) | DBG_FUNC_START
,
2793 (int)f_offset
, resid
, (int)filesize
, devblocksize
, 0);
2795 while (resid
&& f_offset
< filesize
&& retval
== 0) {
2797 * compute the size of the upl needed to encompass
2798 * the requested read... limit each call to cluster_io
2799 * to the maximum UPL size... cluster_io will clip if
2800 * this exceeds the maximum io_size for the device,
2801 * make sure to account for
2802 * a starting offset that's not page aligned
2804 start_offset
= (int)(f_offset
& PAGE_MASK_64
);
2805 upl_f_offset
= f_offset
- (off_t
)start_offset
;
2806 max_size
= filesize
- f_offset
;
2808 if (resid
< max_size
)
2813 upl_size
= (start_offset
+ io_size
+ (PAGE_SIZE
- 1)) & ~PAGE_MASK
;
2814 if (upl_size
> (MAX_UPL_TRANSFER
* PAGE_SIZE
))
2815 upl_size
= MAX_UPL_TRANSFER
* PAGE_SIZE
;
2816 pages_in_upl
= upl_size
/ PAGE_SIZE
;
2818 kret
= ubc_create_upl(vp
,
2824 if (kret
!= KERN_SUCCESS
)
2825 panic("advisory_read: failed to get pagelist");
2828 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 61)) | DBG_FUNC_NONE
,
2829 upl
, (int)upl_f_offset
, upl_size
, start_offset
, 0);
2832 * scan from the beginning of the upl looking for the first
2833 * non-valid page.... this will become the first page in
2834 * the request we're going to make to 'cluster_io'... if all
2835 * of the pages are valid, we won't call through to 'cluster_io'
2837 for (start_pg
= 0; start_pg
< pages_in_upl
; start_pg
++) {
2838 if (!upl_valid_page(pl
, start_pg
))
2843 * scan from the starting invalid page looking for a valid
2844 * page before the end of the upl is reached, if we
2845 * find one, then it will be the last page of the request to
2848 for (last_pg
= start_pg
; last_pg
< pages_in_upl
; last_pg
++) {
2849 if (upl_valid_page(pl
, last_pg
))
2853 if (start_pg
< last_pg
) {
2855 * we found a range of 'invalid' pages that must be filled
2856 * if the last page in this range is the last page of the file
2857 * we may have to clip the size of it to keep from reading past
2858 * the end of the last physical block associated with the file
2860 upl_offset
= start_pg
* PAGE_SIZE
;
2861 io_size
= (last_pg
- start_pg
) * PAGE_SIZE
;
2863 if ((upl_f_offset
+ upl_offset
+ io_size
) > filesize
) {
2864 io_size
= filesize
- (upl_f_offset
+ upl_offset
);
2865 io_size
= (io_size
+ (devblocksize
- 1)) & ~(devblocksize
- 1);
2868 * issue an asynchronous read to cluster_io
2870 retval
= cluster_io(vp
, upl
, upl_offset
, upl_f_offset
+ upl_offset
, io_size
,
2871 CL_ASYNC
| CL_READ
| CL_COMMIT
| CL_AGE
, (struct buf
*)0);
2875 * start_pg of non-zero indicates we found some already valid pages
2876 * at the beginning of the upl.... we need to release these without
2877 * modifying there state
2879 ubc_upl_abort_range(upl
, 0, start_pg
* PAGE_SIZE
,
2880 UPL_ABORT_FREE_ON_EMPTY
);
2882 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 62)) | DBG_FUNC_NONE
,
2883 upl
, 0, start_pg
* PAGE_SIZE
, 0, 0);
2885 if (last_pg
< pages_in_upl
) {
2887 * the set of pages that we issued an I/O for did not extend all the
2888 * way to the end of the upl..so just release them without modifying
2891 ubc_upl_abort_range(upl
, last_pg
* PAGE_SIZE
, (pages_in_upl
- last_pg
) * PAGE_SIZE
,
2892 UPL_ABORT_FREE_ON_EMPTY
);
2894 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 63)) | DBG_FUNC_NONE
,
2895 upl
, last_pg
* PAGE_SIZE
,
2896 (pages_in_upl
- last_pg
) * PAGE_SIZE
, 0, 0);
2898 io_size
= (last_pg
* PAGE_SIZE
) - start_offset
;
2900 if (io_size
> resid
)
2902 f_offset
+= io_size
;
2905 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 60)) | DBG_FUNC_END
,
2906 (int)f_offset
, resid
, retval
, 0, 0);
2915 upl_page_info_t
*pl
;
2917 vm_offset_t upl_offset
;
2929 if (!UBCINFOEXISTS(vp
))
2932 if (vp
->v_clen
== 0 || (pages_in_upl
= vp
->v_lastw
- vp
->v_cstart
) == 0)
2934 upl_size
= pages_in_upl
* PAGE_SIZE
;
2935 upl_f_offset
= ((off_t
)vp
->v_cstart
) * PAGE_SIZE_64
;
2936 size
= vp
->v_ciosiz
;
2939 if (size
> upl_size
|| (upl_size
- size
) > PAGE_SIZE
)
2940 panic("cluster_push: v_ciosiz doesn't match size of cluster\n");
2942 kret
= ubc_create_upl(vp
,
2948 if (kret
!= KERN_SUCCESS
)
2949 panic("cluster_push: failed to get pagelist");
2955 for (start_pg
= last_pg
; start_pg
< pages_in_upl
; start_pg
++) {
2956 if (upl_valid_page(pl
, start_pg
) && upl_dirty_page(pl
, start_pg
))
2959 if (start_pg
> last_pg
) {
2960 io_size
= (start_pg
- last_pg
) * PAGE_SIZE
;
2962 ubc_upl_abort_range(upl
, last_pg
* PAGE_SIZE
, io_size
,
2963 UPL_ABORT_FREE_ON_EMPTY
);
2970 for (last_pg
= start_pg
; last_pg
< pages_in_upl
; last_pg
++) {
2971 if (!upl_valid_page(pl
, last_pg
) || !upl_dirty_page(pl
, last_pg
))
2974 upl_offset
= start_pg
* PAGE_SIZE
;
2976 io_size
= min(size
, (last_pg
- start_pg
) * PAGE_SIZE
);
2978 if (vp
->v_flag
& VNOCACHE_DATA
)
2979 io_flags
= CL_COMMIT
| CL_AGE
| CL_ASYNC
| CL_DUMP
;
2981 io_flags
= CL_COMMIT
| CL_AGE
| CL_ASYNC
;
2983 while (vp
->v_numoutput
>= ASYNC_THROTTLE
) {
2984 vp
->v_flag
|= VTHROTTLED
;
2985 tsleep((caddr_t
)&vp
->v_numoutput
, PRIBIO
+ 1, "cluster_push", 0);
2987 cluster_io(vp
, upl
, upl_offset
, upl_f_offset
+ upl_offset
, io_size
, io_flags
, (struct buf
*)0);