viced-fetchdata64-should-call-common-code-in-64-mode-20011119
[openafs.git] / src / viced / afsfileprocs.c
index d81af30..8b66cfc 100644 (file)
@@ -273,6 +273,7 @@ static CallPreamble(acall, activecall)
     struct client *tclient;
     int retry_flag=1;
     int code = 0;
+    char hoststr[16];
     tconn = rx_ConnectionOf(*acall);
     *acall = (struct rx_call *)tconn;      /* change it! */
 
@@ -312,21 +313,23 @@ retry:
 
     h_Lock_r(thost);
     if (thost->hostFlags & HOSTDELETED) {
-      ViceLog(3,("Discarded a packet for deleted host %08x\n",thost->host));
+      ViceLog(3,("Discarded a packet for deleted host %s\n",afs_inet_ntoa_r(thost->host,hoststr)));
       code = VBUSY; /* raced, so retry */
     }
     else if (thost->hostFlags & VENUSDOWN) {
       if (BreakDelayedCallBacks_r(thost)) {
-       ViceLog(0,("BreakDelayedCallbacks FAILED for host %08x which IS UP.  Possible network or routing failure.\n",thost->host));
+       ViceLog(0,("BreakDelayedCallbacks FAILED for host %s which IS UP.  Possible network or routing failure.\n",
+               afs_inet_ntoa_r(thost->host, hoststr)));
        if ( MultiProbeAlternateAddress_r (thost) ) {
-           ViceLog(0, ("MultiProbe failed to find new address for host %x.%d\n",
-                       thost->host, thost->port));
+           ViceLog(0, ("MultiProbe failed to find new address for host %s:%d\n",
+                       afs_inet_ntoa_r(thost->host, hoststr), thost->port));
            code = -1;
        } else {
-           ViceLog(0, ("MultiProbe found new address for host %x.%d\n",
-                       thost->host, thost->port));
+           ViceLog(0, ("MultiProbe found new address for host %s:%d\n",
+                       afs_inet_ntoa_r(thost->host, hoststr), thost->port));
            if (BreakDelayedCallBacks_r(thost)) {
-               ViceLog(0,("BreakDelayedCallbacks FAILED AGAIN for host %08x which IS UP.  Possible network or routing failure.\n",thost->host));
+               ViceLog(0,("BreakDelayedCallbacks FAILED AGAIN for host %s which IS UP.  Possible network or routing failure.\n",
+                       afs_inet_ntoa_r(thost->host, hoststr)));
                code = -1;
            }
        }
@@ -441,6 +444,51 @@ SRXAFS_FetchData (tcon, Fid, Pos, Len, OutStatus, CallBack, Sync)
     struct AFSVolSync *Sync;           /* synchronization info */
 
 {
+    int code;
+
+    code = common_FetchData (tcon, Fid, Pos, Len, OutStatus,
+                                                 CallBack, Sync, 0);
+    return code;
+}
+
+SRXAFS_FetchData64 (tcon, Fid, Pos, Len, OutStatus, CallBack, Sync)
+    struct rx_connection *tcon;         /* Rx connection handle */
+    struct AFSFid *Fid;                 /* Fid of file to fetch */
+    afs_int64 Pos, Len;                 /* Not implemented yet */
+    struct AFSFetchStatus *OutStatus;   /* Returned status for Fid */
+    struct AFSCallBack *CallBack;       /* If r/w return CB for Fid */
+    struct AFSVolSync *Sync;            /* synchronization info */
+{
+    int code;
+    afs_int32 tPos, tLen;
+
+#ifdef AFS_64BIT_ENV
+    if (Pos + Len > 0x7fffffff)
+        return E2BIG;
+    tPos = Pos;
+    tLen = Len;
+#else /* AFS_64BIT_ENV */
+    if (Pos.high || Len.high)
+        return E2BIG;
+    tPos = Pos.low;
+    tLen = Len.low;
+#endif /* AFS_64BIT_ENV */
+
+    code = common_FetchData (tcon, Fid, tPos, tLen, OutStatus,
+                                                 CallBack, Sync, 1);
+    return code;
+}
+
+common_FetchData (tcon, Fid, Pos, Len, OutStatus, CallBack, Sync, type)
+    struct rx_connection *tcon;         /* Rx connection handle */
+    struct AFSFid *Fid;                 /* Fid of file to fetch */
+    afs_int32 Pos, Len;                 /* Not implemented yet */
+    struct AFSFetchStatus *OutStatus;   /* Returned status for Fid */
+    struct AFSCallBack *CallBack;       /* If r/w return CB for Fid */
+    struct AFSVolSync *Sync;            /* synchronization info */
+    int type;                           /* 32 bit or 64 bit call */
+
+{ 
     Vnode * targetptr =        0;                  /* pointer to vnode to fetch */
     Vnode * parentwhentargetnotdir = 0;            /* parent vnode if vptr is a file */
     Vnode   tparentwhentargetnotdir;       /* parent vnode for GetStatus */
@@ -546,10 +594,10 @@ SRXAFS_FetchData (tcon, Fid, Pos, Len, OutStatus, CallBack, Sync)
 
     /* actually do the data transfer */
 #if FS_STATS_DETAILED
-    errorCode = FetchData_RXStyle(volptr, targetptr, tcall, Pos, Len,
+    errorCode = FetchData_RXStyle(volptr, targetptr, tcall, Pos, Len, type,
                                  &bytesToXfer, &bytesXferred);
 #else
-    if (errorCode = FetchData_RXStyle(volptr, targetptr, tcall, Pos, Len))
+    if (errorCode = FetchData_RXStyle(volptr, targetptr, tcall, Pos, Len, type))
        goto Bad_FetchData;
 #endif /* FS_STATS_DETAILED */
 
@@ -991,6 +1039,155 @@ Audit_and_Return:
 } /*SRXAFS_BulkStatus*/
 
 
+SRXAFS_InlineBulkStatus(tcon, Fids, OutStats, CallBacks, Sync)
+    struct rx_connection *tcon;
+    struct AFSCBFids *Fids;
+    struct AFSBulkStats *OutStats;
+    struct AFSCBs *CallBacks;
+    struct AFSVolSync *Sync;
+{
+    register int i;
+    afs_int32 nfiles;
+    Vnode * targetptr =        0;              /* pointer to vnode to fetch */
+    Vnode * parentwhentargetnotdir = 0;        /* parent vnode if targetptr is a file */
+    int            errorCode = 0;              /* return code to caller */
+    Volume * volptr = 0;               /* pointer to the volume */
+    struct client *client;             /* pointer to the client data */
+    afs_int32 rights, anyrights;               /* rights for this and any user */
+    register struct AFSFid *tfid;      /* file id we're dealing with now */
+    struct rx_call *tcall = (struct rx_call *) tcon; 
+    AFSFetchStatus *tstatus;
+#if FS_STATS_DETAILED
+    struct fs_stats_opTimingData *opP;      /* Ptr to this op's timing struct */
+    struct timeval opStartTime,
+                   opStopTime;             /* Start/stop times for RPC op*/
+    struct timeval elapsedTime;                    /* Transfer time */
+
+    /*
+     * Set our stats pointer, remember when the RPC operation started, and
+     * tally the operation.
+     */
+    opP = &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_BULKSTATUS]);
+    FS_LOCK
+    (opP->numOps)++;
+    FS_UNLOCK
+    TM_GetTimeOfDay(&opStartTime, 0);
+#endif /* FS_STATS_DETAILED */
+
+    ViceLog(1, ("SAFS_InlineBulkStatus\n"));
+    FS_LOCK
+    AFSCallStats.TotalCalls++;
+    FS_UNLOCK
+
+    nfiles = Fids->AFSCBFids_len;      /* # of files in here */
+    if (nfiles <= 0) {                  /* Sanity check */
+       errorCode = EINVAL;
+       goto Audit_and_Return;
+    }
+
+    /* allocate space for return output parameters */
+    OutStats->AFSBulkStats_val = (struct AFSFetchStatus *)
+       malloc(nfiles * sizeof(struct AFSFetchStatus));
+    OutStats->AFSBulkStats_len = nfiles;
+    CallBacks->AFSCBs_val = (struct AFSCallBack *)
+       malloc(nfiles * sizeof(struct AFSCallBack));
+    CallBacks->AFSCBs_len = nfiles;
+
+    if (errorCode = CallPreamble((struct rx_call **) &tcon, ACTIVECALL)) {
+       goto Bad_InlineBulkStatus;
+    }
+
+    tfid = Fids->AFSCBFids_val;
+    for (i=0; i<nfiles; i++, tfid++) {
+       /*
+        * Get volume/vnode for the fetched file; caller's rights to it
+        * are also returned
+        */
+       if (errorCode =
+           GetVolumePackage(tcon, tfid, &volptr, &targetptr,
+                            DONTCHECK, &parentwhentargetnotdir, &client,
+                            READ_LOCK, &rights, &anyrights)) {
+           tstatus = &OutStats->AFSBulkStats_val[i];
+           tstatus->errorCode = errorCode;
+           parentwhentargetnotdir = (Vnode *) 0;
+           targetptr = (Vnode *) 0;
+           volptr = (Volume *) 0;
+           continue;
+       }
+
+       /* set volume synchronization information, but only once per call */
+       if (i == nfiles)
+           SetVolumeSync(Sync, volptr);
+
+       /* Are we allowed to fetch Fid's status? */
+       if (targetptr->disk.type != vDirectory) {
+           if (errorCode = Check_PermissionRights(targetptr, client, rights,
+                                                  CHK_FETCHSTATUS, 0)) {
+               tstatus = &OutStats->AFSBulkStats_val[i];
+               tstatus->errorCode = errorCode;
+               PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0, volptr);
+               parentwhentargetnotdir = (Vnode *) 0;
+               targetptr = (Vnode *) 0;
+               volptr = (Volume *) 0;
+               continue;
+           }
+       }
+
+       /* set OutStatus From the Fid  */
+       GetStatus(targetptr, &OutStats->AFSBulkStats_val[i],
+                 rights, anyrights, parentwhentargetnotdir);
+
+       /* If a r/w volume, also set the CallBack state */
+       if (VolumeWriteable(volptr))
+           SetCallBackStruct(AddBulkCallBack(client->host, tfid),
+                             &CallBacks->AFSCBs_val[i]);
+       else {
+         struct AFSFid myFid;          
+         memset(&myFid, 0, sizeof(struct AFSFid));
+         myFid.Volume = tfid->Volume;
+         SetCallBackStruct(AddVolCallBack(client->host, &myFid),
+                             &CallBacks->AFSCBs_val[i]);
+       }
+
+       /* put back the file ID and volume */
+       PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0, volptr);
+       parentwhentargetnotdir = (Vnode *) 0;
+       targetptr = (Vnode *) 0;
+       volptr = (Volume *) 0;
+    }
+
+Bad_InlineBulkStatus: 
+    /* Update and store volume/vnode and parent vnodes back */
+    PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *)0, volptr);
+    CallPostamble(tcon);
+
+#if FS_STATS_DETAILED
+    TM_GetTimeOfDay(&opStopTime, 0);
+    if (errorCode == 0) {
+       FS_LOCK
+        (opP->numSuccesses)++;
+        fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
+        fs_stats_AddTo((opP->sumTime), elapsedTime);
+        fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
+        if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
+           fs_stats_TimeAssign((opP->minTime), elapsedTime);
+        }
+        if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
+           fs_stats_TimeAssign((opP->maxTime), elapsedTime);
+        }
+       FS_UNLOCK
+    }  
+
+#endif /* FS_STATS_DETAILED */
+
+Audit_and_Return:
+    ViceLog(2, ("SAFS_InlineBulkStatus returns %d\n", errorCode)); 
+    osi_auditU (tcall, InlineBulkFetchStatusEvent, errorCode, AUD_FIDS, Fids, AUD_END);
+    return 0;
+
+} /*SRXAFS_InlineBulkStatus*/
+
+
 SRXAFS_FetchStatus (tcon, Fid, OutStatus, CallBack, Sync)
     struct AFSVolSync *Sync;
     struct rx_connection *tcon;                /* Rx connection handle */
