afs: Remove afs_xosi
[openafs.git] / src / afs / HPUX / 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
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"      /* igetinode() */
18
19
20 int afs_osicred_initialized = 0;
21 afs_ucred_t afs_osi_cred;
22 extern struct osi_dev cacheDev;
23 extern struct vfs *afs_cacheVfsp;
24
25
26 void *
27 osi_UFSOpen(afs_dcache_id_t *ainode)
28 {
29     struct inode *ip;
30     struct osi_file *afile = NULL;
31     extern int cacheDiskType;
32     afs_int32 code = 0;
33     int dummy;
34     AFS_STATCNT(osi_UFSOpen);
35     if (cacheDiskType != AFS_FCACHE_TYPE_UFS) {
36         osi_Panic("UFSOpen called for non-UFS cache\n");
37     }
38     if (!afs_osicred_initialized) {
39         /* valid for SunOS, Ultrix */
40         memset(&afs_osi_cred, 0, sizeof(afs_ucred_t));
41         crhold(&afs_osi_cred);  /* don't let it evaporate, since it is static */
42         afs_osicred_initialized = 1;
43     }
44     afile = osi_AllocSmallSpace(sizeof(struct osi_file));
45     setuerror(0);
46     AFS_GUNLOCK();
47     ip = (struct inode *)igetinode(afs_cacheVfsp, (dev_t) cacheDev.dev,
48                                    (ino_t) ainode->ufs, &dummy);
49     AFS_GLOCK();
50     if (getuerror()) {
51         osi_FreeSmallSpace(afile);
52         osi_Panic("UFSOpen: igetinode failed");
53     }
54     iunlock(ip);
55     afile->vnode = ITOV(ip);
56     afile->size = VTOI(afile->vnode)->i_size;
57     afile->offset = 0;
58     afile->proc = (int (*)())0;
59     return (void *)afile;
60 }
61
62 int
63 afs_osi_Stat(struct osi_file *afile, struct osi_stat *astat)
64 {
65     afs_int32 code;
66     struct vattr tvattr;
67     AFS_STATCNT(osi_Stat);
68     AFS_GUNLOCK();
69     code = VOP_GETATTR(afile->vnode, &tvattr, &afs_osi_cred, VSYNC);
70     AFS_GLOCK();
71     if (code == 0) {
72         astat->size = tvattr.va_size;
73         astat->mtime = tvattr.va_mtime.tv_sec;
74         astat->atime = tvattr.va_atime.tv_sec;
75     }
76     return code;
77 }
78
79 int
80 osi_UFSClose(struct osi_file *afile)
81 {
82     AFS_STATCNT(osi_Close);
83     if (afile->vnode) {
84         AFS_RELE(afile->vnode);
85     }
86
87     osi_FreeSmallSpace(afile);
88     return 0;
89 }
90
91 int
92 osi_UFSTruncate(struct osi_file *afile, afs_int32 asize)
93 {
94     afs_ucred_t *oldCred;
95     struct vattr tvattr;
96     afs_int32 code;
97     struct osi_stat tstat;
98     AFS_STATCNT(osi_Truncate);
99
100     /* This routine only shrinks files, and most systems
101      * have very slow truncates, even when the file is already
102      * small enough.  Check now and save some time.
103      */
104     code = afs_osi_Stat(afile, &tstat);
105     if (code || tstat.size <= asize)
106         return code;
107     VATTR_NULL(&tvattr);
108     /* note that this credential swapping stuff is only necessary because
109      * of ufs's references directly to u.u_cred instead of to
110      * credentials parameter.  Probably should fix ufs some day. */
111     oldCred = p_cred(u.u_procp);
112     set_p_cred(u.u_procp, &afs_osi_cred);
113     tvattr.va_size = asize;
114     AFS_GUNLOCK();
115     code = VOP_SETATTR(afile->vnode, &tvattr, &afs_osi_cred, 0);
116     AFS_GLOCK();
117     set_p_cred(u.u_procp, oldCred);     /* restore */
118     return code;
119 }
120
121 void
122 osi_DisableAtimes(struct vnode *avp)
123 {
124     struct inode *ip = VTOI(avp);
125     ip->i_flag &= ~IACC;
126 }
127
128
129 /* Generic read interface */
130 int
131 afs_osi_Read(struct osi_file *afile, int offset, void *aptr,
132              afs_int32 asize)
133 {
134     afs_ucred_t *oldCred;
135     long resid;
136     afs_int32 code;
137     afs_int32 cnt1 = 0;
138     AFS_STATCNT(osi_Read);
139
140     /**
141       * If the osi_file passed in is NULL, panic only if AFS is not shutting
142       * down. No point in crashing when we are already shutting down
143       */
144     if (!afile) {
145         if (afs_shuttingdown == AFS_RUNNING)
146             osi_Panic("osi_Read called with null param");
147         else
148             return -EIO;
149     }
150
151     if (offset != -1)
152         afile->offset = offset;
153   retry_IO:
154     AFS_GUNLOCK();
155     code =
156         gop_rdwr(UIO_READ, afile->vnode, (caddr_t) aptr, asize, afile->offset,
157                  AFS_UIOSYS, IO_UNIT, &resid);
158     AFS_GLOCK();
159     if (code == 0) {
160         code = asize - resid;
161         afile->offset += code;
162         osi_DisableAtimes(afile->vnode);
163     } else {
164         afs_Trace2(afs_iclSetp, CM_TRACE_READFAILED, ICL_TYPE_INT32,
165                    (afs_int32) resid, ICL_TYPE_INT32, code);
166         /*
167          * To handle periodic low-level EFAULT failures that we've seen with the
168          * Weitek chip; in all observed failed cases a second read succeeded.
169          */
170         if ((code == EFAULT) && (cnt1++ < 5)) {
171             afs_stats_cmperf.osiread_efaults++;
172             goto retry_IO;
173         }
174         setuerror(code);
175         if (code > 0) {
176             code = -code;
177         }
178     }
179     return code;
180 }
181
182 /* Generic write interface */
183 int
184 afs_osi_Write(struct osi_file *afile, afs_int32 offset, void *aptr,
185               afs_int32 asize)
186 {
187     afs_ucred_t *oldCred;
188     long resid;
189     afs_int32 code;
190     AFS_STATCNT(osi_Write);
191     if (!afile)
192         osi_Panic("afs_osi_Write called with null param");
193     if (offset != -1)
194         afile->offset = offset;
195     AFS_GUNLOCK();
196     code =
197         gop_rdwr(UIO_WRITE, afile->vnode, (caddr_t) aptr, asize,
198                  afile->offset, AFS_UIOSYS, IO_UNIT, &resid);
199     AFS_GLOCK();
200     if (code == 0) {
201         code = asize - resid;
202         afile->offset += code;
203     } else {
204         if (code == ENOSPC)
205             afs_warnuser
206                 ("\n\n\n*** Cache partition is FULL - Decrease cachesize!!! ***\n\n");
207         setuerror(code);
208         if (code > 0) {
209             code = -code;
210         }
211     }
212     if (afile->proc) {
213         (*afile->proc) (afile, code);
214     }
215     return code;
216 }
217
218
219 void
220 shutdown_osifile(void)
221 {
222     AFS_STATCNT(shutdown_osifile);
223     if (afs_cold_shutdown) {
224         afs_osicred_initialized = 0;
225     }
226 }