MFC numerous features from HEAD.
authorMatthew Dillon <dillon@dragonflybsd.org>
Thu, 25 Sep 2008 02:20:57 +0000 (25 02:20 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Thu, 25 Sep 2008 02:20:57 +0000 (25 02:20 +0000)
* 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.

25 files changed:
sys/emulation/dragonfly12/dfbsd12_stat.c
sys/kern/kern_checkpoint.c
sys/kern/vfs_default.c
sys/kern/vfs_mount.c
sys/kern/vfs_subr.c
sys/kern/vfs_syscalls.c
sys/sys/mount.h
sys/sys/vnode.h
sys/vfs/gnu/ext2fs/ext2_vfsops.c
sys/vfs/hpfs/hpfs_vfsops.c
sys/vfs/isofs/cd9660/cd9660_vfsops.c
sys/vfs/msdosfs/msdosfs_vfsops.c
sys/vfs/nfs/nfs.h
sys/vfs/nfs/nfs_serv.c
sys/vfs/nfs/nfs_subs.c
sys/vfs/nfs/nfsm_subs.h
sys/vfs/ntfs/ntfs_vfsops.c
sys/vfs/nullfs/null.h
sys/vfs/nullfs/null_vfsops.c
sys/vfs/nullfs/null_vnops.c
sys/vfs/udf/udf_vfsops.c
sys/vfs/ufs/ffs_extern.h
sys/vfs/ufs/ffs_vfsops.c
sys/vfs/ufs/ufs_extern.h
sys/vfs/ufs/ufs_vfsops.c

index 13099fa..f2d72cf 100644 (file)
@@ -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);
index bcf0880..c120c8e 100644 (file)
@@ -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 <sys/types.h>
@@ -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;
index 8f655b1..94d5a1b 100644 (file)
@@ -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 <sys/param.h>
@@ -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);
 }
index 6ca1234..65aaffc 100644 (file)
@@ -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 <count> vnodes and will potentially free vnodes that still
  * have VM backing store (VM backing store is typically the cause
index f79136f..72e6152 100644 (file)
@@ -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)
index c05d073..e615390 100644 (file)
@@ -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 <sys/param.h>
@@ -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;
index 7192671..606e3c2 100644 (file)
@@ -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 *);
index 350ae6c..9557493 100644 (file)
@@ -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 */
index 85b99a6..fc72108 100644 (file)
@@ -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;
index 1ab55b5..298b852 100644 (file)
@@ -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;
index 3eb9e4a..eafd461 100644 (file)
@@ -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 <sys/param.h>
@@ -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;
index be0ca0d..6c98200 100644 (file)
@@ -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;
index 5c50092..f7833c3 100644 (file)
@@ -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 *);
index ffe5b0e..43ff91f 100644 (file)
@@ -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:
index 271a352..26db6e9 100644 (file)
@@ -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
index c9fa45f..de44cfe 100644 (file)
@@ -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)
index 4d5b2d1..b527329 100644 (file)
@@ -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;
index df766fd..11b2d6b 100644 (file)
  *     @(#)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 */
index 7e646ed..a75fd4c 100644 (file)
@@ -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 <sys/vnode.h>
 #include <sys/mount.h>
 #include <sys/nlookup.h>
+#include <sys/mountctl.h>
 #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);
index f46b3de..44df527 100644 (file)
@@ -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.
  *
 #include <sys/sysctl.h>
 #include <sys/vnode.h>
 #include <sys/mount.h>
+#include <sys/mountctl.h>
 #include <sys/proc.h>
 #include <sys/namei.h>
 #include <sys/malloc.h>
@@ -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
 };
 
index a906cba..675a8e4 100644 (file)
@@ -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;
index 777e0d3..368034b 100644 (file)
@@ -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 );
index ebeb848..fa83192 100644 (file)
@@ -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));
 }
 
 /*
index 7948910..7c74626 100644 (file)
@@ -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);
index a5a0b8b..7edf554 100644 (file)
@@ -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;