]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/nfs/nfs_serv.c
xnu-201.19.tar.gz
[apple/xnu.git] / bsd / nfs / nfs_serv.c
index 0cbfa43348181dad02b4ac7296d41865ffb63e85..f03085e4e0b5b43ad3d470403be168eddb174014 100644 (file)
@@ -2648,10 +2648,16 @@ again:
        io.uio_rw = UIO_READ;
        io.uio_procp = (struct proc *)0;
        eofflag = 0;
-       vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, procp);
-       if (cookies) {
-               _FREE((caddr_t)cookies, M_TEMP);
-               cookies = NULL;
+
+        if (cookies) {
+                _FREE((caddr_t)cookies, M_TEMP);
+                cookies = NULL;
+        }
+       if (error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, procp)) {
+               FREE((caddr_t)rbuf, M_TEMP);
+               nfsm_reply(NFSX_POSTOPATTR(v3));
+               nfsm_srvpostop_attr(getret, &at);
+               return (0);
        }
        error = VOP_READDIR(vp, &io, cred, &eofflag, &ncookies, &cookies);
        off = (off_t)io.uio_offset;
@@ -2873,6 +2879,7 @@ nfsrv_readdirplus(nfsd, slp, procp, mrq)
        int siz, cnt, fullsiz, eofflag, rdonly, cache, dirlen, ncookies = 0;
        u_quad_t frev, off, toff, verf;
        u_long *cookies = NULL, *cookiep;
+       void *file;
 
        fhp = &nfh.fh_generic;
        nfsm_srvmtofh(fhp);
@@ -2921,11 +2928,16 @@ again:
        io.uio_rw = UIO_READ;
        io.uio_procp = (struct proc *)0;
        eofflag = 0;
-       vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, procp);
        if (cookies) {
-               _FREE((caddr_t)cookies, M_TEMP);
-               cookies = NULL;
-       }
+                _FREE((caddr_t)cookies, M_TEMP);
+                cookies = NULL;
+        }       
+        if (error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, procp)) {
+                FREE((caddr_t)rbuf, M_TEMP);
+                nfsm_reply(NFSX_V3POSTOPATTR);
+                nfsm_srvpostop_attr(getret, &at);
+                return (0);
+        }
        error = VOP_READDIR(vp, &io, cred, &eofflag, &ncookies, &cookies);
        off = (u_quad_t)io.uio_offset;
        getret = VOP_GETATTR(vp, &at, cred, procp);
@@ -3004,10 +3016,17 @@ again:
 
        /*
         * Probe one of the directory entries to see if the filesystem
-        * supports VGET.
+        * supports VGET. See later comment for VFS_VGET changes.
         */
-       if (VFS_VGET(vp->v_mount, dp->d_fileno, &nvp) == EOPNOTSUPP) {
-               error = NFSERR_NOTSUPP;
+       if (vp->v_tag == VT_UFS) 
+               file = (void *) dp->d_fileno;
+       else {
+               file = &dp->d_fileno;
+       }
+       
+       if (error = VFS_VGET(vp->v_mount, file, &nvp)) {
+               if (error == EOPNOTSUPP) /* let others get passed back */
+                       error = NFSERR_NOTSUPP; 
                vrele(vp);
                _FREE((caddr_t)cookies, M_TEMP);
                _FREE((caddr_t)rbuf, M_TEMP);
@@ -3032,11 +3051,22 @@ again:
                        nlen = dp->d_namlen;
                        rem = nfsm_rndup(nlen)-nlen;
 
-                       /*
-                        * For readdir_and_lookup get the vnode using
-                        * the file number.
+                       /* 
+                        * Got to get the vnode for lookup per entry.
+                        * HFS+/volfs and others use address of file identifier to VGET
+                        * UFS, nullfs, umapfs use inode (u_int32_t)
+                        * until they are consistent, we must differentiate now. 
+                        * UFS is the only one of the latter class that is exported.
+                        * Note this will be pulled out as we resolve the VGET issue
+                        * of which it should use u_in32_t or addresses. 
                         */
-                       if (VFS_VGET(vp->v_mount, dp->d_fileno, &nvp))
+                         
+                       if (vp->v_tag == VT_UFS) 
+                               file = (void *) dp->d_fileno;
+                       else 
+                               file = &dp->d_fileno;
+                               
+                       if (VFS_VGET(vp->v_mount, file, &nvp))
                                goto invalid;
                        bzero((caddr_t)nfhp, NFSX_V3FH);
                        nfhp->fh_fsid =