2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include "afs/param.h"
14 #include "afs/sysincludes.h" /* Standard vendor system headers */
15 #include "afsincludes.h" /* Afs-based standard headers */
16 #include "afs/afs_stats.h" /* statistics */
17 #include "afs/afs_cbqueue.h"
18 #include "afs/nfsclient.h"
19 #include "afs/afs_osidnlc.h"
26 #ifndef AFS_DARWIN80_ENV
27 /* routine to make copy of uio structure in ainuio, using aoutvec for space */
29 afsio_copy(struct uio
*ainuio
, struct uio
*aoutuio
,
30 struct iovec
*aoutvec
)
35 AFS_STATCNT(afsio_copy
);
36 if (ainuio
->afsio_iovcnt
> AFS_MAXIOVCNT
)
38 memcpy((char *)aoutuio
, (char *)ainuio
, sizeof(struct uio
));
39 tvec
= ainuio
->afsio_iov
;
40 aoutuio
->afsio_iov
= aoutvec
;
41 for (i
= 0; i
< ainuio
->afsio_iovcnt
; i
++) {
42 memcpy((char *)aoutvec
, (char *)tvec
, sizeof(struct iovec
));
43 tvec
++; /* too many compiler bugs to do this as one expr */
49 /* trim the uio structure to the specified size */
51 afsio_trim(struct uio
*auio
, afs_int32 asize
)
56 AFS_STATCNT(afsio_trim
);
57 auio
->afsio_resid
= asize
;
59 /* It isn't clear that multiple iovecs work ok (hasn't been tested!) */
60 for (i
= 0;; i
++, tv
++) {
61 if (i
>= auio
->afsio_iovcnt
|| asize
<= 0) {
63 auio
->afsio_iovcnt
= i
;
66 if (tv
->iov_len
<= asize
)
67 /* entire iovec is included */
68 asize
-= tv
->iov_len
; /* this many fewer bytes */
70 /* this is the last one */
72 auio
->afsio_iovcnt
= i
+ 1;
79 /* Allocate space for, then partially copy, over an existing iovec up to the
80 * length given in len.
82 * This requires that SmallSpace can alloc space big enough to hold a struct
87 afsio_partialcopy(struct uio
*auio
, size_t len
) {
91 size_t space_len
= sizeof(struct uio
) +
92 sizeof(struct iovec
) * AFS_MAXIOVCNT
;
94 /* Allocate a block that can contain both the UIO and the iovec */
95 space
= osi_AllocSmallSpace(space_len
);
96 memset(space
, 0, space_len
);
98 newuio
= (struct uio
*) space
;
99 newvec
= (struct iovec
*) (space
+ sizeof(struct uio
));
101 afsio_copy(auio
, newuio
, newvec
);
102 afsio_trim(newuio
, len
);
108 afsio_free(struct uio
*uio
) {
109 osi_FreeSmallSpace(uio
);
113 /* skip asize bytes in the current uio structure */
115 afsio_skip(struct uio
*auio
, afs_int32 asize
)
117 struct iovec
*tv
; /* pointer to current iovec */
120 AFS_STATCNT(afsio_skip
);
121 #ifdef AFS_DARWIN80_ENV
122 uio_update(auio
, asize
);
124 /* It isn't guaranteed that multiple iovecs work ok (hasn't been tested!) */
125 while (asize
> 0 && auio
->afsio_resid
) {
126 tv
= auio
->afsio_iov
;
130 auio
->afsio_iovcnt
--;
135 tv
->iov_base
= (char *)(tv
->iov_base
) + cnt
;
137 auio
->uio_resid
-= cnt
;
138 auio
->afsio_offset
+= cnt
;