Revert "osi_UFSOpen returns struct osi_file *"
[openafs.git] / src / afs / FBSD / 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
18
19 int afs_osicred_initialized = 0;
20 afs_ucred_t afs_osi_cred;
21 afs_lock_t afs_xosi;            /* lock is for tvattr */
22 extern struct osi_dev cacheDev;
23 extern struct mount *afs_cacheVfsp;
24
25
26 void *
27 osi_UFSOpen(afs_dcache_id_t *ainode)
28 {
29     struct osi_file *afile;
30     struct vnode *vp;
31     extern int cacheDiskType;
32     afs_int32 code;
33
34     AFS_STATCNT(osi_UFSOpen);
35     if (cacheDiskType != AFS_FCACHE_TYPE_UFS)
36         osi_Panic("UFSOpen called for non-UFS cache\n");
37     afile = (struct osi_file *)osi_AllocSmallSpace(sizeof(struct osi_file));
38     AFS_GUNLOCK();
39 #if defined(AFS_FBSD50_ENV)
40     code = VFS_VGET(afs_cacheVfsp, (ino_t) ainode->ufs, LK_EXCLUSIVE, &vp);
41 #else
42     code = VFS_VGET(afs_cacheVfsp, (ino_t) ainode->ufs, &vp);
43 #endif
44     AFS_GLOCK();
45     if (code == 0 && vp->v_type == VNON)
46         code = ENOENT;
47     if (code) {
48         osi_FreeSmallSpace(afile);
49         osi_Panic("UFSOpen: igetinode failed");
50     }
51 #if defined(AFS_FBSD80_ENV)
52     VOP_UNLOCK(vp, 0);
53 #elif defined(AFS_FBSD50_ENV)
54     VOP_UNLOCK(vp, 0, curthread);
55 #else
56     VOP_UNLOCK(vp, 0, curproc);
57 #endif
58     afile->vnode = vp;
59     afile->size = VTOI(vp)->i_size;
60     afile->offset = 0;
61     afile->proc = NULL;
62     return (void *)afile;
63 }
64
65 int
66 afs_osi_Stat(register struct osi_file *afile, register struct osi_stat *astat)
67 {
68     register afs_int32 code;
69     struct vattr tvattr;
70     AFS_STATCNT(osi_Stat);
71     ObtainWriteLock(&afs_xosi, 320);
72     AFS_GUNLOCK();
73 #if defined(AFS_FBSD80_ENV)
74     vn_lock(afile->vnode, LK_EXCLUSIVE | LK_RETRY);
75     code = VOP_GETATTR(afile->vnode, &tvattr, afs_osi_credp, curthread);
76     VOP_UNLOCK(afile->vnode, 0);
77 #elif defined(AFS_FBSD50_ENV)
78     vn_lock(afile->vnode, LK_EXCLUSIVE | LK_RETRY, curthread);
79     code = VOP_GETATTR(afile->vnode, &tvattr, afs_osi_credp, curthread);
80     VOP_UNLOCK(afile->vnode, LK_EXCLUSIVE, curthread);
81 #else
82     code = VOP_GETATTR(afile->vnode, &tvattr, afs_osi_credp, curproc);
83 #endif
84     AFS_GLOCK();
85     if (code == 0) {
86         astat->size = tvattr.va_size;
87         astat->mtime = tvattr.va_mtime.tv_sec;
88         astat->atime = tvattr.va_atime.tv_sec;
89     }
90     ReleaseWriteLock(&afs_xosi);
91     return code;
92 }
93
94 int
95 osi_UFSClose(register struct osi_file *afile)
96 {
97     AFS_STATCNT(osi_Close);
98     if (afile->vnode) {
99         AFS_RELE(afile->vnode);
100     }
101
102     osi_FreeSmallSpace(afile);
103     return 0;
104 }
105
106 int
107 osi_UFSTruncate(register struct osi_file *afile, afs_int32 asize)
108 {
109     struct vattr tvattr;
110     struct vnode *vp;
111     register afs_int32 code, glocked;
112     AFS_STATCNT(osi_Truncate);
113
114     ObtainWriteLock(&afs_xosi, 321);
115     vp = afile->vnode;
116     /*
117      * This routine only shrinks files, and most systems
118      * have very slow truncates, even when the file is already
119      * small enough.  Check now and save some time.
120      */
121     glocked = ISAFS_GLOCK();
122     if (glocked)
123       AFS_GUNLOCK();
124 #if defined(AFS_FBSD80_ENV)
125     vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
126     code = VOP_GETATTR(afile->vnode, &tvattr, afs_osi_credp, curthread);
127 #elif defined(AFS_FBSD50_ENV)
128     vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curthread);
129     code = VOP_GETATTR(afile->vnode, &tvattr, afs_osi_credp, curthread);
130 #else
131     vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc);
132     code = VOP_GETATTR(afile->vnode, &tvattr, afs_osi_credp, curproc);
133 #endif
134     if (code != 0 || tvattr.va_size <= asize)
135         goto out;
136
137     VATTR_NULL(&tvattr);
138     tvattr.va_size = asize;
139 #if defined(AFS_FBSD50_ENV)
140     code = VOP_SETATTR(vp, &tvattr, afs_osi_credp, curthread);
141 #else
142     code = VOP_SETATTR(vp, &tvattr, afs_osi_credp, curproc);
143 #endif
144
145 out:
146 #if defined(AFS_FBSD80_ENV)
147     VOP_UNLOCK(vp, 0);
148 #elif defined(AFS_FBSD50_ENV)
149     VOP_UNLOCK(vp, LK_EXCLUSIVE, curthread);
150 #else
151     VOP_UNLOCK(vp, LK_EXCLUSIVE, curproc);
152 #endif
153     if (glocked)
154       AFS_GLOCK();
155     ReleaseWriteLock(&afs_xosi);
156     return code;
157 }
158
159 void
160 osi_DisableAtimes(struct vnode *avp)
161 {
162     struct inode *ip = VTOI(avp);
163     ip->i_flag &= ~IN_ACCESS;
164 }
165
166
167 /* Generic read interface */
168 int
169 afs_osi_Read(register struct osi_file *afile, int offset, void *aptr,
170              afs_int32 asize)
171 {
172     unsigned int resid;
173     register afs_int32 code;
174     AFS_STATCNT(osi_Read);
175
176     /**
177       * If the osi_file passed in is NULL, panic only if AFS is not shutting
178       * down. No point in crashing when we are already shutting down
179       */
180     if (!afile) {
181         if (!afs_shuttingdown)
182             osi_Panic("osi_Read called with null param");
183         else
184             return EIO;
185     }
186
187     if (offset != -1)
188         afile->offset = offset;
189     AFS_GUNLOCK();
190     code =
191         gop_rdwr(UIO_READ, afile->vnode, (caddr_t) aptr, asize, afile->offset,
192                  AFS_UIOSYS, IO_UNIT, afs_osi_credp, &resid);
193     AFS_GLOCK();
194     if (code == 0) {
195         code = asize - resid;
196         afile->offset += code;
197         osi_DisableAtimes(afile->vnode);
198     } else {
199         afs_Trace2(afs_iclSetp, CM_TRACE_READFAILED, ICL_TYPE_INT32, resid,
200                    ICL_TYPE_INT32, code);
201         code = -1;
202     }
203     return code;
204 }
205
206 /* Generic write interface */
207 int
208 afs_osi_Write(register struct osi_file *afile, afs_int32 offset, void *aptr,
209               afs_int32 asize)
210 {
211     unsigned int resid;
212     register afs_int32 code;
213     AFS_STATCNT(osi_Write);
214     if (!afile)
215         osi_Panic("afs_osi_Write called with null param");
216     if (offset != -1)
217         afile->offset = offset;
218     {
219         AFS_GUNLOCK();
220         code =
221             gop_rdwr(UIO_WRITE, afile->vnode, (caddr_t) aptr, asize,
222                      afile->offset, AFS_UIOSYS, IO_UNIT, afs_osi_credp,
223                      &resid);
224         AFS_GLOCK();
225     }
226     if (code == 0) {
227         code = asize - resid;
228         afile->offset += code;
229     } else {
230         code = -1;
231     }
232     if (afile->proc) {
233         (*afile->proc) (afile, code);
234     }
235     return code;
236 }
237
238
239 /*  This work should be handled by physstrat in ca/machdep.c.
240     This routine written from the RT NFS port strategy routine.
241     It has been generalized a bit, but should still be pretty clear. */
242 int
243 afs_osi_MapStrategy(int (*aproc) (), register struct buf *bp)
244 {
245     afs_int32 returnCode;
246
247     AFS_STATCNT(osi_MapStrategy);
248     returnCode = (*aproc) (bp);
249
250     return returnCode;
251 }
252
253
254
255 void
256 shutdown_osifile(void)
257 {
258     AFS_STATCNT(shutdown_osifile);
259     if (afs_cold_shutdown) {
260         afs_osicred_initialized = 0;
261     }
262 }