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"
16 #include "afs/sysincludes.h" /* Standard vendor system headers */
17 #include "afsincludes.h" /* Afs-based standard headers */
18 #include "afs/afs_stats.h" /* afs statistics */
21 int afs_osicred_initialized = 0;
22 struct AFS_UCRED afs_osi_cred;
23 afs_lock_t afs_xosi; /* lock is for tvattr */
24 extern struct osi_dev cacheDev;
25 extern struct mount *afs_cacheVfsp;
29 osi_UFSOpen(afs_int32 ainode)
31 static struct vnode *tags_vnode = NULL;
33 register struct osi_file *afile = NULL;
34 extern int cacheDiskType;
37 AFS_STATCNT(osi_UFSOpen);
38 if (cacheDiskType != AFS_FCACHE_TYPE_UFS)
39 osi_Panic("UFSOpen called for non-UFS cache\n");
41 afile = (struct osi_file *)osi_AllocSmallSpace(sizeof(struct osi_file));
44 switch (afs_cacheVfsp->m_stat.f_type) {
47 igetinode(afs_cacheVfsp, (dev_t) cacheDev.dev, (ino_t) ainode,
50 osi_FreeSmallSpace(afile);
51 osi_Panic("UFSOpen: igetinode failed");
54 afile->vnode = ITOV(ip);
55 afile->size = VTOI(afile->vnode)->i_size;
58 afile->inum = ainode; /* for hint validity checking */
62 struct nameidata nd, *ndp = &nd;
63 struct utask_nd utnd = { NULL, NULL };
66 memset(&nd, 0, sizeof(nd));
68 ndp->ni_nameiop = LOOKUP;
69 ndp->ni_cred = &afs_osi_cred;
70 ndp->ni_segflg = UIO_SYSSPACE;
72 /* get hold of a vnode for the .tags directory, so we can
73 * lookup files relative to it */
74 if (tags_vnode == NULL) {
75 ndp->ni_cdir = afs_cacheVfsp->m_vnodecovered;
76 strcpy(path, afs_cacheVfsp->m_stat.f_mntonname);
77 strcat(path, "/.tags");
79 if ((code = namei(ndp)))
80 osi_Panic("failed to lookup %s (%d)", path, code);
81 tags_vnode = ndp->ni_vp;
83 sprintf(path, "%d", ainode);
85 ndp->ni_cdir = tags_vnode;
86 if ((code = namei(ndp)))
87 osi_Panic("failed to lookup %s (%d)", path, code);
89 /* XXX this sucks, chances are we're going to do this again right
90 * away, but apparently we can't just set the size to 0 */
91 VOP_GETATTR(ndp->ni_vp, &attr, &afs_osi_cred, code);
93 osi_Panic("failed to stat %s (%d)", path, code);
95 afile->vnode = ndp->ni_vp;
96 afile->size = attr.va_size;
99 afile->inum = ainode; /* for hint validity checking */
103 osi_Panic("UFSOpen called for unknown cache-type (%d)",
104 afs_cacheVfsp->m_stat.f_type);
112 afs_osi_Stat(register struct osi_file *afile, register struct osi_stat *astat)
114 register afs_int32 code;
116 AFS_STATCNT(osi_Stat);
117 MObtainWriteLock(&afs_xosi, 320);
119 VOP_GETATTR(afile->vnode, &tvattr, &afs_osi_cred, code);
122 astat->size = tvattr.va_size;
123 astat->blksize = tvattr.va_blocksize;
124 astat->mtime = tvattr.va_mtime.tv_sec;
125 astat->atime = tvattr.va_atime.tv_sec;
127 MReleaseWriteLock(&afs_xosi);
132 osi_UFSClose(register struct osi_file *afile)
134 AFS_STATCNT(osi_Close);
136 AFS_RELE(afile->vnode);
139 osi_FreeSmallSpace(afile);
144 osi_UFSTruncate(register struct osi_file *afile, afs_int32 asize)
146 struct AFS_UCRED *oldCred;
148 register afs_int32 code;
149 struct osi_stat tstat;
150 AFS_STATCNT(osi_Truncate);
152 /* This routine only shrinks files, and most systems
153 * have very slow truncates, even when the file is already
154 * small enough. Check now and save some time.
156 code = afs_osi_Stat(afile, &tstat);
157 if (code || tstat.size <= asize)
159 MObtainWriteLock(&afs_xosi, 321);
161 /* note that this credential swapping stuff is only necessary because
162 * of ufs's references directly to u.u_cred instead of to
163 * credentials parameter. Probably should fix ufs some day. */
164 oldCred = u.u_cred; /* remember old credentials pointer */
165 u.u_cred = &afs_osi_cred; /* temporarily use superuser credentials */
166 tvattr.va_size = asize;
168 VOP_SETATTR(afile->vnode, &tvattr, &afs_osi_cred, code);
170 u.u_cred = oldCred; /* restore */
171 MReleaseWriteLock(&afs_xosi);
176 osi_DisableAtimes(struct vnode *avp)
179 assert(avp->v_tag == VT_UFS);
185 /* Generic read interface */
187 afs_osi_Read(register struct osi_file *afile, int offset, void *aptr,
190 struct AFS_UCRED *oldCred;
192 register afs_int32 code;
193 register afs_int32 cnt1 = 0;
194 AFS_STATCNT(osi_Read);
197 * If the osi_file passed in is NULL, panic only if AFS is not shutting
198 * down. No point in crashing when we are already shutting down
201 if (!afs_shuttingdown)
202 osi_Panic("osi_Read called with null param");
208 afile->offset = offset;
211 gop_rdwr(UIO_READ, afile->vnode, (caddr_t) aptr, asize, afile->offset,
212 AFS_UIOSYS, IO_UNIT, &afs_osi_cred, &resid);
215 code = asize - resid;
216 afile->offset += code;
217 osi_DisableAtimes(afile->vnode);
219 afs_Trace2(afs_iclSetp, CM_TRACE_READFAILED, ICL_TYPE_INT32, resid,
220 ICL_TYPE_INT32, code);
226 /* Generic write interface */
228 afs_osi_Write(register struct osi_file *afile, afs_int32 offset, void *aptr,
231 struct AFS_UCRED *oldCred;
233 register afs_int32 code;
234 AFS_STATCNT(osi_Write);
236 osi_Panic("afs_osi_Write called with null param");
238 afile->offset = offset;
240 struct ucred *tmpcred = u.u_cred;
241 u.u_cred = &afs_osi_cred;
244 gop_rdwr(UIO_WRITE, afile->vnode, (caddr_t) aptr, asize,
245 afile->offset, AFS_UIOSYS, IO_UNIT, &afs_osi_cred,
251 code = asize - resid;
252 afile->offset += code;
257 (*afile->proc) (afile, code);
263 /* This work should be handled by physstrat in ca/machdep.c.
264 This routine written from the RT NFS port strategy routine.
265 It has been generalized a bit, but should still be pretty clear. */
267 afs_osi_MapStrategy(int (*aproc) (), register struct buf *bp)
269 afs_int32 returnCode;
271 AFS_STATCNT(osi_MapStrategy);
272 returnCode = (*aproc) (bp);
280 shutdown_osifile(void)
282 extern int afs_cold_shutdown;
284 AFS_STATCNT(shutdown_osifile);
285 if (afs_cold_shutdown) {
286 afs_osicred_initialized = 0;