@@ -1285,6 +1482,38 @@ Bad_StoreData:
 
 } /*SRXAFS_StoreData*/
 
+SRXAFS_StoreData64 (tcon, Fid, InStatus, Pos, Length, FileLength, OutStatus, Sync)
+    struct AFSVolSync *Sync;
+    struct rx_connection *tcon;         /* Rx connection Handle */
+    struct AFSFid *Fid;                 /* Fid of taret file */
+    struct AFSStoreStatus *InStatus;    /* Input Status for Fid */
+    afs_int64 Pos;                              /* Not implemented yet */           afs_int64 Length;                   /* Length of data to store */
+    afs_int64 FileLength;                       /* Length of file after store */
+    struct AFSFetchStatus *OutStatus;   /* Returned status for target fid */
+{
+    int code;
+    afs_int32 tPos;
+    afs_int32 tLength;
+    afs_int32 tFileLength;
+
+#ifdef AFS_64BIT_ENV
+    if (FileLength > 0x7fffffff)
+        return E2BIG;
+    tPos = Pos;
+    tLength = Length;
+    tFileLength = FileLength;
+#else /* AFS_64BIT_ENV */
+    if (FileLength.high)
+        return E2BIG;
+    tPos = Pos.low;
+    tLength = Length.low;
+    tFileLength = FileLength.low;
+#endif /* AFS_64BIT_ENV */
+
+    code = SRXAFS_StoreData (tcon, Fid, InStatus, tPos, tLength, tFileLength,
+                                OutStatus, Sync);
+    return code;
+}
 
 SRXAFS_StoreACL (tcon, Fid, AccessList, OutStatus, Sync)
     struct AFSVolSync *Sync;
