154947Sheideman /* 254947Sheideman * Copyright (c) 1992 The Regents of the University of California 354947Sheideman * Copyright (c) 1990, 1992 Jan-Simon Pendry 454947Sheideman * All rights reserved. 554947Sheideman * 654947Sheideman * This code is derived from software donated to Berkeley by 7*54959Sheideman * the UCLA Ficus project. 854947Sheideman * 954947Sheideman * %sccs.include.redist.c% 1054947Sheideman * 11*54959Sheideman * @(#)umap_vfsops.c 1.2 (Berkeley) 07/11/92 1254947Sheideman * 13*54959Sheideman * @(#)null_vfsops.c 1.5 (Berkeley) 7/10/92 1454947Sheideman */ 1554947Sheideman 1654947Sheideman /* 17*54959Sheideman * Umap Layer 18*54959Sheideman * (See mount_umap(8) for a descritpion of this layer.) 1954947Sheideman */ 2054947Sheideman 2154947Sheideman #include <sys/param.h> 2254947Sheideman #include <sys/systm.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> 2954947Sheideman #include <umapfs/umap.h> 3054947Sheideman 3154947Sheideman /* 3254947Sheideman * Mount umap layer 3354947Sheideman */ 3454947Sheideman int 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 int i; 4354947Sheideman int error = 0; 4454947Sheideman struct umap_args args; 4554947Sheideman struct vnode *lowerrootvp, *vp; 4654947Sheideman struct vnode *umapm_rootvp; 4754947Sheideman struct umap_mount *amp; 4854947Sheideman u_int size; 4954947Sheideman 5054947Sheideman #ifdef UMAPFS_DIAGNOSTIC 5154947Sheideman printf("umapfs_mount(mp = %x)\n", mp); 5254947Sheideman #endif 5354947Sheideman 5454947Sheideman /* 5554947Sheideman * Update is a no-op 5654947Sheideman */ 5754947Sheideman if (mp->mnt_flag & MNT_UPDATE) { 5854947Sheideman return (EOPNOTSUPP); 5954947Sheideman /* return VFS_MOUNT(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, path, data, ndp, p);*/ 6054947Sheideman } 6154947Sheideman 6254947Sheideman /* 6354947Sheideman * Get argument 6454947Sheideman */ 6554947Sheideman if (error = copyin(data, (caddr_t)&args, sizeof(struct umap_args))) 6654947Sheideman return (error); 6754947Sheideman 6854947Sheideman /* 69*54959Sheideman * Find lower node 7054947Sheideman */ 7154947Sheideman NDINIT(ndp, LOOKUP, FOLLOW|WANTPARENT|LOCKLEAF, 7254947Sheideman UIO_USERSPACE, args.target, p); 7354947Sheideman if (error = namei(ndp)) 7454947Sheideman return (error); 7554947Sheideman 7654947Sheideman /* 77*54959Sheideman * Sanity check on lower vnode 7854947Sheideman */ 7954947Sheideman lowerrootvp = ndp->ni_vp; 8054947Sheideman #ifdef UMAPFS_DIAGNOSTIC 8154947Sheideman printf("vp = %x, check for VDIR...\n", lowerrootvp); 8254947Sheideman #endif 8354947Sheideman vrele(ndp->ni_dvp); 8454947Sheideman ndp->ni_dvp = 0; 8554947Sheideman 8654947Sheideman if (lowerrootvp->v_type != VDIR) { 8754947Sheideman vput(lowerrootvp); 8854947Sheideman return (EINVAL); 8954947Sheideman } 9054947Sheideman 9154947Sheideman #ifdef UMAPFS_DIAGNOSTIC 9254947Sheideman printf("mp = %x\n", mp); 9354947Sheideman #endif 9454947Sheideman 9554947Sheideman amp = (struct umap_mount *) malloc(sizeof(struct umap_mount), 9654947Sheideman M_UFSMNT, M_WAITOK); /* XXX */ 9754947Sheideman 9854947Sheideman /* 99*54959Sheideman * Save reference to underlying FS 10054947Sheideman */ 10154947Sheideman amp->umapm_vfs = lowerrootvp->v_mount; 10254947Sheideman 10354947Sheideman /* 10454947Sheideman * Now copy in the number of entries and maps for umap mapping. 10554947Sheideman */ 10654947Sheideman amp->info_nentries = args.nentries; 10754947Sheideman amp->info_gnentries = args.gnentries; 10854947Sheideman error = copyin(args.mapdata, (caddr_t)amp->info_mapdata, 109*54959Sheideman 2*sizeof(int)*args.nentries); 11054947Sheideman if (error) return (error); 111*54959Sheideman 112*54959Sheideman #ifdef UMAP_DIAGNOSTIC 11354947Sheideman printf("umap_mount:nentries %d\n",args.nentries); 114*54959Sheideman 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]); 117*54959Sheideman #endif 11854947Sheideman 11954947Sheideman error = copyin(args.gmapdata, (caddr_t)amp->info_gmapdata, 120*54959Sheideman 2*sizeof(int)*args.nentries); 12154947Sheideman if (error) return (error); 122*54959Sheideman 123*54959Sheideman #ifdef UMAP_DIAGNOSTIC 12454947Sheideman printf("umap_mount:gnentries %d\n",args.gnentries); 125*54959Sheideman for (i = 0; i < args.gnentries; i++) 12654947Sheideman printf(" group %d maps to %d\n", 12754947Sheideman amp->info_gmapdata[i][0], 12854947Sheideman amp->info_gmapdata[i][1]); 129*54959Sheideman #endif 13054947Sheideman 13154947Sheideman 13254947Sheideman /* 13354947Sheideman * Save reference. Each mount also holds 13454947Sheideman * a reference on the root vnode. 13554947Sheideman */ 13654947Sheideman error = umap_node_create(mp, lowerrootvp, &vp); 13754947Sheideman /* 138*54959Sheideman * Unlock the node (either the lower or the alias) 13954947Sheideman */ 14054947Sheideman VOP_UNLOCK(vp); 14154947Sheideman /* 14254947Sheideman * Make sure the node alias worked 14354947Sheideman */ 14454947Sheideman if (error) { 14554947Sheideman vrele(lowerrootvp); 14654947Sheideman free(amp, M_UFSMNT); /* XXX */ 14754947Sheideman return (error); 14854947Sheideman } 14954947Sheideman 15054947Sheideman /* 15154947Sheideman * Keep a held reference to the root vnode. 15254947Sheideman * It is vrele'd in umapfs_unmount. 15354947Sheideman */ 15454947Sheideman umapm_rootvp = vp; 15554947Sheideman umapm_rootvp->v_flag |= VROOT; 15654947Sheideman amp->umapm_rootvp = umapm_rootvp; 15754947Sheideman if (UMAPVPTOLOWERVP(umapm_rootvp)->v_mount->mnt_flag & MNT_LOCAL) 15854947Sheideman mp->mnt_flag |= MNT_LOCAL; 15954947Sheideman mp->mnt_data = (qaddr_t) amp; 16054947Sheideman getnewfsid(mp, MOUNT_LOFS); 16154947Sheideman 16254947Sheideman (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); 16354947Sheideman bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); 16454947Sheideman (void) copyinstr(args.target, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, 16554947Sheideman &size); 16654947Sheideman bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 16754947Sheideman #ifdef UMAPFS_DIAGNOSTIC 168*54959Sheideman printf("umapfs_mount: lower %s, alias at %s\n", 16954947Sheideman mp->mnt_stat.f_mntfromname, mp->mnt_stat.f_mntonname); 17054947Sheideman #endif 17154947Sheideman return (0); 17254947Sheideman } 17354947Sheideman 17454947Sheideman /* 17554947Sheideman * VFS start. Nothing needed here - the start routine 17654947Sheideman * on the underlying filesystem will have been called 17754947Sheideman * when that filesystem was mounted. 17854947Sheideman */ 17954947Sheideman int 18054947Sheideman umapfs_start(mp, flags, p) 18154947Sheideman struct mount *mp; 18254947Sheideman int flags; 18354947Sheideman struct proc *p; 18454947Sheideman { 18554947Sheideman return (0); 18654947Sheideman /* return VFS_START(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, flags, p); */ 18754947Sheideman } 18854947Sheideman 18954947Sheideman /* 19054947Sheideman * Free reference to umap layer 19154947Sheideman */ 19254947Sheideman int 19354947Sheideman umapfs_unmount(mp, mntflags, p) 19454947Sheideman struct mount *mp; 19554947Sheideman int mntflags; 19654947Sheideman struct proc *p; 19754947Sheideman { 19854947Sheideman struct vnode *umapm_rootvp = MOUNTTOUMAPMOUNT(mp)->umapm_rootvp; 19954947Sheideman int error; 20054947Sheideman int flags = 0; 20154947Sheideman extern int doforce; 20254947Sheideman 20354947Sheideman #ifdef UMAPFS_DIAGNOSTIC 20454947Sheideman printf("umapfs_unmount(mp = %x)\n", mp); 20554947Sheideman #endif 20654947Sheideman 20754947Sheideman if (mntflags & MNT_FORCE) { 20854947Sheideman /* lofs can never be rootfs so don't check for it */ 20954947Sheideman if (!doforce) 21054947Sheideman return (EINVAL); 21154947Sheideman flags |= FORCECLOSE; 21254947Sheideman } 21354947Sheideman 21454947Sheideman /* 21554947Sheideman * Clear out buffer cache. I don't think we 21654947Sheideman * ever get anything cached at this level at the 21754947Sheideman * moment, but who knows... 21854947Sheideman */ 21954947Sheideman #if 0 22054947Sheideman mntflushbuf(mp, 0); 22154947Sheideman if (mntinvalbuf(mp, 1)) 22254947Sheideman return (EBUSY); 22354947Sheideman #endif 22454947Sheideman if (umapm_rootvp->v_usecount > 1) 22554947Sheideman return (EBUSY); 22654947Sheideman if (error = vflush(mp, umapm_rootvp, flags)) 22754947Sheideman return (error); 22854947Sheideman 22954947Sheideman #ifdef UMAPFS_DIAGNOSTIC 230*54959Sheideman vprint("alias root of lower", umapm_rootvp); 23154947Sheideman #endif 23254947Sheideman /* 23354947Sheideman * Release reference on underlying root vnode 23454947Sheideman */ 23554947Sheideman vrele(umapm_rootvp); 23654947Sheideman /* 23754947Sheideman * And blow it away for future re-use 23854947Sheideman */ 23954947Sheideman vgone(umapm_rootvp); 24054947Sheideman /* 24154947Sheideman * Finally, throw away the umap_mount structure 24254947Sheideman */ 24354947Sheideman free(mp->mnt_data, M_UFSMNT); /* XXX */ 24454947Sheideman mp->mnt_data = 0; 24554947Sheideman return 0; 24654947Sheideman } 24754947Sheideman 24854947Sheideman int 24954947Sheideman umapfs_root(mp, vpp) 25054947Sheideman struct mount *mp; 25154947Sheideman struct vnode **vpp; 25254947Sheideman { 25354947Sheideman struct vnode *vp; 25454947Sheideman 25554947Sheideman #ifdef UMAPFS_DIAGNOSTIC 25654947Sheideman printf("umapfs_root(mp = %x, vp = %x->%x)\n", mp, 25754947Sheideman MOUNTTOUMAPMOUNT(mp)->umapm_rootvp, 25854947Sheideman UMAPVPTOLOWERVP(MOUNTTOUMAPMOUNT(mp)->umapm_rootvp) 25954947Sheideman ); 26054947Sheideman #endif 26154947Sheideman 26254947Sheideman /* 26354947Sheideman * Return locked reference to root. 26454947Sheideman */ 26554947Sheideman vp = MOUNTTOUMAPMOUNT(mp)->umapm_rootvp; 26654947Sheideman VREF(vp); 26754947Sheideman VOP_LOCK(vp); 26854947Sheideman *vpp = vp; 26954947Sheideman return 0; 27054947Sheideman } 27154947Sheideman 27254947Sheideman int 27354947Sheideman umapfs_quotactl(mp, cmd, uid, arg, p) 27454947Sheideman struct mount *mp; 27554947Sheideman int cmd; 27654947Sheideman uid_t uid; 27754947Sheideman caddr_t arg; 27854947Sheideman struct proc *p; 27954947Sheideman { 28054947Sheideman return VFS_QUOTACTL(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, cmd, uid, arg, p); 28154947Sheideman } 28254947Sheideman 28354947Sheideman int 28454947Sheideman umapfs_statfs(mp, sbp, p) 28554947Sheideman struct mount *mp; 28654947Sheideman struct statfs *sbp; 28754947Sheideman struct proc *p; 28854947Sheideman { 28954947Sheideman int error; 29054947Sheideman struct statfs mstat; 29154947Sheideman 29254947Sheideman #ifdef UMAPFS_DIAGNOSTIC 29354947Sheideman printf("umapfs_statfs(mp = %x, vp = %x->%x)\n", mp, 29454947Sheideman MOUNTTOUMAPMOUNT(mp)->umapm_rootvp, 29554947Sheideman UMAPVPTOLOWERVP(MOUNTTOUMAPMOUNT(mp)->umapm_rootvp) 29654947Sheideman ); 29754947Sheideman #endif 29854947Sheideman 29954947Sheideman bzero(&mstat, sizeof(mstat)); 30054947Sheideman 30154947Sheideman error = VFS_STATFS(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, &mstat, p); 30254947Sheideman if (error) 30354947Sheideman return (error); 30454947Sheideman 30554947Sheideman /* now copy across the "interesting" information and fake the rest */ 30654947Sheideman sbp->f_type = mstat.f_type; 30754947Sheideman sbp->f_flags = mstat.f_flags; 30854947Sheideman sbp->f_bsize = mstat.f_bsize; 30954947Sheideman sbp->f_iosize = mstat.f_iosize; 31054947Sheideman sbp->f_blocks = mstat.f_blocks; 31154947Sheideman sbp->f_bfree = mstat.f_bfree; 31254947Sheideman sbp->f_bavail = mstat.f_bavail; 31354947Sheideman sbp->f_files = mstat.f_files; 31454947Sheideman sbp->f_ffree = mstat.f_ffree; 31554947Sheideman if (sbp != &mp->mnt_stat) { 31654947Sheideman bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 31754947Sheideman bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 31854947Sheideman bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 31954947Sheideman } 32054947Sheideman return (0); 32154947Sheideman } 32254947Sheideman 32354947Sheideman int 32454947Sheideman umapfs_sync(mp, waitfor, cred, p) 32554947Sheideman struct mount *mp; 32654947Sheideman int waitfor; 32754947Sheideman struct ucred *cred; 32854947Sheideman struct proc *p; 32954947Sheideman { 33054947Sheideman /* 33154947Sheideman * XXX - Assumes no data cached at umap layer. 33254947Sheideman */ 33354947Sheideman return (0); 33454947Sheideman } 33554947Sheideman 33654947Sheideman int 33754947Sheideman umapfs_vget(mp, ino, vpp) 33854947Sheideman struct mount *mp; 33954947Sheideman ino_t ino; 34054947Sheideman struct vnode **vpp; 34154947Sheideman { 34254947Sheideman 34354947Sheideman return VFS_VGET(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, ino, vpp); 34454947Sheideman } 34554947Sheideman 34654947Sheideman int 34754947Sheideman umapfs_fhtovp(mp, fidp, nam, vpp, exflagsp, credanonp) 34854947Sheideman struct mount *mp; 34954947Sheideman struct fid *fidp; 35054947Sheideman struct mbuf *nam; 35154947Sheideman struct vnode **vpp; 35254947Sheideman int *exflagsp; 35354947Sheideman struct ucred**credanonp; 35454947Sheideman { 35554947Sheideman 35654947Sheideman return VFS_FHTOVP(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, fidp, nam, vpp, exflagsp,credanonp); 35754947Sheideman } 35854947Sheideman 35954947Sheideman int 36054947Sheideman umapfs_vptofh(vp, fhp) 36154947Sheideman struct vnode *vp; 36254947Sheideman struct fid *fhp; 36354947Sheideman { 36454947Sheideman return VFS_VPTOFH(UMAPVPTOLOWERVP(vp), fhp); 36554947Sheideman } 36654947Sheideman 36754947Sheideman int umapfs_init __P((void)); 36854947Sheideman 36954947Sheideman struct vfsops umap_vfsops = { 37054947Sheideman umapfs_mount, 37154947Sheideman umapfs_start, 37254947Sheideman umapfs_unmount, 37354947Sheideman umapfs_root, 37454947Sheideman umapfs_quotactl, 37554947Sheideman umapfs_statfs, 37654947Sheideman umapfs_sync, 37754947Sheideman umapfs_vget, 37854947Sheideman umapfs_fhtovp, 37954947Sheideman umapfs_vptofh, 38054947Sheideman umapfs_init, 38154947Sheideman }; 382