* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
* This code is derived from software donated to Berkeley by
* the UCLA Ficus project.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* @(#)umap_vfsops.c 8.3 (Berkeley) 1/21/94
* @(#)null_vfsops.c 1.5 (Berkeley) 7/10/92
* (See mount_umap(8) for a description of this layer.)
#include <miscfs/umapfs/umap.h>
umapfs_mount(mp
, path
, data
, ndp
, p
)
struct vnode
*lowerrootvp
, *vp
;
struct vnode
*umapm_rootvp
;
printf("umapfs_mount(mp = %x)\n", mp
);
if (mp
->mnt_flag
& MNT_UPDATE
) {
/* return (VFS_MOUNT(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, path, data, ndp, p));*/
if (error
= copyin(data
, (caddr_t
)&args
, sizeof(struct umap_args
)))
NDINIT(ndp
, LOOKUP
, FOLLOW
|WANTPARENT
|LOCKLEAF
,
UIO_USERSPACE
, args
.target
, p
);
* Sanity check on lower vnode
lowerrootvp
= ndp
->ni_vp
;
printf("vp = %x, check for VDIR...\n", lowerrootvp
);
if (lowerrootvp
->v_type
!= VDIR
) {
amp
= (struct umap_mount
*) malloc(sizeof(struct umap_mount
),
M_UFSMNT
, M_WAITOK
); /* XXX */
* Save reference to underlying FS
amp
->umapm_vfs
= lowerrootvp
->v_mount
;
* Now copy in the number of entries and maps for umap mapping.
amp
->info_nentries
= args
.nentries
;
amp
->info_gnentries
= args
.gnentries
;
error
= copyin(args
.mapdata
, (caddr_t
)amp
->info_mapdata
,
2*sizeof(u_long
)*args
.nentries
);
printf("umap_mount:nentries %d\n",args
.nentries
);
for (i
= 0; i
< args
.nentries
; i
++)
printf(" %d maps to %d\n", amp
->info_mapdata
[i
][0],
amp
->info_mapdata
[i
][1]);
error
= copyin(args
.gmapdata
, (caddr_t
)amp
->info_gmapdata
,
2*sizeof(u_long
)*args
.nentries
);
printf("umap_mount:gnentries %d\n",args
.gnentries
);
for (i
= 0; i
< args
.gnentries
; i
++)
printf(" group %d maps to %d\n",
amp
->info_gmapdata
[i
][0],
amp
->info_gmapdata
[i
][1]);
* Save reference. Each mount also holds
* a reference on the root vnode.
error
= umap_node_create(mp
, lowerrootvp
, &vp
);
* Unlock the node (either the lower or the alias)
* Make sure the node alias worked
free(amp
, M_UFSMNT
); /* XXX */
* Keep a held reference to the root vnode.
* It is vrele'd in umapfs_unmount.
umapm_rootvp
->v_flag
|= VROOT
;
amp
->umapm_rootvp
= umapm_rootvp
;
if (UMAPVPTOLOWERVP(umapm_rootvp
)->v_mount
->mnt_flag
& MNT_LOCAL
)
mp
->mnt_flag
|= MNT_LOCAL
;
mp
->mnt_data
= (qaddr_t
) amp
;
getnewfsid(mp
, MOUNT_LOFS
);
(void) copyinstr(path
, mp
->mnt_stat
.f_mntonname
, MNAMELEN
- 1, &size
);
bzero(mp
->mnt_stat
.f_mntonname
+ size
, MNAMELEN
- size
);
(void) copyinstr(args
.target
, mp
->mnt_stat
.f_mntfromname
, MNAMELEN
- 1,
bzero(mp
->mnt_stat
.f_mntfromname
+ size
, MNAMELEN
- size
);
printf("umapfs_mount: lower %s, alias at %s\n",
mp
->mnt_stat
.f_mntfromname
, mp
->mnt_stat
.f_mntonname
);
* VFS start. Nothing needed here - the start routine
* on the underlying filesystem will have been called
* when that filesystem was mounted.
umapfs_start(mp
, flags
, p
)
/* return (VFS_START(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, flags, p)); */
* Free reference to umap layer
umapfs_unmount(mp
, mntflags
, p
)
struct vnode
*umapm_rootvp
= MOUNTTOUMAPMOUNT(mp
)->umapm_rootvp
;
printf("umapfs_unmount(mp = %x)\n", mp
);
if (mntflags
& MNT_FORCE
) {
/* lofs can never be rootfs so don't check for it */
* Clear out buffer cache. I don't think we
* ever get anything cached at this level at the
* moment, but who knows...
if (umapm_rootvp
->v_usecount
> 1)
if (error
= vflush(mp
, umapm_rootvp
, flags
))
vprint("alias root of lower", umapm_rootvp
);
* Release reference on underlying root vnode
* And blow it away for future re-use
* Finally, throw away the umap_mount structure
free(mp
->mnt_data
, M_UFSMNT
); /* XXX */
printf("umapfs_root(mp = %x, vp = %x->%x)\n", mp
,
MOUNTTOUMAPMOUNT(mp
)->umapm_rootvp
,
UMAPVPTOLOWERVP(MOUNTTOUMAPMOUNT(mp
)->umapm_rootvp
)
* Return locked reference to root.
vp
= MOUNTTOUMAPMOUNT(mp
)->umapm_rootvp
;
umapfs_quotactl(mp
, cmd
, uid
, arg
, p
)
return (VFS_QUOTACTL(MOUNTTOUMAPMOUNT(mp
)->umapm_vfs
, cmd
, uid
, arg
, p
));
umapfs_statfs(mp
, sbp
, p
)
printf("umapfs_statfs(mp = %x, vp = %x->%x)\n", mp
,
MOUNTTOUMAPMOUNT(mp
)->umapm_rootvp
,
UMAPVPTOLOWERVP(MOUNTTOUMAPMOUNT(mp
)->umapm_rootvp
)
bzero(&mstat
, sizeof(mstat
));
error
= VFS_STATFS(MOUNTTOUMAPMOUNT(mp
)->umapm_vfs
, &mstat
, p
);
/* now copy across the "interesting" information and fake the rest */
sbp
->f_type
= mstat
.f_type
;
sbp
->f_flags
= mstat
.f_flags
;
sbp
->f_bsize
= mstat
.f_bsize
;
sbp
->f_iosize
= mstat
.f_iosize
;
sbp
->f_blocks
= mstat
.f_blocks
;
sbp
->f_bfree
= mstat
.f_bfree
;
sbp
->f_bavail
= mstat
.f_bavail
;
sbp
->f_files
= mstat
.f_files
;
sbp
->f_ffree
= mstat
.f_ffree
;
if (sbp
!= &mp
->mnt_stat
) {
bcopy(&mp
->mnt_stat
.f_fsid
, &sbp
->f_fsid
, sizeof(sbp
->f_fsid
));
bcopy(mp
->mnt_stat
.f_mntonname
, sbp
->f_mntonname
, MNAMELEN
);
bcopy(mp
->mnt_stat
.f_mntfromname
, sbp
->f_mntfromname
, MNAMELEN
);
umapfs_sync(mp
, waitfor
, cred
, p
)
* XXX - Assumes no data cached at umap layer.
umapfs_vget(mp
, ino
, vpp
)
return (VFS_VGET(MOUNTTOUMAPMOUNT(mp
)->umapm_vfs
, ino
, vpp
));
umapfs_fhtovp(mp
, fidp
, nam
, vpp
, exflagsp
, credanonp
)
return (VFS_FHTOVP(MOUNTTOUMAPMOUNT(mp
)->umapm_vfs
, fidp
, nam
, vpp
, exflagsp
,credanonp
));
return (VFS_VPTOFH(UMAPVPTOLOWERVP(vp
), fhp
));
int umapfs_init
__P((void));
struct vfsops umap_vfsops
= {