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" /* afs statistics */
17 #include "afs/osi_inode.h"
20 int afs_osicred_initialized
= 0;
21 extern struct osi_dev cacheDev
;
22 extern struct vfs
*afs_cacheVfsp
;
27 /* Support for UFS and VXFS caches. The assumption here is that the size of
28 * a cache file also does not exceed 32 bits.
31 /* Initialized in osi_InitCacheFSType(). Used to determine inode type. */
32 int afs_CacheFSType
= -1;
34 /* pointer to VXFS routine to access vnodes by inode number */
35 int (*vxfs_vx_vp_byino
) ();
37 /* Initialize the cache operations. Called while initializing cache files. */
39 afs_InitDualFSCacheOps(struct vnode
*vp
)
42 static int inited
= 0;
44 struct statvfs64 vfst
;
55 osi_Panic("afs_InitDualFSCacheOps: vp->v_vfsp is NULL");
56 code
= VFS_STATVFS(vfsp
, &vfst
);
58 osi_Panic("afs_InitDualFSCacheOps: statvfs failed");
60 if (strcmp(vfst
.f_basetype
, "vxfs") == 0) {
61 vxfs_vx_vp_byino
= (int (*)())modlookup("vxfs", "vx_vp_byino");
62 if (vxfs_vx_vp_byino
== NULL
)
64 ("afs_InitDualFSCacheOps: modlookup(vx_vp_byino) failed");
66 afs_CacheFSType
= AFS_SUN_VXFS_CACHE
;
70 afs_CacheFSType
= AFS_SUN_UFS_CACHE
;
75 VnodeToIno(vnode_t
* vp
)
80 vattr
.va_mask
= AT_FSID
| AT_NODEID
; /* quick return using this mask. */
82 code
= VOP_GETATTR(vp
, &vattr
, 0, afs_osi_credp
, NULL
);
84 code
= VOP_GETATTR(vp
, &vattr
, 0, afs_osi_credp
);
87 osi_Panic("VnodeToIno");
89 return vattr
.va_nodeid
;
93 VnodeToDev(vnode_t
* vp
)
98 vattr
.va_mask
= AT_FSID
| AT_NODEID
; /* quick return using this mask. */
100 #ifdef AFS_SUN511_ENV
101 code
= VOP_GETATTR(vp
, &vattr
, 0, afs_osi_credp
, NULL
);
103 code
= VOP_GETATTR(vp
, &vattr
, 0, afs_osi_credp
);
107 osi_Panic("VnodeToDev");
109 return (dev_t
) vattr
.va_fsid
;
113 VnodeToSize(vnode_t
* vp
)
118 vattr
.va_mask
= AT_SIZE
;
120 #ifdef AFS_SUN511_ENV
121 code
= VOP_GETATTR(vp
, &vattr
, 0, afs_osi_credp
, NULL
);
123 code
= VOP_GETATTR(vp
, &vattr
, 0, afs_osi_credp
);
127 osi_Panic("VnodeToSize");
129 return (afs_int32
) (vattr
.va_size
);
133 osi_VxfsOpen(afs_dcache_id_t
*ainode
)
136 struct osi_file
*afile
= NULL
;
139 afile
= osi_AllocSmallSpace(sizeof(struct osi_file
));
141 code
= (*vxfs_vx_vp_byino
) (afs_cacheVfsp
, &vp
, (unsigned int)ainode
->ufs
);
144 osi_FreeSmallSpace(afile
);
145 osi_Panic("VxfsOpen: vx_vp_byino failed");
148 afile
->size
= VnodeToSize(afile
->vnode
);
150 afile
->proc
= (int (*)())0;
151 return (void *)afile
;
153 #endif /* AFS_HAVE_VXFS */
156 osi_UfsOpen(afs_dcache_id_t
*ainode
)
158 #ifdef AFS_CACHE_VNODE_PATH
163 struct osi_file
*afile
= NULL
;
166 #ifdef AFS_CACHE_VNODE_PATH
168 struct pathname lookpn
;
170 struct osi_stat tstat
;
171 afile
= osi_AllocSmallSpace(sizeof(struct osi_file
));
175 * AFS_CACHE_VNODE_PATH can be used with any file system, including ZFS or tmpfs.
176 * The ainode is not an inode number but a path.
178 #ifdef AFS_CACHE_VNODE_PATH
179 /* Can not use vn_open or lookupname, they use user's CRED()
180 * We need to run as root So must use low level lookuppnvp
181 * assume fname starts with /
184 code
= pn_get_buf(ainode
->ufs
, AFS_UIOSYS
, &lookpn
, namebuf
, sizeof(namebuf
));
186 osi_Panic("UfsOpen: pn_get_buf failed %ld %s", code
, ainode
->ufs
);
188 VN_HOLD(rootdir
); /* released in loopuppnvp */
189 code
= lookuppnvp(&lookpn
, NULL
, FOLLOW
, NULL
, &vp
,
190 rootdir
, rootdir
, afs_osi_credp
);
192 osi_Panic("UfsOpen: lookuppnvp failed %ld %s", code
, ainode
->ufs
);
194 #ifdef AFS_SUN511_ENV
195 code
= VOP_OPEN(&vp
, FREAD
|FWRITE
, afs_osi_credp
, NULL
);
197 code
= VOP_OPEN(&vp
, FREAD
|FWRITE
, afs_osi_credp
);
201 osi_Panic("UfsOpen: VOP_OPEN failed %ld %s", code
, ainode
->ufs
);
205 igetinode(afs_cacheVfsp
, (dev_t
) cacheDev
.dev
, ainode
->ufs
, &ip
,
210 osi_FreeSmallSpace(afile
);
211 osi_Panic("UfsOpen: igetinode failed %ld %s", code
, ainode
->ufs
);
213 #ifdef AFS_CACHE_VNODE_PATH
215 code
= afs_osi_Stat(afile
, &tstat
);
216 afile
->size
= tstat
.size
;
218 afile
->vnode
= ITOV(ip
);
219 afile
->size
= VTOI(afile
->vnode
)->i_size
;
222 afile
->proc
= (int (*)())0;
223 return (void *)afile
;
227 * In Solaris 7 we use 64 bit inode numbers
230 osi_UFSOpen(afs_dcache_id_t
*ainode
)
232 extern int cacheDiskType
;
233 AFS_STATCNT(osi_UFSOpen
);
234 if (cacheDiskType
!= AFS_FCACHE_TYPE_UFS
) {
235 osi_Panic("UFSOpen called for non-UFS cache\n");
237 if (!afs_osicred_initialized
) {
238 afs_osi_credp
= kcred
;
239 afs_osicred_initialized
= 1;
242 if (afs_CacheFSType
== AFS_SUN_VXFS_CACHE
)
243 return osi_VxfsOpen(ainode
);
245 return osi_UfsOpen(ainode
);
249 afs_osi_Stat(struct osi_file
*afile
, struct osi_stat
*astat
)
253 AFS_STATCNT(osi_Stat
);
254 /* Ufs doesn't seem to care about the flags so we pass 0 for now */
255 tvattr
.va_mask
= AT_ALL
;
257 #ifdef AFS_SUN511_ENV
258 code
= VOP_GETATTR(afile
->vnode
, &tvattr
, 0, afs_osi_credp
, NULL
);
260 code
= VOP_GETATTR(afile
->vnode
, &tvattr
, 0, afs_osi_credp
);
264 astat
->size
= tvattr
.va_size
;
265 astat
->mtime
= tvattr
.va_mtime
.tv_sec
;
266 astat
->atime
= tvattr
.va_atime
.tv_sec
;
272 osi_UFSClose(struct osi_file
*afile
)
274 AFS_STATCNT(osi_Close
);
276 AFS_RELE(afile
->vnode
);
279 osi_FreeSmallSpace(afile
);
284 osi_UFSTruncate(struct osi_file
*afile
, afs_int32 asize
)
286 afs_ucred_t
*oldCred
;
289 struct osi_stat tstat
;
290 AFS_STATCNT(osi_Truncate
);
292 /* This routine only shrinks files, and most systems
293 * have very slow truncates, even when the file is already
294 * small enough. Check now and save some time.
296 code
= afs_osi_Stat(afile
, &tstat
);
297 if (code
|| tstat
.size
<= asize
)
299 tvattr
.va_mask
= AT_SIZE
;
300 tvattr
.va_size
= asize
;
302 * The only time a flag is used (ATTR_UTIME) is when we're changing the time
305 #ifdef AFS_SUN510_ENV
306 code
= VOP_SETATTR(afile
->vnode
, &tvattr
, 0, afs_osi_credp
, NULL
);
308 code
= VOP_SETATTR(afile
->vnode
, &tvattr
, 0, afs_osi_credp
);
315 osi_DisableAtimes(struct vnode
*avp
)
317 if (afs_CacheFSType
== AFS_SUN_UFS_CACHE
) {
318 #ifndef AFS_CACHE_VNODE_PATH
319 struct inode
*ip
= VTOI(avp
);
320 rw_enter(&ip
->i_contents
, RW_READER
);
321 mutex_enter(&ip
->i_tlock
);
323 mutex_exit(&ip
->i_tlock
);
324 rw_exit(&ip
->i_contents
);
330 /* Generic read interface */
332 afs_osi_Read(struct osi_file
*afile
, int offset
, void *aptr
,
335 afs_ucred_t
*oldCred
;
339 AFS_STATCNT(osi_Read
);
342 * If the osi_file passed in is NULL, panic only if AFS is not shutting
343 * down. No point in crashing when we are already shutting down
346 if (afs_shuttingdown
== AFS_RUNNING
)
347 osi_Panic("osi_Read called with null param");
353 afile
->offset
= offset
;
356 gop_rdwr(UIO_READ
, afile
->vnode
, (caddr_t
) aptr
, asize
, afile
->offset
,
357 AFS_UIOSYS
, 0, 0, afs_osi_credp
, &resid
);
360 code
= asize
- resid
;
361 afile
->offset
+= code
;
362 osi_DisableAtimes(afile
->vnode
);
364 afs_Trace2(afs_iclSetp
, CM_TRACE_READFAILED
, ICL_TYPE_INT32
, resid
,
365 ICL_TYPE_INT32
, code
);
373 /* Generic write interface */
375 afs_osi_Write(struct osi_file
*afile
, afs_int32 offset
, void *aptr
,
378 afs_ucred_t
*oldCred
;
381 AFS_STATCNT(osi_Write
);
383 osi_Panic("afs_osi_Write called with null param");
385 afile
->offset
= offset
;
388 gop_rdwr(UIO_WRITE
, afile
->vnode
, (caddr_t
) aptr
, asize
,
389 afile
->offset
, AFS_UIOSYS
, 0, RLIM64_INFINITY
, afs_osi_credp
,
393 code
= asize
- resid
;
394 afile
->offset
+= code
;
401 (*afile
->proc
) (afile
, code
);
407 /* This work should be handled by physstrat in ca/machdep.c.
408 This routine written from the RT NFS port strategy routine.
409 It has been generalized a bit, but should still be pretty clear. */
411 afs_osi_MapStrategy(int (*aproc
) (), struct buf
*bp
)
413 afs_int32 returnCode
;
415 AFS_STATCNT(osi_MapStrategy
);
416 returnCode
= (*aproc
) (bp
);
424 shutdown_osifile(void)
426 AFS_STATCNT(shutdown_osifile
);
427 if (afs_cold_shutdown
) {
428 afs_osicred_initialized
= 0;