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