154947Sheideman /* 263248Sbostic * Copyright (c) 1992, 1993 363248Sbostic * The Regents of the University of California. All rights reserved. 454947Sheideman * All rights reserved. 554947Sheideman * 654947Sheideman * This code is derived from software donated to Berkeley by 754959Sheideman * the UCLA Ficus project. 854947Sheideman * 954947Sheideman * %sccs.include.redist.c% 1054947Sheideman * 11*65726Sbostic * @(#)umap_vfsops.c 8.2 (Berkeley) 01/13/94 1254947Sheideman * 1354959Sheideman * @(#)null_vfsops.c 1.5 (Berkeley) 7/10/92 1454947Sheideman */ 1554947Sheideman 1654947Sheideman /* 1754959Sheideman * Umap Layer 1855053Spendry * (See mount_umap(8) for a description 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> 2955053Spendry #include <miscfs/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 struct umap_args args; 4354947Sheideman struct vnode *lowerrootvp, *vp; 4454947Sheideman struct vnode *umapm_rootvp; 4554947Sheideman struct umap_mount *amp; 4654947Sheideman u_int size; 47*65726Sbostic 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); 58*65726Sbostic /* 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, 108*65726Sbostic 2*sizeof(u_long)*args.nentries); 109*65726Sbostic if (error) 110*65726Sbostic 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, 120*65726Sbostic 2*sizeof(u_long)*args.nentries); 121*65726Sbostic if (error) 122*65726Sbostic 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 */ 14154947Sheideman VOP_UNLOCK(vp); 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; 16154947Sheideman getnewfsid(mp, MOUNT_LOFS); 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 18154947Sheideman umapfs_start(mp, flags, p) 18254947Sheideman struct mount *mp; 18354947Sheideman int flags; 18454947Sheideman struct proc *p; 18554947Sheideman { 18654947Sheideman return (0); 187*65726Sbostic /* return (VFS_START(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, flags, p)); */ 18854947Sheideman } 18954947Sheideman 19054947Sheideman /* 19154947Sheideman * Free reference to umap layer 19254947Sheideman */ 19354947Sheideman int 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 extern int doforce; 20354947Sheideman 20454947Sheideman #ifdef UMAPFS_DIAGNOSTIC 20554947Sheideman printf("umapfs_unmount(mp = %x)\n", mp); 20654947Sheideman #endif 20754947Sheideman 20854947Sheideman if (mntflags & MNT_FORCE) { 20954947Sheideman /* lofs can never be rootfs so don't check for it */ 21054947Sheideman if (!doforce) 21154947Sheideman return (EINVAL); 21254947Sheideman flags |= FORCECLOSE; 21354947Sheideman } 21454947Sheideman 21554947Sheideman /* 21654947Sheideman * Clear out buffer cache. I don't think we 21754947Sheideman * ever get anything cached at this level at the 21854947Sheideman * moment, but who knows... 21954947Sheideman */ 22055031Smckusick #ifdef notyet 22154947Sheideman mntflushbuf(mp, 0); 22254947Sheideman if (mntinvalbuf(mp, 1)) 22354947Sheideman return (EBUSY); 22454947Sheideman #endif 22554947Sheideman if (umapm_rootvp->v_usecount > 1) 22654947Sheideman return (EBUSY); 22754947Sheideman if (error = vflush(mp, umapm_rootvp, flags)) 22854947Sheideman return (error); 22954947Sheideman 23054947Sheideman #ifdef UMAPFS_DIAGNOSTIC 23154959Sheideman vprint("alias root of lower", umapm_rootvp); 23254947Sheideman #endif 23354947Sheideman /* 23454947Sheideman * Release reference on underlying root vnode 23554947Sheideman */ 23654947Sheideman vrele(umapm_rootvp); 23754947Sheideman /* 23854947Sheideman * And blow it away for future re-use 23954947Sheideman */ 24054947Sheideman vgone(umapm_rootvp); 24154947Sheideman /* 24254947Sheideman * Finally, throw away the umap_mount structure 24354947Sheideman */ 24454947Sheideman free(mp->mnt_data, M_UFSMNT); /* XXX */ 24554947Sheideman mp->mnt_data = 0; 246*65726Sbostic return (0); 24754947Sheideman } 24854947Sheideman 24954947Sheideman int 25054947Sheideman umapfs_root(mp, vpp) 25154947Sheideman struct mount *mp; 25254947Sheideman struct vnode **vpp; 25354947Sheideman { 25454947Sheideman struct vnode *vp; 25554947Sheideman 25654947Sheideman #ifdef UMAPFS_DIAGNOSTIC 25754947Sheideman printf("umapfs_root(mp = %x, vp = %x->%x)\n", mp, 25854947Sheideman MOUNTTOUMAPMOUNT(mp)->umapm_rootvp, 25954947Sheideman UMAPVPTOLOWERVP(MOUNTTOUMAPMOUNT(mp)->umapm_rootvp) 26054947Sheideman ); 26154947Sheideman #endif 26254947Sheideman 26354947Sheideman /* 26454947Sheideman * Return locked reference to root. 26554947Sheideman */ 26654947Sheideman vp = MOUNTTOUMAPMOUNT(mp)->umapm_rootvp; 26754947Sheideman VREF(vp); 26854947Sheideman VOP_LOCK(vp); 26954947Sheideman *vpp = vp; 270*65726Sbostic return (0); 27154947Sheideman } 27254947Sheideman 27354947Sheideman int 27454947Sheideman umapfs_quotactl(mp, cmd, uid, arg, p) 27554947Sheideman struct mount *mp; 27654947Sheideman int cmd; 27754947Sheideman uid_t uid; 27854947Sheideman caddr_t arg; 27954947Sheideman struct proc *p; 28054947Sheideman { 281*65726Sbostic return (VFS_QUOTACTL(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, cmd, uid, arg, p)); 28254947Sheideman } 28354947Sheideman 28454947Sheideman int 28554947Sheideman umapfs_statfs(mp, sbp, p) 28654947Sheideman struct mount *mp; 28754947Sheideman struct statfs *sbp; 28854947Sheideman struct proc *p; 28954947Sheideman { 29054947Sheideman int error; 29154947Sheideman struct statfs mstat; 29254947Sheideman 29354947Sheideman #ifdef UMAPFS_DIAGNOSTIC 29454947Sheideman printf("umapfs_statfs(mp = %x, vp = %x->%x)\n", mp, 29554947Sheideman MOUNTTOUMAPMOUNT(mp)->umapm_rootvp, 29654947Sheideman UMAPVPTOLOWERVP(MOUNTTOUMAPMOUNT(mp)->umapm_rootvp) 29754947Sheideman ); 29854947Sheideman #endif 29954947Sheideman 30054947Sheideman bzero(&mstat, sizeof(mstat)); 30154947Sheideman 30254947Sheideman error = VFS_STATFS(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, &mstat, p); 30354947Sheideman if (error) 30454947Sheideman return (error); 30554947Sheideman 30654947Sheideman /* now copy across the "interesting" information and fake the rest */ 30754947Sheideman sbp->f_type = mstat.f_type; 30854947Sheideman sbp->f_flags = mstat.f_flags; 30954947Sheideman sbp->f_bsize = mstat.f_bsize; 31054947Sheideman sbp->f_iosize = mstat.f_iosize; 31154947Sheideman sbp->f_blocks = mstat.f_blocks; 31254947Sheideman sbp->f_bfree = mstat.f_bfree; 31354947Sheideman sbp->f_bavail = mstat.f_bavail; 31454947Sheideman sbp->f_files = mstat.f_files; 31554947Sheideman sbp->f_ffree = mstat.f_ffree; 31654947Sheideman if (sbp != &mp->mnt_stat) { 31754947Sheideman bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 31854947Sheideman bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 31954947Sheideman bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 32054947Sheideman } 32154947Sheideman return (0); 32254947Sheideman } 32354947Sheideman 32454947Sheideman int 32554947Sheideman umapfs_sync(mp, waitfor, cred, p) 32654947Sheideman struct mount *mp; 32754947Sheideman int waitfor; 32854947Sheideman struct ucred *cred; 32954947Sheideman struct proc *p; 33054947Sheideman { 33154947Sheideman /* 33254947Sheideman * XXX - Assumes no data cached at umap layer. 33354947Sheideman */ 33454947Sheideman return (0); 33554947Sheideman } 33654947Sheideman 33754947Sheideman int 33854947Sheideman umapfs_vget(mp, ino, vpp) 33954947Sheideman struct mount *mp; 34054947Sheideman ino_t ino; 34154947Sheideman struct vnode **vpp; 34254947Sheideman { 34354947Sheideman 344*65726Sbostic return (VFS_VGET(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, ino, vpp)); 34554947Sheideman } 34654947Sheideman 34754947Sheideman int 34854947Sheideman umapfs_fhtovp(mp, fidp, nam, vpp, exflagsp, credanonp) 34954947Sheideman struct mount *mp; 35054947Sheideman struct fid *fidp; 35154947Sheideman struct mbuf *nam; 35254947Sheideman struct vnode **vpp; 35354947Sheideman int *exflagsp; 35454947Sheideman struct ucred**credanonp; 35554947Sheideman { 35654947Sheideman 357*65726Sbostic return (VFS_FHTOVP(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, fidp, nam, vpp, exflagsp,credanonp)); 35854947Sheideman } 35954947Sheideman 36054947Sheideman int 36154947Sheideman umapfs_vptofh(vp, fhp) 36254947Sheideman struct vnode *vp; 36354947Sheideman struct fid *fhp; 36454947Sheideman { 365*65726Sbostic return (VFS_VPTOFH(UMAPVPTOLOWERVP(vp), fhp)); 36654947Sheideman } 36754947Sheideman 36854947Sheideman int umapfs_init __P((void)); 36954947Sheideman 37054947Sheideman struct vfsops umap_vfsops = { 37154947Sheideman umapfs_mount, 37254947Sheideman umapfs_start, 37354947Sheideman umapfs_unmount, 37454947Sheideman umapfs_root, 37554947Sheideman umapfs_quotactl, 37654947Sheideman umapfs_statfs, 37754947Sheideman umapfs_sync, 37854947Sheideman umapfs_vget, 37954947Sheideman umapfs_fhtovp, 38054947Sheideman umapfs_vptofh, 38154947Sheideman umapfs_init, 38254947Sheideman }; 383