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"
15 #include "../afs/sysincludes.h" /* Standard vendor system headers */
16 #include "../afs/afsincludes.h" /* Afs-based standard headers */
17 #include "../afs/afs_stats.h" /* afs statistics */
18 #include "../afs/osi_inode.h"
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;
26 int afs_CacheFSType = -1;
28 /* Initialize the cache operations. Called while initializing cache files. */
29 void afs_InitDualFSCacheOps(struct vnode *vp)
32 static int inited = 0;
40 if (strncmp("hfs", vp->v_mount->mnt_vfc->vfc_name, 3) == 0)
41 afs_CacheFSType = AFS_APPL_HFS_CACHE;
43 if (strncmp("ufs", vp->v_mount->mnt_vfc->vfc_name, 3) == 0)
44 afs_CacheFSType = AFS_APPL_UFS_CACHE;
46 osi_Panic("Unknown cache vnode type\n");
49 ino_t VnodeToIno(vnode_t *avp)
53 if (afs_CacheFSType == AFS_APPL_UFS_CACHE) {
54 struct inode *ip = VTOI(avp);
56 } else if (afs_CacheFSType == AFS_APPL_HFS_CACHE) {
59 if (VOP_GETATTR(avp, &va, &afs_osi_cred, current_proc()))
60 osi_Panic("VOP_GETATTR failed in VnodeToIno\n");
63 struct hfsnode *hp = VTOH(avp);
67 osi_Panic("VnodeToIno called before cacheops initialized\n");
72 dev_t VnodeToDev(vnode_t *avp)
76 if (afs_CacheFSType == AFS_APPL_UFS_CACHE) {
77 struct inode *ip = VTOI(avp);
80 if (afs_CacheFSType == AFS_APPL_HFS_CACHE) {
81 #ifndef VTOH /* slow, but works */
83 if (VOP_GETATTR(avp, &va, &afs_osi_cred, current_proc()))
84 osi_Panic("VOP_GETATTR failed in VnodeToDev\n");
85 return va.va_fsid; /* XXX they say it's the dev.... */
87 struct hfsnode *hp = VTOH(avp);
91 osi_Panic("VnodeToDev called before cacheops initialized\n");
94 void *osi_UFSOpen(afs_int32 ainode)
98 register struct osi_file *afile = NULL;
99 extern int cacheDiskType;
102 AFS_STATCNT(osi_UFSOpen);
103 if(cacheDiskType != AFS_FCACHE_TYPE_UFS) {
104 osi_Panic("UFSOpen called for non-UFS cache\n");
106 if (!afs_osicred_initialized) {
107 /* valid for alpha_osf, SunOS, Ultrix */
108 memset((char *)&afs_osi_cred, 0, sizeof(struct AFS_UCRED));
109 afs_osi_cred.cr_ref++;
110 afs_osi_cred.cr_ngroups=1;
111 afs_osicred_initialized = 1;
113 afile = (struct osi_file *) osi_AllocSmallSpace(sizeof(struct osi_file));
115 if (afs_CacheFSType == AFS_APPL_HFS_CACHE)
116 code = igetinode(afs_cacheVfsp, (dev_t) cacheDev.dev, &ainode, &vp, &va, &dummy); /* XXX hfs is broken */
118 if (afs_CacheFSType == AFS_APPL_UFS_CACHE)
119 code = igetinode(afs_cacheVfsp, (dev_t) cacheDev.dev, (ino_t)ainode, &vp, &va, &dummy);
121 panic("osi_UFSOpen called before cacheops initialized\n");
124 osi_FreeSmallSpace(afile);
125 osi_Panic("UFSOpen: igetinode failed");
128 afile->size = va.va_size;
130 afile->proc = (int (*)()) 0;
131 afile->inum = ainode; /* for hint validity checking */
132 return (void *)afile;
135 int afs_osi_Stat(register struct osi_file *afile, register struct osi_stat *astat)
137 register afs_int32 code;
139 AFS_STATCNT(osi_Stat);
140 MObtainWriteLock(&afs_xosi,320);
142 code=VOP_GETATTR(afile->vnode, &tvattr, &afs_osi_cred, current_proc());
145 astat->size = tvattr.va_size;
146 astat->blksize = tvattr.va_blocksize;
147 astat->mtime = tvattr.va_mtime.tv_sec;
148 astat->atime = tvattr.va_atime.tv_sec;
150 MReleaseWriteLock(&afs_xosi);
154 int osi_UFSClose(register struct osi_file *afile)
156 AFS_STATCNT(osi_Close);
158 AFS_RELE(afile->vnode);
161 osi_FreeSmallSpace(afile);
165 int osi_UFSTruncate(register struct osi_file *afile, afs_int32 asize)
167 struct AFS_UCRED *oldCred;
169 register afs_int32 code;
170 struct osi_stat tstat;
171 AFS_STATCNT(osi_Truncate);
173 /* This routine only shrinks files, and most systems
174 * have very slow truncates, even when the file is already
175 * small enough. Check now and save some time.
177 code = afs_osi_Stat(afile, &tstat);
178 if (code || tstat.size <= asize) return code;
179 MObtainWriteLock(&afs_xosi,321);
181 tvattr.va_size = asize;
183 code=VOP_SETATTR(afile->vnode, &tvattr, &afs_osi_cred, current_proc());
185 MReleaseWriteLock(&afs_xosi);
189 void osi_DisableAtimes(struct vnode *avp)
193 if (afs_CacheFSType == AFS_APPL_UFS_CACHE) {
194 struct inode *ip = VTOI(avp);
195 ip->i_flag &= ~IN_ACCESS;
197 #ifdef VTOH /* can't do this without internals */
198 else if (afs_CacheFSType == AFS_APPL_HFS_CACHE) {
199 struct hfsnode *hp = VTOH(avp);
200 hp->h_nodeflags &= ~IN_ACCESS;
206 /* Generic read interface */
207 int afs_osi_Read(register struct osi_file *afile, int offset, void *aptr, afs_int32 asize)
209 struct AFS_UCRED *oldCred;
211 register afs_int32 code;
212 AFS_STATCNT(osi_Read);
215 * If the osi_file passed in is NULL, panic only if AFS is not shutting
216 * down. No point in crashing when we are already shutting down
219 if ( !afs_shuttingdown )
220 osi_Panic("osi_Read called with null param");
225 if (offset != -1) afile->offset = offset;
227 code = gop_rdwr(UIO_READ, afile->vnode, (caddr_t) aptr, asize, afile->offset,
228 AFS_UIOSYS, IO_UNIT, &afs_osi_cred, &resid);
231 code = asize - resid;
232 afile->offset += code;
233 osi_DisableAtimes(afile->vnode);
236 afs_Trace2(afs_iclSetp, CM_TRACE_READFAILED, ICL_TYPE_INT32, resid,
237 ICL_TYPE_INT32, code);
243 /* Generic write interface */
244 int afs_osi_Write(register struct osi_file *afile, afs_int32 offset, void *aptr, afs_int32 asize)
246 struct AFS_UCRED *oldCred;
248 register afs_int32 code;
249 AFS_STATCNT(osi_Write);
251 osi_Panic("afs_osi_Write called with null param");
252 if (offset != -1) afile->offset = offset;
255 code = gop_rdwr(UIO_WRITE, afile->vnode, (caddr_t) aptr, asize, afile->offset,
256 AFS_UIOSYS, IO_UNIT, &afs_osi_cred, &resid);
260 code = asize - resid;
261 afile->offset += code;
267 (*afile->proc)(afile, code);
276 void shutdown_osifile(void)
278 extern int afs_cold_shutdown;
280 AFS_STATCNT(shutdown_osifile);
281 if (afs_cold_shutdown) {
282 afs_osicred_initialized = 0;