From: Jeffrey Altman Date: Sun, 13 Jan 2013 15:15:02 +0000 (-0500) Subject: windows: Update raw fetch/store operations X-Git-Tag: openafs-stable-1_8_0pre1~1611 X-Git-Url: https://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=24b6365169e48d21bbb97fb456860f63389a5bcf windows: Update raw fetch/store operations rawops.c is a hold over from Eric Williams' original attempt to implement an AFS redirector. When the rest of the his code was purged from the tree and replaced with a more complete implementation based upon the Kernel Drivers's File System framework rawops.c was left behind. Although the source file has been compiled as part of the build, its functions ReadData and WriteData have never been called. This patchset: 1. renames the functions to raw_ReadData and raw_WriteData 2. modifies the function signatures and provides a header with prototypes 3. requires that cm_scache.rw be write-locked upon entry 4. renames variables 5. removes the #define CM_BUF_BUFSIZE and relies upon cm_data.blockSize instead 6. Always write back the current range as an async store instead of the previous chunk as random write patterns will fail to store all of the dirty buffers. Change-Id: I1594b2950ab14da0c0de2a382fd1ba8248a9d1c6 Reviewed-on: http://gerrit.openafs.org/8953 Tested-by: BuildBot Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- diff --git a/src/WINNT/afsd/rawops.c b/src/WINNT/afsd/rawops.c index ecc6f24..85751ce 100644 --- a/src/WINNT/afsd/rawops.c +++ b/src/WINNT/afsd/rawops.c @@ -14,31 +14,25 @@ #include #include "afsd.h" -#define CM_BUF_SIZE 4096 -long buf_bufferSize = CM_BUF_SIZE; - -long ReadData(cm_scache_t *scp, osi_hyper_t offset, long count, char *op, - cm_user_t *userp, long *readp) +/* + * called with scp->rw lock held exclusive + */ +afs_int32 +raw_ReadData( cm_scache_t *scp, osi_hyper_t *offsetp, + afs_uint32 length, char *bufferp, afs_uint32 *readp, + cm_user_t *userp, cm_req_t *reqp) { - //osi_hyper_t offset; long code; - cm_buf_t *bufferp; + cm_buf_t *bufp = NULL; osi_hyper_t fileLength; osi_hyper_t thyper; osi_hyper_t lastByte; osi_hyper_t bufferOffset; long bufIndex, nbytes; int sequential = 0; - cm_req_t req; - - cm_InitReq(&req); - - bufferp = NULL; - - lock_ObtainWrite(&scp->rw); /* start by looking up the file's end */ - code = cm_SyncOp(scp, NULL, userp, &req, 0, + code = cm_SyncOp(scp, NULL, userp, reqp, 0, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); if (code) goto done; @@ -48,45 +42,45 @@ long ReadData(cm_scache_t *scp, osi_hyper_t offset, long count, char *op, /* now we have the entry locked, look up the length */ fileLength = scp->length; - /* adjust count down so that it won't go past EOF */ - thyper.LowPart = count; + /* adjust length down so that it won't go past EOF */ + thyper.LowPart = length; thyper.HighPart = 0; - thyper = LargeIntegerAdd(offset, thyper); /* where read should end */ + thyper = LargeIntegerAdd(*offsetp, thyper); /* where read should end */ lastByte = thyper; if (LargeIntegerGreaterThan(thyper, fileLength)) { /* we'd read past EOF, so just stop at fileLength bytes. * Start by computing how many bytes remain in the file. */ - thyper = LargeIntegerSubtract(fileLength, offset); + thyper = LargeIntegerSubtract(fileLength, *offsetp); /* if we are past EOF, read 0 bytes */ if (LargeIntegerLessThanZero(thyper)) - count = 0; + length = 0; else - count = thyper.LowPart; + length = thyper.LowPart; } - *readp = count; + *readp = length; /* now, copy the data one buffer at a time, * until we've filled the request packet */ while (1) { /* if we've copied all the data requested, we're done */ - if (count <= 0) break; + if (length <= 0) break; /* otherwise, load up a buffer of data */ - thyper.HighPart = offset.HighPart; - thyper.LowPart = offset.LowPart & ~(buf_bufferSize-1); - if (!bufferp || !LargeIntegerEqualTo(thyper, bufferOffset)) { + thyper.HighPart = offsetp->HighPart; + thyper.LowPart = offsetp->LowPart & ~(cm_data.blockSize-1); + if (!bufp || !LargeIntegerEqualTo(thyper, bufferOffset)) { /* wrong buffer */ - if (bufferp) { - buf_Release(bufferp); - bufferp = NULL; + if (bufp) { + buf_Release(bufp); + bufp = NULL; } lock_ReleaseWrite(&scp->rw); - code = buf_Get(scp, &thyper, &req, &bufferp); + code = buf_Get(scp, &thyper, reqp, &bufp); lock_ObtainWrite(&scp->rw); if (code) goto done; @@ -94,23 +88,22 @@ long ReadData(cm_scache_t *scp, osi_hyper_t offset, long count, char *op, /* now get the data in the cache */ while (1) { - code = cm_SyncOp(scp, bufferp, userp, &req, 0, - CM_SCACHESYNC_NEEDCALLBACK - | CM_SCACHESYNC_READ); + code = cm_SyncOp(scp, bufp, userp, reqp, 0, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ); if (code) goto done; - cm_SyncOpDone(scp, bufferp, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ); + cm_SyncOpDone(scp, bufp, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ); - if (cm_HaveBuffer(scp, bufferp, 0)) break; + if (cm_HaveBuffer(scp, bufp, 0)) break; /* otherwise, load the buffer and try again */ - code = cm_GetBuffer(scp, bufferp, NULL, userp, &req); + code = cm_GetBuffer(scp, bufp, NULL, userp, reqp); if (code) break; } if (code) { - buf_Release(bufferp); - bufferp = NULL; + buf_Release(bufp); + bufp = NULL; goto done; } } /* if (wrong buffer) ... */ @@ -118,63 +111,58 @@ long ReadData(cm_scache_t *scp, osi_hyper_t offset, long count, char *op, /* now we have the right buffer loaded. Copy out the * data from here to the user's buffer. */ - bufIndex = offset.LowPart & (buf_bufferSize - 1); + bufIndex = offsetp->LowPart & (cm_data.blockSize - 1); /* and figure out how many bytes we want from this buffer */ - nbytes = buf_bufferSize - bufIndex; /* what remains in buffer */ - if (nbytes > count) nbytes = count; /* don't go past EOF */ + nbytes = cm_data.blockSize - bufIndex; /* what remains in buffer */ + if (nbytes > length) nbytes = length; /* don't go past EOF */ /* now copy the data */ - memcpy(op, bufferp->datap + bufIndex, nbytes); + memcpy(bufferp, bufp->datap + bufIndex, nbytes); - /* adjust counters, pointers, etc. */ - op += nbytes; - count -= nbytes; + /* adjust lengthers, pointers, etc. */ + bufferp += nbytes; + length -= nbytes; thyper.LowPart = nbytes; thyper.HighPart = 0; - offset = LargeIntegerAdd(thyper, offset); + *offsetp = LargeIntegerAdd(thyper, *offsetp); } /* while 1 */ done: - lock_ReleaseWrite(&scp->rw); - //lock_ReleaseMutex(&fidp->mx); - if (bufferp) - buf_Release(bufferp); + if (bufp) + buf_Release(bufp); if (code == 0 && sequential) - cm_ConsiderPrefetch(scp, &lastByte, *readp, userp, &req); + cm_ConsiderPrefetch(scp, &lastByte, *readp, userp, reqp); return code; } -long WriteData(cm_scache_t *scp, osi_hyper_t offset, long count, char *op, - cm_user_t *userp, long *writtenp) +/* + * called with scp->rw lock held exclusive + */ + +afs_uint32 +raw_WriteData( cm_scache_t *scp, osi_hyper_t *offsetp, afs_uint32 length, char *bufferp, + cm_user_t *userp, cm_req_t *reqp, afs_uint32 *writtenp) { long code = 0; long written = 0; osi_hyper_t fileLength; /* file's length at start of write */ osi_hyper_t minLength; /* don't read past this */ afs_uint32 nbytes; /* # of bytes to transfer this iteration */ - cm_buf_t *bufferp; + cm_buf_t *bufp = NULL; osi_hyper_t thyper; /* hyper tmp variable */ osi_hyper_t bufferOffset; afs_uint32 bufIndex; /* index in buffer where our data is */ - int doWriteBack; - osi_hyper_t writeBackOffset;/* offset of region to write back when - * I/O is done */ + int doWriteBack = 0; + osi_hyper_t writeBackOffset;/* offset of region to write back when I/O is done */ + afs_uint32 writeBackLength; DWORD filter = 0; - cm_req_t req; - - cm_InitReq(&req); - - bufferp = NULL; - doWriteBack = 0; - - lock_ObtainWrite(&scp->rw); /* start by looking up the file's end */ - code = cm_SyncOp(scp, NULL, userp, &req, 0, + code = cm_SyncOp(scp, NULL, userp, reqp, 0, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_SETSTATUS | CM_SCACHESYNC_GETSTATUS); @@ -183,14 +171,6 @@ long WriteData(cm_scache_t *scp, osi_hyper_t offset, long count, char *op, cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_SETSTATUS | CM_SCACHESYNC_GETSTATUS); -#if 0 - /* make sure we have a writable FD */ - if (!(fidp->flags & SMB_FID_OPENWRITE)) { - code = CM_ERROR_BADFDOP; - goto done; - } -#endif - /* now we have the entry locked, look up the length */ fileLength = scp->length; minLength = fileLength; @@ -198,9 +178,9 @@ long WriteData(cm_scache_t *scp, osi_hyper_t offset, long count, char *op, minLength = scp->serverLength; /* adjust file length if we extend past EOF */ - thyper.LowPart = count; + thyper.LowPart = length; thyper.HighPart = 0; - thyper = LargeIntegerAdd(offset, thyper); /* where write should end */ + thyper = LargeIntegerAdd(*offsetp, thyper); /* where write should end */ if (LargeIntegerGreaterThan(thyper, fileLength)) { /* we'd write past EOF, so extend the file */ scp->mask |= CM_SCACHEMASK_LENGTH; @@ -209,47 +189,32 @@ long WriteData(cm_scache_t *scp, osi_hyper_t offset, long count, char *op, } else filter |= FILE_NOTIFY_CHANGE_LAST_WRITE; - /* now, if the new position (thyper) and the old (offset) are in - * different storeback windows, remember to store back the previous - * storeback window when we're done with the write. - */ - if ((thyper.LowPart & (-cm_chunkSize)) != - (offset.LowPart & (-cm_chunkSize))) { - /* they're different */ - doWriteBack = 1; - writeBackOffset.HighPart = offset.HighPart; - writeBackOffset.LowPart = offset.LowPart & (-cm_chunkSize); - } - - *writtenp = count; + doWriteBack = 1; + writeBackOffset = *offsetp; + writeBackLength = length; /* now, copy the data one buffer at a time, until we've filled the * request packet */ while (1) { /* if we've copied all the data requested, we're done */ - if (count <= 0) break; - - /* handle over quota or out of space */ - if (scp->flags & (CM_SCACHEFLAG_OVERQUOTA | CM_SCACHEFLAG_OUTOFSPACE)) { - *writtenp = written; - break; - } + if (length <= 0) break; /* otherwise, load up a buffer of data */ - thyper.HighPart = offset.HighPart; - thyper.LowPart = offset.LowPart & ~(buf_bufferSize-1); - if (!bufferp || !LargeIntegerEqualTo(thyper, bufferOffset)) { + thyper.HighPart = offsetp->HighPart; + thyper.LowPart = offsetp->LowPart & ~(cm_data.blockSize-1); + if (!bufp || !LargeIntegerEqualTo(thyper, bufferOffset)) { /* wrong buffer */ - if (bufferp) { - lock_ReleaseMutex(&bufferp->mx); - buf_Release(bufferp); - bufferp = NULL; + if (bufp) { + lock_ReleaseMutex(&bufp->mx); + buf_Release(bufp); + bufp = NULL; } lock_ReleaseWrite(&scp->rw); - code = buf_Get(scp, &thyper, &req, &bufferp); + code = buf_Get(scp, &thyper, reqp, &bufp); + if (bufp) + lock_ObtainMutex(&bufp->mx); - lock_ObtainMutex(&bufferp->mx); lock_ObtainWrite(&scp->rw); if (code) goto done; @@ -258,14 +223,14 @@ long WriteData(cm_scache_t *scp, osi_hyper_t offset, long count, char *op, /* now get the data in the cache */ while (1) { - code = cm_SyncOp(scp, bufferp, userp, &req, 0, + code = cm_SyncOp(scp, bufp, userp, reqp, 0, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_WRITE | CM_SCACHESYNC_BUFLOCKED); if (code) goto done; - cm_SyncOpDone(scp, bufferp, + cm_SyncOpDone(scp, bufp, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_WRITE | CM_SCACHESYNC_BUFLOCKED); @@ -283,33 +248,32 @@ long WriteData(cm_scache_t *scp, osi_hyper_t offset, long count, char *op, * the latter has already been updated by this * call. */ - if (LargeIntegerGreaterThanOrEqualTo(bufferp->offset, minLength) || - LargeIntegerEqualTo(offset, bufferp->offset) && - (count >= buf_bufferSize || - LargeIntegerGreaterThanOrEqualTo(LargeIntegerAdd(offset, ConvertLongToLargeInteger(count)), minLength))) { - if (count < buf_bufferSize - && bufferp->dataVersion == CM_BUF_VERSION_BAD) - memset(bufferp->datap, 0, - buf_bufferSize); - bufferp->dataVersion = scp->dataVersion; + if (LargeIntegerGreaterThanOrEqualTo(bufp->offset, minLength) || + LargeIntegerEqualTo(*offsetp, bufp->offset) && + (length >= cm_data.blockSize || + LargeIntegerGreaterThanOrEqualTo(LargeIntegerAdd(*offsetp, ConvertLongToLargeInteger(length)), minLength))) { + if (length < cm_data.blockSize + && bufp->dataVersion == CM_BUF_VERSION_BAD) + memset(bufp->datap, 0, + cm_data.blockSize); + bufp->dataVersion = scp->dataVersion; } - if (cm_HaveBuffer(scp, bufferp, 1)) break; + if (cm_HaveBuffer(scp, bufp, 1)) break; /* otherwise, load the buffer and try again */ - lock_ReleaseMutex(&bufferp->mx); - code = cm_GetBuffer(scp, bufferp, NULL, userp, - &req); + lock_ReleaseMutex(&bufp->mx); + code = cm_GetBuffer(scp, bufp, NULL, userp, reqp); lock_ReleaseWrite(&scp->rw); - lock_ObtainMutex(&bufferp->mx); + lock_ObtainMutex(&bufp->mx); lock_ObtainWrite(&scp->rw); if (code) break; } if (code) { - lock_ReleaseMutex(&bufferp->mx); - buf_Release(bufferp); - bufferp = NULL; + lock_ReleaseMutex(&bufp->mx); + buf_Release(bufp); + bufp = NULL; goto done; } } /* if (wrong buffer) ... */ @@ -317,40 +281,40 @@ long WriteData(cm_scache_t *scp, osi_hyper_t offset, long count, char *op, /* now we have the right buffer loaded. Copy out the * data from here to the user's buffer. */ - bufIndex = offset.LowPart & (buf_bufferSize - 1); + bufIndex = offsetp->LowPart & (cm_data.blockSize - 1); /* and figure out how many bytes we want from this buffer */ - nbytes = buf_bufferSize - bufIndex; /* what remains in buffer */ - if (nbytes > count) - nbytes = count; /* don't go past end of request */ + nbytes = cm_data.blockSize - bufIndex; /* what remains in buffer */ + if (nbytes > length) + nbytes = length; /* don't go past end of request */ /* now copy the data */ - memcpy(bufferp->datap + bufIndex, op, nbytes); - buf_SetDirty(bufferp, &req, bufIndex, nbytes, userp); + memcpy(bufp->datap + bufIndex, bufferp, nbytes); + buf_SetDirty(bufp, reqp, bufIndex, nbytes, userp); - /* adjust counters, pointers, etc. */ - op += nbytes; - count -= nbytes; + /* adjust lengthers, pointers, etc. */ + bufferp += nbytes; + length -= nbytes; written += nbytes; thyper.LowPart = nbytes; thyper.HighPart = 0; - offset = LargeIntegerAdd(thyper, offset); + *offsetp = LargeIntegerAdd(thyper, *offsetp); } /* while 1 */ done: - lock_ReleaseWrite(&scp->rw); - if (bufferp) { - lock_ReleaseMutex(&bufferp->mx); - buf_Release(bufferp); + if (writtenp) + *writtenp = written; + + if (bufp) { + lock_ReleaseMutex(&bufp->mx); + buf_Release(bufp); } if (code == 0 && doWriteBack) { - lock_ObtainWrite(&scp->rw); - code = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_ASYNCSTORE); - lock_ReleaseWrite(&scp->rw); + code = cm_SyncOp(scp, NULL, userp, reqp, 0, CM_SCACHESYNC_ASYNCSTORE); if (code == 0) cm_QueueBKGRequest(scp, cm_BkgStore, writeBackOffset.LowPart, - writeBackOffset.HighPart, cm_chunkSize, 0, userp, &req); + writeBackOffset.HighPart, writeBackLength, 0, userp, reqp); } /* cm_SyncOpDone is called when cm_BkgStore completes */ diff --git a/src/WINNT/afsd/rawops.h b/src/WINNT/afsd/rawops.h new file mode 100644 index 0000000..da44b8a --- /dev/null +++ b/src/WINNT/afsd/rawops.h @@ -0,0 +1,19 @@ +/* + * 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 + */ + +extern afs_int32 +raw_ReadData( cm_scache_t *scp, osi_hyper_t *offsetp, + afs_uint32 length, char *bufferp, afs_uint32 *readp, + cm_user_t *userp, cm_req_t *reqp); + + +extern afs_uint32 +raw_WriteData( cm_scache_t *scp, osi_hyper_t *offsetp, afs_uint32 length, + char *bufferp, cm_user_t *userp, cm_req_t *reqp, + afs_uint32 *writtenp);