@@ -2387,15 +2616,15 @@ SAFSS_Symlink (tcon, DirFid, Name, LinkContents, InStatus, OutFid, OutFidStatus,
     }
 
     /*
-     * If we're creating a mount point (owner mode bits sans x bit), we must
-     * have administer access to the directory, too.  Always allow sysadmins
+     * If we're creating a mount point (any x bits clear), we must have
+     * administer access to the directory, too.  Always allow sysadmins
      * to do this.
      */
-    if ((InStatus->Mask & AFS_SETMODE) && !(InStatus->UnixModeBits & 0100)) {
+    if ((InStatus->Mask & AFS_SETMODE) && !(InStatus->UnixModeBits & 0111)) {
        /*
-        * We have a symlink, 'cause we're trying to set the Unix mode bits
-        * to something without the owner x bits (default mode bits if
-        * AFS_SETMODE is false is 0777)
+        * We have a mountpoint, 'cause we're trying to set the Unix mode
+        * bits to something with some x bits missing (default mode bits
+        * if AFS_SETMODE is false is 0777)
         */
        if (VanillaUser(client) && !(rights & PRSFS_ADMINISTER)) {
            errorCode = EACCES;
@@ -4812,15 +5041,16 @@ PutVolumePackage(parentwhentargetnotdir, targetptr, parentptr, volptr)
  #                       the File Server.
  */
 
-FetchData_RXStyle(volptr, targetptr, Call, Pos, Len, a_bytesToFetchP, a_bytesFetchedP)
+FetchData_RXStyle(volptr, targetptr, Call, Pos, Len, Int64Mode, a_bytesToFetchP, a_bytesFetchedP)
 #else
-FetchData_RXStyle(volptr, targetptr, Call, Pos, Len)
+FetchData_RXStyle(volptr, targetptr, Call, Pos, Len, Int64Mode)
 #endif /* FS_STATS_DETAILED */
 Volume                 * volptr;
 Vnode                  * targetptr;
 register struct rx_call                * Call;
 afs_int32                      Pos;
 afs_int32                      Len;
+afs_int32                      Int64Mode;
 #if FS_STATS_DETAILED
 afs_int32 *a_bytesToFetchP;
 afs_int32 *a_bytesFetchedP;
@@ -4858,6 +5088,8 @@ afs_int32 *a_bytesFetchedP;
         * back to make the cache manager happy...
         */
        tlen = htonl(0);
+        if (Int64Mode)
+            rx_Write(Call, &tlen, sizeof(afs_int32));   /* send 0-length  */
        rx_Write(Call, &tlen, sizeof(afs_int32));       /* send 0-length  */
        return (0);
     }
@@ -4875,6 +5107,10 @@ afs_int32 *a_bytesFetchedP;
     if (Pos + Len > tlen) Len =        tlen - Pos;     /* get length we should send */
     FDH_SEEK(fdP, Pos, 0);
     tlen = htonl(Len);
+    if (Int64Mode) {
+        afs_int32 zero = 0;
+        rx_Write(Call, &zero, sizeof(afs_int32)); /* High order bits */
+    }
     rx_Write(Call, &tlen, sizeof(afs_int32));  /* send length on fetch */
 #if FS_STATS_DETAILED
     (*a_bytesToFetchP) = Len;
@@ -6220,8 +6456,9 @@ void GetStatus(targetptr, status, rights, anyrights, parentptr)
 {
     /* initialize return status from a vnode  */
     status->InterfaceVersion = 1;
-    status->SyncCounter = status->dataVersionHigh = status->spare2 =
-    status->spare3 = status->spare4 = 0;
+    status->SyncCounter = status->dataVersionHigh = status->lockCount =
+    status->errorCode = 0;
+    status->ResidencyMask = 1; /* means for MR-AFS: file in /vicepr-partition */
     if (targetptr->disk.type == vFile)
        status->FileType = File;
     else if (targetptr->disk.type == vDirectory)
@@ -6241,10 +6478,10 @@ void GetStatus(targetptr, status, rights, anyrights, parentptr)
     status->ClientModTime = targetptr->disk.unixModifyTime;    /* This might need rework */
     status->ParentVnode = (status->FileType == Directory ? targetptr->vnodeNumber : parentptr->vnodeNumber);
     status->ParentUnique = (status->FileType == Directory ? targetptr->disk.uniquifier : parentptr->disk.uniquifier);
-    status->SegSize = 0;
     status->ServerModTime = targetptr->disk.serverModifyTime;                  
     status->Group = targetptr->disk.group;
-    status->spare2 = targetptr->disk.lock.lockCount;
+    status->lockCount = targetptr->disk.lock.lockCount;
+    status->errorCode = 0;
 
 } /*GetStatus*/