solaris-9-support-20011008
[openafs.git] / src / afs / SOLARIS / osi_vnodeops.c
index d491ff1..a005ec1 100644 (file)
@@ -1,10 +1,17 @@
-/* Copyright (C) 1995 Transarc Corporation - All rights reserved. */
 /*
- * (C) COPYRIGHT IBM CORPORATION 1987, 1988
- * LICENSED MATERIALS - PROPERTY OF IBM
+ * Copyright 2000, International Business Machines Corporation and others.
+ * All Rights Reserved.
+ * 
+ * This software has been released under the terms of the IBM Public
+ * License.  For details, see the LICENSE file in the top-level source
+ * directory or online at http://www.openafs.org/dl/license10.html
  */
 
-#include "../afs/param.h"      /* Should be always first */
+#include <afsconfig.h>
+#include "../afs/param.h"
+
+RCSID("$Header$");
+
 #if    defined(AFS_SUN_ENV) || defined(AFS_SUN5_ENV)
 /*
  * SOLARIS/osi_vnodeops.c
@@ -258,10 +265,6 @@ struct AFS_UCRED *acred;
     afs_int32       toffset;
 #endif
 
-    if (!pl) return 0;                 /* punt asynch requests */
-
-    len = PAGESIZE;
-    pl[0] = NULL;                      /* Make sure it's empty */
     if (!acred) 
 #ifdef AFS_SUN5_ENV
        osi_Panic("GetOnePage: !acred");
@@ -269,9 +272,36 @@ struct AFS_UCRED *acred;
        acred = u.u_cred;               /* better than nothing */
 #endif
 
-    /* first, obtain the proper lock for the VM system */
     avc = (struct vcache *) vp;        /* cast to afs vnode */
 
