Commit 18a0315a authored by Robert Sprowson's avatar Robert Sprowson
Browse files

Fix and speed up EXT#handle=number doing nothing when number is beyond 2GB

Internally LanManFS was representing file offsets and data lengths as signed numbers, while in general this doesn't matter (they are passed through opaquely as just numbers and not manipulated) in a couple of places they were being used as while () loop exit conditions.
Function WriteZeroes (used when extending a file via OS_Args) therefore never performed the call to SMB_Write when beyond 2G because the loop condition was never met.
Additionally, it was literally transferring buffers of zeros across the network which is unnecessary as the server is documented as doing a zero fill itself, this represents at least a x40 speed up (on a slow 1MB/s drive write speed at the server end) or more.
Changed offset & lengths from int to uint.
Added the earlier CIFS spec (the later copy is missing section 5 for some reason) to docs.

Version 2.38. Tagged as 'LanManFS-2_38'
parent db8c11e7
/* (2.37)
/* (2.38)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 2.37
#define Module_MajorVersion_CMHG 2.38
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 21 Sep 2012
#define Module_Date_CMHG 11 Nov 2012
#define Module_MajorVersion "2.37"
#define Module_Version 237
#define Module_MajorVersion "2.38"
#define Module_Version 238
#define Module_MinorVersion ""
#define Module_Date "21 Sep 2012"
#define Module_Date "11 Nov 2012"
#define Module_ApplicationDate "21-Sep-12"
#define Module_ApplicationDate "11-Nov-12"
#define Module_ComponentName "LanManFS"
#define Module_ComponentPath "castle/RiscOS/Sources/Networking/Omni/Protocols/LanManFS"
#define Module_FullVersion "2.37"
#define Module_HelpVersion "2.37 (21 Sep 2012)"
#define Module_LibraryVersionInfo "2:37"
#define Module_FullVersion "2.38"
#define Module_HelpVersion "2.38 (11 Nov 2012)"
#define Module_LibraryVersionInfo "2:38"
......@@ -225,7 +225,8 @@ static int GetEntryPos ( char *name )
static int SearchFileForEntry ( int FH, char *name )
{
int len, pos;
uint len;
int pos;
AttrCacheStart = 0;
AttrAllInCache = false;
......@@ -267,21 +268,20 @@ static bool CacheEmpty (void)
/* --------------------------- */
static void FileDataMove( int FH, int from, int to )
static void FileDataMove( int FH, uint from, uint to )
{
/* ONLY WORKS IF FROM > TO */
int req_len;
int len;
uint req_len, len;
req_len = (from-to);
if ( req_len <= 0 ) return;
if (from <= to) return;
req_len = from - to;
do
{
len = 0;
SMB_Read ( FH, from, req_len, (BYTE *)AttrCache, &len );
if ( len > 0 )
if ( len != 0 )
SMB_Write ( FH, to, len, (BYTE *)AttrCache, NULL );
from += len;
......@@ -622,7 +622,8 @@ write_new:
void Attr_CheckEmptyDir (char *dirname)
{
int i, FH, pos, len;
int i, FH;
uint pos, len;
DOS_ATTRIBS da, da2;
AttrAllInCache = false;
......
......@@ -924,17 +924,34 @@ _kernel_oserror *fsentry_close( int *R )
/* Args ========================================== */
static err_t WriteZeros ( int FH, int offset, int len )
static err_t WriteZeros ( int FH, uint offset, uint len )
{
int tmp;
uint tmp;
err_t res=OK;
memset ( DOSnamebuf, 0, NAMEBUF_LEN );
while ( len > 0 )
{
tmp = (len > NAMEBUF_LEN) ? NAMEBUF_LEN : len;
#if 0
tmp = min(NAMEBUF_LEN, len);
res = SMB_Write ( FH, offset, tmp, (BYTE *)DOSnamebuf, NULL );
#else
/* SMB_Write uses the write bytes command (v1-spec-02 section 5.22)
* which states that any bytes between the previous EOF and the new
* one are filled to zero by the server - so don't waste time
* sending them over the network. However, very large extends can
* end up with a timeout, so the extend is chopped up a bit assuming
* the server can write at least 1MB/s to the disc.
* SMB_Truncate pends all the zero filling which leads to a timeout
* when closing the file, so we just write 1 byte of 0 each jump.
*/
tmp = min(1024 * 1024 * (REPLY_TIMEOUT / 100), len);
if ( offset == 0 )
res = SMB_Write ( FH, 0, 1, (BYTE *)DOSnamebuf, NULL );
else
res = SMB_Write ( FH, offset - 1, 1, (BYTE *)DOSnamebuf, NULL );
#endif
if ( res != OK ) break;
offset += tmp;
len -= tmp;
......@@ -948,7 +965,7 @@ _kernel_oserror *fsentry_args( int *R )
{
err_t err=OK;
int fid = R[1]-1;
int tmp;
uint tmp;
debug1("FS_args(%d)\n", R[0]);
......@@ -986,8 +1003,8 @@ _kernel_oserror *fsentry_args( int *R )
case FSEntry_Args_Reason_WriteZerosToFile:
err = WriteZeros ( FileTbl[fid].SMB_FH,
R[2], /* Offset */
R[3] /* Length */ );
(uint)R[2], /* Offset */
(uint)R[3] /* Length */ );
break;
case FSEntry_Args_Reason_ReadFileDateStamp:
......
......@@ -1835,7 +1835,7 @@ EXPORT err_t _NB_SendData ( hSESSION hS, BUFCHAIN Data )
/* ----------------------- */
EXPORT err_t _NB_SendBlockData ( hSESSION hS, BYTE *where, int datalen )
EXPORT err_t _NB_SendBlockData ( hSESSION hS, BYTE *where, uint datalen )
{
NBIP_SESSION *pNS;
BYTE hdr[4];
......@@ -1950,7 +1950,7 @@ retry:
/* ----------------------- */
EXPORT err_t _NB_GetBlockData ( hSESSION hS, BYTE *where, int *len_in_out,
EXPORT err_t _NB_GetBlockData ( hSESSION hS, BYTE *where, uint *len_in_out,
int timeout )
{
NBIP_SESSION *pNS;
......
......@@ -1027,7 +1027,7 @@ EXPORT err_t _NB_SendData ( hSESSION hSession, BUFCHAIN pB )
/* ----------------------- */
EXPORT err_t _NB_SendBlockData ( hSESSION hSession, BYTE *data, int datalen )
EXPORT err_t _NB_SendBlockData ( hSESSION hSession, BYTE *data, uint datalen )
{
BUFCHAIN pB;
err_t res;
......@@ -1147,7 +1147,7 @@ EXPORT err_t _NB_GetData ( hSESSION hSession, BUFCHAIN *pOutData, int timeout )
to try to optimise this further.
*/
EXPORT err_t _NB_GetBlockData ( hSESSION hSession, BYTE *where, int *len_in_out,
EXPORT err_t _NB_GetBlockData ( hSESSION hSession, BYTE *where, uint *len_in_out,
int timeout )
{
int timer;
......
......@@ -97,23 +97,6 @@
/* Definitions ===================================================== */
/* Timeouts * */
/* Reply timeout, in cs */
#ifdef LONGNAMES
#define REPLY_TIMEOUT 4000
#else
#define REPLY_TIMEOUT 1200
#endif
/* Timeout to put in 'Transact' params, in ms */
#define TRANSACT_TIMEOUT 5000
#ifdef LONGNAMES
#define TRANSACT2_TIMEOUT 10000
#endif
/* Our definitions */
#define MAX_SERVERS (MAX_DRIVES + 4)
......@@ -348,7 +331,7 @@ static int DOS_Errs[] =
18, ENOMOREFILES,
2, EFILENOTFOUND,
12, ENOTPRESENT, /* Returned by OS2-Connect from SetAttrib */
50, ENOTPRESENT, /* Return~ed by W4WG from SetAttrib call */
50, ENOTPRESENT, /* Returned by W4WG from SetAttrib call */
110, EFILENOTFOUND, /* Returned by OS2 servers for hidden files */
3, EPATHNOTFOUND,
1, EBADPARAM,
......@@ -357,7 +340,7 @@ static int DOS_Errs[] =
80, EFILEEXISTS,
32, ESHARING, /* Normal sharing violation */
67, ENOSUCHSHARE, /* Returned by NT3.5 for bad share names */
112, EDISKFULL, /* Returned by NT3.5 when disk full */
112, EDISCFULL, /* Returned by NT3.5 when disk full */
65, ENOACCESS, /* Returned by W4WG on set-attribs on CDROM */
145, EDIRNOTEMPTY, /* Attempt to remove non-empty directory */
-1, EDOSERROR
......@@ -742,8 +725,8 @@ static err_t Do_SMB ( hSHARE hS, int cmd, int wct_in, BUFCHAIN pB_in,
*/
static int SMB_ReadRaw ( hSHARE hS,
int fid, int offset, int len, BYTE *where )
static uint SMB_ReadRaw ( hSHARE hS,
int fid, uint offset, uint len, BYTE *where )
{
err_t res;
BUFCHAIN pB;
......@@ -799,8 +782,8 @@ static int SMB_ReadRaw ( hSHARE hS,
/* ---------------------------- */
static err_t SMB_WriteRaw ( hSHARE hS, int fid, int offset,
int len, BYTE *where )
static err_t SMB_WriteRaw ( hSHARE hS, int fid, uint offset,
uint len, BYTE *where )
{
err_t res;
......@@ -2538,7 +2521,7 @@ err_t SMB_Open ( int mode, char *filename,
/* ---------------- */
err_t SMB_GetLength ( int FH, int *pOutLen )
err_t SMB_GetLength ( int FH, uint *pOutLen )
{
err_t res;
hSHARE hS = GetShareFromFH(FH, &res);
......@@ -2562,10 +2545,11 @@ err_t SMB_GetLength ( int FH, int *pOutLen )
/* ---------------- */
err_t SMB_Read ( int FH, int offset, int len, BYTE *where,
int *pOutLen )
err_t SMB_Read ( int FH, uint offset, uint len, BYTE *where,
uint *pOutLen )
{
int len_left, n_read, fid;
uint len_left, n_read;
int fid;
hSHARE hS;
BUFCHAIN pB_res;
err_t res = OK;
......@@ -2584,7 +2568,7 @@ err_t SMB_Read ( int FH, int offset, int len, BYTE *where,
while ( len_left > FILE_BLOCK_SIZE )
{
n_read = SMB_ReadRaw ( hS, fid, offset, len_left, where );
if ( n_read <= 0 ) /* Didn't work? Find out why */
if ( n_read == 0 ) /* Didn't work? Find out why */
break;
len_left -= n_read;
......@@ -2637,7 +2621,7 @@ err_t SMB_Read ( int FH, int offset, int len, BYTE *where,
/* ---------------- */
err_t SMB_Truncate ( int FH, int length )
err_t SMB_Truncate ( int FH, uint length )
{
BUFCHAIN pB;
err_t res;
......@@ -2663,11 +2647,12 @@ err_t SMB_Truncate ( int FH, int length )
/* ---------------- */
err_t SMB_Write ( int FH, int offset, int len, BYTE *where,
int *pOutLen )
err_t SMB_Write ( int FH, uint offset, uint len, BYTE *where,
uint *pOutLen )
{
BUFCHAIN pB;
int len_left, n_written, fid;
uint len_left, n_written;
int fid;
hSHARE hS;
err_t res=OK;
......
This diff is collapsed.
......@@ -83,10 +83,10 @@ struct NETBIOS_TRANSPORT
err_t (*pfnOpenSession) ( hNAME hLocalName, NETNAME *pnnFarEnd,
hSESSION *phSession );
err_t (*pfnSendData) ( hSESSION hS, BUFCHAIN Data );
err_t (*pfnSendBlockData) ( hSESSION hS, BYTE *where, int datalen );
err_t (*pfnSendBlockData) ( hSESSION hS, BYTE *where, uint datalen );
err_t (*pfnClearRxQueue) ( hSESSION hS );
err_t (*pfnGetData) ( hSESSION hS, BUFCHAIN *pOutData, int timeout );
err_t (*pfnGetBlockData) ( hSESSION hS, BYTE *where, int *len_in_out,
err_t (*pfnGetBlockData) ( hSESSION hS, BYTE *where, uint *len_in_out,
int timeout );
bool (*pfnLinkOK) ( hSESSION hS );
err_t (*pfnCloseSession) ( hSESSION hS );
......
......@@ -100,13 +100,13 @@ extern err_t SMB_Create ( char *filename, DOS_ATTRIBS *pInAttr,
extern err_t SMB_Open ( int mode, char *filename,
DOS_ATTRIBS *pOutAttr, int *pOutFH, int *pOutMode );
extern err_t SMB_GetLength ( int fh, int *pOutLen );
extern err_t SMB_GetLength ( int fh, uint *pOutLen );
extern err_t SMB_Read ( int fh, int offset, int len, BYTE *where,
int *pOutLen ) ;
extern err_t SMB_Write ( int fh, int offset, int len, BYTE *where,
int *pOutLen ) ;
extern err_t SMB_Truncate ( int fh, int length );
extern err_t SMB_Read ( int fh, uint offset, uint len, BYTE *where,
uint *pOutLen ) ;
extern err_t SMB_Write ( int fh, uint offset, uint len, BYTE *where,
uint *pOutLen ) ;
extern err_t SMB_Truncate ( int fh, uint length );
extern err_t SMB_Flush ( int fh ) ;
extern err_t SMB_Close ( int fh, DOS_ATTRIBS *pAttr );
......@@ -208,6 +208,22 @@ extern bool SMB_ConnectedTo ( char *server );
/* Implement idle out protection for broken Microsoft servers */
extern void SMB_AntiIdle ( void );
/* Timeouts * */
/* Reply timeout, in cs */
#ifdef LONGNAMES
#define REPLY_TIMEOUT 4000
#else
#define REPLY_TIMEOUT 1200
#endif
/* Timeout to put in 'Transact' params, in ms */
#define TRANSACT_TIMEOUT 5000
#ifdef LONGNAMES
#define TRANSACT2_TIMEOUT 10000
#endif
/* Startup/shutdown */
......
......@@ -93,7 +93,7 @@ typedef int err_t;
#define EMBUFMODULE 44
#define ERPCERROR 45
#define EDISKFULL 46
#define EDISCFULL 46
#define EDIRNOTEMPTY 47
#define EBADRENAME 48
#define EFILEHANDLE 49
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment