1 /* Copyright (C) 1995, 1998 Transarc Corporation - All rights reserved. */
3 * (C) COPYRIGHT IBM CORPORATION 1987, 1988
4 * LICENSED MATERIALS - PROPERTY OF IBM
9 #include "../afs/param.h" /* Should be always first */
10 #include "../afs/sysincludes.h" /* Standard vendor system headers */
11 #include "../afs/afsincludes.h" /* Afs-based standard headers */
12 #include "../afs/afs_stats.h" /* statistics stuff */
13 #include <sys/types.h>
14 #include <kern/mach_param.h>
15 #include <sys/sysconfig.h>
16 #include <sys/systm.h>
17 #include <sys/resource.h>
18 #include <sys/errno.h>
20 #include <machine/machlimits.h>
23 struct vcache *afs_globalVp = 0;
24 struct mount *afs_globalVFS = 0;
26 static u_char afs_mntid;
28 udecl_simple_lock_data(, afsmntid_lock)
29 #define AFSMNTID_LOCK() usimple_lock(&afsmntid_lock)
30 #define AFSMNTID_UNLOCK() usimple_unlock(&afsmntid_lock)
31 #define AFSMNTID_LOCK_INIT() usimple_lock_init(&afsmntid_lock)
34 int mp_afs_mount(struct mount *afsp,char * path, caddr_t data,
35 struct nameidata *ndp)
40 struct mount *xmp, *getvfs();
44 AFS_STATCNT(afs_mount);
46 if (afs_globalVFS) { /* Don't allow remounts. */
52 afsp->vfs_bsize = 8192;
54 * Generate a unique afs mount i.d. ( see nfs_mount() ).
56 afsp->m_stat.f_fsid.val[0] = makedev(130, 0);
57 afsp->m_stat.f_fsid.val[1] = MOUNT_AFS;
63 tfsid.val[0] = makedev(130, afs_mntid);
64 tfsid.val[1] = MOUNT_AFS;
65 BM(AFSMNTID_UNLOCK());
67 while (xmp = getvfs(&tfsid)) {
68 UNMOUNT_READ_UNLOCK(xmp);
74 if (major(tfsid.val[0]) != 130) {
78 afsp->m_stat.f_fsid.val[0] = tfsid.val[0];
80 afsp->m_stat.f_mntonname = AFS_KALLOC(MNAMELEN);
81 afsp->m_stat.f_mntfromname = AFS_KALLOC(MNAMELEN);
82 if ( !afsp->m_stat.f_mntonname || !afsp->m_stat.f_mntfromname)
83 panic("malloc failure in afs_mount\n");
85 bzero(afsp->m_stat.f_mntonname, MNAMELEN);
86 bzero(afsp->m_stat.f_mntfromname, MNAMELEN);
87 AFS_COPYINSTR(path, (caddr_t)afsp->m_stat.f_mntonname, MNAMELEN, &size, code);
88 bcopy("AFS", afsp->m_stat.f_mntfromname, 4);
90 (void) mp_afs_statfs(afsp);
92 afs_vfsdev = afsp->m_stat.f_fsid.val[0];
94 #ifndef AFS_NONFSTRANS
95 /* Set up the xlator in case it wasn't done elsewhere */
104 int mp_afs_unmount (struct mount *afsp, int flag)
107 AFS_STATCNT(afs_unmount);
115 int mp_afs_start(struct mount *mp, int flags)
120 int mp_afs_root (struct mount *afsp, struct vnode **avpp)
122 register afs_int32 code = 0;
123 struct vrequest treq;
124 register struct vcache *tvp=0;
127 AFS_STATCNT(afs_root);
128 if (afs_globalVp && (afs_globalVp->states & CStatd)) {
131 if (!(code = afs_InitReq(&treq, u.u_cred)) &&
132 !(code = afs_CheckInit())) {
133 tvp = afs_GetVCache(&afs_rootFid, &treq, (afs_int32 *)0,
134 (struct vcache*)0, WRITE_LOCK);
135 /* we really want this to stay around */
144 VN_HOLD((struct vnode *)tvp);
145 VN_LOCK((struct vnode *)tvp);
146 tvp->v.v_flag |= VROOT; /* No-op on Ultrix 2.2 */
147 VN_UNLOCK((struct vnode *)tvp);
150 afs_globalVFS = afsp;
151 *avpp = (struct vnode *) tvp;
154 afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, *avpp,
155 ICL_TYPE_INT32, code);
161 mp_afs_quotactl(struct mount *mp, int cmd, uid_t uid, caddr_t arg)
166 int mp_afs_statfs(struct mount *afsp)
168 struct nstatfs *abp = &afsp->m_stat;
171 AFS_STATCNT(afs_statfs);
173 abp->f_type = MOUNT_AFS;
174 abp->f_bsize = afsp->vfs_bsize;
176 /* Fake a high number below to satisfy programs that use the statfs call
177 * to make sure that there's enough space in the device partition before
178 * storing something there.
180 abp->f_blocks = abp->f_bfree = abp->f_bavail = abp->f_files =
181 abp->f_ffree = 2000000;
184 abp->f_fsid.val[0] = afsp->m_stat.f_fsid.val[0];
185 abp->f_fsid.val[1] = afsp->m_stat.f_fsid.val[1];
192 int mp_afs_sync(struct mount *mp, int flags)
194 AFS_STATCNT(afs_sync);
199 int mp_afs_fhtovp(struct mount *afsp, struct fid *fidp, struct vnode **avcp)
201 struct vrequest treq;
205 AFS_STATCNT(afs_vget);
209 if ((code = afs_InitReq(&treq, u.u_cred)) == 0) {
210 code = afs_osi_vget((struct vcache**)avcp, fidp, &treq);
213 afs_Trace3(afs_iclSetp, CM_TRACE_VGET, ICL_TYPE_POINTER, *avcp,
214 ICL_TYPE_INT32, treq.uid, ICL_TYPE_FID, fidp);
216 code = afs_CheckCode(code, &treq, 42);
225 * afs_vptofh can return two flavors of NFS fid, depending on if submounts are
226 * allowed. The reason for this is that we can't guarantee that we found all
227 * the entry points any OS might use to get the fid for the NFS mountd.
228 * Hence we return a "magic" fid for all but /afs. If it goes through the
229 * translator code, it will get transformed into a SmallFid that we recognize.
230 * So, if submounts are disallowed, and an NFS client tries a submount, it will
231 * get a fid which we don't recognize and the mount will either fail or we
232 * will ignore subsequent requests for that mount.
234 * The Alpha fid is organized differently than for other platforms. Their
235 * intention was to have the data portion of the fid aligned on a 4 byte
236 * boundary. To do so, the fid is organized as:
240 * The len field is the length of the entire fid, from reserved through data.
241 * This length is used by fid_copy to include copying the reserved field.
242 * Alpha's zero the reserved field before handing us the fid, but they use
243 * it in fid_cmp. We use the reserved field to store the 16 bits of the Vnode.
245 * Note that the SmallFid only allows for 8 bits of the cell index and
246 * 16 bits of the vnode.
249 #define AFS_FIDDATASIZE 8
250 #define AFS_SIZEOFSMALLFID 12 /* full size of fid, including len field */
251 extern int afs_NFSRootOnly; /* 1 => only allow NFS mounts of /afs. */
252 int afs_fid_vnodeoverflow=0, afs_fid_uniqueoverflow=0;
254 int mp_afs_vptofh(struct vnode *avn, struct fid *fidp)
256 struct SmallFid Sfid;
258 register struct cell *tcell;
260 struct vcache *avc = (struct vcache *)avn;
263 AFS_STATCNT(afs_fid);
265 if (afs_shuttingdown) {
270 if (afs_NFSRootOnly && (avc == afs_globalVp)) rootvp = 1;
271 if (!afs_NFSRootOnly || rootvp) {
272 tcell = afs_GetCell(avc->fid.Cell, READ_LOCK);
273 Sfid.Volume = avc->fid.Fid.Volume;
274 fidp->fid_reserved = avc->fid.Fid.Vnode;
275 Sfid.CellAndUnique = ((tcell->cellIndex << 24) +
276 (avc->fid.Fid.Unique & 0xffffff));
277 afs_PutCell(tcell, READ_LOCK);
278 if (avc->fid.Fid.Vnode > 0xffff)
279 afs_fid_vnodeoverflow++;
280 if (avc->fid.Fid.Unique > 0xffffff)
281 afs_fid_uniqueoverflow++;
283 fidp->fid_reserved = AFS_XLATOR_MAGIC;
286 VN_HOLD((struct vnode *)avc);
290 /* Use the fid pointer passed to us. */
291 fidp->fid_len = AFS_SIZEOFSMALLFID;
292 if (afs_NFSRootOnly) {
294 bcopy((caddr_t)&Sfid, fidp->fid_data, AFS_FIDDATASIZE);
296 bcopy((caddr_t)addr, fidp->fid_data, AFS_FIDDATASIZE);
299 bcopy((caddr_t)&Sfid, fidp->fid_data, AFS_FIDDATASIZE);
306 int mp_Afs_init(void); /* vfs_init - defined below */
309 /* This is only called by vfs_mount when afs is going to be mounted as root.
310 * Since we don't support diskless clients we shouldn't come here.
313 int mp_afs_mountroot(struct mount *afsp, struct vnode **vp)
316 AFS_STATCNT(afs_mountroot);
323 /* It's called to setup swapping over the net for diskless clients; again
327 int mp_afs_swapvp(void)
330 AFS_STATCNT(afs_swapvp);
337 struct vfsops afs_vfsops = {
345 mp_afs_fhtovp, /* afs_vget */
354 * System Call Entry Points
356 #define NULL_FUNC (int (*)(int))0
358 int (*afs_syscall_func)() = NULL_FUNC;
359 int (*afs_xsetgroups_func)() = NULL_FUNC;
360 int (*afs_xioctl_func)() = NULL_FUNC;
362 afssyscall(p, args, retval)
371 func = afs_syscall_func;
372 if (func == NULL_FUNC) {
373 code = nosys(p, args, retval);
375 code = (*func)(p, args, retval);
381 afsxsetgroups(p, args, retval)
390 func = afs_xsetgroups_func;
391 if (func == NULL_FUNC) {
392 code = nosys(p, args, retval);
394 code = (*func)(p, args, retval);
400 afsxioctl(p, args, retval)
409 func = afs_xioctl_func;
410 if (func == NULL_FUNC) {
411 code = nosys(p, args, retval);
413 code = (*func)(p, args, retval);
421 * VFS initialization and unload
430 cfg_subsys_attr_t afs_attributes[] = {
431 {"", 0, 0, 0, 0, 0, 0} /* must be the last element */
434 afs_configure(cfg_op_t op, caddr_t indata, size_t indata_size, caddr_t outdata, size_t outdata_size)
436 cfg_attr_t *attributes;
442 case CFG_OP_CONFIGURE:
444 * The indata parameter is a list of attributes to be configured, and
445 * indata_size is the count of attributes.
447 if ((ret = vfssw_add_fsname(MOUNT_AFS, &afs_vfsops, "afs")) != 0)
450 case CFG_OP_UNCONFIGURE:
451 if ((ret = afs_unconfig()) != 0)
462 int mp_Afs_init(void)
464 extern int Afs_xsetgroups(), afs_xioctl(), afs3_syscall();
467 sysent[AFS_SYSCALL].sy_call = afs3_syscall;
468 sysent[AFS_SYSCALL].sy_parallel = 0;
469 sysent[AFS_SYSCALL].sy_narg = 6;
470 sysent[SYS_setgroups].sy_call = Afs_xsetgroups;
471 afs_xioctl_func = afsxioctl;
472 afs_xsetgroups_func = afsxsetgroups;
473 afs_syscall_func = afssyscall;