From: Matthew Dillon Date: Wed, 17 Sep 2008 21:44:25 +0000 (+0000) Subject: * Implement the ability to export NULLFS mounts via NFS. X-Git-Tag: v2.1.1~361 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/67863d0455efd86aaa48fea3c0fb0325ad049f18 * Implement the ability to export NULLFS mounts via NFS. * Enforce PFS isolation when exporting a HAMMER PFS via a NULLFS mount. NOTE: Exporting anything other then HAMMER PFS root's via nullfs does NOT protect the parent of the exported directory from being accessed via NFS. Generally speaking this feature is implemented by giving each nullfs mount a synthesized fsid based on what is being mounted and implementing the NFS export infrastructure in the nullfs code instead of just bypassing those functions to the underyling VFS. --- diff --git a/sys/emulation/dragonfly12/dfbsd12_stat.c b/sys/emulation/dragonfly12/dfbsd12_stat.c index 13099fa1da..ffbeae7da3 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.4 2008/09/17 21:44:16 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..221a6f4c2a 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.20 2008/09/17 21:44:18 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..5b878e9b84 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.54 2008/09/17 21:44:18 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 73048f2a01..86489591c1 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.36 2008/07/14 22:16:35 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_mount.c,v 1.37 2008/09/17 21:44:18 dillon Exp $ */ /* @@ -363,6 +363,26 @@ vfs_getnewfsid(struct mount *mp) lwkt_reltoken(&ilock); } +/* + * 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 diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index b67f73ba37..9b055c45e1 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.117 2008/07/27 17:37:52 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_subr.c,v 1.118 2008/09/17 21:44:18 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..36c9a1d24c 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.134 2008/09/17 21:44:18 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..90f0f13966 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.47 2008/09/17 21:44:19 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..0cbbb2977c 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.83 2008/09/17 21:44:19 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..eb4adf589d 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.57 2008/09/17 21:44:21 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/hammer/hammer_inode.c b/sys/vfs/hammer/hammer_inode.c index 675100b34a..dac2f06270 100644 --- a/sys/vfs/hammer/hammer_inode.c +++ b/sys/vfs/hammer/hammer_inode.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/vfs/hammer/hammer_inode.c,v 1.110 2008/08/09 07:04:16 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer_inode.c,v 1.111 2008/09/17 21:44:20 dillon Exp $ */ #include "hammer.h" @@ -293,12 +293,16 @@ hammer_get_vnode(struct hammer_inode *ip, struct vnode **vpp) * confused. The other half of the special handling * is in hammer_vop_nlookupdotdot(). * - * Pseudo-filesystem roots also do not count. + * Pseudo-filesystem roots can be accessed via + * non-root filesystem paths and setting VROOT may + * confuse the namecache. Set VPFSROOT instead. */ if (ip->obj_id == HAMMER_OBJID_ROOT && - ip->obj_asof == hmp->asof && - ip->obj_localization == 0) { - vp->v_flag |= VROOT; + ip->obj_asof == hmp->asof) { + if (ip->obj_localization == 0) + vp->v_flag |= VROOT; + else + vp->v_flag |= VPFSROOT; } vp->v_data = (void *)ip; diff --git a/sys/vfs/hammer/hammer_mount.h b/sys/vfs/hammer/hammer_mount.h index 28bb8da364..1d8ca8dfba 100644 --- a/sys/vfs/hammer/hammer_mount.h +++ b/sys/vfs/hammer/hammer_mount.h @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/vfs/hammer/hammer_mount.h,v 1.10 2008/07/19 18:44:49 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer_mount.h,v 1.11 2008/09/17 21:44:20 dillon Exp $ */ #ifndef _SYS_TYPES_H_ @@ -51,8 +51,8 @@ struct hammer_mount_info { int hflags; /* extended hammer mount flags */ int master_id; /* -1=no-mirror mode, or 0-15 */ u_int64_t asof; /* asof - HAMMER_MAX_TID is current */ - struct export_args export; /* export arguments */ - u_int64_t reserved[15]; + char reserved1[136]; /* was struct export_args */ + u_int64_t reserved2[15]; }; #define HMNT_NOHISTORY 0x00000001 diff --git a/sys/vfs/hammer/hammer_vfsops.c b/sys/vfs/hammer/hammer_vfsops.c index 286fd5ad20..30f94cafae 100644 --- a/sys/vfs/hammer/hammer_vfsops.c +++ b/sys/vfs/hammer/hammer_vfsops.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/vfs/hammer/hammer_vfsops.c,v 1.70 2008/07/31 04:42:04 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer_vfsops.c,v 1.71 2008/09/17 21:44:20 dillon Exp $ */ #include @@ -227,8 +227,8 @@ static int hammer_vfs_sync(struct mount *mp, int waitfor); static int hammer_vfs_vget(struct mount *mp, ino_t ino, struct vnode **vpp); static int hammer_vfs_init(struct vfsconf *conf); -static int hammer_vfs_fhtovp(struct mount *mp, struct fid *fhp, - struct vnode **vpp); +static int hammer_vfs_fhtovp(struct mount *mp, struct vnode *rootvp, + struct fid *fhp, struct vnode **vpp); static int hammer_vfs_vptofh(struct vnode *vp, struct fid *fhp); static int hammer_vfs_checkexp(struct mount *mp, struct sockaddr *nam, int *exflagsp, struct ucred **credanonp); @@ -900,9 +900,13 @@ hammer_vfs_vptofh(struct vnode *vp, struct fid *fhp) /* * Convert a file handle back to a vnode. + * + * Use rootvp to enforce PFS isolation when a PFS is exported via a + * null mount. */ static int -hammer_vfs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) +hammer_vfs_fhtovp(struct mount *mp, struct vnode *rootvp, + struct fid *fhp, struct vnode **vpp) { struct hammer_transaction trans; struct hammer_inode *ip; @@ -912,7 +916,10 @@ hammer_vfs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) bcopy(fhp->fid_data + 0, &info.obj_id, sizeof(info.obj_id)); bcopy(fhp->fid_data + 8, &info.obj_asof, sizeof(info.obj_asof)); - localization = (u_int32_t)fhp->fid_ext << 16; + if (rootvp) + localization = VTOI(rootvp)->obj_localization; + else + localization = (u_int32_t)fhp->fid_ext << 16; hammer_simple_transaction(&trans, (void *)mp->mnt_data); diff --git a/sys/vfs/hpfs/hpfs_vfsops.c b/sys/vfs/hpfs/hpfs_vfsops.c index 1ab55b5d66..e6d1cba3ce 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.43 2008/09/17 21:44:22 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..cc13d993dc 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.46 2008/09/17 21:44:23 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..1cda067848 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.52 2008/09/17 21:44:24 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 9aeb797dc5..0238bf5885 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.20 2008/07/14 17:45:49 dillon Exp $ + * $DragonFly: src/sys/vfs/nfs/nfs.h,v 1.21 2008/09/17 21:44:24 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 d8a3c884d0..8a8f7d3bc8 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.47 2008/07/14 17:45:49 dillon Exp $ + * $DragonFly: src/sys/vfs/nfs/nfs_serv.c,v 1.48 2008/09/17 21:44:24 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..3e67bc3aa7 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.48 2008/09/17 21:44:24 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..23a9809870 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.10 2008/09/17 21:44:25 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..e0408655a3 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.48 2008/09/17 21:44:25 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..78db32ebd0 100644 --- a/sys/vfs/nullfs/null.h +++ b/sys/vfs/nullfs/null.h @@ -36,7 +36,7 @@ * @(#)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.9 2008/09/17 21:44:25 dillon Exp $ */ struct null_args { @@ -46,6 +46,7 @@ struct null_args { struct null_mount { struct mount *nullm_vfs; struct vnode *nullm_rootvp; /* Reference to root null_node */ + struct netexport export; }; #ifdef _KERNEL @@ -57,4 +58,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 093ebe33a5..919fd3717b 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.30 2008/09/05 23:27:12 dillon Exp $ + * $DragonFly: src/sys/vfs/nullfs/null_vfsops.c,v 1.31 2008/09/17 21:44:25 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 @@ -165,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); @@ -270,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 @@ -295,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 ac320e6a30..fb60b95cfd 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.29 2008/09/05 23:27:12 dillon Exp $ + * $DragonFly: src/sys/vfs/nullfs/null_vnops.c,v 1.30 2008/09/17 21:44:25 dillon Exp $ * ...and... * @(#)null_vnodeops.c 1.20 92/07/07 UCLA Ficus project * @@ -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..a00c9ed2a5 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.28 2008/09/17 21:44:25 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..2eccc5e1cc 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.15 2008/09/17 21:44:25 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..cfffa4f889 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.59 2008/09/17 21:44:25 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..d05c3505d8 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.16 2008/09/17 21:44:25 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..f9de89020d 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.17 2008/09/17 21:44:25 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;