]>
git.saurik.com Git - apple/xnu.git/blob - bsd/miscfs/umapfs/umap_vfsops.c
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
22 /* $NetBSD: umap_vfsops.c,v 1.7 1995/03/09 12:05:59 mycroft Exp $ */
25 * Copyright (c) 1992, 1993
26 * The Regents of the University of California. All rights reserved.
28 * This code is derived from software donated to Berkeley by
29 * the UCLA Ficus project.
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
34 * 1. Redistributions of source code must retain the above copyright
35 * notice, this list of conditions and the following disclaimer.
36 * 2. Redistributions in binary form must reproduce the above copyright
37 * notice, this list of conditions and the following disclaimer in the
38 * documentation and/or other materials provided with the distribution.
39 * 3. All advertising materials mentioning features or use of this software
40 * must display the following acknowledgement:
41 * This product includes software developed by the University of
42 * California, Berkeley and its contributors.
43 * 4. Neither the name of the University nor the names of its contributors
44 * may be used to endorse or promote products derived from this software
45 * without specific prior written permission.
47 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
48 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
50 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
51 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
52 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
53 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
55 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
56 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * from: @(#)null_vfsops.c 1.5 (Berkeley) 7/10/92
60 * @(#)umap_vfsops.c 8.3 (Berkeley) 1/21/94
65 * (See mount_umap(8) for a description of this layer.)
68 #include <sys/param.h>
69 #include <sys/systm.h>
71 #include <sys/types.h>
72 #include <sys/vnode.h>
73 #include <sys/mount.h>
74 #include <sys/namei.h>
75 #include <sys/malloc.h>
76 #include <miscfs/umapfs/umap.h>
82 umapfs_mount(mp
, path
, data
, ndp
, p
)
86 struct nameidata
*ndp
;
89 struct umap_args args
;
90 struct vnode
*lowerrootvp
, *vp
;
91 struct vnode
*umapm_rootvp
;
92 struct umap_mount
*amp
;
96 #ifdef UMAPFS_DIAGNOSTIC
97 printf("umapfs_mount(mp = %x)\n", mp
);
103 if (mp
->mnt_flag
& MNT_UPDATE
) {
105 /* return (VFS_MOUNT(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, path, data, ndp, p));*/
111 if (error
= copyin(data
, (caddr_t
)&args
, sizeof(struct umap_args
)))
117 NDINIT(ndp
, LOOKUP
, FOLLOW
|WANTPARENT
|LOCKLEAF
,
118 UIO_USERSPACE
, args
.target
, p
);
119 if (error
= namei(ndp
))
123 * Sanity check on lower vnode
125 lowerrootvp
= ndp
->ni_vp
;
126 #ifdef UMAPFS_DIAGNOSTIC
127 printf("vp = %x, check for VDIR...\n", lowerrootvp
);
132 if (lowerrootvp
->v_type
!= VDIR
) {
137 #ifdef UMAPFS_DIAGNOSTIC
138 printf("mp = %x\n", mp
);
141 // amp = (struct umap_mount *) malloc(sizeof(struct umap_mount),
142 // M_UFSMNT, M_WAITOK); /* XXX */
143 MALLOC(amp
, struct umap_mount
*, sizeof(struct umap_mount
),
147 * Save reference to underlying FS
149 amp
->umapm_vfs
= lowerrootvp
->v_mount
;
152 * Now copy in the number of entries and maps for umap mapping.
154 amp
->info_nentries
= args
.nentries
;
155 amp
->info_gnentries
= args
.gnentries
;
156 error
= copyin(args
.mapdata
, (caddr_t
)amp
->info_mapdata
,
157 2*sizeof(u_long
)*args
.nentries
);
161 #ifdef UMAP_DIAGNOSTIC
162 printf("umap_mount:nentries %d\n",args
.nentries
);
163 for (i
= 0; i
< args
.nentries
; i
++)
164 printf(" %d maps to %d\n", amp
->info_mapdata
[i
][0],
165 amp
->info_mapdata
[i
][1]);
168 error
= copyin(args
.gmapdata
, (caddr_t
)amp
->info_gmapdata
,
169 2*sizeof(u_long
)*args
.nentries
);
173 #ifdef UMAP_DIAGNOSTIC
174 printf("umap_mount:gnentries %d\n",args
.gnentries
);
175 for (i
= 0; i
< args
.gnentries
; i
++)
176 printf(" group %d maps to %d\n",
177 amp
->info_gmapdata
[i
][0],
178 amp
->info_gmapdata
[i
][1]);
183 * Save reference. Each mount also holds
184 * a reference on the root vnode.
186 error
= umap_node_create(mp
, lowerrootvp
, &vp
);
188 * Unlock the node (either the lower or the alias)
192 * Make sure the node alias worked
196 free(amp
, M_UFSMNT
); /* XXX */
201 * Keep a held reference to the root vnode.
202 * It is vrele'd in umapfs_unmount.
205 umapm_rootvp
->v_flag
|= VROOT
;
206 amp
->umapm_rootvp
= umapm_rootvp
;
207 if (UMAPVPTOLOWERVP(umapm_rootvp
)->v_mount
->mnt_flag
& MNT_LOCAL
)
208 mp
->mnt_flag
|= MNT_LOCAL
;
209 mp
->mnt_data
= (qaddr_t
) amp
;
210 getnewfsid(mp
, makefstype(MOUNT_LOFS
));
212 (void) copyinstr(path
, mp
->mnt_stat
.f_mntonname
, MNAMELEN
- 1, &size
);
213 bzero(mp
->mnt_stat
.f_mntonname
+ size
, MNAMELEN
- size
);
214 (void) copyinstr(args
.target
, mp
->mnt_stat
.f_mntfromname
, MNAMELEN
- 1,
216 bzero(mp
->mnt_stat
.f_mntfromname
+ size
, MNAMELEN
- size
);
217 #ifdef UMAPFS_DIAGNOSTIC
218 printf("umapfs_mount: lower %s, alias at %s\n",
219 mp
->mnt_stat
.f_mntfromname
, mp
->mnt_stat
.f_mntonname
);
225 * VFS start. Nothing needed here - the start routine
226 * on the underlying filesystem will have been called
227 * when that filesystem was mounted.
230 umapfs_start(mp
, flags
, p
)
237 /* return (VFS_START(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, flags, p)); */
241 * Free reference to umap layer
244 umapfs_unmount(mp
, mntflags
, p
)
249 struct vnode
*umapm_rootvp
= MOUNTTOUMAPMOUNT(mp
)->umapm_rootvp
;
254 #ifdef UMAPFS_DIAGNOSTIC
255 printf("umapfs_unmount(mp = %x)\n", mp
);
258 if (mntflags
& MNT_FORCE
) {
259 /* lofs can never be rootfs so don't check for it */
266 * Clear out buffer cache. I don't think we
267 * ever get anything cached at this level at the
268 * moment, but who knows...
272 if (mntinvalbuf(mp
, 1))
275 if (umapm_rootvp
->v_usecount
> 1)
277 if (error
= vflush(mp
, umapm_rootvp
, flags
))
280 #ifdef UMAPFS_DIAGNOSTIC
281 vprint("alias root of lower", umapm_rootvp
);
284 * Release reference on underlying root vnode
288 * And blow it away for future re-use
292 * Finally, throw away the umap_mount structure
294 free(mp
->mnt_data
, M_UFSMNT
); /* XXX */
306 #ifdef UMAPFS_DIAGNOSTIC
307 printf("umapfs_root(mp = %x, vp = %x->%x)\n", mp
,
308 MOUNTTOUMAPMOUNT(mp
)->umapm_rootvp
,
309 UMAPVPTOLOWERVP(MOUNTTOUMAPMOUNT(mp
)->umapm_rootvp
)
314 * Return locked reference to root.
316 vp
= MOUNTTOUMAPMOUNT(mp
)->umapm_rootvp
;
324 umapfs_quotactl(mp
, cmd
, uid
, arg
, p
)
332 return (VFS_QUOTACTL(MOUNTTOUMAPMOUNT(mp
)->umapm_vfs
, cmd
, uid
, arg
, p
));
336 umapfs_statfs(mp
, sbp
, p
)
344 #ifdef UMAPFS_DIAGNOSTIC
345 printf("umapfs_statfs(mp = %x, vp = %x->%x)\n", mp
,
346 MOUNTTOUMAPMOUNT(mp
)->umapm_rootvp
,
347 UMAPVPTOLOWERVP(MOUNTTOUMAPMOUNT(mp
)->umapm_rootvp
)
351 bzero(&mstat
, sizeof(mstat
));
353 error
= VFS_STATFS(MOUNTTOUMAPMOUNT(mp
)->umapm_vfs
, &mstat
, p
);
357 /* now copy across the "interesting" information and fake the rest */
358 sbp
->f_type
= mstat
.f_type
;
359 sbp
->f_flags
= mstat
.f_flags
;
360 sbp
->f_bsize
= mstat
.f_bsize
;
361 sbp
->f_iosize
= mstat
.f_iosize
;
362 sbp
->f_blocks
= mstat
.f_blocks
;
363 sbp
->f_bfree
= mstat
.f_bfree
;
364 sbp
->f_bavail
= mstat
.f_bavail
;
365 sbp
->f_files
= mstat
.f_files
;
366 sbp
->f_ffree
= mstat
.f_ffree
;
367 if (sbp
!= &mp
->mnt_stat
) {
368 bcopy(&mp
->mnt_stat
.f_fsid
, &sbp
->f_fsid
, sizeof(sbp
->f_fsid
));
369 bcopy(mp
->mnt_stat
.f_mntonname
, sbp
->f_mntonname
, MNAMELEN
);
370 bcopy(mp
->mnt_stat
.f_mntfromname
, sbp
->f_mntfromname
, MNAMELEN
);
372 strncpy(sbp
->f_fstypename
, mp
->mnt_op
->vfs_name
, MFSNAMELEN
);
373 sbp
->f_fstypename
[MFSNAMELEN
] = '\0';
378 umapfs_sync(mp
, waitfor
, cred
, p
)
386 * XXX - Assumes no data cached at umap layer.
392 umapfs_vget(mp
, ino
, vpp
)
398 return (VFS_VGET(MOUNTTOUMAPMOUNT(mp
)->umapm_vfs
, ino
, vpp
));
402 umapfs_fhtovp(mp
, fidp
, nam
, vpp
, exflagsp
, credanonp
)
408 struct ucred
**credanonp
;
415 umapfs_vptofh(vp
, fhp
)
423 int umapfs_init
__P((void));
425 struct vfsops umap_vfsops
= {