Commit 65d77f70 authored by Stewart Brodie's avatar Stewart Brodie
Browse files

Free space now 64-bit aware plus *-command implemented.

  Anti-idleout measures implemented.
  Boot behaviour sanitised.
Detail:
  Free space code now knows about 64-bit versions of the various
    calls that can be made to it (OS_FSControl and Free module's i/f)
  *Free implemented.
  CallEvery set up to periodically ping each share to stop buggy
    Microsoft servers going to sleep on it.
  The filesystem does not get deregistered from FileSwitch whenever
    any interface on the machine changes(!)   More subtle changes
    are still required to finalise things in this area though.
Admin:
  Requires TCPIPLibs 5.06 or later
    (CVS: RiscOS/Sources/Libs/TCPIPLibs  tag: TCPIPLibs-5_06)
  Tested by booting an STB22 against an NT4SP4 machine.

Version 1.87, 1.1.1.1.2.12. Tagged as 'LanManFS-1_87-1_1_1_1_2_12'
parent 38063824
...@@ -4,11 +4,11 @@ ...@@ -4,11 +4,11 @@
* *
*/ */
#define Module_MajorVersion_CMHG 1.87 #define Module_MajorVersion_CMHG 1.87
#define Module_MinorVersion_CMHG 1.1.1.1.2.11 #define Module_MinorVersion_CMHG 1.1.1.1.2.12
#define Module_Date_CMHG 10 Feb 1999 #define Module_Date_CMHG 12 Feb 1999
#define Module_MajorVersion "1.87" #define Module_MajorVersion "1.87"
#define Module_Version 187 #define Module_Version 187
#define Module_MinorVersion "1.1.1.1.2.11" #define Module_MinorVersion "1.1.1.1.2.12"
#define Module_Date "10 Feb 1999" #define Module_Date "12 Feb 1999"
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> #include <ctype.h>
#include <locale.h>
#include <string.h> #include <string.h>
#include "kernel.h" #include "kernel.h"
...@@ -73,6 +74,9 @@ enum { ...@@ -73,6 +74,9 @@ enum {
LMInitState_Boot LMInitState_Boot
}; };
static void startcallbacks(void);
static void stopcallbacks(void);
static _kernel_oserror *LM_init_phase_2(void); static _kernel_oserror *LM_init_phase_2(void);
/* ---------------------------------- */ /* ---------------------------------- */
...@@ -178,13 +182,10 @@ static void LM_Undeclare ( void ) ...@@ -178,13 +182,10 @@ static void LM_Undeclare ( void )
/* ------------------ */ /* ------------------ */
_kernel_oserror * LM_Finalise (int fatal, int podule, void *pw) static void LM_GracefulClosedown(void)
{ {
debug0("Finalise\n");
(void) fatal;
(void) podule;
(void) pw;
if (LM_Vars.initialised == LMInitState_FullyInited) { if (LM_Vars.initialised == LMInitState_FullyInited) {
stopcallbacks();
Omni_Shutdown(); Omni_Shutdown();
OmniS_ResourceShutdown(); OmniS_ResourceShutdown();
Prn_Shutdown(); Prn_Shutdown();
...@@ -193,7 +194,16 @@ _kernel_oserror * LM_Finalise (int fatal, int podule, void *pw) ...@@ -193,7 +194,16 @@ _kernel_oserror * LM_Finalise (int fatal, int podule, void *pw)
Buf_Shutdown(); Buf_Shutdown();
LM_Vars.initialised = LMInitState_PreInit; LM_Vars.initialised = LMInitState_PreInit;
} }
}
_kernel_oserror * LM_Finalise (int fatal, int podule, void *pw)
{
debug0("Finalise\n");
(void) fatal;
(void) podule;
(void) pw;
LM_GracefulClosedown();
LM_Undeclare(); LM_Undeclare();
return NULL; return NULL;
} }
...@@ -294,15 +304,67 @@ static _kernel_oserror *Cmd_LANMAN ( const char *args ) ...@@ -294,15 +304,67 @@ static _kernel_oserror *Cmd_LANMAN ( const char *args )
} }
/* --------------------- */ /* --------------------- */
#if 0
static char *(LM_local_num)(char *buf)
{
char *sep, *map, *space = buf;
if (_swix(Territory_ReadSymbols, _INR(0,1)|_OUT(0), -1, 1, &sep)) return buf;
if (_swix(Territory_ReadSymbols, _INR(0,1)|_OUT(0), -1, 2, &map)) return buf;
while (space && *sep) {
space = strchr(space, ' ');
if (space) *space = *sep;
}
return buf;
}
#endif
static _kernel_oserror *Cmd_FREE ( const char *args ) static _kernel_oserror *Cmd_FREE ( const char *args )
{ {
(void) args; _kernel_swi_regs r;
printf("Not immplemented yet\n"); _kernel_oserror *e;
int values[6];
char *argv[1];
if (GetArgs(args, argv, sizeof(argv)/sizeof(*argv)) == 0)
argv[0] = getenv("FileSwitch$" FilingSystemName "$CSD");
if (argv[0] == NULL)
return Xlt_Error( EBADDRV );
r.r[0] = 4; /* 64-bit free space - will not fail! */
r.r[1] = Our_FS_Number;
r.r[2] = (int) values;
r.r[3] = (int) argv[0];
e = Omni_FreeOp_SWI(&r);
if (e == NULL) {
if (values[3] == 0 && values[5] == 0) {
printf("Bytes free &%08x\n", values[2] );
if (values[4] != -1) {
printf("Bytes used &%08x\n", values[4] );
}
else {
printf("Bytes used unavailable\n");
}
}
else {
printf("Bytes free &%08x%08x\n", values[3], values[2] );
if (values[4] != -1) {
printf("Bytes used &%08x%08x\n", values[5], values[4] );
}
else {
printf("Bytes used unavailable\n");
}
}
}
#ifdef TRACE #ifdef TRACE
module_printf(NULL); module_printf(NULL);
#endif #endif
return NULL; return e;
} }
/* --------------------- */ /* --------------------- */
...@@ -915,7 +977,9 @@ void LM_Boot(void) ...@@ -915,7 +977,9 @@ void LM_Boot(void)
if ( strlen(fs_name) == 0 ) if ( strlen(fs_name) == 0 )
{ {
printf("Auto-boot: server name has not been set...\n"); if (LM_Vars.verbose) {
printf("Auto-boot: server name has not been set...\n");
}
return; return;
} }
...@@ -942,6 +1006,7 @@ void LM_Boot(void) ...@@ -942,6 +1006,7 @@ void LM_Boot(void)
} }
} }
/* ------------------------------- */ /* ------------------------------- */
...@@ -1052,7 +1117,7 @@ static _kernel_oserror *LM_init_phase_2(void) ...@@ -1052,7 +1117,7 @@ static _kernel_oserror *LM_init_phase_2(void)
} }
#endif #endif
/*atexit(LM_Finalise); Somebody appears to have a lack of confidence in CMHG..? */ startcallbacks();
/* We have now managed to fully initialise everything that we need - whee! */ /* We have now managed to fully initialise everything that we need - whee! */
LM_Vars.initialised = LMInitState_FullyInited; LM_Vars.initialised = LMInitState_FullyInited;
...@@ -1134,18 +1199,52 @@ static void LM_check_driver_status(_kernel_swi_regs *r) ...@@ -1134,18 +1199,52 @@ static void LM_check_driver_status(_kernel_swi_regs *r)
debug0("Ding! This was our interface\n"); debug0("Ding! This was our interface\n");
if (r->r[2] == 0) { if (r->r[2] == 0) {
if (LM_Vars.initialised == LMInitState_FullyInited) { if (LM_Vars.initialised == LMInitState_FullyInited) {
LM_Finalise(0,0,0); LM_GracefulClosedown();
LM_Declare();
} }
LM_init_phase_2(); LM_init_phase_2();
} }
else if (r->r[2] == 1) { else if (r->r[2] == 1) {
LM_Finalise(0,0,0); LM_GracefulClosedown();
LM_Declare();
} }
} }
} }
#ifdef TRACE
static void DumpBuffer(void *ptr, int len)
{
static char db[512];
char *p = db;
const char *membuf = ptr;
int i,j;
db[0] = '\0';
for (i=0; i<((len+31)&~31); ++i) {
if (!(i & 31)) {
p += sprintf (p, " ");
if (i) for (j = i - 32; j != i; ++j) {
p+=sprintf(p, "%c", (membuf[j]>=32 && membuf[j] != 0x7f) ?
membuf[j] : '.');
}
printf("$%s\n", db);
p=db+sprintf(db,"%04x: ", i);
}
if (i>=len) {
p+=sprintf (p," ");
if (3==(i & 3)) p+=sprintf (p," ");
}
else {
p+=sprintf (p,"%02x", membuf[i]);
if (3==(i & 3)) p+=sprintf (p," ");
}
}
if (i) for ( p+=sprintf (p," "), j = i - 32; j != i; ++j) p+=sprintf (p,"%c",
j>=len ? ' ' : (membuf[j]>=32 && membuf[j] != 0x7f) ?
membuf[j] : '.');
printf("$%s\n", db);
}
#endif
/* SNB 981029 added this function to verify the contents of the Service_InternetStatus /* SNB 981029 added this function to verify the contents of the Service_InternetStatus
* service call to determine whether we were waiting for the interface to go up so * service call to determine whether we were waiting for the interface to go up so
* that we could boot * that we could boot
...@@ -1154,22 +1253,36 @@ static void LM_check_internet_status(_kernel_swi_regs *r) ...@@ -1154,22 +1253,36 @@ static void LM_check_internet_status(_kernel_swi_regs *r)
{ {
char *cp = (char *) r->r[3]; char *cp = (char *) r->r[3];
printf ("InternetStatus: %d %d %d %p %s\n", r->r[0], r->r[1], r->r[2], cp, cp);
if (r->r[0] == InternetStatus_AddressChanged) { if (r->r[0] == InternetStatus_AddressChanged) {
goto testjump; if (LM_Vars.initialised != LMInitState_PreInit &&
LM_Vars.initialised != LMInitState_Boot) {
return;
}
/* An interface address was set - almost certainly ours! */
}
#ifdef TRACE
else if (r->r[0] == InternetStatus_DynamicBootReply) {
DumpBuffer((void *)r->r[4], r->r[5]);
} }
else if (r->r[0] == InternetStatus_DynamicBootStart) {
DumpBuffer((void *)r->r[4], r->r[5]);
}
#endif
else {
/* Were we actually waiting for the driver to appear */
if (LM_Vars.initialised != LMInitState_PreInit &&
LM_Vars.initialised != LMInitState_Boot) return;
/* Was it the right reason code? */
if (r->r[0] != InternetStatus_InterfaceUpDown) return;
/* Was it the right interface? */
if (stricmp(LM_Vars.drivername, cp) != 0) return;
/* was the interface coming up? */
if (r->r[2] != 1) return;
}
/* Was it the right reason code? */
if (r->r[0] != InternetStatus_InterfaceUpDown) return;
/* Was it the right interface? */
if (stricmp(LM_Vars.drivername, cp) != 0) return;
/* was the interface coming up? */
if (r->r[2] != 1) return;
testjump:
if (LM_Vars.initialised == LMInitState_FullyInited) { if (LM_Vars.initialised == LMInitState_FullyInited) {
LM_Finalise(0,0,0); /* Should never happen nowadays ?? */
LM_Declare(); LM_GracefulClosedown();
} }
LM_init_phase_2(); LM_init_phase_2();
} }
...@@ -1226,17 +1339,71 @@ int module_printf(const char *str, ...) ...@@ -1226,17 +1339,71 @@ int module_printf(const char *str, ...)
} }
++callcount; ++callcount;
if (f != NULL) { if (*str != '$' && f != NULL) {
fprintf(f, "(%4d) ", callcount);
va_start(ap, str); va_start(ap, str);
vfprintf(f, str, ap); vfprintf(f, str, ap);
va_end(ap); va_end(ap);
} }
va_start(ap, str); va_start(ap, str);
_swix(OS_ReadMonotonicTime, _OUT(0), inblock); _swix(OS_ReadMonotonicTime, _OUT(0), inblock);
if (*str == '$') ++str; else
pbufferptr += sprintf(pbuffer + pbufferptr, "(%8d) (%4d) ", inblock[0], callcount); pbufferptr += sprintf(pbuffer + pbufferptr, "(%8d) (%4d) ", inblock[0], callcount);
pbufferptr += vsprintf(pbuffer + pbufferptr, str, ap); pbufferptr += vsprintf(pbuffer + pbufferptr, str, ap);
if (pbufferptr > 60000) pbufferptr = 0; if (pbufferptr > 60000) pbufferptr = 0;
return 0; return 0;
} }
#endif #endif
/* ========== Callback code ========== */
/* Callback management. Some servers tend to idle-out connections. This code stops
* that happening.
*/
static volatile int callbackflag = 0;
_kernel_oserror *callback_handler(_kernel_swi_regs *r, void *pw)
{
(void) r;
(void) pw;
if (callbackflag != 0) {
debug0("Anti IdleOut Callback entered\n");
SMB_AntiIdle();
callbackflag = 0;
}
return 0;
}
static void clearcallback(void)
{
if (callbackflag != 0) {
(void) _swix(OS_RemoveCallBack, _INR(0,1), callback_entry, LM_pw);
callbackflag = 0;
}
}
_kernel_oserror *callevery_handler(_kernel_swi_regs *r, void *pw)
{
(void) r;
if (callbackflag == 0) {
if (_swix(OS_AddCallBack, _INR(0,1), callback_entry, pw) == NULL) {
callbackflag = 1;
debug0(Module_Title ": (setcallback) just set a callback\n");
}
}
return 0;
}
static void startcallbacks(void)
{
/* Remember that as the SMB_AntiIdle routine rotates through all the shares,
* each share will only be every pinged MAX_SHARES * 100 * 45 seconds.
*/
(void) _swix(OS_CallEvery, _INR(0,2), 100*45, callevery_entry, LM_pw);
}
static void stopcallbacks(void)
{
(void) _swix(OS_RemoveTickerEvent, _INR(0,1), callevery_entry, LM_pw);
clearcallback();
}
...@@ -548,18 +548,25 @@ static uint size_clip ( uint val, uint limit, uint blksize ) ...@@ -548,18 +548,25 @@ static uint size_clip ( uint val, uint limit, uint blksize )
/* ------------------ */ /* ------------------ */
static err_t Omni_DetermineFreeSpace ( int mount_id,
struct disk_size_response *DSR)
{
NAMELIST *pNL = Validate(mount_id, M_VALID_TAG);
if ( pNL == NULL )
return EBADPARAM;
return SMB_GetFreeSpace ( pNL->u.mount.smb_lettr, DSR );
}
static err_t Omni_FreeSpace ( int mount_id, static err_t Omni_FreeSpace ( int mount_id,
int *freespace_out, int *usedspace_out, int *totspace_out ) int *freespace_out, int *usedspace_out, int *totspace_out )
{ {
struct disk_size_response DSR; struct disk_size_response DSR;
uint blklimit; uint blklimit;
err_t res; err_t res;
NAMELIST *pNL = Validate(mount_id, M_VALID_TAG);
if ( pNL == NULL )
return EBADPARAM;
res = SMB_GetFreeSpace ( pNL->u.mount.smb_lettr, &DSR ); res = Omni_DetermineFreeSpace ( mount_id, &DSR );
if ( res != OK ) if ( res != OK )
return res; return res;
...@@ -576,6 +583,84 @@ static err_t Omni_FreeSpace ( int mount_id, ...@@ -576,6 +583,84 @@ static err_t Omni_FreeSpace ( int mount_id,
return OK; return OK;
} }
typedef struct fspc_64 {
unsigned lo, hi;
} fspc_64;
/* Multiply macro taken from NSPRLib */
#define LL_MUL(r, a, b) { \
fspc_64 _a, _b; \
_a = a; _b = b; \
LL_MUL32(r, _a.lo, _b.lo); \
(r).hi += _a.hi * _b.lo + _a.lo * _b.hi; \
}
#define PR_BIT(n) ((unsigned)1 << (n))
#define PR_BITMASK(n) (PR_BIT(n) - 1)
#define _lo16(a) ((a) & PR_BITMASK(16))
#define _hi16(a) ((a) >> 16)
#define LL_MUL32(r, a, b) { \
unsigned _a1, _a0, _b1, _b0, _y0, _y1, _y2, _y3; \
_a1 = _hi16(a), _a0 = _lo16(a); \
_b1 = _hi16(b), _b0 = _lo16(b); \
_y0 = _a0 * _b0; \
_y1 = _a0 * _b1; \
_y2 = _a1 * _b0; \
_y3 = _a1 * _b1; \
_y1 += _hi16(_y0); /* can't carry */ \
_y1 += _y2; /* might carry */ \
if (_y1 < _y2) \
_y3 += (unsigned)(PR_BIT(16)); /* propagate */ \
(r).lo = (_lo16(_y1) << 16) + _lo16(_y0); \
(r).hi = _y3 + _hi16(_y1); \
}
#ifdef __CC_NORCROFT
/* No way of checking version number though.
* Version 5.11 of the compiler should be OK because I fixed this bug
* in that version [sbrodie]
*/
static void _Omni_ForceCSESync(void) {}
#else
# define _Omni_ForceCSESync() ((void)0)
#endif
#ifdef __CC_NORCROFT
/* May as well optimise this a bit */
__value_in_regs
#endif
static fspc_64 Omni_Multiply64(uint plo1, uint plo2)
{
fspc_64 p1, p2, res;
p1.hi = p2.hi = 0;
p1.lo = plo1;
p2.lo = plo2;
_Omni_ForceCSESync();
LL_MUL(res, p1, p2);
_Omni_ForceCSESync();
return res;
}
static err_t Omni_FreeSpace64 ( int mount_id, int *success,
fspc_64 *freespace_out, fspc_64 *usedspace_out, fspc_64 *totspace_out )
{
struct disk_size_response DSR;
err_t res;
res = Omni_DetermineFreeSpace ( mount_id, &DSR );
if ( res != OK )
return res;
*freespace_out = Omni_Multiply64(DSR.freeblks, DSR.blksize);
*totspace_out = Omni_Multiply64(DSR.totalblks, DSR.blksize);
*usedspace_out = Omni_Multiply64(DSR.totalblks - DSR.freeblks, DSR.blksize);
*success = 0;
return OK;
}
/* Subroutines to help enumeration routines ----------------------- */ /* Subroutines to help enumeration routines ----------------------- */
...@@ -1269,6 +1354,23 @@ _kernel_oserror *Omni_FreeOp_SWI (_kernel_swi_regs *R ) ...@@ -1269,6 +1354,23 @@ _kernel_oserror *Omni_FreeOp_SWI (_kernel_swi_regs *R )
return NULL; return NULL;
} }
case 4: /* Get free space on device (64 bit) */
/* R->r[3] on entry points to a device name.
Methinks this is the same as returned from
case 1 */
/* This code can be entered directly by Cmd_FREE */
{
int m_id = Omni_GetMountID ( ExtractName( (char *)(R->r[3]) ));
if ( m_id == 0 )
return Xlt_Error(EBADDRV);
return Xlt_Error ( Omni_FreeSpace64 ( m_id,
(int *)&(R->r[0]), /* zero it on success */
(fspc_64 *)(R->r[2]+8) /* freespace_out */,
(fspc_64 *)(R->r[2]+16) /* usedspace_out */,
(fspc_64 *)(R->r[2]) /* totspace_out */ ) );
}
default: default:
break; break;
} }
......
...@@ -229,6 +229,7 @@ typedef struct ...@@ -229,6 +229,7 @@ typedef struct
/* And now the sub-commands for SMBtrans2 */ /* And now the sub-commands for SMBtrans2 */
#define TRANSACT2_FINDFIRST 0x01 #define TRANSACT2_FINDFIRST 0x01
#define TRANSACT2_FINDNEXT 0x02 #define TRANSACT2_FINDNEXT 0x02
#define TRANSACT2_QUERYFSINFORMATION 0x03
#define TRANSACT2_QUERYPATHINFORMATION 0x05 #define TRANSACT2_QUERYPATHINFORMATION 0x05
#endif #endif
...@@ -688,8 +689,7 @@ static err_t Do_SMBResponse(hSHARE hS, int cmd, BUFCHAIN *ppB_out ) ...@@ -688,8 +689,7 @@ static err_t Do_SMBResponse(hSHARE hS, int cmd, BUFCHAIN *ppB_out )
return OK; return OK;
} }
static err_t Do_SMB_threadsafe ( hSHARE hS, int cmd, int wct_in, BUFCHAIN pB_in,
static err_t Do_SMB ( hSHARE hS, int cmd, int wct_in, BUFCHAIN pB_in,
BUFCHAIN *ppB_out ) BUFCHAIN *ppB_out )
{ {
#ifdef RETRYONERROR #ifdef RETRYONERROR
...@@ -783,6 +783,23 @@ do_smb_retry: ...@@ -783,6 +783,23 @@ do_smb_retry:
return Do_SMBResponse(hS, cmd, ppB_out); return Do_SMBResponse(hS, cmd, ppB_out);
} }
static err_t Do_SMB ( hSHARE hS, int cmd, int wct_in, BUFCHAIN pB_in,
BUFCHAIN *ppB_out )
{
static volatile int threaded = 0;
if (threaded) {
return EBOOTREENTRY;
}
else {
err_t res;
++threaded;
res = Do_SMB_threadsafe(hS, cmd, wct_in, pB_in, ppB_out);
--threaded;
return res;
}
}
/* ---------------------------- */ /* ---------------------------- */
...@@ -1433,22 +1450,6 @@ static hSHARE GetShare ( const char *filename, err_t *pRes ) ...@@ -1433,22 +1450,6 @@ static hSHARE GetShare ( const char *filename, err_t *pRes )
} }