Commit b815f1e5 authored by Steve French's avatar Steve French

[CIFS] Allow for 15 minute TZs (e.g. Nepal) and be more explicit about

not setting time on close
Signed-off-by: default avatarGuenter Kukkukk <linux@kukkukk.com>
Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
parent 203cf2fc
...@@ -409,6 +409,8 @@ typedef struct negotiate_req { ...@@ -409,6 +409,8 @@ typedef struct negotiate_req {
/* Dialect index is 13 for LANMAN */ /* Dialect index is 13 for LANMAN */
#define MIN_TZ_ADJ (15 * 60) /* minimum grid for timezones in seconds */
typedef struct lanman_neg_rsp { typedef struct lanman_neg_rsp {
struct smb_hdr hdr; /* wct = 13 */ struct smb_hdr hdr; /* wct = 13 */
__le16 DialectIndex; __le16 DialectIndex;
...@@ -678,7 +680,7 @@ typedef union smb_com_tree_disconnect { /* as an altetnative can use flag on ...@@ -678,7 +680,7 @@ typedef union smb_com_tree_disconnect { /* as an altetnative can use flag on
typedef struct smb_com_close_req { typedef struct smb_com_close_req {
struct smb_hdr hdr; /* wct = 3 */ struct smb_hdr hdr; /* wct = 3 */
__u16 FileID; __u16 FileID;
__u32 LastWriteTime; /* should be zero */ __u32 LastWriteTime; /* should be zero or -1 */
__u16 ByteCount; /* 0 */ __u16 ByteCount; /* 0 */
} __attribute__((packed)) CLOSE_REQ; } __attribute__((packed)) CLOSE_REQ;
......
...@@ -450,7 +450,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) ...@@ -450,7 +450,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
} else if((pSMBr->hdr.WordCount == 13) } else if((pSMBr->hdr.WordCount == 13)
&& ((pSMBr->DialectIndex == LANMAN_PROT) && ((pSMBr->DialectIndex == LANMAN_PROT)
|| (pSMBr->DialectIndex == LANMAN2_PROT))) { || (pSMBr->DialectIndex == LANMAN2_PROT))) {
int tmp, adjust; __s16 tmp;
struct lanman_neg_rsp * rsp = (struct lanman_neg_rsp *)pSMBr; struct lanman_neg_rsp * rsp = (struct lanman_neg_rsp *)pSMBr;
if((secFlags & CIFSSEC_MAY_LANMAN) || if((secFlags & CIFSSEC_MAY_LANMAN) ||
...@@ -476,14 +476,16 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) ...@@ -476,14 +476,16 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
server->maxRw = 0;/* we do not need to use raw anyway */ server->maxRw = 0;/* we do not need to use raw anyway */
server->capabilities = CAP_MPX_MODE; server->capabilities = CAP_MPX_MODE;
} }
tmp = le16_to_cpu(rsp->ServerTimeZone); tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone);
if (tmp == (int)0xffff) { if (tmp == 0xffff) {
/* OS/2 often does not set timezone therefore /* OS/2 often does not set timezone therefore
* we must use server time to calc time zone. * we must use server time to calc time zone.
* Could deviate slightly from the right zone. Not easy * Could deviate slightly from the right zone.
* to adjust, since timezones are not always a multiple * Smallest defined timezone difference is 15 minutes
* of 60 (sometimes 30 minutes - are there smaller?) * (i.e. Nepal). Rounding up/down is done to match
* this requirement.
*/ */
int val, seconds, remain, result;
struct timespec ts, utc; struct timespec ts, utc;
utc = CURRENT_TIME; utc = CURRENT_TIME;
ts = cnvrtDosUnixTm(le16_to_cpu(rsp->SrvTime.Date), ts = cnvrtDosUnixTm(le16_to_cpu(rsp->SrvTime.Date),
...@@ -491,12 +493,18 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) ...@@ -491,12 +493,18 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
cFYI(1,("SrvTime: %d sec since 1970 (utc: %d) diff: %d", cFYI(1,("SrvTime: %d sec since 1970 (utc: %d) diff: %d",
(int)ts.tv_sec, (int)utc.tv_sec, (int)ts.tv_sec, (int)utc.tv_sec,
(int)(utc.tv_sec - ts.tv_sec))); (int)(utc.tv_sec - ts.tv_sec)));
tmp = (int)(utc.tv_sec - ts.tv_sec); val = (int)(utc.tv_sec - ts.tv_sec);
adjust = tmp < 0 ? -29 : 29; seconds = val < 0 ? -val : val;
tmp = ((tmp + adjust) / 60) * 60; result = (seconds / IN_TZ_ADJ) * MIN_TZ_ADJ;
server->timeAdj = tmp; remain = seconds % MIN_TZ_ADJ;
if(remain >= (MIN_TZ_ADJ / 2))
result += MIN_TZ_ADJ;
if(val < 0)
result = - result;
server->timeAdj = result;
} else { } else {
server->timeAdj = tmp * 60; /* also in seconds */ server->timeAdj = (int)tmp;
server->timeAdj *= 60; /* also in seconds */
} }
cFYI(1,("server->timeAdj: %d seconds", server->timeAdj)); cFYI(1,("server->timeAdj: %d seconds", server->timeAdj));
...@@ -559,7 +567,8 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) ...@@ -559,7 +567,8 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
cFYI(0, ("Max buf = %d", ses->server->maxBuf)); cFYI(0, ("Max buf = %d", ses->server->maxBuf));
GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey); GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey);
server->capabilities = le32_to_cpu(pSMBr->Capabilities); server->capabilities = le32_to_cpu(pSMBr->Capabilities);
server->timeAdj = le16_to_cpu(pSMBr->ServerTimeZone) * 60; server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
server->timeAdj *= 60;
if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
memcpy(server->cryptKey, pSMBr->u.EncryptionKey, memcpy(server->cryptKey, pSMBr->u.EncryptionKey,
CIFS_CRYPTO_KEY_SIZE); CIFS_CRYPTO_KEY_SIZE);
...@@ -1645,7 +1654,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id) ...@@ -1645,7 +1654,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */ pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */
pSMB->FileID = (__u16) smb_file_id; pSMB->FileID = (__u16) smb_file_id;
pSMB->LastWriteTime = 0; pSMB->LastWriteTime = 0xFFFFFFFF;
pSMB->ByteCount = 0; pSMB->ByteCount = 0;
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
......
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