dux50-largefile-client-20040808
[openafs.git] / src / afs / IRIX / osi_file.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
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
8  */
9
10 #include <afsconfig.h>
11 #include "afs/param.h"
12
13 RCSID
14     ("$Header$");
15
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 */
19
20 int afs_osicred_initialized = 0;
21 afs_lock_t afs_xosi;            /* lock is for tvattr */
22 extern struct osi_dev cacheDev;
23 extern struct vfs *afs_cacheVfsp;
24
25
26 /* As of 6.2, we support either XFS or EFS clients. osi_UFSOpen
27  * now vectors to the correct EFS or XFS function. If new functionality is
28  * added which accesses the inode, that will also need EFS/XFS variants.
29  */
30 #ifdef AFS_SGI_EFS_IOPS_ENV
31 vnode_t *
32 afs_EFSIGetVnode(ino_t ainode)
33 {
34     struct inode *ip;
35     int error;
36
37     if ((error = igetinode(afs_cacheVfsp, (dev_t) cacheDev.dev, ainode, &ip))) {
38         osi_Panic("afs_EFSIGetVnode: igetinode failed, error=%d", error);
39     }
40     /* We don't care about atimes on the cache files, so disable them.  I'm not
41      * sure that this is the right place to do this: it should be *after* readi 
42      * and getattr and stuff. 
43      */
44     ip->i_flags &= ~(ISYN | IACC);
45     iunlock(ip);
46     return (EFS_ITOV(ip));
47 }
48 #endif /* AFS_SGI_EFS_IOPS_ENV */
49
50 vnode_t *
51 afs_XFSIGetVnode(ino_t ainode)
52 {
53     struct xfs_inode *ip;
54     int error;
55     vnode_t *vp;
56
57     if ((error =
58          xfs_igetinode(afs_cacheVfsp, (dev_t) cacheDev.dev, ainode, &ip))) {
59         osi_Panic("afs_XFSIGetVnode: xfs_igetinode failed, error=%d", error);
60     }
61     vp = XFS_ITOV(ip);
62     return vp;
63 }
64
65 /* Force to 64 bits, even for EFS filesystems. */
66 void *
67 osi_UFSOpen(ino_t ainode)
68 {
69     struct inode *ip;
70     register struct osi_file *afile = NULL;
71     extern int cacheDiskType;
72     afs_int32 code = 0;
73     int dummy;
74     AFS_STATCNT(osi_UFSOpen);
75     if (cacheDiskType != AFS_FCACHE_TYPE_UFS) {
76         osi_Panic("UFSOpen called for non-UFS cache\n");
77     }
78     if (!afs_osicred_initialized) {
79         /* valid for alpha_osf, SunOS, Ultrix */
80         memset((char *)&afs_osi_cred, 0, sizeof(struct AFS_UCRED));
81         crhold(&afs_osi_cred);  /* don't let it evaporate, since it is static */
82         afs_osicred_initialized = 1;
83     }
84     afile = (struct osi_file *)osi_AllocSmallSpace(sizeof(struct osi_file));
85     AFS_GUNLOCK();
86     afile->vnode = AFS_SGI_IGETVNODE(ainode);
87     AFS_GLOCK();
88     afile->size = VnodeToSize(afile->vnode);
89     afile->offset = 0;
90     afile->proc = (int (*)())0;
91     afile->inum = ainode;       /* for hint validity checking */
92     return (void *)afile;
93 }
94
95 int
96 afs_osi_Stat(register struct osi_file *afile, register struct osi_stat *astat)
97 {
98     register afs_int32 code;
99     struct vattr tvattr;
100     AFS_STATCNT(osi_Stat);
101     MObtainWriteLock(&afs_xosi, 320);
102     AFS_GUNLOCK();
103     tvattr.va_mask = AT_SIZE | AT_BLKSIZE | AT_MTIME | AT_ATIME;
104     AFS_VOP_GETATTR(afile->vnode, &tvattr, 0, &afs_osi_cred, code);
105     AFS_GLOCK();
106     if (code == 0) {
107         astat->size = tvattr.va_size;
108         astat->blksize = tvattr.va_blocksize;
109         astat->mtime = tvattr.va_mtime.tv_sec;
110         astat->atime = tvattr.va_atime.tv_sec;
111     }
112     MReleaseWriteLock(&afs_xosi);
113     return code;
114 }
115
116 int
117 osi_UFSClose(register struct osi_file *afile)
118 {
119     AFS_STATCNT(osi_Close);
120     if (afile->vnode) {
121         VN_RELE(afile->vnode);
122     }
123
124     osi_FreeSmallSpace(afile);
125     return 0;
126 }
127
128 int
129 osi_UFSTruncate(register struct osi_file *afile, afs_int32 asize)
130 {
131     struct AFS_UCRED *oldCred;
132     struct vattr tvattr;
133     register afs_int32 code;
134     struct osi_stat tstat;
135     mon_state_t ms;
136     AFS_STATCNT(osi_Truncate);
137
138     /* This routine only shrinks files, and most systems
139      * have very slow truncates, even when the file is already
140      * small enough.  Check now and save some time.
141      */
142     code = afs_osi_Stat(afile, &tstat);
143     if (code || tstat.size <= asize)
144         return code;
145     MObtainWriteLock(&afs_xosi, 321);
146     AFS_GUNLOCK();
147     tvattr.va_mask = AT_SIZE;
148     tvattr.va_size = asize;
149     AFS_VOP_SETATTR(afile->vnode, &tvattr, 0, &afs_osi_cred, code);
150     AFS_GLOCK();
151     MReleaseWriteLock(&afs_xosi);
152     return code;
153 }
154
155 #ifdef AFS_SGI_EFS_IOPS_ENV
156 void
157 osi_DisableAtimes(struct vnode *avp)
158 {
159     if (afs_CacheFSType == AFS_SGI_EFS_CACHE) {
160         struct inode *ip = EFS_VTOI(avp);
161         ip->i_flags &= ~IACC;
162     }
163
164 }
165 #endif /* AFS_SGI_EFS_IOPS_ENV */
166
167
168 /* Generic read interface */
169 int
170 afs_osi_Read(register struct osi_file *afile, int offset, void *aptr,
171              afs_int32 asize)
172 {
173     struct AFS_UCRED *oldCred;
174     ssize_t resid;
175     register afs_int32 code;
176     register afs_int32 cnt1 = 0;
177     AFS_STATCNT(osi_Read);
178
179     /**
180       * If the osi_file passed in is NULL, panic only if AFS is not shutting
181       * down. No point in crashing when we are already shutting down
182       */
183     if (!afile) {
184         if (!afs_shuttingdown)
185             osi_Panic("osi_Read called with null param");
186         else
187             return EIO;
188     }
189
190     if (offset != -1)
191         afile->offset = offset;
192     AFS_GUNLOCK();
193     code =
194         gop_rdwr(UIO_READ, afile->vnode, (caddr_t) aptr, asize, afile->offset,
195                  AFS_UIOSYS, 0, 0x7fffffff, &afs_osi_cred, &resid);
196     AFS_GLOCK();
197     if (code == 0) {
198         code = asize - resid;
199         afile->offset += code;
200 #ifdef AFS_SGI_EFS_IOPS_ENV
201         osi_DisableAtimes(afile->vnode);
202 #endif /* AFS_SGI_EFS_IOPS_ENV */
203     } else {
204         afs_Trace2(afs_iclSetp, CM_TRACE_READFAILED, ICL_TYPE_INT32, resid,
205                    ICL_TYPE_INT32, code);
206         code = -1;
207     }
208     return code;
209 }
210
211 /* Generic write interface */
212 int
213 afs_osi_Write(register struct osi_file *afile, afs_int32 offset, void *aptr,
214               afs_int32 asize)
215 {
216     struct AFS_UCRED *oldCred;
217     ssize_t resid;
218     register afs_int32 code;
219     AFS_STATCNT(osi_Write);
220     if (!afile)
221         osi_Panic("afs_osi_Write called with null param");
222     if (offset != -1)
223         afile->offset = offset;
224     AFS_GUNLOCK();
225     code =
226         gop_rdwr(UIO_WRITE, afile->vnode, (caddr_t) aptr, asize,
227                  afile->offset, AFS_UIOSYS, 0, 0x7fffffff, &afs_osi_cred,
228                  &resid);
229     AFS_GLOCK();
230     if (code == 0) {
231         code = asize - resid;
232         afile->offset += code;
233     } else {
234         if (code == ENOSPC)
235             afs_warnuser
236                 ("\n\n\n*** Cache partition is FULL - Decrease cachesize!!! ***\n\n");
237         code = -1;
238     }
239     if (afile->proc) {
240         (*afile->proc) (afile, code);
241     }
242     return code;
243 }
244
245
246 /*  This work should be handled by physstrat in ca/machdep.c.
247     This routine written from the RT NFS port strategy routine.
248     It has been generalized a bit, but should still be pretty clear. */
249 int
250 afs_osi_MapStrategy(int (*aproc) (), register struct buf *bp)
251 {
252     afs_int32 returnCode;
253
254     AFS_STATCNT(osi_MapStrategy);
255     returnCode = (*aproc) (bp);
256
257     return returnCode;
258 }
259
260
261
262 void
263 shutdown_osifile(void)
264 {
265     extern int afs_cold_shutdown;
266
267     AFS_STATCNT(shutdown_osifile);
268     if (afs_cold_shutdown) {
269         afs_osicred_initialized = 0;
270     }
271 }