death to register
[openafs.git] / src / afs / FBSD / osi_vfsops.c
1 #include <afsconfig.h>
2 #include <afs/param.h>
3
4
5 #include <afs/sysincludes.h>    /* Standard vendor system headers */
6 #include <afsincludes.h>        /* Afs-based standard headers */
7 #include <afs/afs_stats.h>      /* statistics */
8 #include <sys/malloc.h>
9 #include <sys/namei.h>
10 #include <sys/conf.h>
11 #include <sys/module.h>
12 #include <sys/sysproto.h>
13 #include <sys/syscall.h>
14 #include <sys/sysent.h>
15
16 struct vcache *afs_globalVp = NULL;
17 struct mount *afs_globalVFS = NULL;
18 int afs_pbuf_freecnt = -1;
19
20 extern int Afs_xsetgroups();
21 extern int afs_xioctl();
22
23 static sy_call_t *old_handler;
24
25
26 int
27 afs_init(struct vfsconf *vfc)
28 {
29     if (sysent[AFS_SYSCALL].sy_call != nosys
30         && sysent[AFS_SYSCALL].sy_call != lkmnosys) {
31         printf("AFS_SYSCALL in use. aborting\n");
32         return EBUSY;
33     }
34     osi_Init();
35     afs_pbuf_freecnt = nswbuf / 2 + 1;
36 #if 0
37     sysent[SYS_setgroups].sy_call = Afs_xsetgroups;
38     sysent[SYS_ioctl].sy_call = afs_xioctl;
39 #endif
40     old_handler = sysent[AFS_SYSCALL].sy_call;
41     sysent[AFS_SYSCALL].sy_call = afs3_syscall;
42     sysent[AFS_SYSCALL].sy_narg = 5;
43     return 0;
44 }
45
46 int
47 afs_uninit(struct vfsconf *vfc)
48 {
49     if (afs_globalVFS)
50         return EBUSY;
51 #if 0
52     sysent[SYS_ioctl].sy_call = ioctl;
53     sysent[SYS_setgroups].sy_call = setgroups;
54 #endif
55     sysent[AFS_SYSCALL].sy_narg = 0;
56     sysent[AFS_SYSCALL].sy_call = old_handler;
57     return 0;
58 }
59
60 int
61 afs_start(struct mount *mp, int flags, struct thread *p)
62 {
63     return (0);                 /* nothing to do. ? */
64 }
65
66 int
67 #if defined(AFS_FBSD80_ENV)
68 afs_omount(struct mount *mp, char *path, caddr_t data)
69 #elif defined(AFS_FBSD53_ENV)
70 afs_omount(struct mount *mp, char *path, caddr_t data, struct thread *p)
71 #else
72 afs_omount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp,
73         struct thread *p)
74 #endif
75 {
76     /* ndp contains the mounted-from device.  Just ignore it.
77      * we also don't care about our thread struct. */
78     size_t size;
79
80     if (mp->mnt_flag & MNT_UPDATE)
81         return EINVAL;
82
83     AFS_GLOCK();
84     AFS_STATCNT(afs_mount);
85
86     if (afs_globalVFS) {        /* Don't allow remounts. */
87         AFS_GUNLOCK();
88         return EBUSY;
89     }
90
91     afs_globalVFS = mp;
92     mp->vfs_bsize = 8192;
93     vfs_getnewfsid(mp);
94 #ifdef AFS_FBSD70_ENV /* XXX 70? */
95     MNT_ILOCK(mp);
96     mp->mnt_flag &= ~MNT_LOCAL;
97     mp->mnt_kern_flag |= MNTK_MPSAFE; /* solid steel */
98 #endif
99     mp->mnt_stat.f_iosize = 8192;
100
101     if (path != NULL)
102         copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
103     else
104         bcopy("/afs", mp->mnt_stat.f_mntonname, size = 4);
105     memset(mp->mnt_stat.f_mntonname + size, 0, MNAMELEN - size);
106     memset(mp->mnt_stat.f_mntfromname, 0, MNAMELEN);
107     strcpy(mp->mnt_stat.f_mntfromname, "AFS");
108     /* null terminated string "AFS" will fit, just leave it be. */
109     strcpy(mp->mnt_stat.f_fstypename, "afs");
110 #ifdef AFS_FBSD70_ENV
111     MNT_IUNLOCK(mp);
112 #endif
113     AFS_GUNLOCK();
114 #ifdef AFS_FBSD80_ENV
115     afs_statfs(mp, &mp->mnt_stat);
116 #else
117     afs_statfs(mp, &mp->mnt_stat, p);
118 #endif
119
120     return 0;
121 }
122
123 #ifdef AFS_FBSD53_ENV
124 int
125 #ifdef AFS_FBSD80_ENV
126 afs_mount(struct mount *mp)
127 #else
128 afs_mount(struct mount *mp, struct thread *td)
129 #endif
130 {
131 #ifdef AFS_FBSD80_ENV
132     return afs_omount(mp, NULL, NULL);
133 #else
134     return afs_omount(mp, NULL, NULL, td);
135 #endif
136 }
137 #endif
138
139 #ifdef AFS_FBSD60_ENV
140 static int
141 #ifdef AFS_FBSD80_ENV
142 afs_cmount(struct mntarg *ma, void *data, int flags)
143 #else
144 afs_cmount(struct mntarg *ma, void *data, int flags, struct thread *td)
145 #endif
146 {
147     return kernel_mount(ma, flags);
148 }
149 #endif
150
151 int
152 #ifdef AFS_FBSD80_ENV
153 afs_unmount(struct mount *mp, int flags)
154 #else
155 afs_unmount(struct mount *mp, int flags, struct thread *p)
156 #endif
157 {
158     int error = 0;
159
160     /*
161      * Release any remaining vnodes on this mount point.
162      * The `1' means that we hold one extra reference on
163      * the root vnode (this is just a guess right now).
164      * This has to be done outside the global lock.
165      */
166 #if defined(AFS_FBSD80_ENV)
167     error = vflush(mp, 1, (flags & MNT_FORCE) ? FORCECLOSE : 0, curthread);
168 #elif defined(AFS_FBSD53_ENV)
169     error = vflush(mp, 1, (flags & MNT_FORCE) ? FORCECLOSE : 0, p);
170 #else
171     error = vflush(mp, 1, (flags & MNT_FORCE) ? FORCECLOSE : 0);
172 #endif
173     if (error)
174         goto out;
175     AFS_GLOCK();
176     AFS_STATCNT(afs_unmount);
177     afs_globalVFS = 0;
178     afs_shutdown();
179     AFS_GUNLOCK();
180
181 out:
182     return error;
183 }
184
185 int
186 #if defined(AFS_FBSD80_ENV)
187 afs_root(struct mount *mp, int flags, struct vnode **vpp)
188 #elif defined(AFS_FBSD60_ENV)
189 afs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td)
190 #elif defined(AFS_FBSD53_ENV)
191 afs_root(struct mount *mp, struct vnode **vpp, struct thread *td)
192 #else
193 afs_root(struct mount *mp, struct vnode **vpp)
194 #endif
195 {
196     int error;
197     struct vrequest treq;
198     struct vcache *tvp = 0;
199 #if !defined(AFS_FBSD53_ENV) || defined(AFS_FBSD80_ENV)
200     struct thread *td = curthread;
201 #endif
202     struct ucred *cr = osi_curcred();
203
204     AFS_GLOCK();
205     AFS_STATCNT(afs_root);
206     crhold(cr);
207     if (afs_globalVp && (afs_globalVp->f.states & CStatd)) {
208         tvp = afs_globalVp;
209         error = 0;
210     } else {
211 tryagain:
212         if (afs_globalVp) {
213             afs_PutVCache(afs_globalVp);
214             /* vrele() needed here or not? */
215             afs_globalVp = NULL;
216         }
217         if (!(error = afs_InitReq(&treq, cr)) && !(error = afs_CheckInit())) {
218             tvp = afs_GetVCache(&afs_rootFid, &treq, NULL, NULL);
219             /* we really want this to stay around */
220             if (tvp)
221                 afs_globalVp = tvp;
222             else
223                 error = ENOENT;
224         }
225     }
226     if (tvp) {
227         struct vnode *vp = AFSTOV(tvp);
228
229         ASSERT_VI_UNLOCKED(vp, "afs_root");
230         AFS_GUNLOCK();
231         /*
232          * I'm uncomfortable about this.  Shouldn't this happen at a
233          * higher level, and shouldn't we busy the top-level directory
234          * to prevent recycling?
235          */
236         error = vget(vp, LK_EXCLUSIVE | LK_RETRY, td);
237         vp->v_vflag |= VV_ROOT;
238         AFS_GLOCK();
239         if (error != 0)
240                 goto tryagain;
241
242         afs_globalVFS = mp;
243         *vpp = vp;
244     }
245
246     afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, tvp ? AFSTOV(tvp) : NULL,
247                ICL_TYPE_INT32, error);
248     AFS_GUNLOCK();
249     crfree(cr);
250     return error;
251 }
252
253 int
254 #ifdef AFS_FBSD80_ENV
255 afs_statfs(struct mount *mp, struct statfs *abp)
256 #else
257 afs_statfs(struct mount *mp, struct statfs *abp, struct thread *p)
258 #endif
259 {
260     AFS_GLOCK();
261     AFS_STATCNT(afs_statfs);
262
263     abp->f_bsize = mp->vfs_bsize;
264     abp->f_iosize = mp->vfs_bsize;
265
266     /* Fake a high number below to satisfy programs that use the statfs call
267      * to make sure that there's enough space in the device partition before
268      * storing something there.
269      */
270     abp->f_blocks = abp->f_bfree = abp->f_bavail = abp->f_files =
271         abp->f_ffree = 2000000;
272
273     abp->f_fsid.val[0] = mp->mnt_stat.f_fsid.val[0];
274     abp->f_fsid.val[1] = mp->mnt_stat.f_fsid.val[1];
275     if (abp != &mp->mnt_stat) {
276         abp->f_type = mp->mnt_vfc->vfc_typenum;
277         memcpy((caddr_t) & abp->f_mntonname[0],
278                (caddr_t) mp->mnt_stat.f_mntonname, MNAMELEN);
279         memcpy((caddr_t) & abp->f_mntfromname[0],
280                (caddr_t) mp->mnt_stat.f_mntfromname, MNAMELEN);
281     }
282
283     AFS_GUNLOCK();
284     return 0;
285 }
286
287 int
288 #if defined(AFS_FBSD80_ENV)
289 afs_sync(struct mount *mp, int waitfor)
290 #elif defined(AFS_FBSD60_ENV)
291 afs_sync(struct mount *mp, int waitfor, struct thread *td)
292 #else
293 afs_sync(struct mount *mp, int waitfor, struct ucred *cred, struct thread *p)
294 #endif
295 {
296     return 0;
297 }
298
299 #ifdef AFS_FBSD60_ENV
300 struct vfsops afs_vfsops = {
301         .vfs_init =             afs_init,
302         .vfs_mount =            afs_mount,
303         .vfs_cmount =           afs_cmount,
304         .vfs_root =             afs_root,
305         .vfs_statfs =           afs_statfs,
306         .vfs_sync =             afs_sync,
307         .vfs_uninit =           afs_uninit,
308         .vfs_unmount =          afs_unmount,
309         .vfs_sysctl =           vfs_stdsysctl,
310 };
311 #else
312 struct vfsops afs_vfsops = {
313 #ifdef AFS_FBSD53_ENV
314     afs_mount,
315 #endif
316     afs_omount,
317     afs_start,
318     afs_unmount,
319     afs_root,
320     vfs_stdquotactl,
321     afs_statfs,
322     afs_sync,
323     vfs_stdvget,
324     vfs_stdfhtovp,
325     vfs_stdcheckexp,
326     vfs_stdvptofh,
327     afs_init,
328     afs_uninit,
329     vfs_stdextattrctl,
330     vfs_stdsysctl,
331 };
332 #endif