+#ifdef AFS_SUN5_ENV
+    if (avc->credp /*&& AFS_NFSXLATORREQ(acred)*/ && AFS_NFSXLATORREQ(avc->credp)) {
+       acred = avc->credp;
+    }
+#endif
+    if (code = afs_InitReq(&treq, acred)) return code;
+
+    if (!pl) {
+       /*
+        * This is a read-ahead request, e.g. due to madvise.
+        */
+       tdc = afs_GetDCache(avc, (afs_int32)off, &treq, &offset, &nlen, 1);
+       if (!tdc) return 0;
+
+       if (!(tdc->flags & DFNextStarted)) {
+           ObtainReadLock(&avc->lock);
+           afs_PrefetchChunk(avc, tdc, acred, &treq);
+           ReleaseReadLock(&avc->lock);
+       }
+       afs_PutDCache(tdc);
+       return 0;
+    }
+
+    len = PAGESIZE;
+    pl[0] = NULL;                      /* Make sure it's empty */
+
+    /* first, obtain the proper lock for the VM system */
+
     /* if this is a read request, map the page in read-only.  This will
      * allow us to swap out the dcache entry if there are only read-only
      * pages created for the chunk, which helps a *lot* when dealing
@@ -283,12 +313,6 @@ struct AFS_UCRED *acred;
        mapForRead = 1;
 
     if (protp) *protp = PROT_ALL;
-#ifdef AFS_SUN5_ENV
-    if (avc->credp /*&& AFS_NFSXLATORREQ(acred)*/ && AFS_NFSXLATORREQ(avc->credp)) {
-       acred = avc->credp;
-    }
-#endif
-    if (code = afs_InitReq(&treq, acred)) return code;
 #ifndef        AFS_SUN5_ENV
     if (AFS_NFSXLATORREQ(acred)) {
        if (rw == S_READ) {
@@ -316,7 +340,7 @@ retry:
     }
 
     afs_BozonLock(&avc->pvnLock, avc);
-    ObtainSharedLock(&avc->lock,566);
+    ObtainReadLock(&avc->lock);
 
     afs_Trace4(afs_iclSetp, CM_TRACE_PAGEIN, ICL_TYPE_POINTER, (afs_int32) vp,
               ICL_TYPE_LONG, (afs_int32) off, ICL_TYPE_LONG, (afs_int32) len,
@@ -330,7 +354,7 @@ retry:
      * the locks and try again when the VM purge is done. */
     ObtainWriteLock(&avc->vlock, 550);
     if (avc->activeV) {
-       ReleaseSharedLock(&avc->lock); 
+       ReleaseReadLock(&avc->lock); 
        ReleaseWriteLock(&avc->vlock); 
        afs_BozonUnlock(&avc->pvnLock, avc);
        afs_PutDCache(tdc);
@@ -352,7 +376,7 @@ retry:
     /* Check to see whether the cache entry is still valid */
     if (!(avc->states & CStatd)
        || !hsame(avc->m.DataVersion, tdc->f.versionNo)) {
-       ReleaseSharedLock(&avc->lock); 
+       ReleaseReadLock(&avc->lock); 
        afs_BozonUnlock(&avc->pvnLock, avc);
        afs_PutDCache(tdc);
        goto retry;
@@ -376,7 +400,11 @@ retry:
         * As of 4/98, that shouldn't be possible, but we'll be defensive here
         * in case someone tries to relax all the serialization of read and write
         * operations with harmless things like stat. */
+#if    defined(AFS_SUN58_ENV)
+        page = page_create_va(vp, toffset, PAGESIZE, PG_WAIT|PG_EXCL, seg, addr);
+#else
        page = page_create_va(vp, toffset, PAGESIZE, PG_WAIT|PG_EXCL, seg->s_as, addr);
+#endif
 #else
        page = page_create(vp, toffset, PAGESIZE, PG_WAIT);
 #endif
@@ -427,19 +455,17 @@ retry:
            buf->b_blkno = btodb(toffset);
            bp_mapin(buf);              /* map it in to our address space */
 #ifndef        AFS_SUN5_ENV    
-           ReleaseSharedLock(&avc->lock);
+           ReleaseReadLock(&avc->lock);
 #endif
 #if    defined(AFS_SUN5_ENV)
            AFS_GLOCK();
-           UpgradeSToWLock(&avc->lock, 564);
            code = afs_ustrategy(buf, acred);   /* do the I/O */
-            ConvertWToSLock(&avc->lock);
            AFS_GUNLOCK();
 #else
            code = afs_ustrategy(buf);  /* do the I/O */
 #endif
 #ifndef        AFS_SUN5_ENV    
-           ObtainSharedLock(&avc->lock,245);
+           ObtainReadLock(&avc->lock);
 #endif
 #ifdef AFS_SUN5_ENV
            /* Before freeing unmap the buffer */
@@ -484,8 +510,13 @@ retry:
 
     AFS_GLOCK();
     pl[slot] = (struct page *) 0;
+    /*
+     * XXX This seems kind-of wrong: we shouldn't be modifying
+     *     avc->states while not holding the write lock (even
+     *     though nothing really uses CHasPages..)
+     */
     avc->states |= CHasPages;
-    ReleaseSharedLock(&avc->lock);
+    ReleaseReadLock(&avc->lock);
 #ifdef AFS_SUN5_ENV
     ObtainWriteLock(&afs_xdcache,246);
     if (!mapForRead) {
@@ -515,7 +546,7 @@ retry:
     for(i=0; i<slot; i++)
        PAGE_RELE(pl[i]);
 #endif
-    ReleaseSharedLock(&avc->lock);
+    ReleaseReadLock(&avc->lock);
     afs_BozonUnlock(&avc->pvnLock, avc);
 #ifdef AFS_SUN5_ENV
     afs_PutDCache(tdc);
@@ -534,7 +565,12 @@ int afs_putpage(vp, off, len, flags, cred)
     struct vcache *avc;
     struct page *pages;
     afs_int32 code = 0;
-    afs_int32 tlen, endPos, NPages=0;
+#if    defined(AFS_SUN58_ENV)
+    size_t tlen;
+#else
+    afs_int32 tlen;
+#endif
+    afs_int32 endPos, NPages=0;
 #if    defined(AFS_SUN56_ENV)
     u_offset_t toff = off;
 #else
@@ -548,10 +584,6 @@ int afs_putpage(vp, off, len, flags, cred)
     /*
      * Putpage (ASYNC) is called every sec to flush out dirty vm pages 
      */
-    if (flags == B_ASYNC) {
-       /* XXX For testing only XXX */
-       return (EINVAL);
-    }
     AFS_GLOCK();
     afs_Trace4(afs_iclSetp, CM_TRACE_PAGEOUT, ICL_TYPE_POINTER, (afs_int32) vp,
               ICL_TYPE_LONG, (afs_int32) off, ICL_TYPE_LONG, (afs_int32) len,
@@ -612,7 +644,12 @@ int afs_putapage(struct vnode *vp, struct page *pages,
 #else
                 u_int *offp,
 #endif
-                u_int *lenp, int flags, struct AFS_UCRED *credp)
+#if    defined(AFS_SUN58_ENV)
+                 size_t *lenp,
+#else
+                 u_int *lenp,
+#endif
+                 int flags, struct AFS_UCRED *credp)
 {
     struct buf *tbuf;
     struct vcache *avc = (struct vcache *)vp;
@@ -1382,7 +1419,11 @@ afs_seek(vnp, ooff, noffp)
     return code;
 }
 
-int afs_frlock(vnp, cmd, ap, flag, off, credp)
+int afs_frlock(vnp, cmd, ap, flag, off,
+#ifdef AFS_SUN59_ENV
+              flkcb,
+#endif
+              credp)
     struct vnode *vnp;
     int cmd;
 #if    defined(AFS_SUN56_ENV)
@@ -1392,6 +1433,9 @@ int afs_frlock(vnp, cmd, ap, flag, off, credp)
 #endif
     int flag;
     offset_t off;
+#ifdef AFS_SUN59_ENV
+    struct flk_callback *flkcb;
+#endif
     struct AFS_UCRED *credp;
 {
     register afs_int32 code = 0;
@@ -1399,6 +1443,10 @@ int afs_frlock(vnp, cmd, ap, flag, off, credp)
      * Implement based on afs_lockctl
      */
     AFS_GLOCK();
+#ifdef AFS_SUN59_ENV
+    if (flkcb)
+       afs_warn("Don't know how to deal with flk_callback's!\n");
+#endif
     if ((cmd == F_GETLK) || (cmd == F_O_GETLK) || (cmd == F_SETLK) || (cmd ==  F_SETLKW)) {
 #ifdef AFS_SUN53_ENV
        ap->l_pid = ttoproc(curthread)->p_pid;
@@ -1496,9 +1544,16 @@ struct cred *credp;
     return EINVAL;
 }
 
-int  afs_dumpctl(vp, i)
+int  afs_dumpctl(vp, i
+#ifdef AFS_SUN59_ENV
+                , blkp
+#endif
+                )
 struct vnode *vp;
 int i;
+#ifdef AFS_SUN59_ENV
+int *blkp;
+#endif
 {
     afs_warn("afs_dumpctl: Not implemented\n");
     return EINVAL;