Remove support for Solaris pre-8
[openafs.git] / src / afs / VNOPS / afs_vnop_readdir.c
index b394239..2dcb576 100644 (file)
 #include "afs/afs_cbqueue.h"
 #include "afs/nfsclient.h"
 #include "afs/afs_osidnlc.h"
-#if defined(AFS_NBSD40_ENV)
-#include <ufs/ufs/ufs_extern.h> /* direct_pool */
-#endif
 
 #if defined(AFS_HPUX1122_ENV)
 #define DIRPAD 7
 #elif defined(AFS_NBSD40_ENV)
-#define DIRPAD 4
+#define DIRPAD 7
 #else
 #define DIRPAD 3
 #endif
@@ -69,15 +66,19 @@ BlobScan(struct dcache * afile, afs_int32 ablob)
     afs_int32 relativeBlob;
     afs_int32 pageBlob;
     struct PageHeader *tpe;
+    struct DirBuffer headerbuf;
     afs_int32 i;
+    int code;
 
     AFS_STATCNT(BlobScan);
     /* advance ablob over free and header blobs */
     while (1) {
        pageBlob = ablob & ~(EPP - 1);  /* base blob in same page */
-       tpe = (struct PageHeader *)afs_dir_GetBlob(afile, pageBlob);
-       if (!tpe)
-           return 0;           /* we've past the end */
+       code = afs_dir_GetBlob(afile, pageBlob, &headerbuf);
+       if (code)
+           return 0;
+       tpe = (struct PageHeader *)headerbuf.data;
+
        relativeBlob = ablob - pageBlob;        /* relative to page's first blob */
        /* first watch for headers */
        if (pageBlob == 0) {    /* first dir page has extra-big header */
@@ -95,7 +96,7 @@ BlobScan(struct dcache * afile, afs_int32 ablob)
        }
        /* now relativeBlob is the page-relative first allocated blob,
         * or EPP (if there are none in this page). */
-       DRelease(tpe, 0);
+       DRelease(&headerbuf, 0);
        if (i != EPP)
            return i + pageBlob;
        ablob = pageBlob + EPP; /* go around again */
@@ -211,11 +212,12 @@ int afs_rd_stash_i = 0;
 #define DIRSIZ_LEN(len) \
     ((sizeof (struct __dirent) - (_MAXNAMLEN+1)) + (((len)+1 + DIRPAD) &~ DIRPAD))
 #else
-#if    defined(AFS_SUN56_ENV)
+#if    defined(AFS_SUN5_ENV)
 #define DIRSIZ_LEN(len) ((18 + (len) + 1 + 7) & ~7 )
 #else
-#ifdef AFS_SUN5_ENV
-#define DIRSIZ_LEN(len)        ((10 + (len) + 1 + (NBPW-1)) & ~(NBPW-1))
+#ifdef AFS_NBSD40_ENV
+#define DIRSIZ_LEN(len) \
+    ((sizeof (struct dirent) - (MAXNAMLEN+1)) + (((len)+1 + 7) & ~7))
 #else
 #ifdef AFS_DIRENT
 #define DIRSIZ_LEN(len) \
@@ -231,8 +233,8 @@ int afs_rd_stash_i = 0;
     ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((len)+1 + 3) &~ 3))
 #endif /* AFS_SGI_ENV */
 #endif /* AFS_DIRENT */
+#endif /* AFS_NBSD40_ENV */
 #endif /* AFS_SUN5_ENV */
-#endif /* AFS_SUN56_ENV */
 #endif /* AFS_HPUX100_ENV */
 
 #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
