From: Matthew Dillon Date: Thu, 25 Sep 2008 02:20:57 +0000 (+0000) Subject: MFC numerous features from HEAD. X-Git-Url: https://repo.or.cz/w/dragonfly.git/commitdiff_plain/a81ad9d1745b5a1699428a64714f13982e657b63 MFC numerous features from HEAD. * NFS export support for nullfs mounted filesystems, intended for nullfs mounted hammer PFSs. * Each nullfs mount constructs a unique fsid based on the underlying mount. * Each nullfs mount maintains its own netexport structure. * The mount pointer in the nch (namecache handle) is passed into FHTOVP and friends, allowing operations to occur on the underlying vnodes but still go through the nullfs mount. --- diff --git a/sys/emulation/dragonfly12/dfbsd12_stat.c b/sys/emulation/dragonfly12/dfbsd12_stat.c index 13099fa1da..f2d72cf1db 100644 --- a/sys/emulation/dragonfly12/dfbsd12_stat.c +++ b/sys/emulation/dragonfly12/dfbsd12_stat.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/emulation/dragonfly12/dfbsd12_stat.c,v 1.3 2006/06/05 07:26:08 dillon Exp $ + * $DragonFly: src/sys/emulation/dragonfly12/dfbsd12_stat.c,v 1.3.10.1 2008/09/25 02:20:45 dillon Exp $ */ #include "opt_compatdf12.h" @@ -147,7 +147,7 @@ sys_dfbsd12_fhstat(struct dfbsd12_fhstat_args *uap) if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) return (ESTALE); - if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp))) + if ((error = VFS_FHTOVP(mp, NULL, &fh.fh_fid, &vp))) return (error); error = vn_stat(vp, &sb, td->td_proc->p_ucred); vput(vp); diff --git a/sys/kern/kern_checkpoint.c b/sys/kern/kern_checkpoint.c index bcf0880491..c120c8e09e 100644 --- a/sys/kern/kern_checkpoint.c +++ b/sys/kern/kern_checkpoint.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/kern/kern_checkpoint.c,v 1.19 2007/06/29 23:40:00 dillon Exp $ + * $DragonFly: src/sys/kern/kern_checkpoint.c,v 1.19.6.1 2008/09/25 02:20:46 dillon Exp $ */ #include @@ -496,7 +496,7 @@ ckpt_fhtovp(fhandle_t *fh, struct vnode **vpp) TRACE_EXIT; return ESTALE; } - error = VFS_FHTOVP(mp, &fh->fh_fid, vpp); + error = VFS_FHTOVP(mp, NULL, &fh->fh_fid, vpp); if (error) { PRINTF(("failed with: %d\n", error)); TRACE_ERR; diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c index 8f655b1fc0..94d5a1b800 100644 --- a/sys/kern/vfs_default.c +++ b/sys/kern/vfs_default.c @@ -38,7 +38,7 @@ * * Source: * @(#)i405_init.c 2.10 92/04/27 UCLA Ficus project * $FreeBSD: src/sys/kern/vfs_default.c,v 1.28.2.7 2003/01/10 18:23:26 bde Exp $ - * $DragonFly: src/sys/kern/vfs_default.c,v 1.53 2008/06/01 19:27:35 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_default.c,v 1.53.2.1 2008/09/25 02:20:46 dillon Exp $ */ #include @@ -1393,7 +1393,8 @@ vfs_stdvget(struct mount *mp, ino_t ino, struct vnode **vpp) } int -vfs_stdfhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) +vfs_stdfhtovp(struct mount *mp, struct vnode *rootvp, + struct fid *fhp, struct vnode **vpp) { return (EOPNOTSUPP); } diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index 6ca1234908..65aaffcebc 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -67,7 +67,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/kern/vfs_mount.c,v 1.35.2.1 2008/07/14 22:19:42 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_mount.c,v 1.35.2.2 2008/09/25 02:20:46 dillon Exp $ */ /* @@ -364,6 +364,26 @@ vfs_getnewfsid(struct mount *mp) } /* + * Set the FSID for a new mount point to the template. Adjust + * the FSID to avoid collisions. + */ +int +vfs_setfsid(struct mount *mp, fsid_t *template) +{ + int didmunge = 0; + + bzero(&mp->mnt_stat.f_fsid, sizeof(mp->mnt_stat.f_fsid)); + for (;;) { + if (vfs_getvfs(template) == NULL) + break; + didmunge = 1; + ++template->val[1]; + } + mp->mnt_stat.f_fsid = *template; + return(didmunge); +} + +/* * This routine is called when we have too many vnodes. It attempts * to free vnodes and will potentially free vnodes that still * have VM backing store (VM backing store is typically the cause diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index f79136f7b1..72e6152704 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -37,7 +37,7 @@ * * @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95 * $FreeBSD: src/sys/kern/vfs_subr.c,v 1.249.2.30 2003/04/04 20:35:57 tegge Exp $ - * $DragonFly: src/sys/kern/vfs_subr.c,v 1.116.2.1 2008/08/02 14:34:29 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_subr.c,v 1.116.2.2 2008/09/25 02:20:46 dillon Exp $ */ /* @@ -1450,6 +1450,8 @@ vprint(char *label, struct vnode *vp) buf[0] = '\0'; if (vp->v_flag & VROOT) strcat(buf, "|VROOT"); + if (vp->v_flag & VPFSROOT) + strcat(buf, "|VPFSROOT"); if (vp->v_flag & VTEXT) strcat(buf, "|VTEXT"); if (vp->v_flag & VSYSTEM) diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index c05d07387f..e615390add 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -37,7 +37,7 @@ * * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 * $FreeBSD: src/sys/kern/vfs_syscalls.c,v 1.151.2.18 2003/04/04 20:35:58 tegge Exp $ - * $DragonFly: src/sys/kern/vfs_syscalls.c,v 1.133 2008/06/28 17:59:49 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_syscalls.c,v 1.133.2.1 2008/09/25 02:20:46 dillon Exp $ */ #include @@ -185,7 +185,7 @@ sys_mount(struct mount_args *uap) * Now we have an unlocked ref'd nch and a locked ref'd vp */ if (uap->flags & MNT_UPDATE) { - if ((vp->v_flag & VROOT) == 0) { + if ((vp->v_flag & (VROOT|VPFSROOT)) == 0) { cache_drop(&nch); vput(vp); return (EINVAL); @@ -975,6 +975,9 @@ done: /* * Execute a mount control operation by resolving the path to a mount point * and calling vop_mountctl(). + * + * Use the mount point from the nch instead of the vnode so nullfs mounts + * can properly spike the VOP. */ int kern_mountctl(const char *path, int op, struct file *fp, @@ -993,16 +996,15 @@ kern_mountctl(const char *path, int op, struct file *fp, error = nlookup(&nd); if (error == 0) error = cache_vget(&nd.nl_nch, nd.nl_cred, LK_EXCLUSIVE, &vp); + mp = nd.nl_nch.mount; nlookup_done(&nd); if (error) return (error); - mp = vp->v_mount; - /* * Must be the root of the filesystem */ - if ((vp->v_flag & VROOT) == 0) { + if ((vp->v_flag & (VROOT|VPFSROOT)) == 0) { vput(vp); return (EINVAL); } @@ -3552,6 +3554,15 @@ sys_revoke(struct revoke_args *uap) * getfh_args(char *fname, fhandle_t *fhp) * * Get (NFS) file handle + * + * NOTE: We use the fsid of the covering mount, even if it is a nullfs + * mount. This allows nullfs mounts to be explicitly exported. + * + * WARNING: nullfs mounts of HAMMER PFS ROOTs are safe. + * + * nullfs mounts of subdirectories are not safe. That is, it will + * work, but you do not really have protection against access to + * the related parent directories. */ int sys_getfh(struct getfh_args *uap) @@ -3560,6 +3571,7 @@ sys_getfh(struct getfh_args *uap) struct nlookupdata nd; fhandle_t fh; struct vnode *vp; + struct mount *mp; int error; /* @@ -3574,10 +3586,11 @@ sys_getfh(struct getfh_args *uap) error = nlookup(&nd); if (error == 0) error = cache_vget(&nd.nl_nch, nd.nl_cred, LK_EXCLUSIVE, &vp); + mp = nd.nl_nch.mount; nlookup_done(&nd); if (error == 0) { bzero(&fh, sizeof(fh)); - fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid; + fh.fh_fsid = mp->mnt_stat.f_fsid; error = VFS_VPTOFH(vp, &fh.fh_fid); vput(vp); if (error == 0) @@ -3630,7 +3643,7 @@ sys_fhopen(struct fhopen_args *uap) if (mp == NULL) return (ESTALE); /* now give me my vnode, it gets returned to me locked */ - error = VFS_FHTOVP(mp, &fhp.fh_fid, &vp); + error = VFS_FHTOVP(mp, NULL, &fhp.fh_fid, &vp); if (error) return (error); /* @@ -3785,7 +3798,7 @@ sys_fhstat(struct fhstat_args *uap) if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) return (ESTALE); - if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp))) + if ((error = VFS_FHTOVP(mp, NULL, &fh.fh_fid, &vp))) return (error); error = vn_stat(vp, &sb, td->td_proc->p_ucred); vput(vp); @@ -3826,7 +3839,7 @@ sys_fhstatfs(struct fhstatfs_args *uap) if (p != NULL && !chroot_visible_mnt(mp, p)) return (ESTALE); - if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp))) + if ((error = VFS_FHTOVP(mp, NULL, &fh.fh_fid, &vp))) return (error); mp = vp->v_mount; sp = &mp->mnt_stat; @@ -3879,7 +3892,7 @@ sys_fhstatvfs(struct fhstatvfs_args *uap) if (p != NULL && !chroot_visible_mnt(mp, p)) return (ESTALE); - if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp))) + if ((error = VFS_FHTOVP(mp, NULL, &fh.fh_fid, &vp))) return (error); mp = vp->v_mount; sp = &mp->mnt_vstat; diff --git a/sys/sys/mount.h b/sys/sys/mount.h index 719267173a..606e3c2171 100644 --- a/sys/sys/mount.h +++ b/sys/sys/mount.h @@ -32,7 +32,7 @@ * * @(#)mount.h 8.21 (Berkeley) 5/20/95 * $FreeBSD: src/sys/sys/mount.h,v 1.89.2.7 2003/04/04 20:35:57 tegge Exp $ - * $DragonFly: src/sys/sys/mount.h,v 1.46 2008/07/07 22:02:10 nant Exp $ + * $DragonFly: src/sys/sys/mount.h,v 1.46.2.1 2008/09/25 02:20:48 dillon Exp $ */ #ifndef _SYS_MOUNT_H_ @@ -424,8 +424,8 @@ typedef int vfs_statvfs_t(struct mount *mp, struct statvfs *sbp, struct ucred *cred); typedef int vfs_sync_t(struct mount *mp, int waitfor); typedef int vfs_vget_t(struct mount *mp, ino_t ino, struct vnode **vpp); -typedef int vfs_fhtovp_t(struct mount *mp, struct fid *fhp, - struct vnode **vpp); +typedef int vfs_fhtovp_t(struct mount *mp, struct vnode *rootvp, + struct fid *fhp, struct vnode **vpp); typedef int vfs_checkexp_t(struct mount *mp, struct sockaddr *nam, int *extflagsp, struct ucred **credanonp); typedef int vfs_vptofh_t(struct vnode *vp, struct fid *fhp); @@ -463,8 +463,8 @@ struct vfsops { #define VFS_STATVFS(MP, SBP, CRED) (*(MP)->mnt_op->vfs_statvfs)(MP, SBP, CRED) #define VFS_SYNC(MP, WAIT) (*(MP)->mnt_op->vfs_sync)(MP, WAIT) #define VFS_VGET(MP, INO, VPP) (*(MP)->mnt_op->vfs_vget)(MP, INO, VPP) -#define VFS_FHTOVP(MP, FIDP, VPP) \ - (*(MP)->mnt_op->vfs_fhtovp)(MP, FIDP, VPP) +#define VFS_FHTOVP(MP, ROOTVP, FIDP, VPP) \ + (*(MP)->mnt_op->vfs_fhtovp)(MP, ROOTVP, FIDP, VPP) #define VFS_VPTOFH(VP, FIDP) (*(VP)->v_mount->mnt_op->vfs_vptofh)(VP, FIDP) #define VFS_CHECKEXP(MP, NAM, EXFLG, CRED) \ (*(MP)->mnt_op->vfs_checkexp)(MP, NAM, EXFLG, CRED) @@ -541,6 +541,7 @@ struct netcred *vfs_export_lookup /* lookup host in fs export list */ (struct mount *, struct netexport *, struct sockaddr *); int vfs_allocate_syncvnode (struct mount *); void vfs_getnewfsid (struct mount *); +int vfs_setfsid(struct mount *mp, fsid_t *template); cdev_t vfs_getrootfsid (struct mount *); struct mount *vfs_getvfs (fsid_t *); /* return vfs given fsid */ int vfs_modevent (module_t, int, void *); diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 350ae6c48c..9557493c9e 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -32,7 +32,7 @@ * * @(#)vnode.h 8.7 (Berkeley) 2/4/94 * $FreeBSD: src/sys/sys/vnode.h,v 1.111.2.19 2002/12/29 18:19:53 dillon Exp $ - * $DragonFly: src/sys/sys/vnode.h,v 1.82 2008/07/12 01:09:45 dillon Exp $ + * $DragonFly: src/sys/sys/vnode.h,v 1.82.2.1 2008/09/25 02:20:48 dillon Exp $ */ #ifndef _SYS_VNODE_H_ @@ -267,7 +267,7 @@ struct vnode { #define VCKPT 0x00020 /* checkpoint-restored vnode */ #define VFSMID 0x00040 /* request FSMID update */ #define VMAYHAVELOCKS 0x00080 /* there may be posix or flock locks on vp */ -/* open for business 0x00100 */ +#define VPFSROOT 0x00100 /* may be a pseudo filesystem root */ /* open for business 0x00200 */ /* open for business 0x00400 */ /* open for business 0x00800 */ diff --git a/sys/vfs/gnu/ext2fs/ext2_vfsops.c b/sys/vfs/gnu/ext2fs/ext2_vfsops.c index 85b99a6daa..fc72108d93 100644 --- a/sys/vfs/gnu/ext2fs/ext2_vfsops.c +++ b/sys/vfs/gnu/ext2fs/ext2_vfsops.c @@ -38,7 +38,7 @@ * * @(#)ffs_vfsops.c 8.8 (Berkeley) 4/18/94 * $FreeBSD: src/sys/gnu/ext2fs/ext2_vfsops.c,v 1.63.2.7 2002/07/01 00:18:51 iedowse Exp $ - * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_vfsops.c,v 1.56 2008/01/05 14:02:41 swildner Exp $ + * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_vfsops.c,v 1.56.4.1 2008/09/25 02:20:49 dillon Exp $ */ #include "opt_quota.h" @@ -75,7 +75,8 @@ extern struct vop_ops ext2_vnode_vops; extern struct vop_ops ext2_spec_vops; extern struct vop_ops ext2_fifo_vops; -static int ext2_fhtovp (struct mount *, struct fid *, struct vnode **); +static int ext2_fhtovp (struct mount *, struct vnode *, + struct fid *, struct vnode **); static int ext2_flushfiles (struct mount *mp, int flags); static int ext2_mount (struct mount *, char *, caddr_t, struct ucred *); static int ext2_mountfs (struct vnode *, struct mount *, struct ucred *); @@ -1203,7 +1204,8 @@ kprintf("ext2_vget(%d) dbn= %d ", ino, fsbtodb(fs, ino_to_fsba(fs, ino))); * those rights via. exflagsp and credanonp */ static int -ext2_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) +ext2_fhtovp(struct mount *mp, struct vnode *rootvp, + struct fid *fhp, struct vnode **vpp) { struct ufid *ufhp; struct ext2_sb_info *fs; diff --git a/sys/vfs/hpfs/hpfs_vfsops.c b/sys/vfs/hpfs/hpfs_vfsops.c index 1ab55b5d66..298b852a72 100644 --- a/sys/vfs/hpfs/hpfs_vfsops.c +++ b/sys/vfs/hpfs/hpfs_vfsops.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/fs/hpfs/hpfs_vfsops.c,v 1.3.2.2 2001/12/25 01:44:45 dillon Exp $ - * $DragonFly: src/sys/vfs/hpfs/hpfs_vfsops.c,v 1.42 2008/01/05 14:02:41 swildner Exp $ + * $DragonFly: src/sys/vfs/hpfs/hpfs_vfsops.c,v 1.42.4.1 2008/09/25 02:20:50 dillon Exp $ */ @@ -69,12 +69,12 @@ static int hpfs_root (struct mount *, struct vnode **); static int hpfs_statfs (struct mount *, struct statfs *, struct ucred *); static int hpfs_unmount (struct mount *, int); static int hpfs_vget (struct mount *mp, ino_t ino, - struct vnode **vpp); + struct vnode **vpp); static int hpfs_mountfs (struct vnode *, struct mount *, - struct hpfs_args *); + struct hpfs_args *); static int hpfs_vptofh (struct vnode *, struct fid *); -static int hpfs_fhtovp (struct mount *, struct fid *, - struct vnode **); +static int hpfs_fhtovp (struct mount *, struct vnode *, + struct fid *, struct vnode **); struct sockaddr; @@ -419,7 +419,8 @@ hpfs_statfs(struct mount *mp, struct statfs *sbp, struct ucred *cred) /*ARGSUSED*/ static int -hpfs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) +hpfs_fhtovp(struct mount *mp, struct vnode *rootvp, + struct fid *fhp, struct vnode **vpp) { struct vnode *nvp; struct hpfid *hpfhp = (struct hpfid *)fhp; diff --git a/sys/vfs/isofs/cd9660/cd9660_vfsops.c b/sys/vfs/isofs/cd9660/cd9660_vfsops.c index 3eb9e4a134..eafd461df5 100644 --- a/sys/vfs/isofs/cd9660/cd9660_vfsops.c +++ b/sys/vfs/isofs/cd9660/cd9660_vfsops.c @@ -37,7 +37,7 @@ * * @(#)cd9660_vfsops.c 8.18 (Berkeley) 5/22/95 * $FreeBSD: src/sys/isofs/cd9660/cd9660_vfsops.c,v 1.74.2.7 2002/04/08 09:39:29 bde Exp $ - * $DragonFly: src/sys/vfs/isofs/cd9660/cd9660_vfsops.c,v 1.45 2008/01/05 14:02:41 swildner Exp $ + * $DragonFly: src/sys/vfs/isofs/cd9660/cd9660_vfsops.c,v 1.45.4.1 2008/09/25 02:20:51 dillon Exp $ */ #include @@ -74,7 +74,8 @@ static int cd9660_unmount (struct mount *, int); static int cd9660_root (struct mount *, struct vnode **); static int cd9660_statfs (struct mount *, struct statfs *, struct ucred *); static int cd9660_vget (struct mount *, ino_t, struct vnode **); -static int cd9660_fhtovp (struct mount *, struct fid *, struct vnode **); +static int cd9660_fhtovp (struct mount *, struct vnode *rootvp, + struct fid *, struct vnode **); static int cd9660_checkexp (struct mount *, struct sockaddr *, int *, struct ucred **); static int cd9660_vptofh (struct vnode *, struct fid *); @@ -616,7 +617,8 @@ struct ifid { /* ARGSUSED */ int -cd9660_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) +cd9660_fhtovp(struct mount *mp, struct vnode *rootvp, + struct fid *fhp, struct vnode **vpp) { struct ifid *ifhp = (struct ifid *)fhp; struct iso_node *ip; diff --git a/sys/vfs/msdosfs/msdosfs_vfsops.c b/sys/vfs/msdosfs/msdosfs_vfsops.c index be0ca0dc80..6c98200b03 100644 --- a/sys/vfs/msdosfs/msdosfs_vfsops.c +++ b/sys/vfs/msdosfs/msdosfs_vfsops.c @@ -1,5 +1,5 @@ /* $FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/msdosfs/Attic/msdosfs_vfsops.c,v 1.60.2.8 2004/03/02 09:43:04 tjr Exp $ */ -/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_vfsops.c,v 1.51 2008/05/20 19:14:38 dillon Exp $ */ +/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_vfsops.c,v 1.51.2.1 2008/09/25 02:20:52 dillon Exp $ */ /* $NetBSD: msdosfs_vfsops.c,v 1.51 1997/11/17 15:36:58 ws Exp $ */ /*- @@ -91,8 +91,8 @@ static MALLOC_DEFINE(M_MSDOSFSFAT, "MSDOSFS FAT", "MSDOSFS file allocation table static int update_mp (struct mount *mp, struct msdosfs_args *argp); static int mountmsdosfs (struct vnode *devvp, struct mount *mp, struct msdosfs_args *argp); -static int msdosfs_fhtovp (struct mount *, struct fid *, - struct vnode **); +static int msdosfs_fhtovp (struct mount *, struct vnode *, + struct fid *, struct vnode **); static int msdosfs_checkexp (struct mount *, struct sockaddr *, int *, struct ucred **); static int msdosfs_mount (struct mount *, char *, caddr_t, @@ -793,7 +793,8 @@ msdosfs_sync_scan(struct mount *mp, struct vnode *vp, void *data) } static int -msdosfs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) +msdosfs_fhtovp(struct mount *mp, struct vnode *rootvp, + struct fid *fhp, struct vnode **vpp) { struct msdosfsmount *pmp = VFSTOMSDOSFS(mp); struct defid *defhp = (struct defid *) fhp; diff --git a/sys/vfs/nfs/nfs.h b/sys/vfs/nfs/nfs.h index 5c50092546..f7833c38ba 100644 --- a/sys/vfs/nfs/nfs.h +++ b/sys/vfs/nfs/nfs.h @@ -35,7 +35,7 @@ * * @(#)nfs.h 8.4 (Berkeley) 5/1/95 * $FreeBSD: src/sys/nfs/nfs.h,v 1.53.2.5 2002/02/20 01:35:34 iedowse Exp $ - * $DragonFly: src/sys/vfs/nfs/nfs.h,v 1.19.8.1 2008/07/14 17:46:41 dillon Exp $ + * $DragonFly: src/sys/vfs/nfs/nfs.h,v 1.19.8.2 2008/09/25 02:20:53 dillon Exp $ */ #ifndef _NFS_NFS_H_ @@ -674,9 +674,9 @@ int nfsrv_commit (struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct thread *td, struct mbuf **mrq); int nfsrv_create (struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct thread *td, struct mbuf **mrq); -int nfsrv_fhtovp (fhandle_t *, int, struct vnode **, struct ucred *, - struct nfssvc_sock *, struct sockaddr *, int *, - int, int); +int nfsrv_fhtovp (fhandle_t *, int, struct mount **, struct vnode **, + struct ucred *, struct nfssvc_sock *, + struct sockaddr *, int *, int, int); int nfsrv_setpublicfs (struct mount *, struct netexport *, struct export_args *); int nfs_ispublicfh (fhandle_t *); diff --git a/sys/vfs/nfs/nfs_serv.c b/sys/vfs/nfs/nfs_serv.c index ffe5b0ec8e..43ff91f378 100644 --- a/sys/vfs/nfs/nfs_serv.c +++ b/sys/vfs/nfs/nfs_serv.c @@ -35,7 +35,7 @@ * * @(#)nfs_serv.c 8.8 (Berkeley) 7/31/95 * $FreeBSD: src/sys/nfs/nfs_serv.c,v 1.93.2.6 2002/12/29 18:19:53 dillon Exp $ - * $DragonFly: src/sys/vfs/nfs/nfs_serv.c,v 1.46.4.1 2008/07/14 17:46:41 dillon Exp $ + * $DragonFly: src/sys/vfs/nfs/nfs_serv.c,v 1.46.4.2 2008/09/25 02:20:53 dillon Exp $ */ /* @@ -141,8 +141,8 @@ static int nfs_commit_miss; SYSCTL_INT(_vfs_nfs, OID_AUTO, commit_blks, CTLFLAG_RW, &nfs_commit_blks, 0, ""); SYSCTL_INT(_vfs_nfs, OID_AUTO, commit_miss, CTLFLAG_RW, &nfs_commit_miss, 0, ""); -static int nfsrv_access (struct vnode *,int,struct ucred *,int, - struct thread *, int); +static int nfsrv_access (struct mount *, struct vnode *, int, + struct ucred *, int, struct thread *, int); static void nfsrvw_coalesce (struct nfsrv_descript *, struct nfsrv_descript *); @@ -158,6 +158,7 @@ nfsrv3_access(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, caddr_t dpos = nfsd->nd_dpos; struct ucred *cred = &nfsd->nd_cr; struct vnode *vp = NULL; + struct mount *mp = NULL; nfsfh_t nfh; fhandle_t *fhp; u_int32_t *tl; @@ -173,7 +174,7 @@ nfsrv3_access(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, fhp = &nfh.fh_generic; nfsm_srvmtofh(fhp); nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); - error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly, + error = nfsrv_fhtovp(fhp, 1, &mp, &vp, cred, slp, nam, &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); if (error) { nfsm_reply(NFSX_UNSIGNED); @@ -183,7 +184,7 @@ nfsrv3_access(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, } nfsmode = fxdr_unsigned(u_int32_t, *tl); if ((nfsmode & NFSV3ACCESS_READ) && - nfsrv_access(vp, VREAD, cred, rdonly, td, 0)) + nfsrv_access(mp, vp, VREAD, cred, rdonly, td, 0)) nfsmode &= ~NFSV3ACCESS_READ; if (vp->v_type == VDIR) testmode = (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND | @@ -191,14 +192,14 @@ nfsrv3_access(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, else testmode = (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND); if ((nfsmode & testmode) && - nfsrv_access(vp, VWRITE, cred, rdonly, td, 0)) + nfsrv_access(mp, vp, VWRITE, cred, rdonly, td, 0)) nfsmode &= ~testmode; if (vp->v_type == VDIR) testmode = NFSV3ACCESS_LOOKUP; else testmode = NFSV3ACCESS_EXECUTE; if ((nfsmode & testmode) && - nfsrv_access(vp, VEXEC, cred, rdonly, td, 0)) + nfsrv_access(mp, vp, VEXEC, cred, rdonly, td, 0)) nfsmode &= ~testmode; getret = VOP_GETATTR(vp, vap); vput(vp); @@ -228,6 +229,7 @@ nfsrv_getattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct vattr va; struct vattr *vap = &va; struct vnode *vp = NULL; + struct mount *mp = NULL; nfsfh_t nfh; fhandle_t *fhp; u_int32_t *tl; @@ -240,7 +242,7 @@ nfsrv_getattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); fhp = &nfh.fh_generic; nfsm_srvmtofh(fhp); - error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, + error = nfsrv_fhtovp(fhp, 1, &mp, &vp, cred, slp, nam, &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); if (error) { nfsm_reply(0); @@ -281,6 +283,7 @@ nfsrv_setattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct nfsv2_sattr *sp; struct nfs_fattr *fp; struct vnode *vp = NULL; + struct mount *mp = NULL; nfsfh_t nfh; fhandle_t *fhp; u_int32_t *tl; @@ -338,7 +341,7 @@ nfsrv_setattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, /* * Now that we have all the fields, lets do it. */ - error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly, + error = nfsrv_fhtovp(fhp, 1, &mp, &vp, cred, slp, nam, &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); if (error) { nfsm_reply(2 * NFSX_UNSIGNED); @@ -372,7 +375,7 @@ nfsrv_setattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, * just check for a read only file system. */ if (vap->va_size == ((u_quad_t)((quad_t) -1))) { - if (rdonly || (vp->v_mount->mnt_flag & MNT_RDONLY)) { + if (rdonly || (mp->mnt_flag & MNT_RDONLY)) { error = EROFS; goto out; } @@ -380,7 +383,7 @@ nfsrv_setattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, if (vp->v_type == VDIR) { error = EISDIR; goto out; - } else if ((error = nfsrv_access(vp, VWRITE, cred, rdonly, + } else if ((error = nfsrv_access(mp, vp, VWRITE, cred, rdonly, td, 0)) != 0){ goto out; } @@ -563,8 +566,7 @@ nfsrv_lookup(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, * Get underlying attribute, then release remaining resources ( for * the same potential blocking reason ) and reply. */ - bzero((caddr_t)fhp, sizeof(nfh)); - fhp->fh_fsid = vp->v_mount->mnt_stat.f_fsid; + bzero(&fhp->fh_fid, sizeof(fhp->fh_fid)); error = VFS_VPTOFH(vp, &fhp->fh_fid); if (!error) error = VOP_GETATTR(vp, vap); @@ -608,15 +610,15 @@ nfsrv_readlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct ucred *cred = &nfsd->nd_cr; struct iovec iv[(NFS_MAXPATHLEN+MLEN-1)/MLEN]; struct iovec *ivp = iv; - struct mbuf *mp; u_int32_t *tl; int32_t t1; caddr_t bpos; int error = 0, rdonly, i, tlen, len, getret; int v3 = (nfsd->nd_flag & ND_NFSV3); char *cp2; - struct mbuf *mb, *mb2, *mp2, *mp3, *mreq; + struct mbuf *mb, *mb2, *mp1, *mp2, *mp3, *mreq; struct vnode *vp = NULL; + struct mount *mp = NULL; struct vattr attr; nfsfh_t nfh; fhandle_t *fhp; @@ -632,21 +634,21 @@ nfsrv_readlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, len = 0; i = 0; while (len < NFS_MAXPATHLEN) { - mp = m_getcl(MB_WAIT, MT_DATA, 0); - mp->m_len = MCLBYTES; + mp1 = m_getcl(MB_WAIT, MT_DATA, 0); + mp1->m_len = MCLBYTES; if (len == 0) - mp3 = mp2 = mp; + mp3 = mp2 = mp1; else { - mp2->m_next = mp; - mp2 = mp; + mp2->m_next = mp1; + mp2 = mp1; } - if ((len+mp->m_len) > NFS_MAXPATHLEN) { - mp->m_len = NFS_MAXPATHLEN-len; + if ((len + mp1->m_len) > NFS_MAXPATHLEN) { + mp1->m_len = NFS_MAXPATHLEN-len; len = NFS_MAXPATHLEN; } else - len += mp->m_len; - ivp->iov_base = mtod(mp, caddr_t); - ivp->iov_len = mp->m_len; + len += mp1->m_len; + ivp->iov_base = mtod(mp1, caddr_t); + ivp->iov_len = mp1->m_len; i++; ivp++; } @@ -657,7 +659,7 @@ nfsrv_readlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, uiop->uio_rw = UIO_READ; uiop->uio_segflg = UIO_SYSSPACE; uiop->uio_td = NULL; - error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, + error = nfsrv_fhtovp(fhp, 1, &mp, &vp, cred, slp, nam, &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); if (error) { nfsm_reply(2 * NFSX_UNSIGNED); @@ -727,6 +729,7 @@ nfsrv_read(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct mbuf *mb, *mb2, *mreq; struct mbuf *m2; struct vnode *vp = NULL; + struct mount *mp = NULL; nfsfh_t nfh; fhandle_t *fhp; struct uio io, *uiop = &io; @@ -753,7 +756,7 @@ nfsrv_read(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, * as well. */ - error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, + error = nfsrv_fhtovp(fhp, 1, &mp, &vp, cred, slp, nam, &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); if (error) { vp = NULL; @@ -770,8 +773,8 @@ nfsrv_read(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, error = (vp->v_type == VDIR) ? EISDIR : EACCES; } if (!error) { - if ((error = nfsrv_access(vp, VREAD, cred, rdonly, td, 1)) != 0) - error = nfsrv_access(vp, VEXEC, cred, rdonly, td, 1); + if ((error = nfsrv_access(mp, vp, VREAD, cred, rdonly, td, 1)) != 0) + error = nfsrv_access(mp, vp, VEXEC, cred, rdonly, td, 1); } getret = VOP_GETATTR(vp, vap); if (!error) @@ -960,7 +963,7 @@ nfsrv_write(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct ucred *cred = &nfsd->nd_cr; struct iovec *ivp; int i, cnt; - struct mbuf *mp; + struct mbuf *mp1; struct nfs_fattr *fp; struct iovec *iv; struct vattr va, forat; @@ -975,6 +978,7 @@ nfsrv_write(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, char *cp2; struct mbuf *mb, *mb2, *mreq; struct vnode *vp = NULL; + struct mount *mp = NULL; nfsfh_t nfh; fhandle_t *fhp; struct uio io, *uiop = &io; @@ -1010,27 +1014,27 @@ nfsrv_write(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, */ if (len > 0) { zeroing = 1; - mp = mrep; - while (mp) { - if (mp == md) { + mp1 = mrep; + while (mp1) { + if (mp1 == md) { zeroing = 0; - adjust = dpos - mtod(mp, caddr_t); - mp->m_len -= adjust; - if (mp->m_len > 0 && adjust > 0) - NFSMADV(mp, adjust); + adjust = dpos - mtod(mp1, caddr_t); + mp1->m_len -= adjust; + if (mp1->m_len > 0 && adjust > 0) + NFSMADV(mp1, adjust); } if (zeroing) - mp->m_len = 0; - else if (mp->m_len > 0) { - i += mp->m_len; + mp1->m_len = 0; + else if (mp1->m_len > 0) { + i += mp1->m_len; if (i > len) { - mp->m_len -= (i - len); + mp1->m_len -= (i - len); zeroing = 1; } - if (mp->m_len > 0) + if (mp1->m_len > 0) cnt++; } - mp = mp->m_next; + mp1 = mp1->m_next; } } if (len > NFS_MAXDATA || len < 0 || i < len) { @@ -1040,7 +1044,7 @@ nfsrv_write(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, error = 0; goto nfsmout; } - error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, + error = nfsrv_fhtovp(fhp, 1, &mp, &vp, cred, slp, nam, &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); if (error) { vp = NULL; @@ -1058,7 +1062,7 @@ nfsrv_write(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, error = (vp->v_type == VDIR) ? EISDIR : EACCES; } if (!error) { - error = nfsrv_access(vp, VWRITE, cred, rdonly, td, 1); + error = nfsrv_access(mp, vp, VWRITE, cred, rdonly, td, 1); } if (error) { vput(vp); @@ -1074,14 +1078,14 @@ nfsrv_write(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, M_WAITOK); uiop->uio_iov = iv = ivp; uiop->uio_iovcnt = cnt; - mp = mrep; - while (mp) { - if (mp->m_len > 0) { - ivp->iov_base = mtod(mp, caddr_t); - ivp->iov_len = mp->m_len; + mp1 = mrep; + while (mp1) { + if (mp1->m_len > 0) { + ivp->iov_base = mtod(mp1, caddr_t); + ivp->iov_len = mp1->m_len; ivp++; } - mp = mp->m_next; + mp1 = mp1->m_next; } /* @@ -1159,7 +1163,6 @@ nfsrv_writegather(struct nfsrv_descript **ndp, struct nfssvc_sock *slp, struct thread *td, struct mbuf **mrq) { struct iovec *ivp; - struct mbuf *mp; struct nfsrv_descript *wp, *nfsd, *owp, *swp; struct nfs_fattr *fp; int i; @@ -1173,8 +1176,9 @@ nfsrv_writegather(struct nfsrv_descript **ndp, struct nfssvc_sock *slp, int error = 0, rdonly, len, forat_ret = 1; int ioflags, aftat_ret = 1, adjust, v3, zeroing; char *cp2; - struct mbuf *mb, *mb2, *mreq, *mrep, *md; + struct mbuf *mb, *mb2, *mreq, *mrep, *md, *mp1; struct vnode *vp = NULL; + struct mount *mp = NULL; struct uio io, *uiop = &io; u_quad_t cur_usec; @@ -1225,25 +1229,25 @@ nfsrv_writegather(struct nfsrv_descript **ndp, struct nfssvc_sock *slp, */ zeroing = 1; i = 0; - mp = mrep; - while (mp) { - if (mp == md) { + mp1 = mrep; + while (mp1) { + if (mp1 == md) { zeroing = 0; - adjust = dpos - mtod(mp, caddr_t); - mp->m_len -= adjust; - if (mp->m_len > 0 && adjust > 0) - NFSMADV(mp, adjust); + adjust = dpos - mtod(mp1, caddr_t); + mp1->m_len -= adjust; + if (mp1->m_len > 0 && adjust > 0) + NFSMADV(mp1, adjust); } if (zeroing) - mp->m_len = 0; + mp1->m_len = 0; else { - i += mp->m_len; + i += mp1->m_len; if (i > len) { - mp->m_len -= (i - len); + mp1->m_len -= (i - len); zeroing = 1; } } - mp = mp->m_next; + mp1 = mp1->m_next; } if (len > NFS_MAXDATA || len < 0 || i < len) { nfsmout: @@ -1328,7 +1332,7 @@ loop1: cred = &nfsd->nd_cr; v3 = (nfsd->nd_flag & ND_NFSV3); forat_ret = aftat_ret = 1; - error = nfsrv_fhtovp(&nfsd->nd_fh, 1, &vp, cred, slp, + error = nfsrv_fhtovp(&nfsd->nd_fh, 1, &mp, &vp, cred, slp, nfsd->nd_nam, &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); if (!error) { if (v3) @@ -1343,7 +1347,7 @@ loop1: vp = NULL; } if (!error) { - error = nfsrv_access(vp, VWRITE, cred, rdonly, td, 1); + error = nfsrv_access(mp, vp, VWRITE, cred, rdonly, td, 1); } if (nfsd->nd_stable == NFSV3WRITE_UNSTABLE) @@ -1358,25 +1362,25 @@ loop1: uiop->uio_offset = nfsd->nd_off; uiop->uio_resid = nfsd->nd_eoff - nfsd->nd_off; if (uiop->uio_resid > 0) { - mp = mrep; + mp1 = mrep; i = 0; - while (mp) { - if (mp->m_len > 0) + while (mp1) { + if (mp1->m_len > 0) i++; - mp = mp->m_next; + mp1 = mp1->m_next; } uiop->uio_iovcnt = i; MALLOC(iov, struct iovec *, i * sizeof (struct iovec), M_TEMP, M_WAITOK); uiop->uio_iov = ivp = iov; - mp = mrep; - while (mp) { - if (mp->m_len > 0) { - ivp->iov_base = mtod(mp, caddr_t); - ivp->iov_len = mp->m_len; + mp1 = mrep; + while (mp1) { + if (mp1->m_len > 0) { + ivp->iov_base = mtod(mp1, caddr_t); + ivp->iov_len = mp1->m_len; ivp++; } - mp = mp->m_next; + mp1 = mp1->m_next; } if (!error) { error = VOP_WRITE(vp, uiop, ioflags, cred); @@ -1481,7 +1485,7 @@ static void nfsrvw_coalesce(struct nfsrv_descript *owp, struct nfsrv_descript *nfsd) { int overlap; - struct mbuf *mp; + struct mbuf *mp1; struct nfsrv_descript *p; NFS_DPF(WG, ("C%03x-%03x", @@ -1494,10 +1498,10 @@ nfsrvw_coalesce(struct nfsrv_descript *owp, struct nfsrv_descript *nfsd) panic("nfsrv_coalesce: bad off"); if (overlap > 0) m_adj(nfsd->nd_mrep, overlap); - mp = owp->nd_mrep; - while (mp->m_next) - mp = mp->m_next; - mp->m_next = nfsd->nd_mrep; + mp1 = owp->nd_mrep; + while (mp1->m_next) + mp1 = mp1->m_next; + mp1->m_next = nfsd->nd_mrep; owp->nd_eoff = nfsd->nd_eoff; } else m_freem(nfsd->nd_mrep); @@ -1549,6 +1553,7 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct vnode *dirp; struct vnode *dvp; struct vnode *vp; + struct mount *mp; nfsfh_t nfh; fhandle_t *fhp; u_quad_t tempsize; @@ -1576,6 +1581,8 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, error = nfs_namei(&nd, cred, NAMEI_CREATE, &dvp, &vp, fhp, len, slp, nam, &md, &dpos, &dirp, td, (nfsd->nd_flag & ND_KERBAUTH), FALSE); + mp = vfs_getvfs(&fhp->fh_fsid); + if (dirp) { if (v3) { dirfor_ret = VOP_GETATTR(dirp, &dirfor); @@ -1740,7 +1747,7 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, } } else { if (vap->va_size != -1) { - error = nfsrv_access(vp, VWRITE, cred, + error = nfsrv_access(mp, vp, VWRITE, cred, (nd.nl_flags & NLC_NFS_RDONLY), td, 0); if (!error) { tempsize = vap->va_size; @@ -1752,8 +1759,7 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, } if (!error) { - bzero((caddr_t)fhp, sizeof(nfh)); - fhp->fh_fsid = vp->v_mount->mnt_stat.f_fsid; + bzero(&fhp->fh_fid, sizeof(fhp->fh_fid)); error = VFS_VPTOFH(vp, &fhp->fh_fid); if (!error) error = VOP_GETATTR(vp, vap); @@ -1909,8 +1915,7 @@ out: dvp = NULL; } if (!error) { - bzero((caddr_t)fhp, sizeof(nfh)); - fhp->fh_fsid = vp->v_mount->mnt_stat.f_fsid; + bzero(&fhp->fh_fid, sizeof(fhp->fh_fid)); error = VFS_VPTOFH(vp, &fhp->fh_fid); if (!error) error = VOP_GETATTR(vp, vap); @@ -2286,6 +2291,8 @@ nfsrv_link(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct vnode *dvp; struct vnode *vp; struct vnode *xp; + struct mount *mp; + struct mount *xmp; struct vattr dirfor, diraft, at; nfsfh_t nfh, dnfh; fhandle_t *fhp, *dfhp; @@ -2293,6 +2300,7 @@ nfsrv_link(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); nlookup_zero(&nd); dirp = dvp = vp = xp = NULL; + mp = xmp = NULL; fhp = &nfh.fh_generic; dfhp = &dnfh.fh_generic; @@ -2300,7 +2308,7 @@ nfsrv_link(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, nfsm_srvmtofh(dfhp); nfsm_srvnamesiz(len); - error = nfsrv_fhtovp(fhp, FALSE, &xp, cred, slp, nam, + error = nfsrv_fhtovp(fhp, FALSE, &xmp, &xp, cred, slp, nam, &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); if (error) { nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3)); @@ -2452,8 +2460,7 @@ nfsrv_symlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, vrele(dvp); dvp = NULL; if (error == 0) { - bzero((caddr_t)fhp, sizeof(nfh)); - fhp->fh_fsid = vp->v_mount->mnt_stat.f_fsid; + bzero(&fhp->fh_fid, sizeof(fhp->fh_fid)); error = VFS_VPTOFH(vp, &fhp->fh_fid); if (!error) error = VOP_GETATTR(vp, vap); @@ -2585,8 +2592,7 @@ nfsrv_mkdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, dvp = NULL; if (error == 0) { - bzero((caddr_t)fhp, sizeof(nfh)); - fhp->fh_fsid = vp->v_mount->mnt_stat.f_fsid; + bzero(&fhp->fh_fid, sizeof(fhp->fh_fid)); error = VFS_VPTOFH(vp, &fhp->fh_fid); if (error == 0) error = VOP_GETATTR(vp, vap); @@ -2770,15 +2776,15 @@ nfsrv_readdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, caddr_t dpos = nfsd->nd_dpos; struct ucred *cred = &nfsd->nd_cr; char *bp, *be; - struct mbuf *mp; struct dirent *dp; caddr_t cp; u_int32_t *tl; int32_t t1; caddr_t bpos; - struct mbuf *mb, *mb2, *mreq, *mp2; + struct mbuf *mb, *mb2, *mreq, *mp1, *mp2; char *cpos, *cend, *cp2, *rbuf; struct vnode *vp = NULL; + struct mount *mp = NULL; struct vattr at; nfsfh_t nfh; fhandle_t *fhp; @@ -2813,7 +2819,7 @@ nfsrv_readdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, if (siz > xfer) siz = xfer; fullsiz = siz; - error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, + error = nfsrv_fhtovp(fhp, 1, &mp, &vp, cred, slp, nam, &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); if (!error && vp->v_type != VDIR) { error = ENOTDIR; @@ -2842,7 +2848,7 @@ nfsrv_readdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, #endif } if (!error) - error = nfsrv_access(vp, VEXEC, cred, rdonly, td, 0); + error = nfsrv_access(mp, vp, VEXEC, cred, rdonly, td, 0); if (error) { vput(vp); vp = NULL; @@ -2956,9 +2962,9 @@ again: nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); txdr_hyper(at.va_filerev, tl); } - mp = mp2 = mb; + mp1 = mp2 = mb; bp = bpos; - be = bp + M_TRAILINGSPACE(mp); + be = bp + M_TRAILINGSPACE(mp1); /* Loop through the records and build reply */ while (cpos < cend && ncookies > 0) { @@ -2976,18 +2982,18 @@ again: * Build the directory record xdr from * the dirent entry. */ - nfsm_clget; + nfsm_clget(mp1, mp2, mb, bp, be, tl); *tl = nfs_true; bp += NFSX_UNSIGNED; if (v3) { - nfsm_clget; + nfsm_clget(mp1, mp2, mb, bp, be, tl); *tl = 0; bp += NFSX_UNSIGNED; } - nfsm_clget; + nfsm_clget(mp1, mp2, mb, bp, be, tl); *tl = txdr_unsigned(dp->d_ino); bp += NFSX_UNSIGNED; - nfsm_clget; + nfsm_clget(mp1, mp2, mb, bp, be, tl); *tl = txdr_unsigned(nlen); bp += NFSX_UNSIGNED; @@ -2995,7 +3001,7 @@ again: xfer = nlen; cp = dp->d_name; while (xfer > 0) { - nfsm_clget; + nfsm_clget(mp1, mp2, mb, bp, be, tl); if ((bp+xfer) > be) tsiz = be-bp; else @@ -3009,13 +3015,13 @@ again: /* And null pad to a int32_t boundary */ for (i = 0; i < rem; i++) *bp++ = '\0'; - nfsm_clget; + nfsm_clget(mp1, mp2, mb, bp, be, tl); /* Finish off the record */ if (v3) { *tl = txdr_unsigned(*cookiep >> 32); bp += NFSX_UNSIGNED; - nfsm_clget; + nfsm_clget(mp1, mp2, mb, bp, be, tl); } *tl = txdr_unsigned(*cookiep); bp += NFSX_UNSIGNED; @@ -3027,20 +3033,20 @@ again: } vrele(vp); vp = NULL; - nfsm_clget; + nfsm_clget(mp1, mp2, mb, bp, be, tl); *tl = nfs_false; bp += NFSX_UNSIGNED; - nfsm_clget; + nfsm_clget(mp1, mp2, mb, bp, be, tl); if (eofflag) *tl = nfs_true; else *tl = nfs_false; bp += NFSX_UNSIGNED; - if (mp != mb) { + if (mp1 != mb) { if (bp < be) - mp->m_len = bp - mtod(mp, caddr_t); + mp1->m_len = bp - mtod(mp1, caddr_t); } else - mp->m_len += bp - bpos; + mp1->m_len += bp - bpos; FREE((caddr_t)rbuf, M_TEMP); FREE((caddr_t)cookies, M_TEMP); @@ -3059,15 +3065,15 @@ nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, caddr_t dpos = nfsd->nd_dpos; struct ucred *cred = &nfsd->nd_cr; char *bp, *be; - struct mbuf *mp; struct dirent *dp; caddr_t cp; u_int32_t *tl; int32_t t1; caddr_t bpos; - struct mbuf *mb, *mb2, *mreq, *mp2; + struct mbuf *mb, *mb2, *mreq, *mp1, *mp2; char *cpos, *cend, *cp2, *rbuf; struct vnode *vp = NULL, *nvp; + struct mount *mp = NULL; struct flrep fl; nfsfh_t nfh; fhandle_t *fhp, *nfhp = (fhandle_t *)fl.fl_nfh; @@ -3098,7 +3104,7 @@ nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, if (siz > xfer) siz = xfer; fullsiz = siz; - error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, + error = nfsrv_fhtovp(fhp, 1, &mp, &vp, cred, slp, nam, &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); if (!error && vp->v_type != VDIR) { error = ENOTDIR; @@ -3120,7 +3126,7 @@ nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, error = NFSERR_BAD_COOKIE; #endif if (!error) { - error = nfsrv_access(vp, VEXEC, cred, rdonly, td, 0); + error = nfsrv_access(mp, vp, VEXEC, cred, rdonly, td, 0); } if (error) { vput(vp); @@ -3244,9 +3250,9 @@ again: nfsm_srvpostop_attr(getret, &at); nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); txdr_hyper(at.va_filerev, tl); - mp = mp2 = mb; + mp1 = mp2 = mb; bp = bpos; - be = bp + M_TRAILINGSPACE(mp); + be = bp + M_TRAILINGSPACE(mp1); /* Loop through the records and build reply */ while (cpos < cend && ncookies > 0) { @@ -3261,8 +3267,7 @@ again: if (VFS_VGET(vp->v_mount, dp->d_ino, &nvp)) goto invalid; bzero((caddr_t)nfhp, NFSX_V3FH); - nfhp->fh_fsid = - nvp->v_mount->mnt_stat.f_fsid; + nfhp->fh_fsid = fhp->fh_fsid; if (VFS_VPTOFH(nvp, &nfhp->fh_fid)) { vput(nvp); nvp = NULL; @@ -3302,16 +3307,16 @@ again: fl.fl_off.nfsuquad[0] = txdr_unsigned(*cookiep >> 32); fl.fl_off.nfsuquad[1] = txdr_unsigned(*cookiep); - nfsm_clget; + nfsm_clget(mp1, mp2, mb, bp, be, tl); *tl = nfs_true; bp += NFSX_UNSIGNED; - nfsm_clget; + nfsm_clget(mp1, mp2, mb, bp, be, tl); *tl = 0; bp += NFSX_UNSIGNED; - nfsm_clget; + nfsm_clget(mp1, mp2, mb, bp, be, tl); *tl = txdr_unsigned(dp->d_ino); bp += NFSX_UNSIGNED; - nfsm_clget; + nfsm_clget(mp1, mp2, mb, bp, be, tl); *tl = txdr_unsigned(nlen); bp += NFSX_UNSIGNED; @@ -3319,7 +3324,7 @@ again: xfer = nlen; cp = dp->d_name; while (xfer > 0) { - nfsm_clget; + nfsm_clget(mp1, mp2, mb, bp, be, tl); if ((bp + xfer) > be) tsiz = be - bp; else @@ -3340,7 +3345,7 @@ again: xfer = sizeof (struct flrep); cp = (caddr_t)&fl; while (xfer > 0) { - nfsm_clget; + nfsm_clget(mp1, mp2, mb, bp, be, tl); if ((bp + xfer) > be) tsiz = be - bp; else @@ -3360,20 +3365,20 @@ invalid: } vrele(vp); vp = NULL; - nfsm_clget; + nfsm_clget(mp1, mp2, mb, bp, be, tl); *tl = nfs_false; bp += NFSX_UNSIGNED; - nfsm_clget; + nfsm_clget(mp1, mp2, mb, bp, be, tl); if (eofflag) *tl = nfs_true; else *tl = nfs_false; bp += NFSX_UNSIGNED; - if (mp != mb) { + if (mp1 != mb) { if (bp < be) - mp->m_len = bp - mtod(mp, caddr_t); + mp1->m_len = bp - mtod(mp1, caddr_t); } else - mp->m_len += bp - bpos; + mp1->m_len += bp - bpos; FREE((caddr_t)cookies, M_TEMP); FREE((caddr_t)rbuf, M_TEMP); nfsmout: @@ -3395,6 +3400,7 @@ nfsrv_commit(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct ucred *cred = &nfsd->nd_cr; struct vattr bfor, aft; struct vnode *vp = NULL; + struct mount *mp = NULL; nfsfh_t nfh; fhandle_t *fhp; u_int32_t *tl; @@ -3417,7 +3423,7 @@ nfsrv_commit(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, off = fxdr_hyper(tl); tl += 2; cnt = fxdr_unsigned(int, *tl); - error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, + error = nfsrv_fhtovp(fhp, 1, &mp, &vp, cred, slp, nam, &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); if (error) { nfsm_reply(2 * NFSX_UNSIGNED); @@ -3534,6 +3540,7 @@ nfsrv_statfs(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, char *cp2; struct mbuf *mb, *mb2, *mreq; struct vnode *vp = NULL; + struct mount *mp = NULL; struct vattr at; nfsfh_t nfh; fhandle_t *fhp; @@ -3543,7 +3550,7 @@ nfsrv_statfs(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); fhp = &nfh.fh_generic; nfsm_srvmtofh(fhp); - error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, + error = nfsrv_fhtovp(fhp, 1, &mp, &vp, cred, slp, nam, &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); if (error) { nfsm_reply(NFSX_UNSIGNED); @@ -3613,6 +3620,7 @@ nfsrv_fsinfo(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, char *cp2; struct mbuf *mb, *mb2, *mreq; struct vnode *vp = NULL; + struct mount *mp = NULL; struct vattr at; nfsfh_t nfh; fhandle_t *fhp; @@ -3622,7 +3630,7 @@ nfsrv_fsinfo(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); fhp = &nfh.fh_generic; nfsm_srvmtofh(fhp); - error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, + error = nfsrv_fhtovp(fhp, 1, &mp, &vp, cred, slp, nam, &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); if (error) { nfsm_reply(NFSX_UNSIGNED); @@ -3690,6 +3698,7 @@ nfsrv_pathconf(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, char *cp2; struct mbuf *mb, *mb2, *mreq; struct vnode *vp = NULL; + struct mount *mp = NULL; struct vattr at; nfsfh_t nfh; fhandle_t *fhp; @@ -3697,7 +3706,7 @@ nfsrv_pathconf(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); fhp = &nfh.fh_generic; nfsm_srvmtofh(fhp); - error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, + error = nfsrv_fhtovp(fhp, 1, &mp, &vp, cred, slp, nam, &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); if (error) { nfsm_reply(NFSX_UNSIGNED); @@ -3797,7 +3806,7 @@ nfsrv_noop(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, * will return EPERM instead of EACCESS. EPERM is always an error. */ static int -nfsrv_access(struct vnode *vp, int flags, struct ucred *cred, +nfsrv_access(struct mount *mp, struct vnode *vp, int flags, struct ucred *cred, int rdonly, struct thread *td, int override) { struct vattr vattr; @@ -3811,7 +3820,8 @@ nfsrv_access(struct vnode *vp, int flags, struct ucred *cred, * unless the file is a socket or a block or character * device resident on the file system. */ - if (rdonly || (vp->v_mount->mnt_flag & MNT_RDONLY)) { + if (rdonly || + ((mp->mnt_flag | vp->v_mount->mnt_flag) & MNT_RDONLY)) { switch (vp->v_type) { case VREG: case VDIR: diff --git a/sys/vfs/nfs/nfs_subs.c b/sys/vfs/nfs/nfs_subs.c index 271a352fdc..26db6e93df 100644 --- a/sys/vfs/nfs/nfs_subs.c +++ b/sys/vfs/nfs/nfs_subs.c @@ -35,7 +35,7 @@ * * @(#)nfs_subs.c 8.8 (Berkeley) 5/22/95 * $FreeBSD: /repoman/r/ncvs/src/sys/nfsclient/nfs_subs.c,v 1.128 2004/04/14 23:23:55 peadar Exp $ - * $DragonFly: src/sys/vfs/nfs/nfs_subs.c,v 1.47 2007/11/02 19:52:28 dillon Exp $ + * $DragonFly: src/sys/vfs/nfs/nfs_subs.c,v 1.47.4.1 2008/09/25 02:20:53 dillon Exp $ */ /* @@ -1457,6 +1457,7 @@ nfs_namei(struct nlookupdata *nd, struct ucred *cred, int nameiop, char *namebuf; struct nchandle nch; struct vnode *dp; + struct mount *mp; int error, rdonly; namebuf = objcache_get(namei_oc, M_WAITOK); @@ -1502,7 +1503,7 @@ nfs_namei(struct nlookupdata *nd, struct ucred *cred, int nameiop, * Extract and set starting directory. The returned dp is refd * but not locked. */ - error = nfsrv_fhtovp(fhp, FALSE, &dp, cred, slp, + error = nfsrv_fhtovp(fhp, FALSE, &mp, &dp, cred, slp, nam, &rdonly, kerbflag, pubflag); if (error) goto out; @@ -1805,7 +1806,8 @@ nfsm_srvfattr(struct nfsrv_descript *nfsd, struct vattr *vap, * - if not lockflag unlock it with vn_unlock() */ int -nfsrv_fhtovp(fhandle_t *fhp, int lockflag, struct vnode **vpp, +nfsrv_fhtovp(fhandle_t *fhp, int lockflag, + struct mount **mpp, struct vnode **vpp, struct ucred *cred, struct nfssvc_sock *slp, struct sockaddr *nam, int *rdonlyp, int kerbflag, int pubflag) { @@ -1817,7 +1819,8 @@ nfsrv_fhtovp(fhandle_t *fhp, int lockflag, struct vnode **vpp, struct sockaddr_int *saddr; #endif - *vpp = (struct vnode *)0; + *vpp = NULL; + *mpp = NULL; if (nfs_ispublicfh(fhp)) { if (!pubflag || !nfs_pub.np_valid) @@ -1825,13 +1828,13 @@ nfsrv_fhtovp(fhandle_t *fhp, int lockflag, struct vnode **vpp, fhp = &nfs_pub.np_handle; } - mp = vfs_getvfs(&fhp->fh_fsid); - if (!mp) + mp = *mpp = vfs_getvfs(&fhp->fh_fsid); + if (mp == NULL) return (ESTALE); error = VFS_CHECKEXP(mp, nam, &exflags, &credanon); if (error) return (error); - error = VFS_FHTOVP(mp, &fhp->fh_fid, vpp); + error = VFS_FHTOVP(mp, NULL, &fhp->fh_fid, vpp); if (error) return (error); #ifdef MNT_EXNORESPORT diff --git a/sys/vfs/nfs/nfsm_subs.h b/sys/vfs/nfs/nfsm_subs.h index c9fa45f61a..de44cfe63f 100644 --- a/sys/vfs/nfs/nfsm_subs.h +++ b/sys/vfs/nfs/nfsm_subs.h @@ -35,7 +35,7 @@ * * @(#)nfsm_subs.h 8.2 (Berkeley) 3/30/95 * $FreeBSD: src/sys/nfs/nfsm_subs.h,v 1.27.2.1 2000/10/28 16:27:27 dwmalone Exp $ - * $DragonFly: src/sys/vfs/nfs/nfsm_subs.h,v 1.9 2006/03/27 16:18:39 dillon Exp $ + * $DragonFly: src/sys/vfs/nfs/nfsm_subs.h,v 1.9.10.1 2008/09/25 02:20:53 dillon Exp $ */ @@ -494,17 +494,17 @@ struct mbuf *nfsm_rpchead (struct ucred *cr, int nmflag, int procid, } \ } while (0) -#define nfsm_clget \ +#define nfsm_clget(mp1, mp2, mb, bp, be, tl) \ do { \ if (bp >= be) { \ - if (mp == mb) \ - mp->m_len += bp-bpos; \ - mp = m_getcl(MB_WAIT, MT_DATA, 0); \ - mp->m_len = MCLBYTES; \ - mp2->m_next = mp; \ - mp2 = mp; \ - bp = mtod(mp, caddr_t); \ - be = bp+mp->m_len; \ + if (mp1 == mb) \ + mp1->m_len += bp-bpos; \ + mp1 = m_getcl(MB_WAIT, MT_DATA, 0); \ + mp1->m_len = MCLBYTES; \ + mp2->m_next = mp1; \ + mp2 = mp1; \ + bp = mtod(mp1, caddr_t); \ + be = bp+mp1->m_len; \ } \ tl = (u_int32_t *)bp; \ } while (0) diff --git a/sys/vfs/ntfs/ntfs_vfsops.c b/sys/vfs/ntfs/ntfs_vfsops.c index 4d5b2d1b06..b527329e22 100644 --- a/sys/vfs/ntfs/ntfs_vfsops.c +++ b/sys/vfs/ntfs/ntfs_vfsops.c @@ -26,7 +26,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/ntfs/ntfs_vfsops.c,v 1.20.2.5 2001/12/25 01:44:45 dillon Exp $ - * $DragonFly: src/sys/vfs/ntfs/ntfs_vfsops.c,v 1.47 2008/01/05 14:02:41 swildner Exp $ + * $DragonFly: src/sys/vfs/ntfs/ntfs_vfsops.c,v 1.47.4.1 2008/09/25 02:20:54 dillon Exp $ */ @@ -86,8 +86,8 @@ static int ntfs_vget (struct mount *mp, ino_t ino, struct vnode **vpp); static int ntfs_mountfs (struct vnode *, struct mount *, struct ntfs_args *, struct ucred *); static int ntfs_vptofh (struct vnode *, struct fid *); -static int ntfs_fhtovp (struct mount *, struct fid *, - struct vnode **); +static int ntfs_fhtovp (struct mount *, struct vnode *rootvp, + struct fid *, struct vnode **); #if !defined (__DragonFly__) static int ntfs_quotactl (struct mount *, int, uid_t, caddr_t, @@ -778,7 +778,8 @@ ntfs_sync(struct mount *mp, int waitfor, struct ucred *cred, struct thread *td) /*ARGSUSED*/ static int -ntfs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) +ntfs_fhtovp(struct mount *mp, struct vnode *rootvp, + struct fid *fhp, struct vnode **vpp) { struct vnode *nvp; struct ntfid *ntfhp = (struct ntfid *)fhp; diff --git a/sys/vfs/nullfs/null.h b/sys/vfs/nullfs/null.h index df766fd601..11b2d6bc4c 100644 --- a/sys/vfs/nullfs/null.h +++ b/sys/vfs/nullfs/null.h @@ -36,18 +36,23 @@ * @(#)null.h 8.3 (Berkeley) 8/20/94 * * $FreeBSD: src/sys/miscfs/nullfs/null.h,v 1.11.2.3 2001/06/26 04:20:09 bp Exp $ - * $DragonFly: src/sys/vfs/nullfs/null.h,v 1.8 2006/12/23 00:41:30 swildner Exp $ + * $DragonFly: src/sys/vfs/nullfs/null.h,v 1.8.8.1 2008/09/25 02:20:55 dillon Exp $ */ struct null_args { char *target; /* Target of loopback */ }; +#if defined(_KERNEL) || defined(_KERNEL_STRUCTURES) + struct null_mount { struct mount *nullm_vfs; struct vnode *nullm_rootvp; /* Reference to root null_node */ + struct netexport export; }; +#endif + #ifdef _KERNEL #define MOUNTTONULLMOUNT(mp) ((struct null_mount *)((mp)->mnt_data)) @@ -57,4 +62,7 @@ struct null_mount { #define NULLFSDEBUG(format, args...) #endif /* NULLFS_DEBUG */ +int nullfs_export(struct mount *mp, int op, + const struct export_args *export); + #endif /* _KERNEL */ diff --git a/sys/vfs/nullfs/null_vfsops.c b/sys/vfs/nullfs/null_vfsops.c index 7e646ed4cc..a75fd4ce51 100644 --- a/sys/vfs/nullfs/null_vfsops.c +++ b/sys/vfs/nullfs/null_vfsops.c @@ -37,7 +37,7 @@ * * @(#)lofs_vfsops.c 1.2 (Berkeley) 6/18/92 * $FreeBSD: src/sys/miscfs/nullfs/null_vfsops.c,v 1.35.2.3 2001/07/26 20:37:11 iedowse Exp $ - * $DragonFly: src/sys/vfs/nullfs/null_vfsops.c,v 1.29 2006/10/27 04:56:34 dillon Exp $ + * $DragonFly: src/sys/vfs/nullfs/null_vfsops.c,v 1.29.8.1 2008/09/25 02:20:55 dillon Exp $ */ /* @@ -53,6 +53,7 @@ #include #include #include +#include #include "null.h" extern struct vop_ops null_vnode_vops; @@ -75,6 +76,7 @@ nullfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred) struct null_mount *xmp; u_int size; struct nlookupdata nd; + fhandle_t fh; NULLFSDEBUG("nullfs_mount(mp = %p)\n", (void *)mp); @@ -107,7 +109,7 @@ nullfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred) goto fail2; xmp = (struct null_mount *) kmalloc(sizeof(struct null_mount), - M_NULLFSMNT, M_WAITOK); /* XXX */ + M_NULLFSMNT, M_WAITOK | M_ZERO); /* * Save reference to underlying FS @@ -121,8 +123,26 @@ nullfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred) * want to set it on the base directory being mounted to prevent * that directory from being destroyed out from under the nullfs * mount. + * + * The forwarding mount pointer (xmp->nullm_vfs) must be set to + * the actual target filesystem. If the target filesystem was + * resolved via a nullfs mount nd.nl_nch.mount will be pointing + * to the nullfs mount structure instead of the target filesystem, + * which would otherwise cause the mount VOPS and VFSOPS to recurse + * endlessly. If we are mounting via a nullfs mount we inherit + * its read-only state, if set. */ xmp->nullm_vfs = nd.nl_nch.mount; + if (xmp->nullm_vfs != rootvp->v_mount) { + if (xmp->nullm_vfs->mnt_flag & MNT_RDONLY) + mp->mnt_flag |= MNT_RDONLY; + xmp->nullm_vfs = rootvp->v_mount; + } + + /* + * ncmountpt is the parent glue. When mounting a nullfs via a nullfs + * we retain the parent nullfs to create a unique chain tuple. + */ mp->mnt_ncmountpt = nd.nl_nch; cache_changemount(&mp->mnt_ncmountpt, mp); mp->mnt_ncmountpt.ncp->nc_flag |= NCF_ISMOUNTPT; @@ -147,7 +167,19 @@ nullfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred) if (xmp->nullm_vfs->mnt_flag & MNT_LOCAL) mp->mnt_flag |= MNT_LOCAL; mp->mnt_data = (qaddr_t) xmp; - vfs_getnewfsid(mp); + + /* + * Try to create a unique but non-random fsid for the nullfs to + * allow it to be exported via NFS. + */ + bzero(&fh, sizeof(fh)); + fh.fh_fsid = rootvp->v_mount->mnt_stat.f_fsid; + if (VFS_VPTOFH(rootvp, &fh.fh_fid) == 0) { + fh.fh_fsid.val[1] ^= crc32(&fh.fh_fid, sizeof(fh.fh_fid)); + vfs_setfsid(mp, &fh.fh_fsid); + } else { + vfs_getnewfsid(mp); + } (void) copyinstr(args.target, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &size); @@ -252,13 +284,71 @@ nullfs_statfs(struct mount *mp, struct statfs *sbp, struct ucred *cred) return (0); } +/* + * Implement NFS export tracking + */ static int nullfs_checkexp(struct mount *mp, struct sockaddr *nam, int *extflagsp, struct ucred **credanonp) { + struct null_mount *xmp = (void *)mp->mnt_data; + struct netcred *np; + int error; + np = vfs_export_lookup(mp, &xmp->export, nam); + if (np) { + *extflagsp = np->netc_exflags; + *credanonp = &np->netc_anon; + error = 0; + } else { + error = EACCES; + } + return(error); +#if 0 return VFS_CHECKEXP(MOUNTTONULLMOUNT(mp)->nullm_vfs, nam, extflagsp, credanonp); +#endif +} + +int +nullfs_export(struct mount *mp, int op, const struct export_args *export) +{ + struct null_mount *xmp = (void *)mp->mnt_data; + int error; + + switch(op) { + case MOUNTCTL_SET_EXPORT: + error = vfs_export(mp, &xmp->export, export); + break; + default: + error = EOPNOTSUPP; + break; + } + return(error); +} + +/* + * Pass through file handle conversion functions. + */ +static int +nullfs_vptofh(struct vnode *vp, struct fid *fhp) +{ + return VFS_VPTOFH(vp, fhp); +} + +/* + * Pass through file handle conversion functions. + * + * NOTE: currently only HAMMER uses rootvp. HAMMER uses rootvp only + * to enforce PFS isolation. + */ +static int +nullfs_fhtovp(struct mount *mp, struct vnode *rootvp, + struct fid *fhp, struct vnode **vpp) +{ + struct null_mount *xmp = MOUNTTONULLMOUNT(mp); + + return VFS_FHTOVP(xmp->nullm_vfs, xmp->nullm_rootvp, fhp, vpp); } static int @@ -277,8 +367,10 @@ static struct vfsops null_vfsops = { .vfs_quotactl = nullfs_quotactl, .vfs_statfs = nullfs_statfs, .vfs_sync = vfs_stdsync, - .vfs_checkexp = nullfs_checkexp, - .vfs_extattrctl = nullfs_extattrctl + .vfs_extattrctl = nullfs_extattrctl, + .vfs_fhtovp = nullfs_fhtovp, + .vfs_vptofh = nullfs_vptofh, + .vfs_checkexp = nullfs_checkexp }; VFS_SET(null_vfsops, null, VFCF_LOOPBACK); diff --git a/sys/vfs/nullfs/null_vnops.c b/sys/vfs/nullfs/null_vnops.c index f46b3deeca..44df527ffe 100644 --- a/sys/vfs/nullfs/null_vnops.c +++ b/sys/vfs/nullfs/null_vnops.c @@ -38,7 +38,7 @@ * Ancestors: * @(#)lofs_vnops.c 1.2 (Berkeley) 6/18/92 * $FreeBSD: src/sys/miscfs/nullfs/null_vnops.c,v 1.38.2.6 2002/07/31 00:32:28 semenu Exp $ - * $DragonFly: src/sys/vfs/nullfs/null_vnops.c,v 1.28 2006/10/27 04:56:34 dillon Exp $ + * $DragonFly: src/sys/vfs/nullfs/null_vnops.c,v 1.28.8.1 2008/09/25 02:20:55 dillon Exp $ * ...and... * @(#)null_vnodeops.c 1.20 92/07/07 UCLA Ficus project * @@ -88,7 +88,7 @@ * passed on operation to their underlying peer. * * However, with the current implementation nullfs doesn't have any private - * vnodes, it rather relies on DragonFly's namecache API. That gives a much + * vnodes, rather it relies on DragonFly's namecache API. That gives a much * more lightweight null layer, as namecache structures are pure data, with * no private operations, so there is no need of subtle dispatching routines. * @@ -105,6 +105,7 @@ #include #include #include +#include #include #include #include @@ -121,6 +122,7 @@ static int null_nwhiteout(struct vop_nwhiteout_args *ap); static int null_nremove(struct vop_nremove_args *ap); static int null_nrmdir(struct vop_nrmdir_args *ap); static int null_nrename(struct vop_nrename_args *ap); +static int null_mountctl(struct vop_mountctl_args *ap); static int null_nresolve(struct vop_nresolve_args *ap) @@ -208,6 +210,33 @@ null_nrename(struct vop_nrename_args *ap) return vop_nrename_ap(ap); } +static int +null_mountctl(struct vop_mountctl_args *ap) +{ + struct mount *mp; + int error; + + mp = ap->a_head.a_ops->head.vv_mount; + + switch(ap->a_op) { + case MOUNTCTL_SET_EXPORT: + if (ap->a_ctllen != sizeof(struct export_args)) + error = EINVAL; + else + error = nullfs_export(mp, ap->a_op, (const void *)ap->a_ctl); + break; + default: + error = EOPNOTSUPP; + break; + } + return (error); +#if 0 + ap->a_head.a_ops = MOUNTTONULLMOUNT(ap->a_nch->mount)->nullm_vfs->mnt_vn_norm_ops; + + return vop_mountctl_ap(ap); +#endif +} + /* * Global vfs data structures */ @@ -221,6 +250,7 @@ struct vop_ops null_vnode_vops = { .vop_nwhiteout = null_nwhiteout, .vop_nremove = null_nremove, .vop_nrmdir = null_nrmdir, - .vop_nrename = null_nrename + .vop_nrename = null_nrename, + .vop_mountctl = null_mountctl }; diff --git a/sys/vfs/udf/udf_vfsops.c b/sys/vfs/udf/udf_vfsops.c index a906cbabac..675a8e48b2 100644 --- a/sys/vfs/udf/udf_vfsops.c +++ b/sys/vfs/udf/udf_vfsops.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/fs/udf/udf_vfsops.c,v 1.16 2003/11/05 06:56:08 scottl Exp $ - * $DragonFly: src/sys/vfs/udf/udf_vfsops.c,v 1.27 2008/01/06 16:55:53 swildner Exp $ + * $DragonFly: src/sys/vfs/udf/udf_vfsops.c,v 1.27.4.1 2008/09/25 02:20:56 dillon Exp $ */ /* udf_vfsops.c */ @@ -103,7 +103,8 @@ static int udf_mount(struct mount *, char *, caddr_t, struct ucred *); static int udf_unmount(struct mount *, int); static int udf_root(struct mount *, struct vnode **); static int udf_statfs(struct mount *, struct statfs *, struct ucred *); -static int udf_fhtovp(struct mount *, struct fid *, struct vnode **); +static int udf_fhtovp(struct mount *, struct vnode *, + struct fid *, struct vnode **); static int udf_vptofh(struct vnode *, struct fid *); static int udf_find_partmaps(struct udf_mnt *, struct logvol_desc *); @@ -583,7 +584,8 @@ struct ifid { }; static int -udf_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) +udf_fhtovp(struct mount *mp, struct vnode *rootvp, + struct fid *fhp, struct vnode **vpp) { struct ifid *ifhp; struct vnode *nvp; diff --git a/sys/vfs/ufs/ffs_extern.h b/sys/vfs/ufs/ffs_extern.h index 777e0d37c7..368034b4f3 100644 --- a/sys/vfs/ufs/ffs_extern.h +++ b/sys/vfs/ufs/ffs_extern.h @@ -32,7 +32,7 @@ * * @(#)ffs_extern.h 8.6 (Berkeley) 3/30/95 * $FreeBSD: src/sys/ufs/ffs/ffs_extern.h,v 1.30 2000/01/09 22:40:02 mckusick Exp $ - * $DragonFly: src/sys/vfs/ufs/ffs_extern.h,v 1.14 2006/05/26 19:57:33 dillon Exp $ + * $DragonFly: src/sys/vfs/ufs/ffs_extern.h,v 1.14.10.1 2008/09/25 02:20:57 dillon Exp $ */ #ifndef _VFS_UFS_EXTERN_H @@ -79,7 +79,8 @@ void ffs_blkfree(struct inode *, ufs_daddr_t, long); ufs_daddr_t ffs_blkpref(struct inode *, ufs_daddr_t, int, ufs_daddr_t *); int ffs_bmap(struct vop_bmap_args *); void ffs_clrblock(struct fs *, u_char *, ufs_daddr_t); -int ffs_fhtovp(struct mount *, struct fid *, struct vnode **); +int ffs_fhtovp(struct mount *, struct vnode *, + struct fid *, struct vnode **); int ffs_flushfiles(struct mount *, int); void ffs_fragacct(struct fs *, int, int32_t [], int); int ffs_freefile( struct vnode *, ino_t, int ); diff --git a/sys/vfs/ufs/ffs_vfsops.c b/sys/vfs/ufs/ffs_vfsops.c index ebeb848566..fa83192523 100644 --- a/sys/vfs/ufs/ffs_vfsops.c +++ b/sys/vfs/ufs/ffs_vfsops.c @@ -32,7 +32,7 @@ * * @(#)ffs_vfsops.c 8.31 (Berkeley) 5/20/95 * $FreeBSD: src/sys/ufs/ffs/ffs_vfsops.c,v 1.117.2.10 2002/06/23 22:34:52 iedowse Exp $ - * $DragonFly: src/sys/vfs/ufs/ffs_vfsops.c,v 1.58 2008/01/05 14:02:41 swildner Exp $ + * $DragonFly: src/sys/vfs/ufs/ffs_vfsops.c,v 1.58.4.1 2008/09/25 02:20:57 dillon Exp $ */ #include "opt_quota.h" @@ -1210,7 +1210,8 @@ restart: * those rights via. exflagsp and credanonp */ int -ffs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) +ffs_fhtovp(struct mount *mp, struct vnode *rootvp, + struct fid *fhp, struct vnode **vpp) { struct ufid *ufhp; struct fs *fs; @@ -1220,7 +1221,7 @@ ffs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) if (ufhp->ufid_ino < ROOTINO || ufhp->ufid_ino >= fs->fs_ncg * fs->fs_ipg) return (ESTALE); - return (ufs_fhtovp(mp, ufhp, vpp)); + return (ufs_fhtovp(mp, rootvp, ufhp, vpp)); } /* diff --git a/sys/vfs/ufs/ufs_extern.h b/sys/vfs/ufs/ufs_extern.h index 79489107d2..7c74626c23 100644 --- a/sys/vfs/ufs/ufs_extern.h +++ b/sys/vfs/ufs/ufs_extern.h @@ -32,7 +32,7 @@ * * @(#)ufs_extern.h 8.10 (Berkeley) 5/14/95 * $FreeBSD: src/sys/ufs/ufs/ufs_extern.h,v 1.27.2.1 2000/12/28 11:01:46 ps Exp $ - * $DragonFly: src/sys/vfs/ufs/ufs_extern.h,v 1.15 2006/09/10 01:26:41 dillon Exp $ + * $DragonFly: src/sys/vfs/ufs/ufs_extern.h,v 1.15.8.1 2008/09/25 02:20:57 dillon Exp $ */ #ifndef _VFS_UFS_EXTERN_H_ @@ -64,7 +64,8 @@ int ufs_bmaparray(struct vnode *, daddr_t, daddr_t *, struct indir *, int *, int *, int *); int ufs_check_export(struct mount *, struct sockaddr *, int *, struct ucred **); -int ufs_fhtovp(struct mount *, struct ufid *, struct vnode **); +int ufs_fhtovp(struct mount *, struct vnode *, + struct ufid *, struct vnode **); int ufs_checkpath(struct inode *, struct inode *, struct ucred *); void ufs_dirbad(struct inode *, doff_t, char *); int ufs_dirbadentry(struct vnode *, struct direct *, int); diff --git a/sys/vfs/ufs/ufs_vfsops.c b/sys/vfs/ufs/ufs_vfsops.c index a5a0b8b642..7edf554ba7 100644 --- a/sys/vfs/ufs/ufs_vfsops.c +++ b/sys/vfs/ufs/ufs_vfsops.c @@ -37,7 +37,7 @@ * * @(#)ufs_vfsops.c 8.8 (Berkeley) 5/20/95 * $FreeBSD: src/sys/ufs/ufs/ufs_vfsops.c,v 1.17.2.3 2001/10/14 19:08:16 iedowse Exp $ - * $DragonFly: src/sys/vfs/ufs/ufs_vfsops.c,v 1.16 2006/08/03 16:40:48 swildner Exp $ + * $DragonFly: src/sys/vfs/ufs/ufs_vfsops.c,v 1.16.8.1 2008/09/25 02:20:57 dillon Exp $ */ #include "opt_quota.h" @@ -177,7 +177,8 @@ ufs_init(struct vfsconf *vfsp) * Call the VFS_CHECKEXP beforehand to verify access. */ int -ufs_fhtovp(struct mount *mp, struct ufid *ufhp, struct vnode **vpp) +ufs_fhtovp(struct mount *mp, struct vnode *rootpv, + struct ufid *ufhp, struct vnode **vpp) { struct inode *ip; struct vnode *nvp;