summaryrefslogtreecommitdiffstats
path: root/source3
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2001-06-05 08:17:16 +0000
committerJeremy Allison <jra@samba.org>2001-06-05 08:17:16 +0000
commit5264e9a2a737d6498be0f346bcbc3b583609abf5 (patch)
treee8c083f14d669229b929ae110e819a3a80f3e1d6 /source3
parent091fd5a1746080b8a988f08557ba5f9df97653a4 (diff)
Set correct reply word in large writeX (greater than 64k) replies.
Also added smbtorture test for this. Jeremy. (This used to be commit 6d65556ae8bea45a203defaded8436cbb56965e1)
Diffstat (limited to 'source3')
-rw-r--r--source3/libsmb/clireadwrite.c6
-rw-r--r--source3/smbd/reply.c7
-rw-r--r--source3/utils/torture.c51
3 files changed, 61 insertions, 3 deletions
diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c
index 86a51da835..6c52d2b776 100644
--- a/source3/libsmb/clireadwrite.c
+++ b/source3/libsmb/clireadwrite.c
@@ -138,7 +138,10 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
- set_message(cli->outbuf,12,size,True);
+ if (size > 0xFFFF)
+ set_message(cli->outbuf,14,size,True);
+ else
+ set_message(cli->outbuf,12,size,True);
CVAL(cli->outbuf,smb_com) = SMBwriteX;
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@@ -152,6 +155,7 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1
SSVAL(cli->outbuf,smb_vwv7,mode);
SSVAL(cli->outbuf,smb_vwv8,(mode & 0x0008) ? size : 0);
+ SSVAL(cli->outbuf,smb_vwv9,((size>>16)&1));
SSVAL(cli->outbuf,smb_vwv10,size);
SSVAL(cli->outbuf,smb_vwv11,
smb_buf(cli->outbuf) - smb_base(cli->outbuf));
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 7cb23d8629..d3f2527b35 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -2674,6 +2674,7 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
unsigned int smb_doff = SVAL(inbuf,smb_vwv11);
unsigned int smblen = smb_len(inbuf);
char *data;
+ BOOL large_writeX = ((CVAL(inbuf,smb_wct) == 14) && (smblen > 0xFFFF));
START_PROFILE(SMBwriteX);
/* If it's an IPC, pass off the pipe handler. */
@@ -2687,7 +2688,7 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
CHECK_ERROR(fsp);
/* Deal with possible LARGE_WRITEX */
- if (smblen > 0xFFFF)
+ if (large_writeX)
numtowrite |= ((((size_t)SVAL(inbuf,smb_vwv9)) & 1 )<<16);
if(smb_doff > smblen || (smb_doff + numtowrite > smblen)) {
@@ -2742,7 +2743,9 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
set_message(outbuf,6,0,True);
SSVAL(outbuf,smb_vwv2,nwritten);
-
+ if (large_writeX)
+ SSVAL(outbuf,smb_vwv4,(nwritten>>16)&1);
+
if (nwritten < (ssize_t)numtowrite) {
CVAL(outbuf,smb_rcls) = ERRHRD;
SSVAL(outbuf,smb_err,ERRdiskfull);
diff --git a/source3/utils/torture.c b/source3/utils/torture.c
index 7298cd9b9a..982be77151 100644
--- a/source3/utils/torture.c
+++ b/source3/utils/torture.c
@@ -483,6 +483,54 @@ static void run_readwritemulti(int dummy)
close_connection(&cli);
}
+static void run_readwritelarge(int dummy)
+{
+ static struct cli_state cli1;
+ int fnum1;
+ char *lockfname = "\\large.dat";
+ size_t fsize;
+ char buf[0x10000];
+
+ if (!open_connection(&cli1)) {
+ return;
+ }
+ cli_sockopt(&cli1, sockops);
+ memset(buf,'\0',sizeof(buf));
+
+ cli1.max_xmit = 0x11000;
+
+ printf("starting readwritelarge\n");
+
+ cli_unlink(&cli1, lockfname);
+
+ fnum1 = cli_open(&cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
+ if (fnum1 == -1) {
+ printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(&cli1));
+ return;
+ }
+
+ cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf));
+
+ if (!cli_close(&cli1, fnum1)) {
+ printf("close failed (%s)\n", cli_errstr(&cli1));
+ }
+
+ if (!cli_qpathinfo(&cli1, lockfname, NULL, NULL, NULL, &fsize, NULL)) {
+ printf("qpathinfo failed (%s)\n", cli_errstr(&cli1));
+ }
+
+ if (fsize == sizeof(buf))
+ printf("readwritelarge test succeeded (size = %x)\n", fsize);
+ else
+ printf("readwritelarge test failed (size = %x)\n", fsize);
+
+ if (!cli_unlink(&cli1, lockfname)) {
+ printf("unlink failed (%s)\n", cli_errstr(&cli1));
+ }
+
+ close_connection(&cli1);
+}
+
int line_count = 0;
/* run a test that simulates an approximate netbench client load */
@@ -2722,6 +2770,7 @@ static struct {
{"TCON", run_tcon_test, 0},
{"RW1", run_readwritetest, 0},
{"RW2", run_readwritemulti, FLAG_MULTIPROC},
+ {"RW3", run_readwritelarge, 0},
{"OPEN", run_opentest, 0},
{"DELETE", run_deletetest, 0},
{NULL, NULL, 0}};
@@ -2811,6 +2860,8 @@ static void usage(void)
codepage_initialise(lp_client_code_page());
+ codepage_initialise(lp_client_code_page());
+
lp_load(servicesf,True,False,False);
load_interfaces();