1 /* Copyright (C) 1995, 1989, 1998 Transarc Corporation - All rights reserved */
3 * (C) COPYRIGHT IBM CORPORATION 1987, 1988
4 * LICENSED MATERIALS - PROPERTY OF IBM
13 #include "../afs/param.h" /* Should be always first */
14 #if !defined(AFS_HPUX_ENV) && !defined(AFS_SGI_ENV) && !defined(AFS_LINUX20_ENV)
16 #include "../afs/sysincludes.h" /* Standard vendor system headers */
17 #include "../afs/afsincludes.h" /* Afs-based standard headers */
18 #include "../afs/afs_stats.h" /* statistics */
19 #include "../afs/afs_cbqueue.h"
20 #include "../afs/nfsclient.h"
21 #include "../afs/afs_osidnlc.h"
26 #if defined(AFS_SUN5_ENV) || defined(AFS_OSF_ENV)
27 afs_ustrategy(abp, credp)
28 struct AFS_UCRED *credp;
32 register struct buf *abp; {
33 register afs_int32 code;
35 register struct vcache *tvc = (struct vcache *) abp->b_vp;
36 register afs_int32 len = abp->b_bcount;
37 #if !defined(AFS_SUN5_ENV) && !defined(AFS_OSF_ENV)
41 struct AFS_UCRED *credp = u.u_cred;
44 #if defined(AFS_SUN_ENV) || defined(AFS_SUN5_ENV)
45 int async = abp->b_flags & B_ASYNC;
47 struct iovec tiovec[1];
49 AFS_STATCNT(afs_ustrategy);
52 * So that it won't change while reading it
54 ObtainReadLock(&tvc->lock);
61 ReleaseReadLock(&tvc->lock);
64 if ((abp->b_flags & B_READ) == B_READ) {
65 /* read b_bcount bytes into kernel address b_un.b_addr starting
66 at byte DEV_BSIZE * b_blkno. Bzero anything we can't read,
67 and finally call iodone(abp). File is in abp->b_vp. Credentials
70 tuio.afsio_iov = tiovec;
71 tuio.afsio_iovcnt = 1;
72 #if defined(AFS_SUN_ENV) || defined(AFS_ALPHA_ENV) || defined(AFS_SUN5_ENV)
73 tuio.afsio_offset = (u_int) dbtob(abp->b_blkno);
74 #if defined(AFS_SUN5_ENV)
75 tuio._uio_offset._p._u = 0;
78 tuio.afsio_offset = DEV_BSIZE * abp->b_blkno;
80 tuio.afsio_seg = AFS_UIOSYS;
84 tuio.afsio_resid = abp->b_bcount;
85 tiovec[0].iov_base = abp->b_un.b_addr;
86 tiovec[0].iov_len = abp->b_bcount;
87 /* are user's credentials valid here? probably, but this
88 sure seems like the wrong things to do. */
89 #if defined(AFS_SUN5_ENV)
90 code = afs_nlrdwr((struct vcache *) abp->b_vp, &tuio, UIO_READ, 0, credp);
92 code = afs_rdwr((struct vcache *) abp->b_vp, &tuio, UIO_READ, 0, credp);
95 if (tuio.afsio_resid > 0)
96 bzero(abp->b_un.b_addr + abp->b_bcount - tuio.afsio_resid, tuio.afsio_resid);
99 * If we read a block that is past EOF and the user was not storing
100 * to it, go ahead and write protect the page. This way we will detect
101 * storing beyond EOF in the future
103 if (dbtob(abp->b_blkno) + abp->b_bcount > tvc->m.Length) {
104 if ((abp->b_flags & B_PFSTORE) == 0) {
106 vm_protectp(tvc->vmh, dbtob(abp->b_blkno)/PAGESIZE,
107 abp->b_bcount/PAGESIZE, RDONLY);
115 tuio.afsio_iov = tiovec;
116 tuio.afsio_iovcnt = 1;
117 #if defined(AFS_SUN_ENV) || defined(AFS_ALPHA_ENV) || defined(AFS_SUN5_ENV)
118 tuio.afsio_offset = (u_int) dbtob(abp->b_blkno);
120 tuio._uio_offset._p._u = 0;
121 tuio.uio_limit = u.u_rlimit[RLIMIT_FSIZE].rlim_cur;
124 tuio.afsio_offset = DEV_BSIZE * abp->b_blkno;
126 tuio.afsio_seg = AFS_UIOSYS;
128 tuio.afsio_fmode = 0;
132 * XXX It this really right? Ideally we should always write block size multiple
133 * and not any arbitrary size, right? XXX
135 len = MIN(len, tvc->m.Length - dbtob(abp->b_blkno));
138 len = MIN(abp->b_bcount, ((struct vcache *)abp->b_vp)->m.Length - dbtob(abp->b_blkno));
139 #endif /* AFS_ALPHA_ENV */
140 tuio.afsio_resid = len;
141 tiovec[0].iov_base = abp->b_un.b_addr;
142 tiovec[0].iov_len = len;
143 /* are user's credentials valid here? probably, but this
144 sure seems like the wrong things to do. */
145 #if defined(AFS_SUN5_ENV)
146 code = afs_nlrdwr((struct vcache *) abp->b_vp, &tuio, UIO_WRITE, 0, credp);
148 code = afs_rdwr((struct vcache *) abp->b_vp, &tuio, UIO_WRITE, 0, credp);
151 #if !defined(AFS_AIX32_ENV) && !defined(AFS_SUN5_ENV)
155 abp->b_flags |= B_ERROR;
158 if (code && !(abp->b_flags & B_READ)) {
159 /* prevent ubc from retrying writes */
161 ubc_invalidate(((struct vnode *)tvc)->v_object,
162 (vm_offset_t)dbtob(abp->b_blkno),
166 #else /* AFS_DUX40_ENV */
168 #endif /* AFS_DUX40_ENV */
173 afs_Trace3(afs_iclSetp, CM_TRACE_STRATEGYDONE, ICL_TYPE_POINTER, tvc,
174 ICL_TYPE_INT32, code,
175 ICL_TYPE_LONG, tuio.afsio_resid);
179 #endif /* !AFS_HPUX_ENV && !AFS_SGI_ENV && !AFS_LINUX20_ENV */