@@ -300,13 +302,13 @@ afs_readdir_move(struct DirEntry *de, struct vcache *vc, struct uio *auio,
     struct volume *tvp;
     afs_uint32 Volume = vc->f.fid.Fid.Volume;
     afs_uint32 Vnode  = de->fid.vnode;
-#if    defined(AFS_SUN56_ENV)
+#if    defined(AFS_SUN5_ENV)
     struct dirent64 *direntp;
 #else
-#if  defined(AFS_SUN5_ENV) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
+#if  (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
     struct dirent *direntp;
 #endif
-#endif /* AFS_SUN56_ENV */
+#endif /* AFS_SUN5_ENV */
 #ifndef        AFS_SGI53_ENV
     struct min_direct sdirEntry;
 #endif /* AFS_SGI53_ENV */
@@ -458,7 +460,7 @@ afs_readdir_move(struct DirEntry *de, struct vcache *vc, struct uio *auio,
     }
 #else /* AFS_SGI53_ENV */
 #if  defined(AFS_SUN5_ENV) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
-#if    defined(AFS_SUN56_ENV)
+#if    defined(AFS_SUN5_ENV)
     direntp = (struct dirent64 *)osi_AllocLargeSpace(AFS_LRALLOCSIZ);
 #else
     direntp = (struct dirent *)osi_AllocLargeSpace(AFS_LRALLOCSIZ);
@@ -503,12 +505,7 @@ afs_readdir_move(struct DirEntry *de, struct vcache *vc, struct uio *auio,
 #if defined(AFS_NBSD40_ENV)
     {
        struct dirent *dp;
-       dp = (struct dirent *)
-#if defined(AFS_NBSD50_ENV)
-         osi_AllocLargeSpace(AFS_LRALLOCSIZ);
-#else
-         pool_get(&ufs_direct_pool, PR_WAITOK);
-#endif
+       dp = osi_AllocLargeSpace(sizeof(struct dirent));
        memset(dp, 0, sizeof(struct dirent));
         dp->d_ino =  (Volume << 16) + ntohl(Vnode);
         FIXUPSTUPIDINODE(dp->d_ino);
@@ -516,14 +513,12 @@ afs_readdir_move(struct DirEntry *de, struct vcache *vc, struct uio *auio,
         dp->d_type = afs_readdir_type(vc, de);
         strcpy(dp->d_name, de->name);
         dp->d_reclen = _DIRENT_SIZE(dp) /* rlen */;
-       afs_warn("afs_readdir_move %s type %d slen %d rlen %d act. rlen %d\n",
-                dp->d_name, dp->d_type, slen, rlen, _DIRENT_SIZE(dp));
-        AFS_UIOMOVE((char*) dp, sizeof(struct dirent), UIO_READ, auio, code);
-#if defined(AFS_NBSD50_ENV)
+       if ((afs_debug & AFSDEB_VNLAYER) != 0) {
+           afs_warn("%s: %s type %d slen %d rlen %d act. rlen %zu\n", __func__,
+               dp->d_name, dp->d_type, slen, rlen, _DIRENT_SIZE(dp));
+       }
+        AFS_UIOMOVE(dp, dp->d_reclen, UIO_READ, auio, code);
         osi_FreeLargeSpace((char *)dp);
-#else
-        pool_put(&ufs_direct_pool, dp);
-#endif
     }
 #else
     AFS_UIOMOVE((char *) &sdirEntry, sizeof(sdirEntry), UIO_READ, auio, code);
@@ -538,6 +533,7 @@ afs_readdir_move(struct DirEntry *de, struct vcache *vc, struct uio *auio,
 #endif
     AFS_MOVE_LOCK();
 #endif /* AFS_SGI_ENV */
+#if !defined(AFS_NBSD_ENV)
     /* pad out the difference between rlen and slen... */
     if (DIRSIZ_LEN(slen) < rlen) {
        AFS_MOVE_UNLOCK();
@@ -550,6 +546,7 @@ afs_readdir_move(struct DirEntry *de, struct vcache *vc, struct uio *auio,
        }
        AFS_MOVE_LOCK();
     }
+#endif
 #endif /* AFS_SUN5_ENV */
 #endif /* AFS_SGI53_ENV */
     return (code);
@@ -600,6 +597,7 @@ afs_readdir(OSI_VC_DECL(avc), struct uio *auio, afs_ucred_t *acred)
     afs_size_t origOffset, tlen;
     afs_int32 len;
     int code = 0;
+    struct DirBuffer oldEntry, nextEntry;
     struct DirEntry *ode = 0, *nde = 0;
     int o_slen = 0, n_slen = 0;
     afs_uint32 us;
@@ -628,6 +626,9 @@ afs_readdir(OSI_VC_DECL(avc), struct uio *auio, afs_ucred_t *acred)
      */
     AFS_STATCNT(afs_readdir);
 
+    memset(&oldEntry, 0, sizeof(struct DirBuffer));
+    memset(&nextEntry, 0, sizeof(struct DirBuffer));
+
 #if defined(AFS_SGI53_ENV)
 #ifdef AFS_SGI61_ENV
 #ifdef AFS_SGI62_ENV
@@ -746,7 +747,7 @@ afs_readdir(OSI_VC_DECL(avc), struct uio *auio, afs_ucred_t *acred)
        /* scan for the next interesting entry scan for in-use blob otherwise up point at
         * this blob note that ode, if non-zero, also represents a held dir page */
        if (!(us = BlobScan(tdc, (origOffset >> 5)))
-           || !(nde = (struct DirEntry *)afs_dir_GetBlob(tdc, us))) {
+           || (afs_dir_GetBlob(tdc, us, &nextEntry) != 0)) {
            /* failed to setup nde, return what we've got, and release ode */
            if (len) {
                /* something to hand over. */
@@ -781,13 +782,13 @@ afs_readdir(OSI_VC_DECL(avc), struct uio *auio, afs_ucred_t *acred)
                }
 #else
                code = afs_readdir_move(ode, avc, auio, o_slen,
-#if defined(AFS_SUN5_ENV)
+#if defined(AFS_SUN5_ENV) || defined(AFS_NBSD_ENV)
                                        len, origOffset);
 #else
                                        AFS_UIO_RESID(auio), origOffset);
 #endif
 #endif /* AFS_HPUX_ENV */
-#if !defined(AFS_SUN5_ENV)
+#if !defined(AFS_SUN5_ENV) && !defined(AFS_NBSD_ENV)
                AFS_UIO_SETRESID(auio, 0);
 #endif
            } else {
@@ -797,11 +798,11 @@ afs_readdir(OSI_VC_DECL(avc), struct uio *auio, afs_ucred_t *acred)
            if (eofp)
                *eofp = 1;      /* Set it properly */
 #endif
-           if (ode)
-               DRelease(ode, 0);
+           DRelease(&oldEntry, 0);
            goto dirend;
        }
-       /* by here nde is set */
+       nde = (struct DirEntry *)nextEntry.data;
+       
        /* Do we have enough user space to carry out our mission? */
 #if defined(AFS_SGI_ENV)
        n_slen = strlen(nde->name) + 1; /* NULL terminate */
@@ -816,7 +817,7 @@ afs_readdir(OSI_VC_DECL(avc), struct uio *auio, afs_ucred_t *acred)
        if (DIRSIZ_LEN(n_slen) >= (AFS_UIO_RESID(auio) - len)) {
 #endif /* AFS_SGI53_ENV */
            /* No can do no more now; ya know... at this time */
-           DRelease(nde, 0);   /* can't use this one. */
+           DRelease(&nextEntry, 0);    /* can't use this one. */
            if (len) {
 #ifdef AFS_HPUX_ENV
                sdirEntry->d_fileno =
@@ -855,7 +856,9 @@ afs_readdir(OSI_VC_DECL(avc), struct uio *auio, afs_ucred_t *acred)
                /* this next line used to be AFSVFS40 or AIX 3.1, but is
                 * really generic */
                AFS_UIO_SETOFFSET(auio, origOffset);
+#if !defined(AFS_NBSD_ENV)
                AFS_UIO_SETRESID(auio, 0);
+#endif
            } else {            /* trouble, can't give anything to the user! */
                /* even though he has given us a buffer, 
                 * even though we have something to give us,
@@ -863,8 +866,7 @@ afs_readdir(OSI_VC_DECL(avc), struct uio *auio, afs_ucred_t *acred)
                 */
                code = EINVAL;
            }
-           if (ode)
-               DRelease(ode, 0);
+           DRelease(&oldEntry, 0);
            goto dirend;
        }
 
@@ -913,13 +915,13 @@ afs_readdir(OSI_VC_DECL(avc), struct uio *auio, afs_ucred_t *acred)
 #else
        len = DIRSIZ_LEN(o_slen = n_slen);
 #endif /* AFS_SGI53_ENV */
-       if (ode)
-           DRelease(ode, 0);
+       
+       DRelease(&oldEntry, 0);
        ode = nde;
        AFS_UIO_SETOFFSET(auio, (afs_int32) ((us + afs_dir_NameBlobs(nde->name)) << 5));
     }
-    if (ode)
-       DRelease(ode, 0);
+    
+    DRelease(&oldEntry, 0);
 
   dirend:
     ReleaseReadLock(&tdc->lock);
@@ -936,233 +938,4 @@ afs_readdir(OSI_VC_DECL(avc), struct uio *auio, afs_ucred_t *acred)
     return code;
 }
 
-#if defined(AFS_HPUX_ENV)
-int
-afs1_readdir(struct vcache *avc, struct uio *auio, afs_ucred_t *acred)
-{
-    struct vrequest treq;
-    struct dcache *tdc;
-    afs_size_t origOffset, len;
-    int code = 0;
-    struct DirEntry *ode = 0, *nde = 0;
-    int o_slen = 0, n_slen = 0;
-    afs_uint32 us;
-    /*
-     * XXX All the hacks for alloced sdirEntry and inlining of
-     * afs_readdir_move instead of calling it is necessary for hpux due to
-     * stack problems that seem to occur when coming thru the nfs
-     * translator side XXX
-     */
-    struct minnfs_direct *sdirEntry = (struct minnfs_direct *)
-       osi_AllocSmallSpace(sizeof(struct min_direct));
-    afs_int32 rlen;
-
-    struct afs_fakestat_state fakestate;
-
-    AFS_STATCNT(afs_readdir);
-    if (code = afs_InitReq(&treq, acred)) {
-       osi_FreeSmallSpace((char *)sdirEntry);
-       return code;
-    }
-    afs_InitFakeStat(&fakestate);
-    AFS_DISCON_LOCK();
-    code = afs_EvalFakeStat(&avc, &fakestate, &treq);
-    if (code) {
-       osi_FreeSmallSpace((char *)sdirEntry);
-       AFS_DISCON_UNLOCK();
-       afs_PutFakeStat(&fakestate);
-       return code;
-    }
-    /* update the cache entry */
-  tagain:
-    code = afs_VerifyVCache(avc, &treq);
-    if (code)
-       goto done;
-    /* get a reference to the entire directory */
-    tdc = afs_GetDCache(avc, (afs_size_t) 0, &treq, &origOffset, &len, 1);
-    if (!tdc) {
-       code = ENOENT;
-       goto done;
-    }
-    ObtainReadLock(&avc->lock);
-    ObtainReadLock(&tdc->lock);
-
-    /*
-     * Make sure that the data in the cache is current. There are two
-     * cases we need to worry about:
-     * 1. The cache data is being fetched by another process.
-     * 2. The cache data is no longer valid
-     */
-    while ((avc->f.states & CStatd)
-          && (tdc->dflags & DFFetching)
-          && hsame(avc->f.m.DataVersion, tdc->f.versionNo)) {
-       afs_Trace4(afs_iclSetp, CM_TRACE_DCACHEWAIT, ICL_TYPE_STRING,
-                  __FILE__, ICL_TYPE_INT32, __LINE__, ICL_TYPE_POINTER, tdc,
-                  ICL_TYPE_INT32, tdc->dflags);
-       ReleaseReadLock(&tdc->lock);
-       ReleaseReadLock(&avc->lock);
-       afs_osi_Sleep(&tdc->validPos);
-       ObtainReadLock(&avc->lock);
-       ObtainReadLock(&tdc->lock);
-    }
-    if (!(avc->f.states & CStatd)
-       || !hsame(avc->f.m.DataVersion, tdc->f.versionNo)) {
-       ReleaseReadLock(&tdc->lock);
-       ReleaseReadLock(&avc->lock);
-       afs_PutDCache(tdc);
-       goto tagain;
-    }
-
-    len = 0;
-    auio->uio_fpflags = 0;
-    while (code == 0) {
-       origOffset = AFS_UIO_OFFSET(auio);
-
-       /* scan for the next interesting entry scan for in-use blob
-        * otherwise up point at this blob note that ode, if non-zero,
-        * also represents a held dir page */
-       if (!(us = BlobScan(tdc, (origOffset >> 5)))
-           || !(nde = (struct DirEntry *)afs_dir_GetBlob(tdc, us))) {
-           /* failed to setup nde, return what we've got, and release ode */
-           if (len) {
-               /* something to hand over. */
-               sdirEntry->d_fileno =
-                   (avc->f.fid.Fid.Volume << 16) + ntohl(ode->fid.vnode);
-               FIXUPSTUPIDINODE(sdirEntry->d_fileno);
-               sdirEntry->d_reclen = rlen = AFS_UIO_RESID(auio);
-               sdirEntry->d_namlen = o_slen;
-               sdirEntry->d_off = origOffset;
-               AFS_UIOMOVE((char *)sdirEntry, sizeof(*sdirEntry), UIO_READ,
-                           auio, code);
-               if (code == 0) {
-                   AFS_UIOMOVE(ode->name, o_slen, UIO_READ, auio, code);
-               }
-               /* pad out the remaining characters with zeros */
-               if (code == 0) {
-                   AFS_UIOMOVE(bufofzeros,
-                               ((o_slen + 1 + DIRPAD) & ~DIRPAD) - o_slen,
-                               UIO_READ, auio, code);
-               }
-               /* pad out the difference between rlen and slen... */
-               if (NDIRSIZ_LEN(o_slen) < rlen) {
-                   while (NDIRSIZ_LEN(o_slen) < rlen) {
-                       int minLen = rlen - NDIRSIZ_LEN(o_slen);
-                       if (minLen > sizeof(bufofzeros))
-                           minLen = sizeof(bufofzeros);
-                       AFS_UIOMOVE(bufofzeros, minLen, UIO_READ, auio, code);
-                       rlen -= minLen;
-                   }
-               }
-               AFS_UIO_SETRESID(auio, 0);
-           } else {
-               /* nothin to hand over */
-           }
-           if (ode)
-               DRelease(ode, 0);
-           goto dirend;
-       }
-       /* by here nde is set */
-
-       /* Do we have enough user space to carry out our mission? */
-       n_slen = strlen(nde->name);
-       if (NDIRSIZ_LEN(n_slen) >= (AFS_UIO_RESID(auio) - len)) {
-           /* No can do no more now; ya know... at this time */
-           DRelease(nde, 0);   /* can't use this one. */
-           if (len) {
-               sdirEntry->d_fileno =
-                   (avc->f.fid.Fid.Volume << 16) + ntohl(ode->fid.vnode);
-               FIXUPSTUPIDINODE(sdirEntry->d_fileno);
-               sdirEntry->d_reclen = rlen = AFS_UIO_RESID(auio);
-               sdirEntry->d_namlen = o_slen;
-               sdirEntry->d_off = origOffset;
-               AFS_UIOMOVE((char *)sdirEntry, sizeof(*sdirEntry), UIO_READ,
-                           auio, code);
-               if (code == 0)
-                   AFS_UIOMOVE(ode->name, o_slen, UIO_READ, auio, code);
-               /* pad out the remaining characters with zeros */
-               if (code == 0) {
-                   AFS_UIOMOVE(bufofzeros,
-                               ((o_slen + 1 + DIRPAD) & ~DIRPAD) - o_slen,
-                               UIO_READ, auio, code);
-               }
-               /* pad out the difference between rlen and slen... */
-               if (NDIRSIZ_LEN(o_slen) < rlen) {
-                   while (NDIRSIZ_LEN(o_slen) < rlen) {
-                       int minLen = rlen - NDIRSIZ_LEN(o_slen);
-                       if (minLen > sizeof(bufofzeros))
-                           minLen = sizeof(bufofzeros);
-                       AFS_UIOMOVE(bufofzeros, minLen, UIO_READ, auio, code);
-                       rlen -= minLen;
-                   }
-               }
-               /* this next line used to be AFSVFS40 or AIX 3.1, but is really generic */
-               AFS_UIO_SETOFFSET(auio, origOffset);
-               AFS_UIO_SETRESID(auio, 0);
-           } else {            /* trouble, can't give anything to the user! */
-               /* even though he has given us a buffer, 
-                * even though we have something to give us,
-                * Looks like we lost something somewhere.
-                */
-               code = EINVAL;
-           }
-           if (ode)
-               DRelease(ode, 0);
-           goto dirend;
-       }
-
-       /*
-        * In any event, we move out the LAST de entry, getting ready
-        * to set up for the next one.
-        */
-       if (len) {
-           sdirEntry->d_fileno =
-               (avc->f.fid.Fid.Volume << 16) + ntohl(ode->fid.vnode);
-           FIXUPSTUPIDINODE(sdirEntry->d_fileno);
-           sdirEntry->d_reclen = rlen = len;
-           sdirEntry->d_namlen = o_slen;
-           sdirEntry->d_off = origOffset;
-           AFS_UIOMOVE((char *)sdirEntry, sizeof(*sdirEntry), UIO_READ, auio,
-                       code);
-           if (code == 0)
-               AFS_UIOMOVE(ode->name, o_slen, UIO_READ, auio, code);
-           /* pad out the remaining characters with zeros */
-           if (code == 0) {
-               AFS_UIOMOVE(bufofzeros,
-                           ((o_slen + 1 + DIRPAD) & ~DIRPAD) - o_slen,
-                           UIO_READ, auio, code);
-           }
-           /* pad out the difference between rlen and slen... */
-           if (NDIRSIZ_LEN(o_slen) < rlen) {
-               while (NDIRSIZ_LEN(o_slen) < rlen) {
-                   int minLen = rlen - NDIRSIZ_LEN(o_slen);
-                   if (minLen > sizeof(bufofzeros))
-                       minLen = sizeof(bufofzeros);
-                   AFS_UIOMOVE(bufofzeros, minLen, UIO_READ, auio, code);
-                   rlen -= minLen;
-               }
-           }
-       }
-       len = NDIRSIZ_LEN(o_slen = n_slen);
-       if (ode)
-           DRelease(ode, 0);
-       ode = nde;
-       AFS_UIO_OFFSET(auio) = ((us + afs_dir_NameBlobs(nde->name)) << 5);
-    }
-    if (ode)
-       DRelease(ode, 0);
-
-  dirend:
-    ReleaseReadLock(&tdc->lock);
-    afs_PutDCache(tdc);
-    ReleaseReadLock(&avc->lock);
-
-  done:
-    osi_FreeSmallSpace((char *)sdirEntry);
-    AFS_DISCON_UNLOCK();
-    afs_PutFakeStat(&fakestate);
-    code = afs_CheckCode(code, &treq, 29);
-    return code;
-}
-
-#endif
 #endif /* !AFS_LINUX20_ENV */