154947Sheideman /*
269363Spendry * Copyright (c) 1992, 1993, 1995
363248Sbostic * The Regents of the University of California. All rights reserved.
454947Sheideman *
554947Sheideman * This code is derived from software donated to Berkeley by
654959Sheideman * the UCLA Ficus project.
754947Sheideman *
854947Sheideman * %sccs.include.redist.c%
954947Sheideman *
10*69446Smckusick * @(#)umap_vfsops.c 8.8 (Berkeley) 05/14/95
1154947Sheideman *
1254959Sheideman * @(#)null_vfsops.c 1.5 (Berkeley) 7/10/92
1354947Sheideman */
1454947Sheideman
1554947Sheideman /*
1654959Sheideman * Umap Layer
1755053Spendry * (See mount_umap(8) for a description of this layer.)
1854947Sheideman */
1954947Sheideman
2054947Sheideman #include <sys/param.h>
2154947Sheideman #include <sys/systm.h>
22*69446Smckusick #include <sys/proc.h>
2354947Sheideman #include <sys/time.h>
2454947Sheideman #include <sys/types.h>
2554947Sheideman #include <sys/vnode.h>
2654947Sheideman #include <sys/mount.h>
2754947Sheideman #include <sys/namei.h>
2854947Sheideman #include <sys/malloc.h>
2955053Spendry #include <miscfs/umapfs/umap.h>
3054947Sheideman
3154947Sheideman /*
3254947Sheideman * Mount umap layer
3354947Sheideman */
3454947Sheideman int
umapfs_mount(mp,path,data,ndp,p)3554947Sheideman umapfs_mount(mp, path, data, ndp, p)
3654947Sheideman struct mount *mp;
3754947Sheideman char *path;
3854947Sheideman caddr_t data;
3954947Sheideman struct nameidata *ndp;
4054947Sheideman struct proc *p;
4154947Sheideman {
4254947Sheideman struct umap_args args;
4354947Sheideman struct vnode *lowerrootvp, *vp;
4454947Sheideman struct vnode *umapm_rootvp;
4554947Sheideman struct umap_mount *amp;
4654947Sheideman u_int size;
4765726Sbostic int error;
4854947Sheideman
4954947Sheideman #ifdef UMAPFS_DIAGNOSTIC
5054947Sheideman printf("umapfs_mount(mp = %x)\n", mp);
5154947Sheideman #endif
5254947Sheideman
5354947Sheideman /*
5454947Sheideman * Update is a no-op
5554947Sheideman */
5654947Sheideman if (mp->mnt_flag & MNT_UPDATE) {
5754947Sheideman return (EOPNOTSUPP);
5865726Sbostic /* return (VFS_MOUNT(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, path, data, ndp, p));*/
5954947Sheideman }
6054947Sheideman
6154947Sheideman /*
6254947Sheideman * Get argument
6354947Sheideman */
6454947Sheideman if (error = copyin(data, (caddr_t)&args, sizeof(struct umap_args)))
6554947Sheideman return (error);
6654947Sheideman
6754947Sheideman /*
6854959Sheideman * Find lower node
6954947Sheideman */
7054947Sheideman NDINIT(ndp, LOOKUP, FOLLOW|WANTPARENT|LOCKLEAF,
7154947Sheideman UIO_USERSPACE, args.target, p);
7254947Sheideman if (error = namei(ndp))
7354947Sheideman return (error);
7454947Sheideman
7554947Sheideman /*
7654959Sheideman * Sanity check on lower vnode
7754947Sheideman */
7854947Sheideman lowerrootvp = ndp->ni_vp;
7954947Sheideman #ifdef UMAPFS_DIAGNOSTIC
8054947Sheideman printf("vp = %x, check for VDIR...\n", lowerrootvp);
8154947Sheideman #endif
8254947Sheideman vrele(ndp->ni_dvp);
8354947Sheideman ndp->ni_dvp = 0;
8454947Sheideman
8554947Sheideman if (lowerrootvp->v_type != VDIR) {
8654947Sheideman vput(lowerrootvp);
8754947Sheideman return (EINVAL);
8854947Sheideman }
8954947Sheideman
9054947Sheideman #ifdef UMAPFS_DIAGNOSTIC
9154947Sheideman printf("mp = %x\n", mp);
9254947Sheideman #endif
9354947Sheideman
9454947Sheideman amp = (struct umap_mount *) malloc(sizeof(struct umap_mount),
9554947Sheideman M_UFSMNT, M_WAITOK); /* XXX */
9654947Sheideman
9754947Sheideman /*
9854959Sheideman * Save reference to underlying FS
9954947Sheideman */
10054947Sheideman amp->umapm_vfs = lowerrootvp->v_mount;
10154947Sheideman
10254947Sheideman /*
10354947Sheideman * Now copy in the number of entries and maps for umap mapping.
10454947Sheideman */
10554947Sheideman amp->info_nentries = args.nentries;
10654947Sheideman amp->info_gnentries = args.gnentries;
10754947Sheideman error = copyin(args.mapdata, (caddr_t)amp->info_mapdata,
10865726Sbostic 2*sizeof(u_long)*args.nentries);
10965726Sbostic if (error)
11065726Sbostic return (error);
11154959Sheideman
11254959Sheideman #ifdef UMAP_DIAGNOSTIC
11354947Sheideman printf("umap_mount:nentries %d\n",args.nentries);
11454959Sheideman for (i = 0; i < args.nentries; i++)
11554947Sheideman printf(" %d maps to %d\n", amp->info_mapdata[i][0],
11654947Sheideman amp->info_mapdata[i][1]);
11754959Sheideman #endif
11854947Sheideman
11954947Sheideman error = copyin(args.gmapdata, (caddr_t)amp->info_gmapdata,
12065726Sbostic 2*sizeof(u_long)*args.nentries);
12165726Sbostic if (error)
12265726Sbostic return (error);
12354959Sheideman
12454959Sheideman #ifdef UMAP_DIAGNOSTIC
12554947Sheideman printf("umap_mount:gnentries %d\n",args.gnentries);
12654959Sheideman for (i = 0; i < args.gnentries; i++)
12754947Sheideman printf(" group %d maps to %d\n",
12854947Sheideman amp->info_gmapdata[i][0],
12954947Sheideman amp->info_gmapdata[i][1]);
13054959Sheideman #endif
13154947Sheideman
13254947Sheideman
13354947Sheideman /*
13454947Sheideman * Save reference. Each mount also holds
13554947Sheideman * a reference on the root vnode.
13654947Sheideman */
13754947Sheideman error = umap_node_create(mp, lowerrootvp, &vp);
13854947Sheideman /*
13954959Sheideman * Unlock the node (either the lower or the alias)
14054947Sheideman */
141*69446Smckusick VOP_UNLOCK(vp, 0, p);
14254947Sheideman /*
14354947Sheideman * Make sure the node alias worked
14454947Sheideman */
14554947Sheideman if (error) {
14654947Sheideman vrele(lowerrootvp);
14754947Sheideman free(amp, M_UFSMNT); /* XXX */
14854947Sheideman return (error);
14954947Sheideman }
15054947Sheideman
15154947Sheideman /*
15254947Sheideman * Keep a held reference to the root vnode.
15354947Sheideman * It is vrele'd in umapfs_unmount.
15454947Sheideman */
15554947Sheideman umapm_rootvp = vp;
15654947Sheideman umapm_rootvp->v_flag |= VROOT;
15754947Sheideman amp->umapm_rootvp = umapm_rootvp;
15854947Sheideman if (UMAPVPTOLOWERVP(umapm_rootvp)->v_mount->mnt_flag & MNT_LOCAL)
15954947Sheideman mp->mnt_flag |= MNT_LOCAL;
16054947Sheideman mp->mnt_data = (qaddr_t) amp;
16168624Smckusick vfs_getnewfsid(mp);
16254947Sheideman
16354947Sheideman (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
16454947Sheideman bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
16554947Sheideman (void) copyinstr(args.target, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
16654947Sheideman &size);
16754947Sheideman bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
16854947Sheideman #ifdef UMAPFS_DIAGNOSTIC
16954959Sheideman printf("umapfs_mount: lower %s, alias at %s\n",
17054947Sheideman mp->mnt_stat.f_mntfromname, mp->mnt_stat.f_mntonname);
17154947Sheideman #endif
17254947Sheideman return (0);
17354947Sheideman }
17454947Sheideman
17554947Sheideman /*
17654947Sheideman * VFS start. Nothing needed here - the start routine
17754947Sheideman * on the underlying filesystem will have been called
17854947Sheideman * when that filesystem was mounted.
17954947Sheideman */
18054947Sheideman int
umapfs_start(mp,flags,p)18154947Sheideman umapfs_start(mp, flags, p)
18254947Sheideman struct mount *mp;
18354947Sheideman int flags;
18454947Sheideman struct proc *p;
18554947Sheideman {
18654947Sheideman return (0);
18765726Sbostic /* return (VFS_START(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, flags, p)); */
18854947Sheideman }
18954947Sheideman
19054947Sheideman /*
19154947Sheideman * Free reference to umap layer
19254947Sheideman */
19354947Sheideman int
umapfs_unmount(mp,mntflags,p)19454947Sheideman umapfs_unmount(mp, mntflags, p)
19554947Sheideman struct mount *mp;
19654947Sheideman int mntflags;
19754947Sheideman struct proc *p;
19854947Sheideman {
19954947Sheideman struct vnode *umapm_rootvp = MOUNTTOUMAPMOUNT(mp)->umapm_rootvp;
20054947Sheideman int error;
20154947Sheideman int flags = 0;
20254947Sheideman
20354947Sheideman #ifdef UMAPFS_DIAGNOSTIC
20454947Sheideman printf("umapfs_unmount(mp = %x)\n", mp);
20554947Sheideman #endif
20654947Sheideman
20769340Smckusick if (mntflags & MNT_FORCE)
20854947Sheideman flags |= FORCECLOSE;
20954947Sheideman
21054947Sheideman /*
21154947Sheideman * Clear out buffer cache. I don't think we
21254947Sheideman * ever get anything cached at this level at the
21354947Sheideman * moment, but who knows...
21454947Sheideman */
21555031Smckusick #ifdef notyet
21654947Sheideman mntflushbuf(mp, 0);
21754947Sheideman if (mntinvalbuf(mp, 1))
21854947Sheideman return (EBUSY);
21954947Sheideman #endif
22054947Sheideman if (umapm_rootvp->v_usecount > 1)
22154947Sheideman return (EBUSY);
22254947Sheideman if (error = vflush(mp, umapm_rootvp, flags))
22354947Sheideman return (error);
22454947Sheideman
22554947Sheideman #ifdef UMAPFS_DIAGNOSTIC
22654959Sheideman vprint("alias root of lower", umapm_rootvp);
22754947Sheideman #endif
22854947Sheideman /*
22954947Sheideman * Release reference on underlying root vnode
23054947Sheideman */
23154947Sheideman vrele(umapm_rootvp);
23254947Sheideman /*
23354947Sheideman * And blow it away for future re-use
23454947Sheideman */
23569363Spendry vgone(umapm_rootvp);
23654947Sheideman /*
23754947Sheideman * Finally, throw away the umap_mount structure
23854947Sheideman */
23954947Sheideman free(mp->mnt_data, M_UFSMNT); /* XXX */
24054947Sheideman mp->mnt_data = 0;
24165726Sbostic return (0);
24254947Sheideman }
24354947Sheideman
24454947Sheideman int
umapfs_root(mp,vpp)24554947Sheideman umapfs_root(mp, vpp)
24654947Sheideman struct mount *mp;
24754947Sheideman struct vnode **vpp;
24854947Sheideman {
249*69446Smckusick struct proc *p = curproc; /* XXX */
25054947Sheideman struct vnode *vp;
25154947Sheideman
25254947Sheideman #ifdef UMAPFS_DIAGNOSTIC
25354947Sheideman printf("umapfs_root(mp = %x, vp = %x->%x)\n", mp,
25454947Sheideman MOUNTTOUMAPMOUNT(mp)->umapm_rootvp,
25554947Sheideman UMAPVPTOLOWERVP(MOUNTTOUMAPMOUNT(mp)->umapm_rootvp)
25654947Sheideman );
25754947Sheideman #endif
25854947Sheideman
25954947Sheideman /*
26054947Sheideman * Return locked reference to root.
26154947Sheideman */
26254947Sheideman vp = MOUNTTOUMAPMOUNT(mp)->umapm_rootvp;
26354947Sheideman VREF(vp);
264*69446Smckusick vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
26554947Sheideman *vpp = vp;
26665726Sbostic return (0);
26754947Sheideman }
26854947Sheideman
26954947Sheideman int
umapfs_quotactl(mp,cmd,uid,arg,p)27054947Sheideman umapfs_quotactl(mp, cmd, uid, arg, p)
27154947Sheideman struct mount *mp;
27254947Sheideman int cmd;
27354947Sheideman uid_t uid;
27454947Sheideman caddr_t arg;
27554947Sheideman struct proc *p;
27654947Sheideman {
27765726Sbostic return (VFS_QUOTACTL(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, cmd, uid, arg, p));
27854947Sheideman }
27954947Sheideman
28054947Sheideman int
umapfs_statfs(mp,sbp,p)28154947Sheideman umapfs_statfs(mp, sbp, p)
28254947Sheideman struct mount *mp;
28354947Sheideman struct statfs *sbp;
28454947Sheideman struct proc *p;
28554947Sheideman {
28654947Sheideman int error;
28754947Sheideman struct statfs mstat;
28854947Sheideman
28954947Sheideman #ifdef UMAPFS_DIAGNOSTIC
29054947Sheideman printf("umapfs_statfs(mp = %x, vp = %x->%x)\n", mp,
29154947Sheideman MOUNTTOUMAPMOUNT(mp)->umapm_rootvp,
29254947Sheideman UMAPVPTOLOWERVP(MOUNTTOUMAPMOUNT(mp)->umapm_rootvp)
29354947Sheideman );
29454947Sheideman #endif
29554947Sheideman
29654947Sheideman bzero(&mstat, sizeof(mstat));
29754947Sheideman
29854947Sheideman error = VFS_STATFS(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, &mstat, p);
29954947Sheideman if (error)
30054947Sheideman return (error);
30154947Sheideman
30254947Sheideman /* now copy across the "interesting" information and fake the rest */
30354947Sheideman sbp->f_type = mstat.f_type;
30454947Sheideman sbp->f_flags = mstat.f_flags;
30554947Sheideman sbp->f_bsize = mstat.f_bsize;
30654947Sheideman sbp->f_iosize = mstat.f_iosize;
30754947Sheideman sbp->f_blocks = mstat.f_blocks;
30854947Sheideman sbp->f_bfree = mstat.f_bfree;
30954947Sheideman sbp->f_bavail = mstat.f_bavail;
31054947Sheideman sbp->f_files = mstat.f_files;
31154947Sheideman sbp->f_ffree = mstat.f_ffree;
31254947Sheideman if (sbp != &mp->mnt_stat) {
31354947Sheideman bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid));
31454947Sheideman bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
31554947Sheideman bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
31654947Sheideman }
31754947Sheideman return (0);
31854947Sheideman }
31954947Sheideman
32054947Sheideman int
umapfs_sync(mp,waitfor,cred,p)32154947Sheideman umapfs_sync(mp, waitfor, cred, p)
32254947Sheideman struct mount *mp;
32354947Sheideman int waitfor;
32454947Sheideman struct ucred *cred;
32554947Sheideman struct proc *p;
32654947Sheideman {
32754947Sheideman /*
32854947Sheideman * XXX - Assumes no data cached at umap layer.
32954947Sheideman */
33054947Sheideman return (0);
33154947Sheideman }
33254947Sheideman
33354947Sheideman int
umapfs_vget(mp,ino,vpp)33454947Sheideman umapfs_vget(mp, ino, vpp)
33554947Sheideman struct mount *mp;
33654947Sheideman ino_t ino;
33754947Sheideman struct vnode **vpp;
33854947Sheideman {
33954947Sheideman
34065726Sbostic return (VFS_VGET(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, ino, vpp));
34154947Sheideman }
34254947Sheideman
34354947Sheideman int
umapfs_fhtovp(mp,fidp,nam,vpp,exflagsp,credanonp)34454947Sheideman umapfs_fhtovp(mp, fidp, nam, vpp, exflagsp, credanonp)
34554947Sheideman struct mount *mp;
34654947Sheideman struct fid *fidp;
34754947Sheideman struct mbuf *nam;
34854947Sheideman struct vnode **vpp;
34954947Sheideman int *exflagsp;
35054947Sheideman struct ucred**credanonp;
35154947Sheideman {
35254947Sheideman
35365726Sbostic return (VFS_FHTOVP(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, fidp, nam, vpp, exflagsp,credanonp));
35454947Sheideman }
35554947Sheideman
35654947Sheideman int
umapfs_vptofh(vp,fhp)35754947Sheideman umapfs_vptofh(vp, fhp)
35854947Sheideman struct vnode *vp;
35954947Sheideman struct fid *fhp;
36054947Sheideman {
36165726Sbostic return (VFS_VPTOFH(UMAPVPTOLOWERVP(vp), fhp));
36254947Sheideman }
36354947Sheideman
36468624Smckusick int umapfs_init __P((struct vfsconf *));
36568624Smckusick #define umapfs_sysctl ((int (*) __P((int *, u_int, void *, size_t *, void *, \
36668624Smckusick size_t, struct proc *)))eopnotsupp)
36754947Sheideman
36854947Sheideman struct vfsops umap_vfsops = {
36954947Sheideman umapfs_mount,
37054947Sheideman umapfs_start,
37154947Sheideman umapfs_unmount,
37254947Sheideman umapfs_root,
37354947Sheideman umapfs_quotactl,
37454947Sheideman umapfs_statfs,
37554947Sheideman umapfs_sync,
37654947Sheideman umapfs_vget,
37754947Sheideman umapfs_fhtovp,
37854947Sheideman umapfs_vptofh,
37954947Sheideman umapfs_init,
38068624Smckusick umapfs_sysctl,
38154947Sheideman };
382