VFS messaging/interfacing work stage 5/99. Start work on the new
[dragonfly.git] / sys / vfs / nfs / nfs_vnops.c
index a34ea4f..28ac6a1 100644 (file)
@@ -35,7 +35,7 @@
  *
  *     @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95
  * $FreeBSD: src/sys/nfs/nfs_vnops.c,v 1.150.2.5 2001/12/20 19:56:28 dillon Exp $
- * $DragonFly: src/sys/vfs/nfs/nfs_vnops.c,v 1.24 2004/06/04 05:06:40 hmp Exp $
+ * $DragonFly: src/sys/vfs/nfs/nfs_vnops.c,v 1.30 2004/09/26 01:24:56 dillon Exp $
  */
 
 
@@ -138,95 +138,83 @@ static int        nfs_bwrite (struct vop_bwrite_args *);
 /*
  * Global vfs data structures for nfs
  */
-vop_t **nfsv2_vnodeop_p;
-static struct vnodeopv_entry_desc nfsv2_vnodeop_entries[] = {
-       { &vop_default_desc,            (vop_t *) vop_defaultop },
-       { &vop_access_desc,             (vop_t *) nfs_access },
-       { &vop_advlock_desc,            (vop_t *) nfs_advlock },
-       { &vop_bmap_desc,               (vop_t *) nfs_bmap },
-       { &vop_bwrite_desc,             (vop_t *) nfs_bwrite },
-       { &vop_close_desc,              (vop_t *) nfs_close },
-       { &vop_create_desc,             (vop_t *) nfs_create },
-       { &vop_fsync_desc,              (vop_t *) nfs_fsync },
-       { &vop_getattr_desc,            (vop_t *) nfs_getattr },
-       { &vop_getpages_desc,           (vop_t *) nfs_getpages },
-       { &vop_putpages_desc,           (vop_t *) nfs_putpages },
-       { &vop_inactive_desc,           (vop_t *) nfs_inactive },
-       { &vop_islocked_desc,           (vop_t *) vop_stdislocked },
-       { &vop_lease_desc,              (vop_t *) vop_null },
-       { &vop_link_desc,               (vop_t *) nfs_link },
-       { &vop_lock_desc,               (vop_t *) vop_sharedlock },
-       { &vop_lookup_desc,             (vop_t *) nfs_lookup },
-       { &vop_mkdir_desc,              (vop_t *) nfs_mkdir },
-       { &vop_mknod_desc,              (vop_t *) nfs_mknod },
-       { &vop_mmap_desc,               (vop_t *) nfs_mmap },
-       { &vop_open_desc,               (vop_t *) nfs_open },
-       { &vop_poll_desc,               (vop_t *) nfs_poll },
-       { &vop_print_desc,              (vop_t *) nfs_print },
-       { &vop_read_desc,               (vop_t *) nfs_read },
-       { &vop_readdir_desc,            (vop_t *) nfs_readdir },
-       { &vop_readlink_desc,           (vop_t *) nfs_readlink },
-       { &vop_reclaim_desc,            (vop_t *) nfs_reclaim },
-       { &vop_remove_desc,             (vop_t *) nfs_remove },
-       { &vop_rename_desc,             (vop_t *) nfs_rename },
-       { &vop_rmdir_desc,              (vop_t *) nfs_rmdir },
-       { &vop_setattr_desc,            (vop_t *) nfs_setattr },
-       { &vop_strategy_desc,           (vop_t *) nfs_strategy },
-       { &vop_symlink_desc,            (vop_t *) nfs_symlink },
-       { &vop_unlock_desc,             (vop_t *) vop_stdunlock },
-       { &vop_write_desc,              (vop_t *) nfs_write },
+struct vnodeopv_entry_desc nfsv2_vnodeop_entries[] = {
+       { &vop_default_desc,            vop_defaultop },
+       { &vop_access_desc,             (void *) nfs_access },
+       { &vop_advlock_desc,            (void *) nfs_advlock },
+       { &vop_bmap_desc,               (void *) nfs_bmap },
+       { &vop_bwrite_desc,             (void *) nfs_bwrite },
+       { &vop_close_desc,              (void *) nfs_close },
+       { &vop_create_desc,             (void *) nfs_create },
+       { &vop_fsync_desc,              (void *) nfs_fsync },
+       { &vop_getattr_desc,            (void *) nfs_getattr },
+       { &vop_getpages_desc,           (void *) nfs_getpages },
+       { &vop_putpages_desc,           (void *) nfs_putpages },
+       { &vop_inactive_desc,           (void *) nfs_inactive },
+       { &vop_islocked_desc,           (void *) vop_stdislocked },
+       { &vop_lease_desc,              vop_null },
+       { &vop_link_desc,               (void *) nfs_link },
+       { &vop_lock_desc,               (void *) vop_stdlock },
+       { &vop_lookup_desc,             (void *) nfs_lookup },
+       { &vop_mkdir_desc,              (void *) nfs_mkdir },
+       { &vop_mknod_desc,              (void *) nfs_mknod },
+       { &vop_mmap_desc,               (void *) nfs_mmap },
+       { &vop_open_desc,               (void *) nfs_open },
+       { &vop_poll_desc,               (void *) nfs_poll },
+       { &vop_print_desc,              (void *) nfs_print },
+       { &vop_read_desc,               (void *) nfs_read },
+       { &vop_readdir_desc,            (void *) nfs_readdir },
+       { &vop_readlink_desc,           (void *) nfs_readlink },
+       { &vop_reclaim_desc,            (void *) nfs_reclaim },
+       { &vop_remove_desc,             (void *) nfs_remove },
+       { &vop_rename_desc,             (void *) nfs_rename },
+       { &vop_rmdir_desc,              (void *) nfs_rmdir },
+       { &vop_setattr_desc,            (void *) nfs_setattr },
+       { &vop_strategy_desc,           (void *) nfs_strategy },
+       { &vop_symlink_desc,            (void *) nfs_symlink },
+       { &vop_unlock_desc,             (void *) vop_stdunlock },
+       { &vop_write_desc,              (void *) nfs_write },
        { NULL, NULL }
 };
-static struct vnodeopv_desc nfsv2_vnodeop_opv_desc =
-       { &nfsv2_vnodeop_p, nfsv2_vnodeop_entries };
-VNODEOP_SET(nfsv2_vnodeop_opv_desc);
 
 /*
  * Special device vnode ops
  */
-vop_t **spec_nfsv2nodeop_p;
-static struct vnodeopv_entry_desc nfsv2_specop_entries[] = {
-       { &vop_default_desc,            (vop_t *) spec_vnoperate },
-       { &vop_access_desc,             (vop_t *) nfsspec_access },
-       { &vop_close_desc,              (vop_t *) nfsspec_close },
-       { &vop_fsync_desc,              (vop_t *) nfs_fsync },
-       { &vop_getattr_desc,            (vop_t *) nfs_getattr },
-       { &vop_inactive_desc,           (vop_t *) nfs_inactive },
-       { &vop_islocked_desc,           (vop_t *) vop_stdislocked },
-       { &vop_lock_desc,               (vop_t *) vop_sharedlock },
-       { &vop_print_desc,              (vop_t *) nfs_print },
-       { &vop_read_desc,               (vop_t *) nfsspec_read },
-       { &vop_reclaim_desc,            (vop_t *) nfs_reclaim },
-       { &vop_setattr_desc,            (vop_t *) nfs_setattr },
-       { &vop_unlock_desc,             (vop_t *) vop_stdunlock },
-       { &vop_write_desc,              (vop_t *) nfsspec_write },
+struct vnodeopv_entry_desc nfsv2_specop_entries[] = {
+       { &vop_default_desc,            (void *) spec_vnoperate },
+       { &vop_access_desc,             (void *) nfsspec_access },
+       { &vop_close_desc,              (void *) nfsspec_close },
+       { &vop_fsync_desc,              (void *) nfs_fsync },
+       { &vop_getattr_desc,            (void *) nfs_getattr },
+       { &vop_inactive_desc,           (void *) nfs_inactive },
+       { &vop_islocked_desc,           (void *) vop_stdislocked },
+       { &vop_lock_desc,               (void *) vop_stdlock },
+       { &vop_print_desc,              (void *) nfs_print },
+       { &vop_read_desc,               (void *) nfsspec_read },
+       { &vop_reclaim_desc,            (void *) nfs_reclaim },
+       { &vop_setattr_desc,            (void *) nfs_setattr },
+       { &vop_unlock_desc,             (void *) vop_stdunlock },
+       { &vop_write_desc,              (void *) nfsspec_write },
        { NULL, NULL }
 };
-static struct vnodeopv_desc spec_nfsv2nodeop_opv_desc =
-       { &spec_nfsv2nodeop_p, nfsv2_specop_entries };
-VNODEOP_SET(spec_nfsv2nodeop_opv_desc);
-
-vop_t **fifo_nfsv2nodeop_p;
-static struct vnodeopv_entry_desc nfsv2_fifoop_entries[] = {
-       { &vop_default_desc,            (vop_t *) fifo_vnoperate },
-       { &vop_access_desc,             (vop_t *) nfsspec_access },
-       { &vop_close_desc,              (vop_t *) nfsfifo_close },
-       { &vop_fsync_desc,              (vop_t *) nfs_fsync },
-       { &vop_getattr_desc,            (vop_t *) nfs_getattr },
-       { &vop_inactive_desc,           (vop_t *) nfs_inactive },
-       { &vop_islocked_desc,           (vop_t *) vop_stdislocked },
-       { &vop_lock_desc,               (vop_t *) vop_sharedlock },
-       { &vop_print_desc,              (vop_t *) nfs_print },
-       { &vop_read_desc,               (vop_t *) nfsfifo_read },
-       { &vop_reclaim_desc,            (vop_t *) nfs_reclaim },
-       { &vop_setattr_desc,            (vop_t *) nfs_setattr },
-       { &vop_unlock_desc,             (vop_t *) vop_stdunlock },
-       { &vop_write_desc,              (vop_t *) nfsfifo_write },
+
+struct vnodeopv_entry_desc nfsv2_fifoop_entries[] = {
+       { &vop_default_desc,            (void *) fifo_vnoperate },
+       { &vop_access_desc,             (void *) nfsspec_access },
+       { &vop_close_desc,              (void *) nfsfifo_close },
+       { &vop_fsync_desc,              (void *) nfs_fsync },
+       { &vop_getattr_desc,            (void *) nfs_getattr },
+       { &vop_inactive_desc,           (void *) nfs_inactive },
+       { &vop_islocked_desc,           (void *) vop_stdislocked },
+       { &vop_lock_desc,               (void *) vop_stdlock },
+       { &vop_print_desc,              (void *) nfs_print },
+       { &vop_read_desc,               (void *) nfsfifo_read },
+       { &vop_reclaim_desc,            (void *) nfs_reclaim },
+       { &vop_setattr_desc,            (void *) nfs_setattr },
+       { &vop_unlock_desc,             (void *) vop_stdunlock },
+       { &vop_write_desc,              (void *) nfsfifo_write },
        { NULL, NULL }
 };
-static struct vnodeopv_desc fifo_nfsv2nodeop_opv_desc =
-       { &fifo_nfsv2nodeop_p, nfsv2_fifoop_entries };
-VNODEOP_SET(fifo_nfsv2nodeop_opv_desc);
 
 static int     nfs_mknodrpc (struct vnode *dvp, struct vnode **vpp,
                                  struct componentname *cnp,
@@ -869,7 +857,7 @@ nfs_lookup(struct vop_lookup_args *ap)
        wantparent = flags & (CNP_LOCKPARENT|CNP_WANTPARENT);
        nmp = VFSTONFS(dvp->v_mount);
        np = VTONFS(dvp);
-       error = cache_lookup(dvp, NCPNULL, vpp, NCPPNULL, cnp);
+       error = cache_lookup(dvp, vpp, cnp);
        if (error != 0) {
                struct vattr vattr;
                int vpid;
@@ -894,13 +882,19 @@ nfs_lookup(struct vop_lookup_args *ap)
                        error = 0;
                } else if (flags & CNP_ISDOTDOT) {
                        VOP_UNLOCK(dvp, NULL, 0, td);
+                       cnp->cn_flags |= CNP_PDIRUNLOCK;
                        error = vget(newvp, NULL, LK_EXCLUSIVE, td);
-                       if (!error && lockparent && (flags & CNP_ISLASTCN))
+                       if (!error && lockparent && (flags & CNP_ISLASTCN)) {
                                error = vn_lock(dvp, NULL, LK_EXCLUSIVE, td);
+                               if (error == 0)
+                                       cnp->cn_flags &= ~CNP_PDIRUNLOCK;
+                       }
                } else {
                        error = vget(newvp, NULL, LK_EXCLUSIVE, td);
-                       if (!lockparent || error || !(flags & CNP_ISLASTCN))
+                       if (!lockparent || error || !(flags & CNP_ISLASTCN)) {
                                VOP_UNLOCK(dvp, NULL, 0, td);
+                               cnp->cn_flags |= CNP_PDIRUNLOCK;
+                       }
                }
                if (!error) {
                        if (vpid == newvp->v_id) {
@@ -915,10 +909,14 @@ nfs_lookup(struct vop_lookup_args *ap)
                           cache_purge(newvp);
                        }
                        vput(newvp);
-                       if (lockparent && dvp != newvp && (flags & CNP_ISLASTCN))
+                       if (lockparent && dvp != newvp && (flags & CNP_ISLASTCN)) {
                                VOP_UNLOCK(dvp, NULL, 0, td);
+                               cnp->cn_flags |= CNP_PDIRUNLOCK;
+                       }
                }
                error = vn_lock(dvp, NULL, LK_EXCLUSIVE, td);
+               if (error == 0)
+                       cnp->cn_flags &= ~CNP_PDIRUNLOCK;
                *vpp = NULLVP;
                if (error)
                        return (error);
@@ -984,23 +982,30 @@ nfs_lookup(struct vop_lookup_args *ap)
                *vpp = newvp;
                m_freem(mrep);
                cnp->cn_flags |= CNP_SAVENAME;
-               if (!lockparent)
+               if (!lockparent) {
                        VOP_UNLOCK(dvp, NULL, 0, td);
+                       cnp->cn_flags |= CNP_PDIRUNLOCK;
+               }
                return (0);
        }
 
        if (flags & CNP_ISDOTDOT) {
                VOP_UNLOCK(dvp, NULL, 0, td);
+               cnp->cn_flags |= CNP_PDIRUNLOCK;
                error = nfs_nget(dvp->v_mount, fhp, fhsize, &np);
                if (error) {
                        vn_lock(dvp, NULL, LK_EXCLUSIVE | LK_RETRY, td);
-                       return (error);
+                       cnp->cn_flags &= ~CNP_PDIRUNLOCK;
+                       return (error); /* NOTE: return error from nget */
                }
                newvp = NFSTOV(np);
-               if (lockparent && (flags & CNP_ISLASTCN) &&
-                   (error = vn_lock(dvp, NULL, LK_EXCLUSIVE, td))) {
-                       vput(newvp);
-                       return (error);
+               if (lockparent && (flags & CNP_ISLASTCN)) {
+                       error = vn_lock(dvp, NULL, LK_EXCLUSIVE, td);
+                       if (error) {
+                               vput(newvp);
+                               return (error);
+                       }
+                       cnp->cn_flags |= CNP_PDIRUNLOCK;
                }
        } else if (NFS_CMPFH(np, fhp, fhsize)) {
                vref(dvp);
@@ -1011,8 +1016,10 @@ nfs_lookup(struct vop_lookup_args *ap)
                        m_freem(mrep);
                        return (error);
                }
-               if (!lockparent || !(flags & CNP_ISLASTCN))
+               if (!lockparent || !(flags & CNP_ISLASTCN)) {
                        VOP_UNLOCK(dvp, NULL, 0, td);
+                       cnp->cn_flags |= CNP_PDIRUNLOCK;
+               }
                newvp = NFSTOV(np);
        }
        if (v3) {
@@ -1037,8 +1044,10 @@ nfsmout:
                }
                if ((cnp->cn_nameiop == NAMEI_CREATE || cnp->cn_nameiop == NAMEI_RENAME) &&
                    (flags & CNP_ISLASTCN) && error == ENOENT) {
-                       if (!lockparent)
+                       if (!lockparent) {
                                VOP_UNLOCK(dvp, NULL, 0, td);
+                               cnp->cn_flags |= CNP_PDIRUNLOCK;
+                       }
                        if (dvp->v_mount->mnt_flag & MNT_RDONLY)
                                error = EROFS;
                        else
@@ -1447,7 +1456,7 @@ again:
                        nfsm_build(tl, u_int32_t *, NFSX_V3CREATEVERF);
 #ifdef INET
                        if (!TAILQ_EMPTY(&in_ifaddrhead))
-                               *tl++ = IA_SIN(in_ifaddrhead.tqh_first)->sin_addr.s_addr;
+                               *tl++ = IA_SIN(TAILQ_FIRST(&in_ifaddrhead))->sin_addr.s_addr;
                        else
 #endif
                                *tl++ = create_verf;
@@ -3200,7 +3209,7 @@ nfsspec_read(struct vop_read_args *ap)
         */
        np->n_flag |= NACC;
        getnanotime(&np->n_atim);
-       return (VOCALL(spec_vnodeop_p, VOFFSET(vop_read), ap));
+       return (VOCALL(spec_vnode_vops, &ap->a_head));
 }
 
 /*
@@ -3219,7 +3228,7 @@ nfsspec_write(struct vop_write_args *ap)
         */
        np->n_flag |= NUPD;
        getnanotime(&np->n_mtim);
-       return (VOCALL(spec_vnodeop_p, VOFFSET(vop_write), ap));
+       return (VOCALL(spec_vnode_vops, &ap->a_head));
 }
 
 /*
@@ -3249,7 +3258,7 @@ nfsspec_close(struct vop_close_args *ap)
                        (void)VOP_SETATTR(vp, &vattr, nfs_vpcred(vp, ND_WRITE), ap->a_td);
                }
        }
-       return (VOCALL(spec_vnodeop_p, VOFFSET(vop_close), ap));
+       return (VOCALL(spec_vnode_vops, &ap->a_head));
 }
 
 /*
@@ -3268,7 +3277,7 @@ nfsfifo_read(struct vop_read_args *ap)
         */
        np->n_flag |= NACC;
        getnanotime(&np->n_atim);
-       return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_read), ap));
+       return (VOCALL(fifo_vnode_vops, &ap->a_head));
 }
 
 /*
@@ -3287,7 +3296,7 @@ nfsfifo_write(struct vop_write_args *ap)
         */
        np->n_flag |= NUPD;
        getnanotime(&np->n_mtim);
-       return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_write), ap));
+       return (VOCALL(fifo_vnode_vops, &ap->a_head));
 }
 
 /*
@@ -3322,6 +3331,6 @@ nfsfifo_close(struct vop_close_args *ap)
                        (void)VOP_SETATTR(vp, &vattr, nfs_vpcred(vp, ND_WRITE), ap->a_td);
                }
        }
-       return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_close), ap));
+       return (VOCALL(fifo_vnode_vops, &ap->a_head));
 }