aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/CHANGES13
-rw-r--r--fs/cifs/README38
-rw-r--r--fs/cifs/TODO12
-rw-r--r--fs/cifs/asn1.c57
-rw-r--r--fs/cifs/cifs_debug.c103
-rw-r--r--fs/cifs/cifs_fs_sb.h2
-rw-r--r--fs/cifs/cifs_unicode.c2
-rw-r--r--fs/cifs/cifs_unicode.h39
-rw-r--r--fs/cifs/cifs_uniupr.h8
-rw-r--r--fs/cifs/cifsencrypt.c262
-rw-r--r--fs/cifs/cifsfs.c199
-rw-r--r--fs/cifs/cifsfs.h23
-rw-r--r--fs/cifs/cifsglob.h78
-rw-r--r--fs/cifs/cifspdu.h297
-rw-r--r--fs/cifs/cifsproto.h123
-rw-r--r--fs/cifs/cifssmb.c1621
-rw-r--r--fs/cifs/connect.c1262
-rw-r--r--fs/cifs/dir.c22
-rw-r--r--fs/cifs/export.c49
-rw-r--r--fs/cifs/fcntl.c2
-rw-r--r--fs/cifs/file.c287
-rw-r--r--fs/cifs/inode.c320
-rw-r--r--fs/cifs/ioctl.c4
-rw-r--r--fs/cifs/link.c116
-rw-r--r--fs/cifs/md4.c10
-rw-r--r--fs/cifs/md5.c8
-rw-r--r--fs/cifs/misc.c239
-rw-r--r--fs/cifs/netmisc.c171
-rw-r--r--fs/cifs/nterr.c8
-rw-r--r--fs/cifs/nterr.h8
-rw-r--r--fs/cifs/ntlmssp.h22
-rw-r--r--fs/cifs/readdir.c375
-rw-r--r--fs/cifs/sess.c249
-rw-r--r--fs/cifs/smbdes.c30
-rw-r--r--fs/cifs/smbencrypt.c52
-rw-r--r--fs/cifs/smberr.h8
-rw-r--r--fs/cifs/transport.c248
-rw-r--r--fs/cifs/xattr.c229
38 files changed, 3440 insertions, 3156 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index a9b6bc5157b8..6d84ca2beead 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,3 +1,10 @@
1Version 1.50
2------------
3Fix NTLMv2 signing. NFS server mounted over cifs works (if cifs mount is
4done with "serverino" mount option). Add support for POSIX Unlink
5(helps with certain sharing violation cases when server such as
6Samba supports newer POSIX CIFS Protocol Extensions).
7
1Version 1.49 8Version 1.49
2------------ 9------------
3IPv6 support. Enable ipv6 addresses to be passed on mount (put the ipv6 10IPv6 support. Enable ipv6 addresses to be passed on mount (put the ipv6
@@ -8,7 +15,11 @@ when Unix Extensions were ignored). This allows users to override the
8default uid and gid for files when they are certain that the uids or 15default uid and gid for files when they are certain that the uids or
9gids on the server do not match those of the client. Make "sec=none" 16gids on the server do not match those of the client. Make "sec=none"
10mount override username (so that null user connection is attempted) 17mount override username (so that null user connection is attempted)
11to match what documentation said. 18to match what documentation said. Support for very large reads, over 127K,
19available to some newer servers (such as Samba 3.0.26 and later but
20note that it also requires setting CIFSMaxBufSize at module install
21time to a larger value which may hurt performance in some cases).
22Make sign option force signing (or fail if server does not support it).
12 23
13Version 1.48 24Version 1.48
14------------ 25------------
diff --git a/fs/cifs/README b/fs/cifs/README
index 4d01697722cc..85f1eb14083e 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -301,10 +301,21 @@ A partial list of the supported mount options follows:
301 during the local client kernel build will be used. 301 during the local client kernel build will be used.
302 If server does not support Unicode, this parameter is 302 If server does not support Unicode, this parameter is
303 unused. 303 unused.
304 rsize default read size (usually 16K) 304 rsize default read size (usually 16K). The client currently
305 wsize default write size (usually 16K, 32K is often better over GigE) 305 can not use rsize larger than CIFSMaxBufSize. CIFSMaxBufSize
306 maximum wsize currently allowed by CIFS is 57344 (14 4096 byte 306 defaults to 16K and may be changed (from 8K to the maximum
307 pages) 307 kmalloc size allowed by your kernel) at module install time
308 for cifs.ko. Setting CIFSMaxBufSize to a very large value
309 will cause cifs to use more memory and may reduce performance
310 in some cases. To use rsize greater than 127K (the original
311 cifs protocol maximum) also requires that the server support
312 a new Unix Capability flag (for very large read) which some
313 newer servers (e.g. Samba 3.0.26 or later) do. rsize can be
314 set from a minimum of 2048 to a maximum of 130048 (127K or
315 CIFSMaxBufSize, whichever is smaller)
316 wsize default write size (default 57344)
317 maximum wsize currently allowed by CIFS is 57344 (fourteen
318 4096 byte pages)
308 rw mount the network share read-write (note that the 319 rw mount the network share read-write (note that the
309 server may still consider the share read-only) 320 server may still consider the share read-only)
310 ro mount network share read-only 321 ro mount network share read-only
@@ -359,7 +370,7 @@ A partial list of the supported mount options follows:
359 Note that this does not affect the normal ACL check on the 370 Note that this does not affect the normal ACL check on the
360 target machine done by the server software (of the server 371 target machine done by the server software (of the server
361 ACL against the user name provided at mount time). 372 ACL against the user name provided at mount time).
362 serverino Use servers inode numbers instead of generating automatically 373 serverino Use server's inode numbers instead of generating automatically
363 incrementing inode numbers on the client. Although this will 374 incrementing inode numbers on the client. Although this will
364 make it easier to spot hardlinked files (as they will have 375 make it easier to spot hardlinked files (as they will have
365 the same inode numbers) and inode numbers may be persistent, 376 the same inode numbers) and inode numbers may be persistent,
@@ -367,12 +378,11 @@ A partial list of the supported mount options follows:
367 are unique if multiple server side mounts are exported under a 378 are unique if multiple server side mounts are exported under a
368 single share (since inode numbers on the servers might not 379 single share (since inode numbers on the servers might not
369 be unique if multiple filesystems are mounted under the same 380 be unique if multiple filesystems are mounted under the same
370 shared higher level directory). Note that this requires that 381 shared higher level directory). Note that some older
371 the server support the CIFS Unix Extensions as other servers 382 (e.g. pre-Windows 2000) do not support returning UniqueIDs
372 do not return a unique IndexNumber on SMB FindFirst (most 383 or the CIFS Unix Extensions equivalent and for those
373 servers return zero as the IndexNumber). Parameter has no 384 this mount option will have no effect. Exporting cifs mounts
374 effect to Windows servers and others which do not support the 385 under nfsd requires this mount option on the cifs mount.
375 CIFS Unix Extensions.
376 noserverino Client generates inode numbers (rather than using the actual one 386 noserverino Client generates inode numbers (rather than using the actual one
377 from the server) by default. 387 from the server) by default.
378 setuids If the CIFS Unix extensions are negotiated with the server 388 setuids If the CIFS Unix extensions are negotiated with the server
@@ -582,10 +592,10 @@ the start of smb requests and responses can be enabled via:
582 592
583 echo 1 > /proc/fs/cifs/traceSMB 593 echo 1 > /proc/fs/cifs/traceSMB
584 594
585Two other experimental features are under development and to test 595Two other experimental features are under development. To test these
586require enabling CONFIG_CIFS_EXPERIMENTAL 596requires enabling CONFIG_CIFS_EXPERIMENTAL
587 597
588 More efficient write operations 598 ipv6 enablement
589 599
590 DNOTIFY fcntl: needed for support of directory change 600 DNOTIFY fcntl: needed for support of directory change
591 notification and perhaps later for file leases) 601 notification and perhaps later for file leases)
diff --git a/fs/cifs/TODO b/fs/cifs/TODO
index 78b620e332bd..d7bd51575fd6 100644
--- a/fs/cifs/TODO
+++ b/fs/cifs/TODO
@@ -18,9 +18,9 @@ better)
18 18
19d) Kerberos/SPNEGO session setup support - (started) 19d) Kerberos/SPNEGO session setup support - (started)
20 20
21e) More testing of NTLMv2 authentication (mostly implemented - double check 21e) Cleanup now unneeded SessSetup code in
22that NTLMv2 signing works, also need to cleanup now unneeded SessSetup code in 22fs/cifs/connect.c and add back in NTLMSSP code if any servers
23fs/cifs/connect.c) 23need it
24 24
25f) MD5-HMAC signing SMB PDUs when SPNEGO style SessionSetup 25f) MD5-HMAC signing SMB PDUs when SPNEGO style SessionSetup
26used (Kerberos or NTLMSSP). Signing alreadyimplemented for NTLM 26used (Kerberos or NTLMSSP). Signing alreadyimplemented for NTLM
@@ -106,6 +106,12 @@ but recognizes them
106succeed but still return access denied (appears to be Windows 106succeed but still return access denied (appears to be Windows
107server not cifs client problem) and has not been reproduced recently. 107server not cifs client problem) and has not been reproduced recently.
108NTFS partitions do not have this problem. 108NTFS partitions do not have this problem.
1094) Unix/POSIX capabilities are reset after reconnection, and affect
110a few fields in the tree connection but we do do not know which
111superblocks to apply these changes to. We should probably walk
112the list of superblocks to set these. Also need to check the
113flags on the second mount to the same share, and see if we
114can do the same trick that NFS does to remount duplicate shares.
109 115
110Misc testing to do 116Misc testing to do
111================== 117==================
diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c
index 2e75883b7f54..f50a88d58f78 100644
--- a/fs/cifs/asn1.c
+++ b/fs/cifs/asn1.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * The ASB.1/BER parsing code is derived from ip_nat_snmp_basic.c which was in 2 * The ASB.1/BER parsing code is derived from ip_nat_snmp_basic.c which was in
3 * turn derived from the gxsnmp package by Gregory McLean & Jochen Friedrich 3 * turn derived from the gxsnmp package by Gregory McLean & Jochen Friedrich
4 * 4 *
5 * Copyright (c) 2000 RP Internet (www.rpi.net.au). 5 * Copyright (c) 2000 RP Internet (www.rpi.net.au).
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -80,7 +80,7 @@
80static unsigned long SPNEGO_OID[7] = { 1, 3, 6, 1, 5, 5, 2 }; 80static unsigned long SPNEGO_OID[7] = { 1, 3, 6, 1, 5, 5, 2 };
81static unsigned long NTLMSSP_OID[10] = { 1, 3, 6, 1, 4, 1, 311, 2, 2, 10 }; 81static unsigned long NTLMSSP_OID[10] = { 1, 3, 6, 1, 4, 1, 311, 2, 2, 10 };
82 82
83/* 83/*
84 * ASN.1 context. 84 * ASN.1 context.
85 */ 85 */
86struct asn1_ctx { 86struct asn1_ctx {
@@ -190,7 +190,7 @@ asn1_header_decode(struct asn1_ctx *ctx,
190 unsigned char **eoc, 190 unsigned char **eoc,
191 unsigned int *cls, unsigned int *con, unsigned int *tag) 191 unsigned int *cls, unsigned int *con, unsigned int *tag)
192{ 192{
193 unsigned int def = 0; 193 unsigned int def = 0;
194 unsigned int len = 0; 194 unsigned int len = 0;
195 195
196 if (!asn1_id_decode(ctx, cls, con, tag)) 196 if (!asn1_id_decode(ctx, cls, con, tag))
@@ -331,7 +331,7 @@ static unsigned char asn1_ulong_decode(struct asn1_ctx *ctx,
331 *integer |= ch; 331 *integer |= ch;
332 } 332 }
333 return 1; 333 return 1;
334} 334}
335 335
336static unsigned char 336static unsigned char
337asn1_octets_decode(struct asn1_ctx *ctx, 337asn1_octets_decode(struct asn1_ctx *ctx,
@@ -376,7 +376,7 @@ asn1_subid_decode(struct asn1_ctx *ctx, unsigned long *subid)
376 return 1; 376 return 1;
377} 377}
378 378
379static int 379static int
380asn1_oid_decode(struct asn1_ctx *ctx, 380asn1_oid_decode(struct asn1_ctx *ctx,
381 unsigned char *eoc, unsigned long **oid, unsigned int *len) 381 unsigned char *eoc, unsigned long **oid, unsigned int *len)
382{ 382{
@@ -459,7 +459,7 @@ decode_negTokenInit(unsigned char *security_blob, int length,
459 unsigned int cls, con, tag, oidlen, rc; 459 unsigned int cls, con, tag, oidlen, rc;
460 int use_ntlmssp = FALSE; 460 int use_ntlmssp = FALSE;
461 461
462 *secType = NTLM; /* BB eventually make Kerberos or NLTMSSP the default */ 462 *secType = NTLM; /* BB eventually make Kerberos or NLTMSSP the default*/
463 463
464 /* cifs_dump_mem(" Received SecBlob ", security_blob, length); */ 464 /* cifs_dump_mem(" Received SecBlob ", security_blob, length); */
465 465
@@ -498,7 +498,8 @@ decode_negTokenInit(unsigned char *security_blob, int length,
498 return 0; 498 return 0;
499 } else if ((cls != ASN1_CTX) || (con != ASN1_CON) 499 } else if ((cls != ASN1_CTX) || (con != ASN1_CON)
500 || (tag != ASN1_EOC)) { 500 || (tag != ASN1_EOC)) {
501 cFYI(1,("cls = %d con = %d tag = %d end = %p (%d) exit 0", 501 cFYI(1,
502 ("cls = %d con = %d tag = %d end = %p (%d) exit 0",
502 cls, con, tag, end, *end)); 503 cls, con, tag, end, *end));
503 return 0; 504 return 0;
504 } 505 }
@@ -508,7 +509,8 @@ decode_negTokenInit(unsigned char *security_blob, int length,
508 return 0; 509 return 0;
509 } else if ((cls != ASN1_UNI) || (con != ASN1_CON) 510 } else if ((cls != ASN1_UNI) || (con != ASN1_CON)
510 || (tag != ASN1_SEQ)) { 511 || (tag != ASN1_SEQ)) {
511 cFYI(1,("cls = %d con = %d tag = %d end = %p (%d) exit 1", 512 cFYI(1,
513 ("cls = %d con = %d tag = %d end = %p (%d) exit 1",
512 cls, con, tag, end, *end)); 514 cls, con, tag, end, *end));
513 return 0; 515 return 0;
514 } 516 }
@@ -540,32 +542,34 @@ decode_negTokenInit(unsigned char *security_blob, int length,
540 rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag); 542 rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag);
541 if (!rc) { 543 if (!rc) {
542 cFYI(1, 544 cFYI(1,
543 ("Error 1 decoding negTokenInit header exit 2")); 545 ("Error decoding negTokenInit hdr exit2"));
544 return 0; 546 return 0;
545 } 547 }
546 if ((tag == ASN1_OJI) && (con == ASN1_PRI)) { 548 if ((tag == ASN1_OJI) && (con == ASN1_PRI)) {
547 rc = asn1_oid_decode(&ctx, end, &oid, &oidlen); 549 rc = asn1_oid_decode(&ctx, end, &oid, &oidlen);
548 if(rc) { 550 if (rc) {
549 cFYI(1, 551 cFYI(1,
550 ("OID len = %d oid = 0x%lx 0x%lx 0x%lx 0x%lx", 552 ("OID len = %d oid = 0x%lx 0x%lx "
551 oidlen, *oid, *(oid + 1), *(oid + 2), 553 "0x%lx 0x%lx",
552 *(oid + 3))); 554 oidlen, *oid, *(oid + 1),
553 rc = compare_oid(oid, oidlen, NTLMSSP_OID, 555 *(oid + 2), *(oid + 3)));
554 NTLMSSP_OID_LEN); 556 rc = compare_oid(oid, oidlen,
557 NTLMSSP_OID, NTLMSSP_OID_LEN);
555 kfree(oid); 558 kfree(oid);
556 if (rc) 559 if (rc)
557 use_ntlmssp = TRUE; 560 use_ntlmssp = TRUE;
558 } 561 }
559 } else { 562 } else {
560 cFYI(1,("This should be an oid what is going on? ")); 563 cFYI(1, ("Should be an oid what is going on?"));
561 } 564 }
562 } 565 }
563 566
564 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { 567 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
565 cFYI(1, 568 cFYI(1,
566 ("Error decoding last part of negTokenInit exit 3")); 569 ("Error decoding last part negTokenInit exit3"));
567 return 0; 570 return 0;
568 } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { /* tag = 3 indicating mechListMIC */ 571 } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) {
572 /* tag = 3 indicating mechListMIC */
569 cFYI(1, 573 cFYI(1,
570 ("Exit 4 cls = %d con = %d tag = %d end = %p (%d)", 574 ("Exit 4 cls = %d con = %d tag = %d end = %p (%d)",
571 cls, con, tag, end, *end)); 575 cls, con, tag, end, *end));
@@ -573,7 +577,7 @@ decode_negTokenInit(unsigned char *security_blob, int length,
573 } 577 }
574 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { 578 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
575 cFYI(1, 579 cFYI(1,
576 ("Error decoding last part of negTokenInit exit 5")); 580 ("Error decoding last part negTokenInit exit5"));
577 return 0; 581 return 0;
578 } else if ((cls != ASN1_UNI) || (con != ASN1_CON) 582 } else if ((cls != ASN1_UNI) || (con != ASN1_CON)
579 || (tag != ASN1_SEQ)) { 583 || (tag != ASN1_SEQ)) {
@@ -584,7 +588,7 @@ decode_negTokenInit(unsigned char *security_blob, int length,
584 588
585 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { 589 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
586 cFYI(1, 590 cFYI(1,
587 ("Error decoding last part of negTokenInit exit 7")); 591 ("Error decoding last part negTokenInit exit 7"));
588 return 0; 592 return 0;
589 } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { 593 } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) {
590 cFYI(1, 594 cFYI(1,
@@ -594,20 +598,21 @@ decode_negTokenInit(unsigned char *security_blob, int length,
594 } 598 }
595 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { 599 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
596 cFYI(1, 600 cFYI(1,
597 ("Error decoding last part of negTokenInit exit 9")); 601 ("Error decoding last part negTokenInit exit9"));
598 return 0; 602 return 0;
599 } else if ((cls != ASN1_UNI) || (con != ASN1_PRI) 603 } else if ((cls != ASN1_UNI) || (con != ASN1_PRI)
600 || (tag != ASN1_GENSTR)) { 604 || (tag != ASN1_GENSTR)) {
601 cFYI(1, 605 cFYI(1,
602 ("Exit 10 cls = %d con = %d tag = %d end = %p (%d)", 606 ("Exit10 cls = %d con = %d tag = %d end = %p (%d)",
603 cls, con, tag, end, *end)); 607 cls, con, tag, end, *end));
604 return 0; 608 return 0;
605 } 609 }
606 cFYI(1, ("Need to call asn1_octets_decode() function for this %s", ctx.pointer)); /* is this UTF-8 or ASCII? */ 610 cFYI(1, ("Need to call asn1_octets_decode() function for %s",
611 ctx.pointer)); /* is this UTF-8 or ASCII? */
607 } 612 }
608 613
609 /* if (use_kerberos) 614 /* if (use_kerberos)
610 *secType = Kerberos 615 *secType = Kerberos
611 else */ 616 else */
612 if (use_ntlmssp) { 617 if (use_ntlmssp) {
613 *secType = NTLMSSP; 618 *secType = NTLMSSP;
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
index 07838b2ac1ce..1bf8cf522ad6 100644
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -58,7 +58,7 @@ cifs_dump_mem(char *label, void *data, int length)
58} 58}
59 59
60#ifdef CONFIG_CIFS_DEBUG2 60#ifdef CONFIG_CIFS_DEBUG2
61void cifs_dump_detail(struct smb_hdr * smb) 61void cifs_dump_detail(struct smb_hdr *smb)
62{ 62{
63 cERROR(1, ("Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d", 63 cERROR(1, ("Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d",
64 smb->Command, smb->Status.CifsError, 64 smb->Command, smb->Status.CifsError,
@@ -67,10 +67,10 @@ void cifs_dump_detail(struct smb_hdr * smb)
67} 67}
68 68
69 69
70void cifs_dump_mids(struct TCP_Server_Info * server) 70void cifs_dump_mids(struct TCP_Server_Info *server)
71{ 71{
72 struct list_head *tmp; 72 struct list_head *tmp;
73 struct mid_q_entry * mid_entry; 73 struct mid_q_entry *mid_entry;
74 74
75 if (server == NULL) 75 if (server == NULL)
76 return; 76 return;
@@ -114,12 +114,12 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
114{ 114{
115 struct list_head *tmp; 115 struct list_head *tmp;
116 struct list_head *tmp1; 116 struct list_head *tmp1;
117 struct mid_q_entry * mid_entry; 117 struct mid_q_entry *mid_entry;
118 struct cifsSesInfo *ses; 118 struct cifsSesInfo *ses;
119 struct cifsTconInfo *tcon; 119 struct cifsTconInfo *tcon;
120 int i; 120 int i;
121 int length = 0; 121 int length = 0;
122 char * original_buf = buf; 122 char *original_buf = buf;
123 123
124 *beginBuffer = buf + offset; 124 *beginBuffer = buf + offset;
125 125
@@ -145,7 +145,6 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
145 (ses->serverNOS == NULL)) { 145 (ses->serverNOS == NULL)) {
146 buf += sprintf(buf, "\nentry for %s not fully " 146 buf += sprintf(buf, "\nentry for %s not fully "
147 "displayed\n\t", ses->serverName); 147 "displayed\n\t", ses->serverName);
148
149 } else { 148 } else {
150 length = 149 length =
151 sprintf(buf, 150 sprintf(buf,
@@ -901,90 +900,14 @@ security_flags_write(struct file *file, const char __user *buffer,
901 } 900 }
902 /* flags look ok - update the global security flags for cifs module */ 901 /* flags look ok - update the global security flags for cifs module */
903 extended_security = flags; 902 extended_security = flags;
903 if (extended_security & CIFSSEC_MUST_SIGN) {
904 /* requiring signing implies signing is allowed */
905 extended_security |= CIFSSEC_MAY_SIGN;
906 cFYI(1, ("packet signing now required"));
907 } else if ((extended_security & CIFSSEC_MAY_SIGN) == 0) {
908 cFYI(1, ("packet signing disabled"));
909 }
910 /* BB should we turn on MAY flags for other MUST options? */
904 return count; 911 return count;
905} 912}
906
907/* static int
908ntlmv2_enabled_read(char *page, char **start, off_t off,
909 int count, int *eof, void *data)
910{
911 int len;
912
913 len = sprintf(page, "%d\n", ntlmv2_support);
914
915 len -= off;
916 *start = page + off;
917
918 if (len > count)
919 len = count;
920 else
921 *eof = 1;
922
923 if (len < 0)
924 len = 0;
925
926 return len;
927}
928static int
929ntlmv2_enabled_write(struct file *file, const char __user *buffer,
930 unsigned long count, void *data)
931{
932 char c;
933 int rc;
934
935 rc = get_user(c, buffer);
936 if (rc)
937 return rc;
938 if (c == '0' || c == 'n' || c == 'N')
939 ntlmv2_support = 0;
940 else if (c == '1' || c == 'y' || c == 'Y')
941 ntlmv2_support = 1;
942 else if (c == '2')
943 ntlmv2_support = 2;
944
945 return count;
946}
947
948static int
949packet_signing_enabled_read(char *page, char **start, off_t off,
950 int count, int *eof, void *data)
951{
952 int len;
953
954 len = sprintf(page, "%d\n", sign_CIFS_PDUs);
955
956 len -= off;
957 *start = page + off;
958
959 if (len > count)
960 len = count;
961 else
962 *eof = 1;
963
964 if (len < 0)
965 len = 0;
966
967 return len;
968}
969static int
970packet_signing_enabled_write(struct file *file, const char __user *buffer,
971 unsigned long count, void *data)
972{
973 char c;
974 int rc;
975
976 rc = get_user(c, buffer);
977 if (rc)
978 return rc;
979 if (c == '0' || c == 'n' || c == 'N')
980 sign_CIFS_PDUs = 0;
981 else if (c == '1' || c == 'y' || c == 'Y')
982 sign_CIFS_PDUs = 1;
983 else if (c == '2')
984 sign_CIFS_PDUs = 2;
985
986 return count;
987} */
988
989
990#endif 913#endif
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index 4cc2012e9322..34af556cdd8d 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -43,6 +43,6 @@ struct cifs_sb_info {
43 mode_t mnt_dir_mode; 43 mode_t mnt_dir_mode;
44 int mnt_cifs_flags; 44 int mnt_cifs_flags;
45 int prepathlen; 45 int prepathlen;
46 char * prepath; 46 char *prepath;
47}; 47};
48#endif /* _CIFS_FS_SB_H */ 48#endif /* _CIFS_FS_SB_H */
diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c
index 701e9a9185f2..b5903b89250d 100644
--- a/fs/cifs/cifs_unicode.c
+++ b/fs/cifs/cifs_unicode.c
@@ -66,7 +66,7 @@ cifs_strtoUCS(__le16 * to, const char *from, int len,
66{ 66{
67 int charlen; 67 int charlen;
68 int i; 68 int i;
69 wchar_t * wchar_to = (wchar_t *)to; /* needed to quiet sparse */ 69 wchar_t *wchar_to = (wchar_t *)to; /* needed to quiet sparse */
70 70
71 for (i = 0; len && *from; i++, from += charlen, len -= charlen) { 71 for (i = 0; len && *from; i++, from += charlen, len -= charlen) {
72 72
diff --git a/fs/cifs/cifs_unicode.h b/fs/cifs/cifs_unicode.h
index 39e5b970325f..614c11fcdcb6 100644
--- a/fs/cifs/cifs_unicode.h
+++ b/fs/cifs/cifs_unicode.h
@@ -5,20 +5,20 @@
5 * Convert a unicode character to upper or lower case using 5 * Convert a unicode character to upper or lower case using
6 * compressed tables. 6 * compressed tables.
7 * 7 *
8 * Copyright (c) International Business Machines Corp., 2000,2005555555555555555555555555555555555555555555555555555555 8 * Copyright (c) International Business Machines Corp., 2000,2007
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or 12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version. 13 * (at your option) any later version.
14 * 14 *
15 * This program is distributed in the hope that it will be useful, 15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
18 * the GNU General Public License for more details. 18 * the GNU General Public License for more details.
19 * 19 *
20 * You should have received a copy of the GNU General Public License 20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software 21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * 23 *
24 * 24 *
@@ -70,7 +70,7 @@ int cifs_strtoUCS(__le16 *, const char *, int, const struct nls_table *);
70 * Address of the first string 70 * Address of the first string
71 */ 71 */
72static inline wchar_t * 72static inline wchar_t *
73UniStrcat(wchar_t * ucs1, const wchar_t * ucs2) 73UniStrcat(wchar_t *ucs1, const wchar_t *ucs2)
74{ 74{
75 wchar_t *anchor = ucs1; /* save a pointer to start of ucs1 */ 75 wchar_t *anchor = ucs1; /* save a pointer to start of ucs1 */
76 76
@@ -88,7 +88,7 @@ UniStrcat(wchar_t * ucs1, const wchar_t * ucs2)
88 * or NULL if the character is not in the string 88 * or NULL if the character is not in the string
89 */ 89 */
90static inline wchar_t * 90static inline wchar_t *
91UniStrchr(const wchar_t * ucs, wchar_t uc) 91UniStrchr(const wchar_t *ucs, wchar_t uc)
92{ 92{
93 while ((*ucs != uc) && *ucs) 93 while ((*ucs != uc) && *ucs)
94 ucs++; 94 ucs++;
@@ -107,7 +107,7 @@ UniStrchr(const wchar_t * ucs, wchar_t uc)
107 * > 0: First string is greater than second 107 * > 0: First string is greater than second
108 */ 108 */
109static inline int 109static inline int
110UniStrcmp(const wchar_t * ucs1, const wchar_t * ucs2) 110UniStrcmp(const wchar_t *ucs1, const wchar_t *ucs2)
111{ 111{
112 while ((*ucs1 == *ucs2) && *ucs1) { 112 while ((*ucs1 == *ucs2) && *ucs1) {
113 ucs1++; 113 ucs1++;
@@ -120,7 +120,7 @@ UniStrcmp(const wchar_t * ucs1, const wchar_t * ucs2)
120 * UniStrcpy: Copy a string 120 * UniStrcpy: Copy a string
121 */ 121 */
122static inline wchar_t * 122static inline wchar_t *
123UniStrcpy(wchar_t * ucs1, const wchar_t * ucs2) 123UniStrcpy(wchar_t *ucs1, const wchar_t *ucs2)
124{ 124{
125 wchar_t *anchor = ucs1; /* save the start of result string */ 125 wchar_t *anchor = ucs1; /* save the start of result string */
126 126
@@ -132,7 +132,7 @@ UniStrcpy(wchar_t * ucs1, const wchar_t * ucs2)
132 * UniStrlen: Return the length of a string (in 16 bit Unicode chars not bytes) 132 * UniStrlen: Return the length of a string (in 16 bit Unicode chars not bytes)
133 */ 133 */
134static inline size_t 134static inline size_t
135UniStrlen(const wchar_t * ucs1) 135UniStrlen(const wchar_t *ucs1)
136{ 136{
137 int i = 0; 137 int i = 0;
138 138
@@ -142,10 +142,11 @@ UniStrlen(const wchar_t * ucs1)
142} 142}
143 143
144/* 144/*
145 * UniStrnlen: Return the length (in 16 bit Unicode chars not bytes) of a string (length limited) 145 * UniStrnlen: Return the length (in 16 bit Unicode chars not bytes) of a
146 * string (length limited)
146 */ 147 */
147static inline size_t 148static inline size_t
148UniStrnlen(const wchar_t * ucs1, int maxlen) 149UniStrnlen(const wchar_t *ucs1, int maxlen)
149{ 150{
150 int i = 0; 151 int i = 0;
151 152
@@ -161,7 +162,7 @@ UniStrnlen(const wchar_t * ucs1, int maxlen)
161 * UniStrncat: Concatenate length limited string 162 * UniStrncat: Concatenate length limited string
162 */ 163 */
163static inline wchar_t * 164static inline wchar_t *
164UniStrncat(wchar_t * ucs1, const wchar_t * ucs2, size_t n) 165UniStrncat(wchar_t *ucs1, const wchar_t *ucs2, size_t n)
165{ 166{
166 wchar_t *anchor = ucs1; /* save pointer to string 1 */ 167 wchar_t *anchor = ucs1; /* save pointer to string 1 */
167 168
@@ -179,7 +180,7 @@ UniStrncat(wchar_t * ucs1, const wchar_t * ucs2, size_t n)
179 * UniStrncmp: Compare length limited string 180 * UniStrncmp: Compare length limited string
180 */ 181 */
181static inline int 182static inline int
182UniStrncmp(const wchar_t * ucs1, const wchar_t * ucs2, size_t n) 183UniStrncmp(const wchar_t *ucs1, const wchar_t *ucs2, size_t n)
183{ 184{
184 if (!n) 185 if (!n)
185 return 0; /* Null strings are equal */ 186 return 0; /* Null strings are equal */
@@ -194,7 +195,7 @@ UniStrncmp(const wchar_t * ucs1, const wchar_t * ucs2, size_t n)
194 * UniStrncmp_le: Compare length limited string - native to little-endian 195 * UniStrncmp_le: Compare length limited string - native to little-endian
195 */ 196 */
196static inline int 197static inline int
197UniStrncmp_le(const wchar_t * ucs1, const wchar_t * ucs2, size_t n) 198UniStrncmp_le(const wchar_t *ucs1, const wchar_t *ucs2, size_t n)
198{ 199{
199 if (!n) 200 if (!n)
200 return 0; /* Null strings are equal */ 201 return 0; /* Null strings are equal */
@@ -209,7 +210,7 @@ UniStrncmp_le(const wchar_t * ucs1, const wchar_t * ucs2, size_t n)
209 * UniStrncpy: Copy length limited string with pad 210 * UniStrncpy: Copy length limited string with pad
210 */ 211 */
211static inline wchar_t * 212static inline wchar_t *
212UniStrncpy(wchar_t * ucs1, const wchar_t * ucs2, size_t n) 213UniStrncpy(wchar_t *ucs1, const wchar_t *ucs2, size_t n)
213{ 214{
214 wchar_t *anchor = ucs1; 215 wchar_t *anchor = ucs1;
215 216
@@ -226,7 +227,7 @@ UniStrncpy(wchar_t * ucs1, const wchar_t * ucs2, size_t n)
226 * UniStrncpy_le: Copy length limited string with pad to little-endian 227 * UniStrncpy_le: Copy length limited string with pad to little-endian
227 */ 228 */
228static inline wchar_t * 229static inline wchar_t *
229UniStrncpy_le(wchar_t * ucs1, const wchar_t * ucs2, size_t n) 230UniStrncpy_le(wchar_t *ucs1, const wchar_t *ucs2, size_t n)
230{ 231{
231 wchar_t *anchor = ucs1; 232 wchar_t *anchor = ucs1;
232 233
@@ -247,7 +248,7 @@ UniStrncpy_le(wchar_t * ucs1, const wchar_t * ucs2, size_t n)
247 * NULL if no matching string is found 248 * NULL if no matching string is found
248 */ 249 */
249static inline wchar_t * 250static inline wchar_t *
250UniStrstr(const wchar_t * ucs1, const wchar_t * ucs2) 251UniStrstr(const wchar_t *ucs1, const wchar_t *ucs2)
251{ 252{
252 const wchar_t *anchor1 = ucs1; 253 const wchar_t *anchor1 = ucs1;
253 const wchar_t *anchor2 = ucs2; 254 const wchar_t *anchor2 = ucs2;
@@ -297,7 +298,7 @@ UniToupper(register wchar_t uc)
297 * UniStrupr: Upper case a unicode string 298 * UniStrupr: Upper case a unicode string
298 */ 299 */
299static inline wchar_t * 300static inline wchar_t *
300UniStrupr(register wchar_t * upin) 301UniStrupr(register wchar_t *upin)
301{ 302{
302 register wchar_t *up; 303 register wchar_t *up;
303 304
@@ -338,7 +339,7 @@ UniTolower(wchar_t uc)
338 * UniStrlwr: Lower case a unicode string 339 * UniStrlwr: Lower case a unicode string
339 */ 340 */
340static inline wchar_t * 341static inline wchar_t *
341UniStrlwr(register wchar_t * upin) 342UniStrlwr(register wchar_t *upin)
342{ 343{
343 register wchar_t *up; 344 register wchar_t *up;
344 345
diff --git a/fs/cifs/cifs_uniupr.h b/fs/cifs/cifs_uniupr.h
index da2ad5b451ac..18a9d978e519 100644
--- a/fs/cifs/cifs_uniupr.h
+++ b/fs/cifs/cifs_uniupr.h
@@ -3,16 +3,16 @@
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by 5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or 6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version. 7 * (at your option) any later version.
8 * 8 *
9 * This program is distributed in the hope that it will be useful, 9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
12 * the GNU General Public License for more details. 12 * the GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software 15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 * 17 *
18 * uniupr.h - Unicode compressed case ranges 18 * uniupr.h - Unicode compressed case ranges
@@ -53,7 +53,7 @@ signed char CifsUniUpperTable[512] = {
53 0, -1, 0, -1, 0, -1, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, /* 1a0-1af */ 53 0, -1, 0, -1, 0, -1, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, /* 1a0-1af */
54 -1, 0, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, /* 1b0-1bf */ 54 -1, 0, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, /* 1b0-1bf */
55 0, 0, 0, 0, 0, -1, -2, 0, -1, -2, 0, -1, -2, 0, -1, 0, /* 1c0-1cf */ 55 0, 0, 0, 0, 0, -1, -2, 0, -1, -2, 0, -1, -2, 0, -1, 0, /* 1c0-1cf */
56 -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -79, 0, -1, /* 1d0-1df */ 56 -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -79, 0, -1, /* 1d0-1df */
57 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1e0-1ef */ 57 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1e0-1ef */
58 0, 0, -1, -2, 0, -1, 0, 0, 0, -1, 0, -1, 0, -1, 0, -1, /* 1f0-1ff */ 58 0, 0, -1, -2, 0, -1, 0, 0, 0, -1, 0, -1, 0, -1, 0, -1, /* 1f0-1ff */
59}; 59};
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index fdeda519eace..36272293027d 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -21,7 +21,7 @@
21 21
22#include <linux/fs.h> 22#include <linux/fs.h>
23#include "cifspdu.h" 23#include "cifspdu.h"
24#include "cifsglob.h" 24#include "cifsglob.h"
25#include "cifs_debug.h" 25#include "cifs_debug.h"
26#include "md5.h" 26#include "md5.h"
27#include "cifs_unicode.h" 27#include "cifs_unicode.h"
@@ -29,54 +29,57 @@
29#include <linux/ctype.h> 29#include <linux/ctype.h>
30#include <linux/random.h> 30#include <linux/random.h>
31 31
32/* Calculate and return the CIFS signature based on the mac key and the smb pdu */ 32/* Calculate and return the CIFS signature based on the mac key and SMB PDU */
33/* the 16 byte signature must be allocated by the caller */ 33/* the 16 byte signature must be allocated by the caller */
34/* Note we only use the 1st eight bytes */ 34/* Note we only use the 1st eight bytes */
35/* Note that the smb header signature field on input contains the 35/* Note that the smb header signature field on input contains the
36 sequence number before this function is called */ 36 sequence number before this function is called */
37 37
38extern void mdfour(unsigned char *out, unsigned char *in, int n); 38extern void mdfour(unsigned char *out, unsigned char *in, int n);
39extern void E_md4hash(const unsigned char *passwd, unsigned char *p16); 39extern void E_md4hash(const unsigned char *passwd, unsigned char *p16);
40extern void SMBencrypt(unsigned char *passwd, unsigned char *c8, 40extern void SMBencrypt(unsigned char *passwd, unsigned char *c8,
41 unsigned char *p24); 41 unsigned char *p24);
42 42
43static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu, 43static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu,
44 const char * key, char * signature) 44 const struct mac_key *key, char *signature)
45{ 45{
46 struct MD5Context context; 46 struct MD5Context context;
47 47
48 if((cifs_pdu == NULL) || (signature == NULL)) 48 if ((cifs_pdu == NULL) || (signature == NULL) || (key == NULL))
49 return -EINVAL; 49 return -EINVAL;
50 50
51 MD5Init(&context); 51 MD5Init(&context);
52 MD5Update(&context,key,CIFS_SESS_KEY_SIZE+16); 52 MD5Update(&context, (char *)&key->data, key->len);
53 MD5Update(&context,cifs_pdu->Protocol,cifs_pdu->smb_buf_length); 53 MD5Update(&context, cifs_pdu->Protocol, cifs_pdu->smb_buf_length);
54 MD5Final(signature,&context); 54
55 MD5Final(signature, &context);
55 return 0; 56 return 0;
56} 57}
57 58
58int cifs_sign_smb(struct smb_hdr * cifs_pdu, struct TCP_Server_Info * server, 59int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
59 __u32 * pexpected_response_sequence_number) 60 __u32 *pexpected_response_sequence_number)
60{ 61{
61 int rc = 0; 62 int rc = 0;
62 char smb_signature[20]; 63 char smb_signature[20];
63 64
64 if((cifs_pdu == NULL) || (server == NULL)) 65 if ((cifs_pdu == NULL) || (server == NULL))
65 return -EINVAL; 66 return -EINVAL;
66 67
67 if((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0) 68 if ((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0)
68 return rc; 69 return rc;
69 70
70 spin_lock(&GlobalMid_Lock); 71 spin_lock(&GlobalMid_Lock);
71 cifs_pdu->Signature.Sequence.SequenceNumber = cpu_to_le32(server->sequence_number); 72 cifs_pdu->Signature.Sequence.SequenceNumber =
73 cpu_to_le32(server->sequence_number);
72 cifs_pdu->Signature.Sequence.Reserved = 0; 74 cifs_pdu->Signature.Sequence.Reserved = 0;
73 75
74 *pexpected_response_sequence_number = server->sequence_number++; 76 *pexpected_response_sequence_number = server->sequence_number++;
75 server->sequence_number++; 77 server->sequence_number++;
76 spin_unlock(&GlobalMid_Lock); 78 spin_unlock(&GlobalMid_Lock);
77 79
78 rc = cifs_calculate_signature(cifs_pdu, server->mac_signing_key,smb_signature); 80 rc = cifs_calculate_signature(cifs_pdu, &server->mac_signing_key,
79 if(rc) 81 smb_signature);
82 if (rc)
80 memset(cifs_pdu->Signature.SecuritySignature, 0, 8); 83 memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
81 else 84 else
82 memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8); 85 memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8);
@@ -84,115 +87,119 @@ int cifs_sign_smb(struct smb_hdr * cifs_pdu, struct TCP_Server_Info * server,
84 return rc; 87 return rc;
85} 88}
86 89
87static int cifs_calc_signature2(const struct kvec * iov, int n_vec, 90static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
88 const char * key, char * signature) 91 const struct mac_key *key, char *signature)
89{ 92{
90 struct MD5Context context; 93 struct MD5Context context;
91 int i; 94 int i;
92 95
93 if((iov == NULL) || (signature == NULL)) 96 if ((iov == NULL) || (signature == NULL) || (key == NULL))
94 return -EINVAL; 97 return -EINVAL;
95 98
96 MD5Init(&context); 99 MD5Init(&context);
97 MD5Update(&context,key,CIFS_SESS_KEY_SIZE+16); 100 MD5Update(&context, (char *)&key->data, key->len);
98 for(i=0;i<n_vec;i++) { 101 for (i = 0; i < n_vec; i++) {
99 if(iov[i].iov_base == NULL) { 102 if (iov[i].iov_base == NULL) {
100 cERROR(1,("null iovec entry")); 103 cERROR(1, ("null iovec entry"));
101 return -EIO; 104 return -EIO;
102 } else if(iov[i].iov_len == 0) 105 } else if (iov[i].iov_len == 0)
103 break; /* bail out if we are sent nothing to sign */ 106 break; /* bail out if we are sent nothing to sign */
104 /* The first entry includes a length field (which does not get 107 /* The first entry includes a length field (which does not get
105 signed that occupies the first 4 bytes before the header */ 108 signed that occupies the first 4 bytes before the header */
106 if(i==0) { 109 if (i == 0) {
107 if (iov[0].iov_len <= 8 ) /* cmd field at offset 9 */ 110 if (iov[0].iov_len <= 8 ) /* cmd field at offset 9 */
108 break; /* nothing to sign or corrupt header */ 111 break; /* nothing to sign or corrupt header */
109 MD5Update(&context,iov[0].iov_base+4, iov[0].iov_len-4); 112 MD5Update(&context, iov[0].iov_base+4,
113 iov[0].iov_len-4);
110 } else 114 } else
111 MD5Update(&context,iov[i].iov_base, iov[i].iov_len); 115 MD5Update(&context, iov[i].iov_base, iov[i].iov_len);
112 } 116 }
113 117
114 MD5Final(signature,&context); 118 MD5Final(signature, &context);
115 119
116 return 0; 120 return 0;
117} 121}
118 122
119 123
120int cifs_sign_smb2(struct kvec * iov, int n_vec, struct TCP_Server_Info *server, 124int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
121 __u32 * pexpected_response_sequence_number) 125 __u32 * pexpected_response_sequence_number)
122{ 126{
123 int rc = 0; 127 int rc = 0;
124 char smb_signature[20]; 128 char smb_signature[20];
125 struct smb_hdr * cifs_pdu = iov[0].iov_base; 129 struct smb_hdr *cifs_pdu = iov[0].iov_base;
126 130
127 if((cifs_pdu == NULL) || (server == NULL)) 131 if ((cifs_pdu == NULL) || (server == NULL))
128 return -EINVAL; 132 return -EINVAL;
129 133
130 if((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0) 134 if ((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0)
131 return rc; 135 return rc;
132 136
133 spin_lock(&GlobalMid_Lock); 137 spin_lock(&GlobalMid_Lock);
134 cifs_pdu->Signature.Sequence.SequenceNumber = 138 cifs_pdu->Signature.Sequence.SequenceNumber =
135 cpu_to_le32(server->sequence_number); 139 cpu_to_le32(server->sequence_number);
136 cifs_pdu->Signature.Sequence.Reserved = 0; 140 cifs_pdu->Signature.Sequence.Reserved = 0;
137 141
138 *pexpected_response_sequence_number = server->sequence_number++; 142 *pexpected_response_sequence_number = server->sequence_number++;
139 server->sequence_number++; 143 server->sequence_number++;
140 spin_unlock(&GlobalMid_Lock); 144 spin_unlock(&GlobalMid_Lock);
141 145
142 rc = cifs_calc_signature2(iov, n_vec, server->mac_signing_key, 146 rc = cifs_calc_signature2(iov, n_vec, &server->mac_signing_key,
143 smb_signature); 147 smb_signature);
144 if(rc) 148 if (rc)
145 memset(cifs_pdu->Signature.SecuritySignature, 0, 8); 149 memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
146 else 150 else
147 memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8); 151 memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8);
148
149 return rc;
150 152
153 return rc;
151} 154}
152 155
153int cifs_verify_signature(struct smb_hdr * cifs_pdu, const char * mac_key, 156int cifs_verify_signature(struct smb_hdr *cifs_pdu,
154 __u32 expected_sequence_number) 157 const struct mac_key *mac_key,
158 __u32 expected_sequence_number)
155{ 159{
156 unsigned int rc; 160 unsigned int rc;
157 char server_response_sig[8]; 161 char server_response_sig[8];
158 char what_we_think_sig_should_be[20]; 162 char what_we_think_sig_should_be[20];
159 163
160 if((cifs_pdu == NULL) || (mac_key == NULL)) 164 if ((cifs_pdu == NULL) || (mac_key == NULL))
161 return -EINVAL; 165 return -EINVAL;
162 166
163 if (cifs_pdu->Command == SMB_COM_NEGOTIATE) 167 if (cifs_pdu->Command == SMB_COM_NEGOTIATE)
164 return 0; 168 return 0;
165 169
166 if (cifs_pdu->Command == SMB_COM_LOCKING_ANDX) { 170 if (cifs_pdu->Command == SMB_COM_LOCKING_ANDX) {
167 struct smb_com_lock_req * pSMB = (struct smb_com_lock_req *)cifs_pdu; 171 struct smb_com_lock_req *pSMB =
168 if(pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE) 172 (struct smb_com_lock_req *)cifs_pdu;
173 if (pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE)
169 return 0; 174 return 0;
170 } 175 }
171 176
172 /* BB what if signatures are supposed to be on for session but server does not 177 /* BB what if signatures are supposed to be on for session but
173 send one? BB */ 178 server does not send one? BB */
174 179
175 /* Do not need to verify session setups with signature "BSRSPYL " */ 180 /* Do not need to verify session setups with signature "BSRSPYL " */
176 if(memcmp(cifs_pdu->Signature.SecuritySignature,"BSRSPYL ",8)==0) 181 if (memcmp(cifs_pdu->Signature.SecuritySignature, "BSRSPYL ", 8) == 0)
177 cFYI(1,("dummy signature received for smb command 0x%x",cifs_pdu->Command)); 182 cFYI(1, ("dummy signature received for smb command 0x%x",
183 cifs_pdu->Command));
178 184
179 /* save off the origiginal signature so we can modify the smb and check 185 /* save off the origiginal signature so we can modify the smb and check
180 its signature against what the server sent */ 186 its signature against what the server sent */
181 memcpy(server_response_sig,cifs_pdu->Signature.SecuritySignature,8); 187 memcpy(server_response_sig, cifs_pdu->Signature.SecuritySignature, 8);
182 188
183 cifs_pdu->Signature.Sequence.SequenceNumber = cpu_to_le32(expected_sequence_number); 189 cifs_pdu->Signature.Sequence.SequenceNumber =
190 cpu_to_le32(expected_sequence_number);
184 cifs_pdu->Signature.Sequence.Reserved = 0; 191 cifs_pdu->Signature.Sequence.Reserved = 0;
185 192
186 rc = cifs_calculate_signature(cifs_pdu, mac_key, 193 rc = cifs_calculate_signature(cifs_pdu, mac_key,
187 what_we_think_sig_should_be); 194 what_we_think_sig_should_be);
188 195
189 if(rc) 196 if (rc)
190 return rc; 197 return rc;
191 198
192 199/* cifs_dump_mem("what we think it should be: ",
193/* cifs_dump_mem("what we think it should be: ",what_we_think_sig_should_be,16); */ 200 what_we_think_sig_should_be, 16); */
194 201
195 if(memcmp(server_response_sig, what_we_think_sig_should_be, 8)) 202 if (memcmp(server_response_sig, what_we_think_sig_should_be, 8))
196 return -EACCES; 203 return -EACCES;
197 else 204 else
198 return 0; 205 return 0;
@@ -200,89 +207,94 @@ int cifs_verify_signature(struct smb_hdr * cifs_pdu, const char * mac_key,
200} 207}
201 208
202/* We fill in key by putting in 40 byte array which was allocated by caller */ 209/* We fill in key by putting in 40 byte array which was allocated by caller */
203int cifs_calculate_mac_key(char * key, const char * rn, const char * password) 210int cifs_calculate_mac_key(struct mac_key *key, const char *rn,
211 const char *password)
204{ 212{
205 char temp_key[16]; 213 char temp_key[16];
206 if ((key == NULL) || (rn == NULL)) 214 if ((key == NULL) || (rn == NULL))
207 return -EINVAL; 215 return -EINVAL;
208 216
209 E_md4hash(password, temp_key); 217 E_md4hash(password, temp_key);
210 mdfour(key,temp_key,16); 218 mdfour(key->data.ntlm, temp_key, 16);
211 memcpy(key+16,rn, CIFS_SESS_KEY_SIZE); 219 memcpy(key->data.ntlm+16, rn, CIFS_SESS_KEY_SIZE);
220 key->len = 40;
212 return 0; 221 return 0;
213} 222}
214 223
215int CalcNTLMv2_partial_mac_key(struct cifsSesInfo * ses, 224int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *ses,
216 const struct nls_table * nls_info) 225 const struct nls_table *nls_info)
217{ 226{
218 char temp_hash[16]; 227 char temp_hash[16];
219 struct HMACMD5Context ctx; 228 struct HMACMD5Context ctx;
220 char * ucase_buf; 229 char *ucase_buf;
221 __le16 * unicode_buf; 230 __le16 *unicode_buf;
222 unsigned int i,user_name_len,dom_name_len; 231 unsigned int i, user_name_len, dom_name_len;
223 232
224 if(ses == NULL) 233 if (ses == NULL)
225 return -EINVAL; 234 return -EINVAL;
226 235
227 E_md4hash(ses->password, temp_hash); 236 E_md4hash(ses->password, temp_hash);
228 237
229 hmac_md5_init_limK_to_64(temp_hash, 16, &ctx); 238 hmac_md5_init_limK_to_64(temp_hash, 16, &ctx);
230 user_name_len = strlen(ses->userName); 239 user_name_len = strlen(ses->userName);
231 if(user_name_len > MAX_USERNAME_SIZE) 240 if (user_name_len > MAX_USERNAME_SIZE)
232 return -EINVAL; 241 return -EINVAL;
233 if(ses->domainName == NULL) 242 if (ses->domainName == NULL)
234 return -EINVAL; /* BB should we use CIFS_LINUX_DOM */ 243 return -EINVAL; /* BB should we use CIFS_LINUX_DOM */
235 dom_name_len = strlen(ses->domainName); 244 dom_name_len = strlen(ses->domainName);
236 if(dom_name_len > MAX_USERNAME_SIZE) 245 if (dom_name_len > MAX_USERNAME_SIZE)
237 return -EINVAL; 246 return -EINVAL;
238 247
239 ucase_buf = kmalloc((MAX_USERNAME_SIZE+1), GFP_KERNEL); 248 ucase_buf = kmalloc((MAX_USERNAME_SIZE+1), GFP_KERNEL);
240 if(ucase_buf == NULL) 249 if (ucase_buf == NULL)
241 return -ENOMEM; 250 return -ENOMEM;
242 unicode_buf = kmalloc((MAX_USERNAME_SIZE+1)*4, GFP_KERNEL); 251 unicode_buf = kmalloc((MAX_USERNAME_SIZE+1)*4, GFP_KERNEL);
243 if(unicode_buf == NULL) { 252 if (unicode_buf == NULL) {
244 kfree(ucase_buf); 253 kfree(ucase_buf);
245 return -ENOMEM; 254 return -ENOMEM;
246 } 255 }
247 256
248 for(i=0;i<user_name_len;i++) 257 for (i = 0; i < user_name_len; i++)
249 ucase_buf[i] = nls_info->charset2upper[(int)ses->userName[i]]; 258 ucase_buf[i] = nls_info->charset2upper[(int)ses->userName[i]];
250 ucase_buf[i] = 0; 259 ucase_buf[i] = 0;
251 user_name_len = cifs_strtoUCS(unicode_buf, ucase_buf, MAX_USERNAME_SIZE*2, nls_info); 260 user_name_len = cifs_strtoUCS(unicode_buf, ucase_buf,
261 MAX_USERNAME_SIZE*2, nls_info);
252 unicode_buf[user_name_len] = 0; 262 unicode_buf[user_name_len] = 0;
253 user_name_len++; 263 user_name_len++;
254 264
255 for(i=0;i<dom_name_len;i++) 265 for (i = 0; i < dom_name_len; i++)
256 ucase_buf[i] = nls_info->charset2upper[(int)ses->domainName[i]]; 266 ucase_buf[i] = nls_info->charset2upper[(int)ses->domainName[i]];
257 ucase_buf[i] = 0; 267 ucase_buf[i] = 0;
258 dom_name_len = cifs_strtoUCS(unicode_buf+user_name_len, ucase_buf, MAX_USERNAME_SIZE*2, nls_info); 268 dom_name_len = cifs_strtoUCS(unicode_buf+user_name_len, ucase_buf,
269 MAX_USERNAME_SIZE*2, nls_info);
259 270
260 unicode_buf[user_name_len + dom_name_len] = 0; 271 unicode_buf[user_name_len + dom_name_len] = 0;
261 hmac_md5_update((const unsigned char *) unicode_buf, 272 hmac_md5_update((const unsigned char *) unicode_buf,
262 (user_name_len+dom_name_len)*2,&ctx); 273 (user_name_len+dom_name_len)*2, &ctx);
263 274
264 hmac_md5_final(ses->server->mac_signing_key,&ctx); 275 hmac_md5_final(ses->server->ntlmv2_hash, &ctx);
265 kfree(ucase_buf); 276 kfree(ucase_buf);
266 kfree(unicode_buf); 277 kfree(unicode_buf);
267 return 0; 278 return 0;
268} 279}
269 280
270#ifdef CONFIG_CIFS_WEAK_PW_HASH 281#ifdef CONFIG_CIFS_WEAK_PW_HASH
271void calc_lanman_hash(struct cifsSesInfo * ses, char * lnm_session_key) 282void calc_lanman_hash(struct cifsSesInfo *ses, char *lnm_session_key)
272{ 283{
273 int i; 284 int i;
274 char password_with_pad[CIFS_ENCPWD_SIZE]; 285 char password_with_pad[CIFS_ENCPWD_SIZE];
275 286
276 if(ses->server == NULL) 287 if (ses->server == NULL)
277 return; 288 return;
278 289
279 memset(password_with_pad, 0, CIFS_ENCPWD_SIZE); 290 memset(password_with_pad, 0, CIFS_ENCPWD_SIZE);
280 if(ses->password) 291 if (ses->password)
281 strncpy(password_with_pad, ses->password, CIFS_ENCPWD_SIZE); 292 strncpy(password_with_pad, ses->password, CIFS_ENCPWD_SIZE);
282 293
283 if((ses->server->secMode & SECMODE_PW_ENCRYPT) == 0) 294 if ((ses->server->secMode & SECMODE_PW_ENCRYPT) == 0)
284 if(extended_security & CIFSSEC_MAY_PLNTXT) { 295 if (extended_security & CIFSSEC_MAY_PLNTXT) {
285 memcpy(lnm_session_key, password_with_pad, CIFS_ENCPWD_SIZE); 296 memcpy(lnm_session_key, password_with_pad,
297 CIFS_ENCPWD_SIZE);
286 return; 298 return;
287 } 299 }
288 300
@@ -297,7 +309,7 @@ void calc_lanman_hash(struct cifsSesInfo * ses, char * lnm_session_key)
297 utf8 and other multibyte codepages each need their own strupper 309 utf8 and other multibyte codepages each need their own strupper
298 function since a byte at a time will ont work. */ 310 function since a byte at a time will ont work. */
299 311
300 for(i = 0; i < CIFS_ENCPWD_SIZE; i++) { 312 for (i = 0; i < CIFS_ENCPWD_SIZE; i++) {
301 password_with_pad[i] = toupper(password_with_pad[i]); 313 password_with_pad[i] = toupper(password_with_pad[i]);
302 } 314 }
303 315
@@ -307,19 +319,19 @@ void calc_lanman_hash(struct cifsSesInfo * ses, char * lnm_session_key)
307} 319}
308#endif /* CIFS_WEAK_PW_HASH */ 320#endif /* CIFS_WEAK_PW_HASH */
309 321
310static int calc_ntlmv2_hash(struct cifsSesInfo *ses, 322static int calc_ntlmv2_hash(struct cifsSesInfo *ses,
311 const struct nls_table * nls_cp) 323 const struct nls_table *nls_cp)
312{ 324{
313 int rc = 0; 325 int rc = 0;
314 int len; 326 int len;
315 char nt_hash[16]; 327 char nt_hash[16];
316 struct HMACMD5Context * pctxt; 328 struct HMACMD5Context *pctxt;
317 wchar_t * user; 329 wchar_t *user;
318 wchar_t * domain; 330 wchar_t *domain;
319 331
320 pctxt = kmalloc(sizeof(struct HMACMD5Context), GFP_KERNEL); 332 pctxt = kmalloc(sizeof(struct HMACMD5Context), GFP_KERNEL);
321 333
322 if(pctxt == NULL) 334 if (pctxt == NULL)
323 return -ENOMEM; 335 return -ENOMEM;
324 336
325 /* calculate md4 hash of password */ 337 /* calculate md4 hash of password */
@@ -331,41 +343,45 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses,
331 /* convert ses->userName to unicode and uppercase */ 343 /* convert ses->userName to unicode and uppercase */
332 len = strlen(ses->userName); 344 len = strlen(ses->userName);
333 user = kmalloc(2 + (len * 2), GFP_KERNEL); 345 user = kmalloc(2 + (len * 2), GFP_KERNEL);
334 if(user == NULL) 346 if (user == NULL)
335 goto calc_exit_2; 347 goto calc_exit_2;
336 len = cifs_strtoUCS(user, ses->userName, len, nls_cp); 348 len = cifs_strtoUCS(user, ses->userName, len, nls_cp);
337 UniStrupr(user); 349 UniStrupr(user);
338 hmac_md5_update((char *)user, 2*len, pctxt); 350 hmac_md5_update((char *)user, 2*len, pctxt);
339 351
340 /* convert ses->domainName to unicode and uppercase */ 352 /* convert ses->domainName to unicode and uppercase */
341 if(ses->domainName) { 353 if (ses->domainName) {
342 len = strlen(ses->domainName); 354 len = strlen(ses->domainName);
343 355
344 domain = kmalloc(2 + (len * 2), GFP_KERNEL); 356 domain = kmalloc(2 + (len * 2), GFP_KERNEL);
345 if(domain == NULL) 357 if (domain == NULL)
346 goto calc_exit_1; 358 goto calc_exit_1;
347 len = cifs_strtoUCS(domain, ses->domainName, len, nls_cp); 359 len = cifs_strtoUCS(domain, ses->domainName, len, nls_cp);
348 UniStrupr(domain); 360 /* the following line was removed since it didn't work well
361 with lower cased domain name that passed as an option.
362 Maybe converting the domain name earlier makes sense */
363 /* UniStrupr(domain); */
349 364
350 hmac_md5_update((char *)domain, 2*len, pctxt); 365 hmac_md5_update((char *)domain, 2*len, pctxt);
351 366
352 kfree(domain); 367 kfree(domain);
353 } 368 }
354calc_exit_1: 369calc_exit_1:
355 kfree(user); 370 kfree(user);
356calc_exit_2: 371calc_exit_2:
357 /* BB FIXME what about bytes 24 through 40 of the signing key? 372 /* BB FIXME what about bytes 24 through 40 of the signing key?
358 compare with the NTLM example */ 373 compare with the NTLM example */
359 hmac_md5_final(ses->server->mac_signing_key, pctxt); 374 hmac_md5_final(ses->server->ntlmv2_hash, pctxt);
360 375
361 return rc; 376 return rc;
362} 377}
363 378
364void setup_ntlmv2_rsp(struct cifsSesInfo * ses, char * resp_buf, 379void setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf,
365 const struct nls_table * nls_cp) 380 const struct nls_table *nls_cp)
366{ 381{
367 int rc; 382 int rc;
368 struct ntlmv2_resp * buf = (struct ntlmv2_resp *)resp_buf; 383 struct ntlmv2_resp *buf = (struct ntlmv2_resp *)resp_buf;
384 struct HMACMD5Context context;
369 385
370 buf->blob_signature = cpu_to_le32(0x00000101); 386 buf->blob_signature = cpu_to_le32(0x00000101);
371 buf->reserved = 0; 387 buf->reserved = 0;
@@ -379,21 +395,31 @@ void setup_ntlmv2_rsp(struct cifsSesInfo * ses, char * resp_buf,
379 395
380 /* calculate buf->ntlmv2_hash */ 396 /* calculate buf->ntlmv2_hash */
381 rc = calc_ntlmv2_hash(ses, nls_cp); 397 rc = calc_ntlmv2_hash(ses, nls_cp);
382 if(rc) 398 if (rc)
383 cERROR(1,("could not get v2 hash rc %d",rc)); 399 cERROR(1, ("could not get v2 hash rc %d", rc));
384 CalcNTLMv2_response(ses, resp_buf); 400 CalcNTLMv2_response(ses, resp_buf);
401
402 /* now calculate the MAC key for NTLMv2 */
403 hmac_md5_init_limK_to_64(ses->server->ntlmv2_hash, 16, &context);
404 hmac_md5_update(resp_buf, 16, &context);
405 hmac_md5_final(ses->server->mac_signing_key.data.ntlmv2.key, &context);
406
407 memcpy(&ses->server->mac_signing_key.data.ntlmv2.resp, resp_buf,
408 sizeof(struct ntlmv2_resp));
409 ses->server->mac_signing_key.len = 16 + sizeof(struct ntlmv2_resp);
385} 410}
386 411
387void CalcNTLMv2_response(const struct cifsSesInfo * ses, char * v2_session_response) 412void CalcNTLMv2_response(const struct cifsSesInfo *ses,
413 char *v2_session_response)
388{ 414{
389 struct HMACMD5Context context; 415 struct HMACMD5Context context;
390 /* rest of v2 struct already generated */ 416 /* rest of v2 struct already generated */
391 memcpy(v2_session_response + 8, ses->server->cryptKey,8); 417 memcpy(v2_session_response + 8, ses->server->cryptKey, 8);
392 hmac_md5_init_limK_to_64(ses->server->mac_signing_key, 16, &context); 418 hmac_md5_init_limK_to_64(ses->server->ntlmv2_hash, 16, &context);
393 419
394 hmac_md5_update(v2_session_response+8, 420 hmac_md5_update(v2_session_response+8,
395 sizeof(struct ntlmv2_resp) - 8, &context); 421 sizeof(struct ntlmv2_resp) - 8, &context);
396 422
397 hmac_md5_final(v2_session_response,&context); 423 hmac_md5_final(v2_session_response, &context);
398/* cifs_dump_mem("v2_sess_rsp: ", v2_session_response, 32); */ 424/* cifs_dump_mem("v2_sess_rsp: ", v2_session_response, 32); */
399} 425}
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index bd0f2f2353ce..1fd0dc85f53c 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -64,23 +64,27 @@ unsigned int multiuser_mount = 0;
64unsigned int extended_security = CIFSSEC_DEF; 64unsigned int extended_security = CIFSSEC_DEF;
65/* unsigned int ntlmv2_support = 0; */ 65/* unsigned int ntlmv2_support = 0; */
66unsigned int sign_CIFS_PDUs = 1; 66unsigned int sign_CIFS_PDUs = 1;
67extern struct task_struct * oplockThread; /* remove sparse warning */ 67extern struct task_struct *oplockThread; /* remove sparse warning */
68struct task_struct * oplockThread = NULL; 68struct task_struct *oplockThread = NULL;
69/* extern struct task_struct * dnotifyThread; remove sparse warning */ 69/* extern struct task_struct * dnotifyThread; remove sparse warning */
70static struct task_struct * dnotifyThread = NULL; 70static struct task_struct *dnotifyThread = NULL;
71static const struct super_operations cifs_super_ops; 71static const struct super_operations cifs_super_ops;
72unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE; 72unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
73module_param(CIFSMaxBufSize, int, 0); 73module_param(CIFSMaxBufSize, int, 0);
74MODULE_PARM_DESC(CIFSMaxBufSize,"Network buffer size (not including header). Default: 16384 Range: 8192 to 130048"); 74MODULE_PARM_DESC(CIFSMaxBufSize, "Network buffer size (not including header). "
75 "Default: 16384 Range: 8192 to 130048");
75unsigned int cifs_min_rcv = CIFS_MIN_RCV_POOL; 76unsigned int cifs_min_rcv = CIFS_MIN_RCV_POOL;
76module_param(cifs_min_rcv, int, 0); 77module_param(cifs_min_rcv, int, 0);
77MODULE_PARM_DESC(cifs_min_rcv,"Network buffers in pool. Default: 4 Range: 1 to 64"); 78MODULE_PARM_DESC(cifs_min_rcv, "Network buffers in pool. Default: 4 Range: "
79 "1 to 64");
78unsigned int cifs_min_small = 30; 80unsigned int cifs_min_small = 30;
79module_param(cifs_min_small, int, 0); 81module_param(cifs_min_small, int, 0);
80MODULE_PARM_DESC(cifs_min_small,"Small network buffers in pool. Default: 30 Range: 2 to 256"); 82MODULE_PARM_DESC(cifs_min_small, "Small network buffers in pool. Default: 30 "
83 "Range: 2 to 256");
81unsigned int cifs_max_pending = CIFS_MAX_REQ; 84unsigned int cifs_max_pending = CIFS_MAX_REQ;
82module_param(cifs_max_pending, int, 0); 85module_param(cifs_max_pending, int, 0);
83MODULE_PARM_DESC(cifs_max_pending,"Simultaneous requests to server. Default: 50 Range: 2 to 256"); 86MODULE_PARM_DESC(cifs_max_pending, "Simultaneous requests to server. "
87 "Default: 50 Range: 2 to 256");
84 88
85extern mempool_t *cifs_sm_req_poolp; 89extern mempool_t *cifs_sm_req_poolp;
86extern mempool_t *cifs_req_poolp; 90extern mempool_t *cifs_req_poolp;
@@ -95,10 +99,10 @@ cifs_read_super(struct super_block *sb, void *data,
95 struct inode *inode; 99 struct inode *inode;
96 struct cifs_sb_info *cifs_sb; 100 struct cifs_sb_info *cifs_sb;
97 int rc = 0; 101 int rc = 0;
98 102
99 /* BB should we make this contingent on mount parm? */ 103 /* BB should we make this contingent on mount parm? */
100 sb->s_flags |= MS_NODIRATIME | MS_NOATIME; 104 sb->s_flags |= MS_NODIRATIME | MS_NOATIME;
101 sb->s_fs_info = kzalloc(sizeof(struct cifs_sb_info),GFP_KERNEL); 105 sb->s_fs_info = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL);
102 cifs_sb = CIFS_SB(sb); 106 cifs_sb = CIFS_SB(sb);
103 if (cifs_sb == NULL) 107 if (cifs_sb == NULL)
104 return -ENOMEM; 108 return -ENOMEM;
@@ -114,12 +118,9 @@ cifs_read_super(struct super_block *sb, void *data,
114 118
115 sb->s_magic = CIFS_MAGIC_NUMBER; 119 sb->s_magic = CIFS_MAGIC_NUMBER;
116 sb->s_op = &cifs_super_ops; 120 sb->s_op = &cifs_super_ops;
117#ifdef CONFIG_CIFS_EXPERIMENTAL
118 if (experimEnabled != 0)
119 sb->s_export_op = &cifs_export_ops;
120#endif /* EXPERIMENTAL */
121/* if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512) 121/* if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512)
122 sb->s_blocksize = cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */ 122 sb->s_blocksize =
123 cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */
123#ifdef CONFIG_CIFS_QUOTA 124#ifdef CONFIG_CIFS_QUOTA
124 sb->s_qcop = &cifs_quotactl_ops; 125 sb->s_qcop = &cifs_quotactl_ops;
125#endif 126#endif
@@ -139,6 +140,13 @@ cifs_read_super(struct super_block *sb, void *data,
139 goto out_no_root; 140 goto out_no_root;
140 } 141 }
141 142
143#ifdef CONFIG_CIFS_EXPERIMENTAL
144 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
145 cFYI(1, ("export ops supported"));
146 sb->s_export_op = &cifs_export_ops;
147 }
148#endif /* EXPERIMENTAL */
149
142 return 0; 150 return 0;
143 151
144out_no_root: 152out_no_root:
@@ -149,7 +157,7 @@ out_no_root:
149out_mount_failed: 157out_mount_failed:
150 if (cifs_sb) { 158 if (cifs_sb) {
151 if (cifs_sb->local_nls) 159 if (cifs_sb->local_nls)
152 unload_nls(cifs_sb->local_nls); 160 unload_nls(cifs_sb->local_nls);
153 kfree(cifs_sb); 161 kfree(cifs_sb);
154 } 162 }
155 return rc; 163 return rc;
@@ -164,10 +172,10 @@ cifs_put_super(struct super_block *sb)
164 cFYI(1, ("In cifs_put_super")); 172 cFYI(1, ("In cifs_put_super"));
165 cifs_sb = CIFS_SB(sb); 173 cifs_sb = CIFS_SB(sb);
166 if (cifs_sb == NULL) { 174 if (cifs_sb == NULL) {
167 cFYI(1,("Empty cifs superblock info passed to unmount")); 175 cFYI(1, ("Empty cifs superblock info passed to unmount"));
168 return; 176 return;
169 } 177 }
170 rc = cifs_umount(sb, cifs_sb); 178 rc = cifs_umount(sb, cifs_sb);
171 if (rc) { 179 if (rc) {
172 cERROR(1, ("cifs_umount failed with return code %d", rc)); 180 cERROR(1, ("cifs_umount failed with return code %d", rc));
173 } 181 }
@@ -180,7 +188,7 @@ static int
180cifs_statfs(struct dentry *dentry, struct kstatfs *buf) 188cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
181{ 189{
182 struct super_block *sb = dentry->d_sb; 190 struct super_block *sb = dentry->d_sb;
183 int xid; 191 int xid;
184 int rc = -EOPNOTSUPP; 192 int rc = -EOPNOTSUPP;
185 struct cifs_sb_info *cifs_sb; 193 struct cifs_sb_info *cifs_sb;
186 struct cifsTconInfo *pTcon; 194 struct cifsTconInfo *pTcon;
@@ -193,7 +201,7 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
193 buf->f_type = CIFS_MAGIC_NUMBER; 201 buf->f_type = CIFS_MAGIC_NUMBER;
194 202
195 /* instead could get the real value via SMB_QUERY_FS_ATTRIBUTE_INFO */ 203 /* instead could get the real value via SMB_QUERY_FS_ATTRIBUTE_INFO */
196 buf->f_namelen = PATH_MAX; /* PATH_MAX may be too long - it would 204 buf->f_namelen = PATH_MAX; /* PATH_MAX may be too long - it would
197 presumably be total path, but note 205 presumably be total path, but note
198 that some servers (includinng Samba 3) 206 that some servers (includinng Samba 3)
199 have a shorter maximum path */ 207 have a shorter maximum path */
@@ -217,8 +225,7 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
217 bypassed it because we detected that this was an older LANMAN sess */ 225 bypassed it because we detected that this was an older LANMAN sess */
218 if (rc) 226 if (rc)
219 rc = SMBOldQFSInfo(xid, pTcon, buf); 227 rc = SMBOldQFSInfo(xid, pTcon, buf);
220 /* 228 /* int f_type;
221 int f_type;
222 __fsid_t f_fsid; 229 __fsid_t f_fsid;
223 int f_namelen; */ 230 int f_namelen; */
224 /* BB get from info in tcon struct at mount time call to QFSAttrInfo */ 231 /* BB get from info in tcon struct at mount time call to QFSAttrInfo */
@@ -227,7 +234,7 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
227 longer available? */ 234 longer available? */
228} 235}
229 236
230static int cifs_permission(struct inode * inode, int mask, struct nameidata *nd) 237static int cifs_permission(struct inode *inode, int mask, struct nameidata *nd)
231{ 238{
232 struct cifs_sb_info *cifs_sb; 239 struct cifs_sb_info *cifs_sb;
233 240
@@ -235,10 +242,10 @@ static int cifs_permission(struct inode * inode, int mask, struct nameidata *nd)
235 242
236 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) { 243 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) {
237 return 0; 244 return 0;
238 } else /* file mode might have been restricted at mount time 245 } else /* file mode might have been restricted at mount time
239 on the client (above and beyond ACL on servers) for 246 on the client (above and beyond ACL on servers) for
240 servers which do not support setting and viewing mode bits, 247 servers which do not support setting and viewing mode bits,
241 so allowing client to check permissions is useful */ 248 so allowing client to check permissions is useful */
242 return generic_permission(inode, mask, NULL); 249 return generic_permission(inode, mask, NULL);
243} 250}
244 251
@@ -267,7 +274,7 @@ cifs_alloc_inode(struct super_block *sb)
267 cifs_inode->clientCanCacheRead = FALSE; 274 cifs_inode->clientCanCacheRead = FALSE;
268 cifs_inode->clientCanCacheAll = FALSE; 275 cifs_inode->clientCanCacheAll = FALSE;
269 cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ 276 cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */
270 277
271 /* Can not set i_flags here - they get immediately overwritten 278 /* Can not set i_flags here - they get immediately overwritten
272 to zero by the VFS */ 279 to zero by the VFS */
273/* cifs_inode->vfs_inode.i_flags = S_NOATIME | S_NOCMTIME;*/ 280/* cifs_inode->vfs_inode.i_flags = S_NOATIME | S_NOCMTIME;*/
@@ -309,26 +316,26 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
309 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) 316 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
310 seq_printf(s, ",posixpaths"); 317 seq_printf(s, ",posixpaths");
311 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) || 318 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) ||
312 !(cifs_sb->tcon->ses->capabilities & CAP_UNIX)) 319 !(cifs_sb->tcon->unix_ext))
313 seq_printf(s, ",uid=%d", cifs_sb->mnt_uid); 320 seq_printf(s, ",uid=%d", cifs_sb->mnt_uid);
314 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) || 321 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) ||
315 !(cifs_sb->tcon->ses->capabilities & CAP_UNIX)) 322 !(cifs_sb->tcon->unix_ext))
316 seq_printf(s, ",gid=%d", cifs_sb->mnt_gid); 323 seq_printf(s, ",gid=%d", cifs_sb->mnt_gid);
317 seq_printf(s, ",rsize=%d",cifs_sb->rsize); 324 seq_printf(s, ",rsize=%d", cifs_sb->rsize);
318 seq_printf(s, ",wsize=%d",cifs_sb->wsize); 325 seq_printf(s, ",wsize=%d", cifs_sb->wsize);
319 } 326 }
320 return 0; 327 return 0;
321} 328}
322 329
323#ifdef CONFIG_CIFS_QUOTA 330#ifdef CONFIG_CIFS_QUOTA
324int cifs_xquota_set(struct super_block * sb, int quota_type, qid_t qid, 331int cifs_xquota_set(struct super_block *sb, int quota_type, qid_t qid,
325 struct fs_disk_quota * pdquota) 332 struct fs_disk_quota *pdquota)
326{ 333{
327 int xid; 334 int xid;
328 int rc = 0; 335 int rc = 0;
329 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 336 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
330 struct cifsTconInfo *pTcon; 337 struct cifsTconInfo *pTcon;
331 338
332 if (cifs_sb) 339 if (cifs_sb)
333 pTcon = cifs_sb->tcon; 340 pTcon = cifs_sb->tcon;
334 else 341 else
@@ -337,7 +344,7 @@ int cifs_xquota_set(struct super_block * sb, int quota_type, qid_t qid,
337 344
338 xid = GetXid(); 345 xid = GetXid();
339 if (pTcon) { 346 if (pTcon) {
340 cFYI(1,("set type: 0x%x id: %d",quota_type,qid)); 347 cFYI(1, ("set type: 0x%x id: %d", quota_type, qid));
341 } else { 348 } else {
342 return -EIO; 349 return -EIO;
343 } 350 }
@@ -346,8 +353,8 @@ int cifs_xquota_set(struct super_block * sb, int quota_type, qid_t qid,
346 return rc; 353 return rc;
347} 354}
348 355
349int cifs_xquota_get(struct super_block * sb, int quota_type, qid_t qid, 356int cifs_xquota_get(struct super_block *sb, int quota_type, qid_t qid,
350 struct fs_disk_quota * pdquota) 357 struct fs_disk_quota *pdquota)
351{ 358{
352 int xid; 359 int xid;
353 int rc = 0; 360 int rc = 0;
@@ -361,7 +368,7 @@ int cifs_xquota_get(struct super_block * sb, int quota_type, qid_t qid,
361 368
362 xid = GetXid(); 369 xid = GetXid();
363 if (pTcon) { 370 if (pTcon) {
364 cFYI(1,("set type: 0x%x id: %d",quota_type,qid)); 371 cFYI(1, ("set type: 0x%x id: %d", quota_type, qid));
365 } else { 372 } else {
366 rc = -EIO; 373 rc = -EIO;
367 } 374 }
@@ -370,9 +377,9 @@ int cifs_xquota_get(struct super_block * sb, int quota_type, qid_t qid,
370 return rc; 377 return rc;
371} 378}
372 379
373int cifs_xstate_set(struct super_block * sb, unsigned int flags, int operation) 380int cifs_xstate_set(struct super_block *sb, unsigned int flags, int operation)
374{ 381{
375 int xid; 382 int xid;
376 int rc = 0; 383 int rc = 0;
377 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 384 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
378 struct cifsTconInfo *pTcon; 385 struct cifsTconInfo *pTcon;
@@ -384,7 +391,7 @@ int cifs_xstate_set(struct super_block * sb, unsigned int flags, int operation)
384 391
385 xid = GetXid(); 392 xid = GetXid();
386 if (pTcon) { 393 if (pTcon) {
387 cFYI(1,("flags: 0x%x operation: 0x%x",flags,operation)); 394 cFYI(1, ("flags: 0x%x operation: 0x%x", flags, operation));
388 } else { 395 } else {
389 rc = -EIO; 396 rc = -EIO;
390 } 397 }
@@ -393,7 +400,7 @@ int cifs_xstate_set(struct super_block * sb, unsigned int flags, int operation)
393 return rc; 400 return rc;
394} 401}
395 402
396int cifs_xstate_get(struct super_block * sb, struct fs_quota_stat *qstats) 403int cifs_xstate_get(struct super_block *sb, struct fs_quota_stat *qstats)
397{ 404{
398 int xid; 405 int xid;
399 int rc = 0; 406 int rc = 0;
@@ -407,7 +414,7 @@ int cifs_xstate_get(struct super_block * sb, struct fs_quota_stat *qstats)
407 } 414 }
408 xid = GetXid(); 415 xid = GetXid();
409 if (pTcon) { 416 if (pTcon) {
410 cFYI(1,("pqstats %p",qstats)); 417 cFYI(1, ("pqstats %p", qstats));
411 } else { 418 } else {
412 rc = -EIO; 419 rc = -EIO;
413 } 420 }
@@ -424,10 +431,10 @@ static struct quotactl_ops cifs_quotactl_ops = {
424}; 431};
425#endif 432#endif
426 433
427static void cifs_umount_begin(struct vfsmount * vfsmnt, int flags) 434static void cifs_umount_begin(struct vfsmount *vfsmnt, int flags)
428{ 435{
429 struct cifs_sb_info *cifs_sb; 436 struct cifs_sb_info *cifs_sb;
430 struct cifsTconInfo * tcon; 437 struct cifsTconInfo *tcon;
431 438
432 if (!(flags & MNT_FORCE)) 439 if (!(flags & MNT_FORCE))
433 return; 440 return;
@@ -445,9 +452,8 @@ static void cifs_umount_begin(struct vfsmount * vfsmnt, int flags)
445 452
446 /* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */ 453 /* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */
447 /* cancel_notify_requests(tcon); */ 454 /* cancel_notify_requests(tcon); */
448 if (tcon->ses && tcon->ses->server) 455 if (tcon->ses && tcon->ses->server) {
449 { 456 cFYI(1, ("wake up tasks now - umount begin not complete"));
450 cFYI(1,("wake up tasks now - umount begin not complete"));
451 wake_up_all(&tcon->ses->server->request_q); 457 wake_up_all(&tcon->ses->server->request_q);
452 wake_up_all(&tcon->ses->server->response_q); 458 wake_up_all(&tcon->ses->server->response_q);
453 msleep(1); /* yield */ 459 msleep(1); /* yield */
@@ -480,10 +486,11 @@ static const struct super_operations cifs_super_ops = {
480 .statfs = cifs_statfs, 486 .statfs = cifs_statfs,
481 .alloc_inode = cifs_alloc_inode, 487 .alloc_inode = cifs_alloc_inode,
482 .destroy_inode = cifs_destroy_inode, 488 .destroy_inode = cifs_destroy_inode,
483/* .drop_inode = generic_delete_inode, 489/* .drop_inode = generic_delete_inode,
484 .delete_inode = cifs_delete_inode, *//* Do not need the above two functions 490 .delete_inode = cifs_delete_inode, */ /* Do not need above two
485 unless later we add lazy close of inodes or unless the kernel forgets to call 491 functions unless later we add lazy close of inodes or unless the
486 us with the same number of releases (closes) as opens */ 492 kernel forgets to call us with the same number of releases (closes)
493 as opens */
487 .show_options = cifs_show_options, 494 .show_options = cifs_show_options,
488 .umount_begin = cifs_umount_begin, 495 .umount_begin = cifs_umount_begin,
489 .remount_fs = cifs_remount, 496 .remount_fs = cifs_remount,
@@ -586,11 +593,11 @@ const struct inode_operations cifs_file_inode_ops = {
586 .getxattr = cifs_getxattr, 593 .getxattr = cifs_getxattr,
587 .listxattr = cifs_listxattr, 594 .listxattr = cifs_listxattr,
588 .removexattr = cifs_removexattr, 595 .removexattr = cifs_removexattr,
589#endif 596#endif
590}; 597};
591 598
592const struct inode_operations cifs_symlink_inode_ops = { 599const struct inode_operations cifs_symlink_inode_ops = {
593 .readlink = generic_readlink, 600 .readlink = generic_readlink,
594 .follow_link = cifs_follow_link, 601 .follow_link = cifs_follow_link,
595 .put_link = cifs_put_link, 602 .put_link = cifs_put_link,
596 .permission = cifs_permission, 603 .permission = cifs_permission,
@@ -602,7 +609,7 @@ const struct inode_operations cifs_symlink_inode_ops = {
602 .getxattr = cifs_getxattr, 609 .getxattr = cifs_getxattr,
603 .listxattr = cifs_listxattr, 610 .listxattr = cifs_listxattr,
604 .removexattr = cifs_removexattr, 611 .removexattr = cifs_removexattr,
605#endif 612#endif
606}; 613};
607 614
608const struct file_operations cifs_file_ops = { 615const struct file_operations cifs_file_ops = {
@@ -628,7 +635,7 @@ const struct file_operations cifs_file_ops = {
628}; 635};
629 636
630const struct file_operations cifs_file_direct_ops = { 637const struct file_operations cifs_file_direct_ops = {
631 /* no mmap, no aio, no readv - 638 /* no mmap, no aio, no readv -
632 BB reevaluate whether they can be done with directio, no cache */ 639 BB reevaluate whether they can be done with directio, no cache */
633 .read = cifs_user_read, 640 .read = cifs_user_read,
634 .write = cifs_user_write, 641 .write = cifs_user_write,
@@ -668,7 +675,7 @@ const struct file_operations cifs_file_nobrl_ops = {
668}; 675};
669 676
670const struct file_operations cifs_file_direct_nobrl_ops = { 677const struct file_operations cifs_file_direct_nobrl_ops = {
671 /* no mmap, no aio, no readv - 678 /* no mmap, no aio, no readv -
672 BB reevaluate whether they can be done with directio, no cache */ 679 BB reevaluate whether they can be done with directio, no cache */
673 .read = cifs_user_read, 680 .read = cifs_user_read,
674 .write = cifs_user_write, 681 .write = cifs_user_write,
@@ -693,11 +700,11 @@ const struct file_operations cifs_dir_ops = {
693#ifdef CONFIG_CIFS_EXPERIMENTAL 700#ifdef CONFIG_CIFS_EXPERIMENTAL
694 .dir_notify = cifs_dir_notify, 701 .dir_notify = cifs_dir_notify,
695#endif /* CONFIG_CIFS_EXPERIMENTAL */ 702#endif /* CONFIG_CIFS_EXPERIMENTAL */
696 .ioctl = cifs_ioctl, 703 .ioctl = cifs_ioctl,
697}; 704};
698 705
699static void 706static void
700cifs_init_once(void *inode, struct kmem_cache * cachep, unsigned long flags) 707cifs_init_once(void *inode, struct kmem_cache *cachep, unsigned long flags)
701{ 708{
702 struct cifsInodeInfo *cifsi = inode; 709 struct cifsInodeInfo *cifsi = inode;
703 710
@@ -749,7 +756,7 @@ cifs_init_request_bufs(void)
749 cifs_min_rcv = 1; 756 cifs_min_rcv = 1;
750 else if (cifs_min_rcv > 64) { 757 else if (cifs_min_rcv > 64) {
751 cifs_min_rcv = 64; 758 cifs_min_rcv = 64;
752 cERROR(1,("cifs_min_rcv set to maximum (64)")); 759 cERROR(1, ("cifs_min_rcv set to maximum (64)"));
753 } 760 }
754 761
755 cifs_req_poolp = mempool_create_slab_pool(cifs_min_rcv, 762 cifs_req_poolp = mempool_create_slab_pool(cifs_min_rcv,
@@ -762,25 +769,25 @@ cifs_init_request_bufs(void)
762 /* MAX_CIFS_SMALL_BUFFER_SIZE bytes is enough for most SMB responses and 769 /* MAX_CIFS_SMALL_BUFFER_SIZE bytes is enough for most SMB responses and
763 almost all handle based requests (but not write response, nor is it 770 almost all handle based requests (but not write response, nor is it
764 sufficient for path based requests). A smaller size would have 771 sufficient for path based requests). A smaller size would have
765 been more efficient (compacting multiple slab items on one 4k page) 772 been more efficient (compacting multiple slab items on one 4k page)
766 for the case in which debug was on, but this larger size allows 773 for the case in which debug was on, but this larger size allows
767 more SMBs to use small buffer alloc and is still much more 774 more SMBs to use small buffer alloc and is still much more
768 efficient to alloc 1 per page off the slab compared to 17K (5page) 775 efficient to alloc 1 per page off the slab compared to 17K (5page)
769 alloc of large cifs buffers even when page debugging is on */ 776 alloc of large cifs buffers even when page debugging is on */
770 cifs_sm_req_cachep = kmem_cache_create("cifs_small_rq", 777 cifs_sm_req_cachep = kmem_cache_create("cifs_small_rq",
771 MAX_CIFS_SMALL_BUFFER_SIZE, 0, SLAB_HWCACHE_ALIGN, 778 MAX_CIFS_SMALL_BUFFER_SIZE, 0, SLAB_HWCACHE_ALIGN,
772 NULL, NULL); 779 NULL, NULL);
773 if (cifs_sm_req_cachep == NULL) { 780 if (cifs_sm_req_cachep == NULL) {
774 mempool_destroy(cifs_req_poolp); 781 mempool_destroy(cifs_req_poolp);
775 kmem_cache_destroy(cifs_req_cachep); 782 kmem_cache_destroy(cifs_req_cachep);
776 return -ENOMEM; 783 return -ENOMEM;
777 } 784 }
778 785
779 if (cifs_min_small < 2) 786 if (cifs_min_small < 2)
780 cifs_min_small = 2; 787 cifs_min_small = 2;
781 else if (cifs_min_small > 256) { 788 else if (cifs_min_small > 256) {
782 cifs_min_small = 256; 789 cifs_min_small = 256;
783 cFYI(1,("cifs_min_small set to maximum (256)")); 790 cFYI(1, ("cifs_min_small set to maximum (256)"));
784 } 791 }
785 792
786 cifs_sm_req_poolp = mempool_create_slab_pool(cifs_min_small, 793 cifs_sm_req_poolp = mempool_create_slab_pool(cifs_min_small,
@@ -841,42 +848,43 @@ cifs_destroy_mids(void)
841 kmem_cache_destroy(cifs_oplock_cachep); 848 kmem_cache_destroy(cifs_oplock_cachep);
842} 849}
843 850
844static int cifs_oplock_thread(void * dummyarg) 851static int cifs_oplock_thread(void *dummyarg)
845{ 852{
846 struct oplock_q_entry * oplock_item; 853 struct oplock_q_entry *oplock_item;
847 struct cifsTconInfo *pTcon; 854 struct cifsTconInfo *pTcon;
848 struct inode * inode; 855 struct inode *inode;
849 __u16 netfid; 856 __u16 netfid;
850 int rc; 857 int rc;
851 858
852 set_freezable(); 859 set_freezable();
853 do { 860 do {
854 if (try_to_freeze()) 861 if (try_to_freeze())
855 continue; 862 continue;
856 863
857 spin_lock(&GlobalMid_Lock); 864 spin_lock(&GlobalMid_Lock);
858 if (list_empty(&GlobalOplock_Q)) { 865 if (list_empty(&GlobalOplock_Q)) {
859 spin_unlock(&GlobalMid_Lock); 866 spin_unlock(&GlobalMid_Lock);
860 set_current_state(TASK_INTERRUPTIBLE); 867 set_current_state(TASK_INTERRUPTIBLE);
861 schedule_timeout(39*HZ); 868 schedule_timeout(39*HZ);
862 } else { 869 } else {
863 oplock_item = list_entry(GlobalOplock_Q.next, 870 oplock_item = list_entry(GlobalOplock_Q.next,
864 struct oplock_q_entry, qhead); 871 struct oplock_q_entry, qhead);
865 if (oplock_item) { 872 if (oplock_item) {
866 cFYI(1,("found oplock item to write out")); 873 cFYI(1, ("found oplock item to write out"));
867 pTcon = oplock_item->tcon; 874 pTcon = oplock_item->tcon;
868 inode = oplock_item->pinode; 875 inode = oplock_item->pinode;
869 netfid = oplock_item->netfid; 876 netfid = oplock_item->netfid;
870 spin_unlock(&GlobalMid_Lock); 877 spin_unlock(&GlobalMid_Lock);
871 DeleteOplockQEntry(oplock_item); 878 DeleteOplockQEntry(oplock_item);
872 /* can not grab inode sem here since it would 879 /* can not grab inode sem here since it would
873 deadlock when oplock received on delete 880 deadlock when oplock received on delete
874 since vfs_unlink holds the i_mutex across 881 since vfs_unlink holds the i_mutex across
875 the call */ 882 the call */
876 /* mutex_lock(&inode->i_mutex);*/ 883 /* mutex_lock(&inode->i_mutex);*/
877 if (S_ISREG(inode->i_mode)) { 884 if (S_ISREG(inode->i_mode)) {
878 rc = filemap_fdatawrite(inode->i_mapping); 885 rc = filemap_fdatawrite(inode->i_mapping);
879 if (CIFS_I(inode)->clientCanCacheRead == 0) { 886 if (CIFS_I(inode)->clientCanCacheRead
887 == 0) {
880 filemap_fdatawait(inode->i_mapping); 888 filemap_fdatawait(inode->i_mapping);
881 invalidate_remote_inode(inode); 889 invalidate_remote_inode(inode);
882 } 890 }
@@ -885,20 +893,22 @@ static int cifs_oplock_thread(void * dummyarg)
885 /* mutex_unlock(&inode->i_mutex);*/ 893 /* mutex_unlock(&inode->i_mutex);*/
886 if (rc) 894 if (rc)
887 CIFS_I(inode)->write_behind_rc = rc; 895 CIFS_I(inode)->write_behind_rc = rc;
888 cFYI(1,("Oplock flush inode %p rc %d",inode,rc)); 896 cFYI(1, ("Oplock flush inode %p rc %d",
889 897 inode, rc));
890 /* releasing a stale oplock after recent reconnection 898
891 of smb session using a now incorrect file 899 /* releasing stale oplock after recent reconnect
892 handle is not a data integrity issue but do 900 of smb session using a now incorrect file
893 not bother sending an oplock release if session 901 handle is not a data integrity issue but do
894 to server still is disconnected since oplock 902 not bother sending an oplock release if session
903 to server still is disconnected since oplock
895 already released by the server in that case */ 904 already released by the server in that case */
896 if (pTcon->tidStatus != CifsNeedReconnect) { 905 if (pTcon->tidStatus != CifsNeedReconnect) {
897 rc = CIFSSMBLock(0, pTcon, netfid, 906 rc = CIFSSMBLock(0, pTcon, netfid,
898 0 /* len */ , 0 /* offset */, 0, 907 0 /* len */ , 0 /* offset */, 0,
899 0, LOCKING_ANDX_OPLOCK_RELEASE, 908 0, LOCKING_ANDX_OPLOCK_RELEASE,
900 0 /* wait flag */); 909 0 /* wait flag */);
901 cFYI(1,("Oplock release rc = %d ",rc)); 910 cFYI(1,
911 ("Oplock release rc = %d ", rc));
902 } 912 }
903 } else 913 } else
904 spin_unlock(&GlobalMid_Lock); 914 spin_unlock(&GlobalMid_Lock);
@@ -910,7 +920,7 @@ static int cifs_oplock_thread(void * dummyarg)
910 return 0; 920 return 0;
911} 921}
912 922
913static int cifs_dnotify_thread(void * dummyarg) 923static int cifs_dnotify_thread(void *dummyarg)
914{ 924{
915 struct list_head *tmp; 925 struct list_head *tmp;
916 struct cifsSesInfo *ses; 926 struct cifsSesInfo *ses;
@@ -925,9 +935,9 @@ static int cifs_dnotify_thread(void * dummyarg)
925 to be woken up and wakeq so the 935 to be woken up and wakeq so the
926 thread can wake up and error out */ 936 thread can wake up and error out */
927 list_for_each(tmp, &GlobalSMBSessionList) { 937 list_for_each(tmp, &GlobalSMBSessionList) {
928 ses = list_entry(tmp, struct cifsSesInfo, 938 ses = list_entry(tmp, struct cifsSesInfo,
929 cifsSessionList); 939 cifsSessionList);
930 if (ses && ses->server && 940 if (ses && ses->server &&
931 atomic_read(&ses->server->inFlight)) 941 atomic_read(&ses->server->inFlight))
932 wake_up_all(&ses->server->response_q); 942 wake_up_all(&ses->server->response_q);
933 } 943 }
@@ -951,13 +961,13 @@ init_cifs(void)
951#ifdef CONFIG_CIFS_EXPERIMENTAL 961#ifdef CONFIG_CIFS_EXPERIMENTAL
952 INIT_LIST_HEAD(&GlobalDnotifyReqList); 962 INIT_LIST_HEAD(&GlobalDnotifyReqList);
953 INIT_LIST_HEAD(&GlobalDnotifyRsp_Q); 963 INIT_LIST_HEAD(&GlobalDnotifyRsp_Q);
954#endif 964#endif
955/* 965/*
956 * Initialize Global counters 966 * Initialize Global counters
957 */ 967 */
958 atomic_set(&sesInfoAllocCount, 0); 968 atomic_set(&sesInfoAllocCount, 0);
959 atomic_set(&tconInfoAllocCount, 0); 969 atomic_set(&tconInfoAllocCount, 0);
960 atomic_set(&tcpSesAllocCount,0); 970 atomic_set(&tcpSesAllocCount, 0);
961 atomic_set(&tcpSesReconnectCount, 0); 971 atomic_set(&tcpSesReconnectCount, 0);
962 atomic_set(&tconInfoReconnectCount, 0); 972 atomic_set(&tconInfoReconnectCount, 0);
963 973
@@ -978,10 +988,10 @@ init_cifs(void)
978 988
979 if (cifs_max_pending < 2) { 989 if (cifs_max_pending < 2) {
980 cifs_max_pending = 2; 990 cifs_max_pending = 2;
981 cFYI(1,("cifs_max_pending set to min of 2")); 991 cFYI(1, ("cifs_max_pending set to min of 2"));
982 } else if (cifs_max_pending > 256) { 992 } else if (cifs_max_pending > 256) {
983 cifs_max_pending = 256; 993 cifs_max_pending = 256;
984 cFYI(1,("cifs_max_pending set to max of 256")); 994 cFYI(1, ("cifs_max_pending set to max of 256"));
985 } 995 }
986 996
987 rc = cifs_init_inodecache(); 997 rc = cifs_init_inodecache();
@@ -1003,14 +1013,14 @@ init_cifs(void)
1003 oplockThread = kthread_run(cifs_oplock_thread, NULL, "cifsoplockd"); 1013 oplockThread = kthread_run(cifs_oplock_thread, NULL, "cifsoplockd");
1004 if (IS_ERR(oplockThread)) { 1014 if (IS_ERR(oplockThread)) {
1005 rc = PTR_ERR(oplockThread); 1015 rc = PTR_ERR(oplockThread);
1006 cERROR(1,("error %d create oplock thread", rc)); 1016 cERROR(1, ("error %d create oplock thread", rc));
1007 goto out_unregister_filesystem; 1017 goto out_unregister_filesystem;
1008 } 1018 }
1009 1019
1010 dnotifyThread = kthread_run(cifs_dnotify_thread, NULL, "cifsdnotifyd"); 1020 dnotifyThread = kthread_run(cifs_dnotify_thread, NULL, "cifsdnotifyd");
1011 if (IS_ERR(dnotifyThread)) { 1021 if (IS_ERR(dnotifyThread)) {
1012 rc = PTR_ERR(dnotifyThread); 1022 rc = PTR_ERR(dnotifyThread);
1013 cERROR(1,("error %d create dnotify thread", rc)); 1023 cERROR(1, ("error %d create dnotify thread", rc));
1014 goto out_stop_oplock_thread; 1024 goto out_stop_oplock_thread;
1015 } 1025 }
1016 1026
@@ -1036,7 +1046,7 @@ init_cifs(void)
1036static void __exit 1046static void __exit
1037exit_cifs(void) 1047exit_cifs(void)
1038{ 1048{
1039 cFYI(0, ("In unregister ie exit_cifs")); 1049 cFYI(0, ("exit_cifs"));
1040#ifdef CONFIG_PROC_FS 1050#ifdef CONFIG_PROC_FS
1041 cifs_proc_clean(); 1051 cifs_proc_clean();
1042#endif 1052#endif
@@ -1049,9 +1059,10 @@ exit_cifs(void)
1049} 1059}
1050 1060
1051MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>"); 1061MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>");
1052MODULE_LICENSE("GPL"); /* combination of LGPL + GPL source behaves as GPL */ 1062MODULE_LICENSE("GPL"); /* combination of LGPL + GPL source behaves as GPL */
1053MODULE_DESCRIPTION 1063MODULE_DESCRIPTION
1054 ("VFS to access servers complying with the SNIA CIFS Specification e.g. Samba and Windows"); 1064 ("VFS to access servers complying with the SNIA CIFS Specification "
1065 "e.g. Samba and Windows");
1055MODULE_VERSION(CIFS_VERSION); 1066MODULE_VERSION(CIFS_VERSION);
1056module_init(init_cifs) 1067module_init(init_cifs)
1057module_exit(exit_cifs) 1068module_exit(exit_cifs)
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index c235d32ad4a8..a20de77a3856 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -16,7 +16,7 @@
16 * 16 *
17 * You should have received a copy of the GNU Lesser General Public License 17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software 18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 21
22#ifndef _CIFSFS_H 22#ifndef _CIFSFS_H
@@ -43,9 +43,9 @@ extern void cifs_read_inode(struct inode *);
43 43
44/* Functions related to inodes */ 44/* Functions related to inodes */
45extern const struct inode_operations cifs_dir_inode_ops; 45extern const struct inode_operations cifs_dir_inode_ops;
46extern int cifs_create(struct inode *, struct dentry *, int, 46extern int cifs_create(struct inode *, struct dentry *, int,
47 struct nameidata *); 47 struct nameidata *);
48extern struct dentry * cifs_lookup(struct inode *, struct dentry *, 48extern struct dentry *cifs_lookup(struct inode *, struct dentry *,
49 struct nameidata *); 49 struct nameidata *);
50extern int cifs_unlink(struct inode *, struct dentry *); 50extern int cifs_unlink(struct inode *, struct dentry *);
51extern int cifs_hardlink(struct dentry *, struct inode *, struct dentry *); 51extern int cifs_hardlink(struct dentry *, struct inode *, struct dentry *);
@@ -63,16 +63,16 @@ extern const struct inode_operations cifs_symlink_inode_ops;
63 63
64/* Functions related to files and directories */ 64/* Functions related to files and directories */
65extern const struct file_operations cifs_file_ops; 65extern const struct file_operations cifs_file_ops;
66extern const struct file_operations cifs_file_direct_ops; /* if directio mount */ 66extern const struct file_operations cifs_file_direct_ops; /* if directio mnt */
67extern const struct file_operations cifs_file_nobrl_ops; 67extern const struct file_operations cifs_file_nobrl_ops;
68extern const struct file_operations cifs_file_direct_nobrl_ops; /* if directio mount */ 68extern const struct file_operations cifs_file_direct_nobrl_ops; /* no brlocks */
69extern int cifs_open(struct inode *inode, struct file *file); 69extern int cifs_open(struct inode *inode, struct file *file);
70extern int cifs_close(struct inode *inode, struct file *file); 70extern int cifs_close(struct inode *inode, struct file *file);
71extern int cifs_closedir(struct inode *inode, struct file *file); 71extern int cifs_closedir(struct inode *inode, struct file *file);
72extern ssize_t cifs_user_read(struct file *file, char __user *read_data, 72extern ssize_t cifs_user_read(struct file *file, char __user *read_data,
73 size_t read_size, loff_t * poffset); 73 size_t read_size, loff_t *poffset);
74extern ssize_t cifs_user_write(struct file *file, const char __user *write_data, 74extern ssize_t cifs_user_write(struct file *file, const char __user *write_data,
75 size_t write_size, loff_t * poffset); 75 size_t write_size, loff_t *poffset);
76extern int cifs_lock(struct file *, int, struct file_lock *); 76extern int cifs_lock(struct file *, int, struct file_lock *);
77extern int cifs_fsync(struct file *, struct dentry *, int); 77extern int cifs_fsync(struct file *, struct dentry *, int);
78extern int cifs_flush(struct file *, fl_owner_t id); 78extern int cifs_flush(struct file *, fl_owner_t id);
@@ -88,8 +88,9 @@ extern struct dentry_operations cifs_ci_dentry_ops;
88 88
89/* Functions related to symlinks */ 89/* Functions related to symlinks */
90extern void *cifs_follow_link(struct dentry *direntry, struct nameidata *nd); 90extern void *cifs_follow_link(struct dentry *direntry, struct nameidata *nd);
91extern void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *); 91extern void cifs_put_link(struct dentry *direntry,
92extern int cifs_readlink(struct dentry *direntry, char __user *buffer, 92 struct nameidata *nd, void *);
93extern int cifs_readlink(struct dentry *direntry, char __user *buffer,
93 int buflen); 94 int buflen);
94extern int cifs_symlink(struct inode *inode, struct dentry *direntry, 95extern int cifs_symlink(struct inode *inode, struct dentry *direntry,
95 const char *symname); 96 const char *symname);
@@ -98,7 +99,7 @@ extern int cifs_setxattr(struct dentry *, const char *, const void *,
98 size_t, int); 99 size_t, int);
99extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); 100extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
100extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); 101extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
101extern int cifs_ioctl (struct inode * inode, struct file * filep, 102extern int cifs_ioctl (struct inode *inode, struct file *filep,
102 unsigned int command, unsigned long arg); 103 unsigned int command, unsigned long arg);
103#define CIFS_VERSION "1.49" 104#define CIFS_VERSION "1.50"
104#endif /* _CIFSFS_H */ 105#endif /* _CIFSFS_H */
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 23655de2f4a4..b98742fc3b5a 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/cifsglob.h 2 * fs/cifs/cifsglob.h
3 * 3 *
4 * Copyright (C) International Business Machines Corp., 2002,2006 4 * Copyright (C) International Business Machines Corp., 2002,2007
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * Jeremy Allison (jra@samba.org) 6 * Jeremy Allison (jra@samba.org)
7 * 7 *
@@ -14,7 +14,7 @@
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
16 * the GNU Lesser General Public License for more details. 16 * the GNU Lesser General Public License for more details.
17 * 17 *
18 */ 18 */
19#include <linux/in.h> 19#include <linux/in.h>
20#include <linux/in6.h> 20#include <linux/in6.h>
@@ -28,7 +28,7 @@
28 28
29#define MAX_TREE_SIZE 2 + MAX_SERVER_SIZE + 1 + MAX_SHARE_SIZE + 1 29#define MAX_TREE_SIZE 2 + MAX_SERVER_SIZE + 1 + MAX_SHARE_SIZE + 1
30#define MAX_SERVER_SIZE 15 30#define MAX_SERVER_SIZE 15
31#define MAX_SHARE_SIZE 64 /* used to be 20 - this should still be enough */ 31#define MAX_SHARE_SIZE 64 /* used to be 20, this should still be enough */
32#define MAX_USERNAME_SIZE 32 /* 32 is to allow for 15 char names + null 32#define MAX_USERNAME_SIZE 32 /* 32 is to allow for 15 char names + null
33 termination then *2 for unicode versions */ 33 termination then *2 for unicode versions */
34#define MAX_PASSWORD_SIZE 16 34#define MAX_PASSWORD_SIZE 16
@@ -38,13 +38,13 @@
38/* 38/*
39 * MAX_REQ is the maximum number of requests that WE will send 39 * MAX_REQ is the maximum number of requests that WE will send
40 * on one socket concurently. It also matches the most common 40 * on one socket concurently. It also matches the most common
41 * value of max multiplex returned by servers. We may 41 * value of max multiplex returned by servers. We may
42 * eventually want to use the negotiated value (in case 42 * eventually want to use the negotiated value (in case
43 * future servers can handle more) when we are more confident that 43 * future servers can handle more) when we are more confident that
44 * we will not have problems oveloading the socket with pending 44 * we will not have problems oveloading the socket with pending
45 * write data. 45 * write data.
46 */ 46 */
47#define CIFS_MAX_REQ 50 47#define CIFS_MAX_REQ 50
48 48
49#define SERVER_NAME_LENGTH 15 49#define SERVER_NAME_LENGTH 15
50#define SERVER_NAME_LEN_WITH_NULL (SERVER_NAME_LENGTH + 1) 50#define SERVER_NAME_LEN_WITH_NULL (SERVER_NAME_LENGTH + 1)
@@ -104,6 +104,17 @@ enum protocolEnum {
104 /* Netbios frames protocol not supported at this time */ 104 /* Netbios frames protocol not supported at this time */
105}; 105};
106 106
107struct mac_key {
108 unsigned int len;
109 union {
110 char ntlm[CIFS_SESS_KEY_SIZE + 16];
111 struct {
112 char key[16];
113 struct ntlmv2_resp resp;
114 } ntlmv2;
115 } data;
116};
117
107/* 118/*
108 ***************************************************************** 119 *****************************************************************
109 * Except the CIFS PDUs themselves all the 120 * Except the CIFS PDUs themselves all the
@@ -120,13 +131,13 @@ struct TCP_Server_Info {
120 struct sockaddr_in sockAddr; 131 struct sockaddr_in sockAddr;
121 struct sockaddr_in6 sockAddr6; 132 struct sockaddr_in6 sockAddr6;
122 } addr; 133 } addr;
123 wait_queue_head_t response_q; 134 wait_queue_head_t response_q;
124 wait_queue_head_t request_q; /* if more than maxmpx to srvr must block*/ 135 wait_queue_head_t request_q; /* if more than maxmpx to srvr must block*/
125 struct list_head pending_mid_q; 136 struct list_head pending_mid_q;
126 void *Server_NlsInfo; /* BB - placeholder for future NLS info */ 137 void *Server_NlsInfo; /* BB - placeholder for future NLS info */
127 unsigned short server_codepage; /* codepage for the server */ 138 unsigned short server_codepage; /* codepage for the server */
128 unsigned long ip_address; /* IP addr for the server if known */ 139 unsigned long ip_address; /* IP addr for the server if known */
129 enum protocolEnum protocolType; 140 enum protocolEnum protocolType;
130 char versionMajor; 141 char versionMajor;
131 char versionMinor; 142 char versionMinor;
132 unsigned svlocal:1; /* local server or remote */ 143 unsigned svlocal:1; /* local server or remote */
@@ -159,14 +170,15 @@ struct TCP_Server_Info {
159 /* 16th byte of RFC1001 workstation name is always null */ 170 /* 16th byte of RFC1001 workstation name is always null */
160 char workstation_RFC1001_name[SERVER_NAME_LEN_WITH_NULL]; 171 char workstation_RFC1001_name[SERVER_NAME_LEN_WITH_NULL];
161 __u32 sequence_number; /* needed for CIFS PDU signature */ 172 __u32 sequence_number; /* needed for CIFS PDU signature */
162 char mac_signing_key[CIFS_SESS_KEY_SIZE + 16]; 173 struct mac_key mac_signing_key;
174 char ntlmv2_hash[16];
163 unsigned long lstrp; /* when we got last response from this server */ 175 unsigned long lstrp; /* when we got last response from this server */
164}; 176};
165 177
166/* 178/*
167 * The following is our shortcut to user information. We surface the uid, 179 * The following is our shortcut to user information. We surface the uid,
168 * and name. We always get the password on the fly in case it 180 * and name. We always get the password on the fly in case it
169 * has changed. We also hang a list of sessions owned by this user off here. 181 * has changed. We also hang a list of sessions owned by this user off here.
170 */ 182 */
171struct cifsUidInfo { 183struct cifsUidInfo {
172 struct list_head userList; 184 struct list_head userList;
@@ -197,11 +209,11 @@ struct cifsSesInfo {
197 int Suid; /* remote smb uid */ 209 int Suid; /* remote smb uid */
198 uid_t linux_uid; /* local Linux uid */ 210 uid_t linux_uid; /* local Linux uid */
199 int capabilities; 211 int capabilities;
200 char serverName[SERVER_NAME_LEN_WITH_NULL * 2]; /* BB make bigger for 212 char serverName[SERVER_NAME_LEN_WITH_NULL * 2]; /* BB make bigger for
201 TCP names - will ipv6 and sctp addresses fit? */ 213 TCP names - will ipv6 and sctp addresses fit? */
202 char userName[MAX_USERNAME_SIZE + 1]; 214 char userName[MAX_USERNAME_SIZE + 1];
203 char * domainName; 215 char *domainName;
204 char * password; 216 char *password;
205}; 217};
206/* no more than one of the following three session flags may be set */ 218/* no more than one of the following three session flags may be set */
207#define CIFS_SES_NT4 1 219#define CIFS_SES_NT4 1
@@ -213,7 +225,7 @@ struct cifsSesInfo {
213#define CIFS_SES_LANMAN 8 225#define CIFS_SES_LANMAN 8
214/* 226/*
215 * there is one of these for each connection to a resource on a particular 227 * there is one of these for each connection to a resource on a particular
216 * session 228 * session
217 */ 229 */
218struct cifsTconInfo { 230struct cifsTconInfo {
219 struct list_head cifsConnectionList; 231 struct list_head cifsConnectionList;
@@ -269,7 +281,9 @@ struct cifsTconInfo {
269 FILE_SYSTEM_UNIX_INFO fsUnixInfo; 281 FILE_SYSTEM_UNIX_INFO fsUnixInfo;
270 unsigned retry:1; 282 unsigned retry:1;
271 unsigned nocase:1; 283 unsigned nocase:1;
272 /* BB add field for back pointer to sb struct? */ 284 unsigned unix_ext:1; /* if off disable Linux extensions to CIFS protocol
285 for this mount even if server would support */
286 /* BB add field for back pointer to sb struct(s)? */
273}; 287};
274 288
275/* 289/*
@@ -291,9 +305,9 @@ struct cifs_search_info {
291 __u16 entries_in_buffer; 305 __u16 entries_in_buffer;
292 __u16 info_level; 306 __u16 info_level;
293 __u32 resume_key; 307 __u32 resume_key;
294 char * ntwrk_buf_start; 308 char *ntwrk_buf_start;
295 char * srch_entries_start; 309 char *srch_entries_start;
296 char * presume_name; 310 char *presume_name;
297 unsigned int resume_name_len; 311 unsigned int resume_name_len;
298 unsigned endOfSearch:1; 312 unsigned endOfSearch:1;
299 unsigned emptyDir:1; 313 unsigned emptyDir:1;
@@ -309,15 +323,15 @@ struct cifsFileInfo {
309 __u16 netfid; /* file id from remote */ 323 __u16 netfid; /* file id from remote */
310 /* BB add lock scope info here if needed */ ; 324 /* BB add lock scope info here if needed */ ;
311 /* lock scope id (0 if none) */ 325 /* lock scope id (0 if none) */
312 struct file * pfile; /* needed for writepage */ 326 struct file *pfile; /* needed for writepage */
313 struct inode * pInode; /* needed for oplock break */ 327 struct inode *pInode; /* needed for oplock break */
314 struct mutex lock_mutex; 328 struct mutex lock_mutex;
315 struct list_head llist; /* list of byte range locks we have. */ 329 struct list_head llist; /* list of byte range locks we have. */
316 unsigned closePend:1; /* file is marked to close */ 330 unsigned closePend:1; /* file is marked to close */
317 unsigned invalidHandle:1; /* file closed via session abend */ 331 unsigned invalidHandle:1; /* file closed via session abend */
318 atomic_t wrtPending; /* handle in use - defer close */ 332 atomic_t wrtPending; /* handle in use - defer close */
319 struct semaphore fh_sem; /* prevents reopen race after dead ses*/ 333 struct semaphore fh_sem; /* prevents reopen race after dead ses*/
320 char * search_resume_name; /* BB removeme BB */ 334 char *search_resume_name; /* BB removeme BB */
321 struct cifs_search_info srch_inf; 335 struct cifs_search_info srch_inf;
322}; 336};
323 337
@@ -327,7 +341,7 @@ struct cifsFileInfo {
327 341
328struct cifsInodeInfo { 342struct cifsInodeInfo {
329 struct list_head lockList; 343 struct list_head lockList;
330 /* BB add in lists for dirty pages - i.e. write caching info for oplock */ 344 /* BB add in lists for dirty pages i.e. write caching info for oplock */
331 struct list_head openFileList; 345 struct list_head openFileList;
332 int write_behind_rc; 346 int write_behind_rc;
333 __u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */ 347 __u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */
@@ -381,9 +395,9 @@ static inline void cifs_stats_bytes_read(struct cifsTconInfo *tcon,
381} 395}
382#else 396#else
383 397
384#define cifs_stats_inc(field) do {} while(0) 398#define cifs_stats_inc(field) do {} while (0)
385#define cifs_stats_bytes_written(tcon, bytes) do {} while(0) 399#define cifs_stats_bytes_written(tcon, bytes) do {} while (0)
386#define cifs_stats_bytes_read(tcon, bytes) do {} while(0) 400#define cifs_stats_bytes_read(tcon, bytes) do {} while (0)
387 401
388#endif 402#endif
389 403
@@ -410,8 +424,8 @@ struct mid_q_entry {
410 424
411struct oplock_q_entry { 425struct oplock_q_entry {
412 struct list_head qhead; 426 struct list_head qhead;
413 struct inode * pinode; 427 struct inode *pinode;
414 struct cifsTconInfo * tcon; 428 struct cifsTconInfo *tcon;
415 __u16 netfid; 429 __u16 netfid;
416}; 430};
417 431
@@ -426,7 +440,7 @@ struct dir_notify_req {
426 __u16 netfid; 440 __u16 netfid;
427 __u32 filter; /* CompletionFilter (for multishot) */ 441 __u32 filter; /* CompletionFilter (for multishot) */
428 int multishot; 442 int multishot;
429 struct file * pfile; 443 struct file *pfile;
430}; 444};
431 445
432#define MID_FREE 0 446#define MID_FREE 0
@@ -464,7 +478,7 @@ require use of the stronger protocol */
464#define CIFSSEC_MUST_LANMAN 0x10010 478#define CIFSSEC_MUST_LANMAN 0x10010
465#define CIFSSEC_MUST_PLNTXT 0x20020 479#define CIFSSEC_MUST_PLNTXT 0x20020
466#define CIFSSEC_MASK 0x37037 /* current flags supported if weak */ 480#define CIFSSEC_MASK 0x37037 /* current flags supported if weak */
467#else 481#else
468#define CIFSSEC_MASK 0x07007 /* flags supported if no weak config */ 482#define CIFSSEC_MASK 0x07007 /* flags supported if no weak config */
469#endif /* WEAK_PW_HASH */ 483#endif /* WEAK_PW_HASH */
470#define CIFSSEC_MUST_SEAL 0x40040 /* not supported yet */ 484#define CIFSSEC_MUST_SEAL 0x40040 /* not supported yet */
@@ -502,7 +516,7 @@ require use of the stronger protocol */
502 * ---------- 516 * ----------
503 * sesSem operations on smb session 517 * sesSem operations on smb session
504 * tconSem operations on tree connection 518 * tconSem operations on tree connection
505 * fh_sem file handle reconnection operations 519 * fh_sem file handle reconnection operations
506 * 520 *
507 ****************************************************************************/ 521 ****************************************************************************/
508 522
@@ -515,7 +529,7 @@ require use of the stronger protocol */
515/* 529/*
516 * The list of servers that did not respond with NT LM 0.12. 530 * The list of servers that did not respond with NT LM 0.12.
517 * This list helps improve performance and eliminate the messages indicating 531 * This list helps improve performance and eliminate the messages indicating
518 * that we had a communications error talking to the server in this list. 532 * that we had a communications error talking to the server in this list.
519 */ 533 */
520/* Feature not supported */ 534/* Feature not supported */
521/* GLOBAL_EXTERN struct servers_not_supported *NotSuppList; */ 535/* GLOBAL_EXTERN struct servers_not_supported *NotSuppList; */
@@ -568,12 +582,12 @@ GLOBAL_EXTERN atomic_t midCount;
568/* Misc globals */ 582/* Misc globals */
569GLOBAL_EXTERN unsigned int multiuser_mount; /* if enabled allows new sessions 583GLOBAL_EXTERN unsigned int multiuser_mount; /* if enabled allows new sessions
570 to be established on existing mount if we 584 to be established on existing mount if we
571 have the uid/password or Kerberos credential 585 have the uid/password or Kerberos credential
572 or equivalent for current user */ 586 or equivalent for current user */
573GLOBAL_EXTERN unsigned int oplockEnabled; 587GLOBAL_EXTERN unsigned int oplockEnabled;
574GLOBAL_EXTERN unsigned int experimEnabled; 588GLOBAL_EXTERN unsigned int experimEnabled;
575GLOBAL_EXTERN unsigned int lookupCacheEnabled; 589GLOBAL_EXTERN unsigned int lookupCacheEnabled;
576GLOBAL_EXTERN unsigned int extended_security; /* if on, session setup sent 590GLOBAL_EXTERN unsigned int extended_security; /* if on, session setup sent
577 with more secure ntlmssp2 challenge/resp */ 591 with more secure ntlmssp2 challenge/resp */
578GLOBAL_EXTERN unsigned int sign_CIFS_PDUs; /* enable smb packet signing */ 592GLOBAL_EXTERN unsigned int sign_CIFS_PDUs; /* enable smb packet signing */
579GLOBAL_EXTERN unsigned int linuxExtEnabled;/*enable Linux/Unix CIFS extensions*/ 593GLOBAL_EXTERN unsigned int linuxExtEnabled;/*enable Linux/Unix CIFS extensions*/
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index d619ca7d1416..6a2056e58ceb 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -144,7 +144,7 @@
144#define SMBOPEN_OAPPEND 0x0001 144#define SMBOPEN_OAPPEND 0x0001
145 145
146/* 146/*
147 * SMB flag definitions 147 * SMB flag definitions
148 */ 148 */
149#define SMBFLG_EXTD_LOCK 0x01 /* server supports lock-read write-unlock smb */ 149#define SMBFLG_EXTD_LOCK 0x01 /* server supports lock-read write-unlock smb */
150#define SMBFLG_RCV_POSTED 0x02 /* obsolete */ 150#define SMBFLG_RCV_POSTED 0x02 /* obsolete */
@@ -157,9 +157,9 @@
157#define SMBFLG_RESPONSE 0x80 /* this PDU is a response from server */ 157#define SMBFLG_RESPONSE 0x80 /* this PDU is a response from server */
158 158
159/* 159/*
160 * SMB flag2 definitions 160 * SMB flag2 definitions
161 */ 161 */
162#define SMBFLG2_KNOWS_LONG_NAMES cpu_to_le16(1) /* can send long (non-8.3) 162#define SMBFLG2_KNOWS_LONG_NAMES cpu_to_le16(1) /* can send long (non-8.3)
163 path names in response */ 163 path names in response */
164#define SMBFLG2_KNOWS_EAS cpu_to_le16(2) 164#define SMBFLG2_KNOWS_EAS cpu_to_le16(2)
165#define SMBFLG2_SECURITY_SIGNATURE cpu_to_le16(4) 165#define SMBFLG2_SECURITY_SIGNATURE cpu_to_le16(4)
@@ -260,7 +260,7 @@
260#define ATTR_SPARSE 0x0200 260#define ATTR_SPARSE 0x0200
261#define ATTR_REPARSE 0x0400 261#define ATTR_REPARSE 0x0400
262#define ATTR_COMPRESSED 0x0800 262#define ATTR_COMPRESSED 0x0800
263#define ATTR_OFFLINE 0x1000 /* ie file not immediately available - 263#define ATTR_OFFLINE 0x1000 /* ie file not immediately available -
264 on offline storage */ 264 on offline storage */
265#define ATTR_NOT_CONTENT_INDEXED 0x2000 265#define ATTR_NOT_CONTENT_INDEXED 0x2000
266#define ATTR_ENCRYPTED 0x4000 266#define ATTR_ENCRYPTED 0x4000
@@ -300,7 +300,7 @@
300#define CREATE_DELETE_ON_CLOSE 0x00001000 300#define CREATE_DELETE_ON_CLOSE 0x00001000
301#define CREATE_OPEN_BY_ID 0x00002000 301#define CREATE_OPEN_BY_ID 0x00002000
302#define OPEN_REPARSE_POINT 0x00200000 302#define OPEN_REPARSE_POINT 0x00200000
303#define CREATE_OPTIONS_MASK 0x007FFFFF 303#define CREATE_OPTIONS_MASK 0x007FFFFF
304#define CREATE_OPTION_SPECIAL 0x20000000 /* system. NB not sent over wire */ 304#define CREATE_OPTION_SPECIAL 0x20000000 /* system. NB not sent over wire */
305 305
306/* ImpersonationLevel flags */ 306/* ImpersonationLevel flags */
@@ -366,17 +366,19 @@ struct smb_hdr {
366#define pByteArea(smb_var) ((unsigned char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) + 2 ) 366#define pByteArea(smb_var) ((unsigned char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) + 2 )
367 367
368/* 368/*
369 * Computer Name Length 369 * Computer Name Length (since Netbios name was length 16 with last byte 0x20)
370 * No longer as important, now that TCP names are more commonly used to
371 * resolve hosts.
370 */ 372 */
371#define CNLEN 15 373#define CNLEN 15
372 374
373/* 375/*
374 * Share Name Length @S8A 376 * Share Name Length (SNLEN)
375 * Note: This length is limited by the SMB used to get @S8A 377 * Note: This length was limited by the SMB used to get
376 * the Share info. NetShareEnum only returns 13 @S8A 378 * the Share info. NetShareEnum only returned 13
377 * chars, including the null termination. @S8A 379 * chars, including the null termination.
380 * This was removed because it no longer is limiting.
378 */ 381 */
379#define SNLEN 12 /*@S8A */
380 382
381/* 383/*
382 * Comment Length 384 * Comment Length
@@ -394,8 +396,8 @@ struct smb_hdr {
394 * 396 *
395 * The Naming convention is the lower case version of the 397 * The Naming convention is the lower case version of the
396 * smb command code name for the struct and this is typedef to the 398 * smb command code name for the struct and this is typedef to the
397 * uppercase version of the same name with the prefix SMB_ removed 399 * uppercase version of the same name with the prefix SMB_ removed
398 * for brevity. Although typedefs are not commonly used for 400 * for brevity. Although typedefs are not commonly used for
399 * structure definitions in the Linux kernel, their use in the 401 * structure definitions in the Linux kernel, their use in the
400 * CIFS standards document, which this code is based on, may 402 * CIFS standards document, which this code is based on, may
401 * make this one of the cases where typedefs for structures make 403 * make this one of the cases where typedefs for structures make
@@ -403,7 +405,7 @@ struct smb_hdr {
403 * Typedefs can always be removed later if they are too distracting 405 * Typedefs can always be removed later if they are too distracting
404 * and they are only used for the CIFSs PDUs themselves, not 406 * and they are only used for the CIFSs PDUs themselves, not
405 * internal cifs vfs structures 407 * internal cifs vfs structures
406 * 408 *
407 */ 409 */
408 410
409typedef struct negotiate_req { 411typedef struct negotiate_req {
@@ -511,7 +513,7 @@ typedef union smb_com_session_setup_andx {
511 unsigned char SecurityBlob[1]; /* followed by */ 513 unsigned char SecurityBlob[1]; /* followed by */
512 /* STRING NativeOS */ 514 /* STRING NativeOS */
513 /* STRING NativeLanMan */ 515 /* STRING NativeLanMan */
514 } __attribute__((packed)) req; /* NTLM request format (with 516 } __attribute__((packed)) req; /* NTLM request format (with
515 extended security */ 517 extended security */
516 518
517 struct { /* request format */ 519 struct { /* request format */
@@ -549,7 +551,7 @@ typedef union smb_com_session_setup_andx {
549/* unsigned char * NativeOS; */ 551/* unsigned char * NativeOS; */
550/* unsigned char * NativeLanMan; */ 552/* unsigned char * NativeLanMan; */
551/* unsigned char * PrimaryDomain; */ 553/* unsigned char * PrimaryDomain; */
552 } __attribute__((packed)) resp; /* NTLM response 554 } __attribute__((packed)) resp; /* NTLM response
553 (with or without extended sec) */ 555 (with or without extended sec) */
554 556
555 struct { /* request format */ 557 struct { /* request format */
@@ -618,7 +620,7 @@ struct ntlmv2_resp {
618#define CAP_NT_SMBS 0x00000010 620#define CAP_NT_SMBS 0x00000010
619#define CAP_STATUS32 0x00000040 621#define CAP_STATUS32 0x00000040
620#define CAP_LEVEL_II_OPLOCKS 0x00000080 622#define CAP_LEVEL_II_OPLOCKS 0x00000080
621#define CAP_NT_FIND 0x00000200 /* reserved should be zero 623#define CAP_NT_FIND 0x00000200 /* reserved should be zero
622 (because NT_SMBs implies the same thing?) */ 624 (because NT_SMBs implies the same thing?) */
623#define CAP_BULK_TRANSFER 0x20000000 625#define CAP_BULK_TRANSFER 0x20000000
624#define CAP_EXTENDED_SECURITY 0x80000000 626#define CAP_EXTENDED_SECURITY 0x80000000
@@ -676,7 +678,7 @@ typedef struct smb_com_logoff_andx_rsp {
676 __u16 ByteCount; 678 __u16 ByteCount;
677} __attribute__((packed)) LOGOFF_ANDX_RSP; 679} __attribute__((packed)) LOGOFF_ANDX_RSP;
678 680
679typedef union smb_com_tree_disconnect { /* as an altetnative can use flag on 681typedef union smb_com_tree_disconnect { /* as an altetnative can use flag on
680 tree_connect PDU to effect disconnect */ 682 tree_connect PDU to effect disconnect */
681 /* tdis is probably simplest SMB PDU */ 683 /* tdis is probably simplest SMB PDU */
682 struct { 684 struct {
@@ -712,6 +714,7 @@ typedef struct smb_com_findclose_req {
712#define REQ_OPLOCK 0x00000002 714#define REQ_OPLOCK 0x00000002
713#define REQ_BATCHOPLOCK 0x00000004 715#define REQ_BATCHOPLOCK 0x00000004
714#define REQ_OPENDIRONLY 0x00000008 716#define REQ_OPENDIRONLY 0x00000008
717#define REQ_EXTENDED_INFO 0x00000010
715 718
716typedef struct smb_com_open_req { /* also handles create */ 719typedef struct smb_com_open_req { /* also handles create */
717 struct smb_hdr hdr; /* wct = 24 */ 720 struct smb_hdr hdr; /* wct = 24 */
@@ -799,27 +802,28 @@ typedef struct smb_com_openx_rsp {
799 __u32 FileId; 802 __u32 FileId;
800 __u16 Reserved; 803 __u16 Reserved;
801 __u16 ByteCount; 804 __u16 ByteCount;
802} __attribute__((packed)) OPENX_RSP; 805} __attribute__((packed)) OPENX_RSP;
803 806
804/* For encoding of POSIX Open Request - see trans2 function 0x209 data struct */ 807/* For encoding of POSIX Open Request - see trans2 function 0x209 data struct */
805 808
806/* Legacy write request for older servers */ 809/* Legacy write request for older servers */
807typedef struct smb_com_writex_req { 810typedef struct smb_com_writex_req {
808 struct smb_hdr hdr; /* wct = 12 */ 811 struct smb_hdr hdr; /* wct = 12 */
809 __u8 AndXCommand; 812 __u8 AndXCommand;
810 __u8 AndXReserved; 813 __u8 AndXReserved;
811 __le16 AndXOffset; 814 __le16 AndXOffset;
812 __u16 Fid; 815 __u16 Fid;
813 __le32 OffsetLow; 816 __le32 OffsetLow;
814 __u32 Reserved; /* Timeout */ 817 __u32 Reserved; /* Timeout */
815 __le16 WriteMode; /* 1 = write through */ 818 __le16 WriteMode; /* 1 = write through */
816 __le16 Remaining; 819 __le16 Remaining;
817 __le16 Reserved2; 820 __le16 Reserved2;
818 __le16 DataLengthLow; 821 __le16 DataLengthLow;
819 __le16 DataOffset; 822 __le16 DataOffset;
820 __le16 ByteCount; 823 __le16 ByteCount;
821 __u8 Pad; /* BB check for whether padded to DWORD boundary and optimum performance here */ 824 __u8 Pad; /* BB check for whether padded to DWORD
822 char Data[0]; 825 boundary and optimum performance here */
826 char Data[0];
823} __attribute__((packed)) WRITEX_REQ; 827} __attribute__((packed)) WRITEX_REQ;
824 828
825typedef struct smb_com_write_req { 829typedef struct smb_com_write_req {
@@ -837,7 +841,8 @@ typedef struct smb_com_write_req {
837 __le16 DataOffset; 841 __le16 DataOffset;
838 __le32 OffsetHigh; 842 __le32 OffsetHigh;
839 __le16 ByteCount; 843 __le16 ByteCount;
840 __u8 Pad; /* BB check for whether padded to DWORD boundary and optimum performance here */ 844 __u8 Pad; /* BB check for whether padded to DWORD
845 boundary and optimum performance here */
841 char Data[0]; 846 char Data[0];
842} __attribute__((packed)) WRITE_REQ; 847} __attribute__((packed)) WRITE_REQ;
843 848
@@ -855,17 +860,17 @@ typedef struct smb_com_write_rsp {
855 860
856/* legacy read request for older servers */ 861/* legacy read request for older servers */
857typedef struct smb_com_readx_req { 862typedef struct smb_com_readx_req {
858 struct smb_hdr hdr; /* wct = 10 */ 863 struct smb_hdr hdr; /* wct = 10 */
859 __u8 AndXCommand; 864 __u8 AndXCommand;
860 __u8 AndXReserved; 865 __u8 AndXReserved;
861 __le16 AndXOffset; 866 __le16 AndXOffset;
862 __u16 Fid; 867 __u16 Fid;
863 __le32 OffsetLow; 868 __le32 OffsetLow;
864 __le16 MaxCount; 869 __le16 MaxCount;
865 __le16 MinCount; /* obsolete */ 870 __le16 MinCount; /* obsolete */
866 __le32 Reserved; 871 __le32 Reserved;
867 __le16 Remaining; 872 __le16 Remaining;
868 __le16 ByteCount; 873 __le16 ByteCount;
869} __attribute__((packed)) READX_REQ; 874} __attribute__((packed)) READX_REQ;
870 875
871typedef struct smb_com_read_req { 876typedef struct smb_com_read_req {
@@ -896,7 +901,8 @@ typedef struct smb_com_read_rsp {
896 __le16 DataLengthHigh; 901 __le16 DataLengthHigh;
897 __u64 Reserved2; 902 __u64 Reserved2;
898 __u16 ByteCount; 903 __u16 ByteCount;
899 __u8 Pad; /* BB check for whether padded to DWORD boundary and optimum performance here */ 904 __u8 Pad; /* BB check for whether padded to DWORD
905 boundary and optimum performance here */
900 char Data[1]; 906 char Data[1];
901} __attribute__((packed)) READ_RSP; 907} __attribute__((packed)) READ_RSP;
902 908
@@ -967,7 +973,7 @@ typedef struct smb_com_rename_req {
967#define COPY_TARGET_MODE_ASCII 0x0004 /* if not set, binary */ 973#define COPY_TARGET_MODE_ASCII 0x0004 /* if not set, binary */
968#define COPY_SOURCE_MODE_ASCII 0x0008 /* if not set, binary */ 974#define COPY_SOURCE_MODE_ASCII 0x0008 /* if not set, binary */
969#define COPY_VERIFY_WRITES 0x0010 975#define COPY_VERIFY_WRITES 0x0010
970#define COPY_TREE 0x0020 976#define COPY_TREE 0x0020
971 977
972typedef struct smb_com_copy_req { 978typedef struct smb_com_copy_req {
973 struct smb_hdr hdr; /* wct = 3 */ 979 struct smb_hdr hdr; /* wct = 3 */
@@ -975,7 +981,7 @@ typedef struct smb_com_copy_req {
975 __le16 OpenFunction; 981 __le16 OpenFunction;
976 __le16 Flags; 982 __le16 Flags;
977 __le16 ByteCount; 983 __le16 ByteCount;
978 __u8 BufferFormat; /* 4 = ASCII or Unicode */ 984 __u8 BufferFormat; /* 4 = ASCII or Unicode */
979 unsigned char OldFileName[1]; 985 unsigned char OldFileName[1];
980 /* followed by __u8 BufferFormat2 */ 986 /* followed by __u8 BufferFormat2 */
981 /* followed by NewFileName string */ 987 /* followed by NewFileName string */
@@ -1083,28 +1089,28 @@ typedef struct smb_com_setattr_rsp {
1083 1089
1084/*******************************************************/ 1090/*******************************************************/
1085/* NT Transact structure defintions follow */ 1091/* NT Transact structure defintions follow */
1086/* Currently only ioctl, acl (get security descriptor) */ 1092/* Currently only ioctl, acl (get security descriptor) */
1087/* and notify are implemented */ 1093/* and notify are implemented */
1088/*******************************************************/ 1094/*******************************************************/
1089typedef struct smb_com_ntransact_req { 1095typedef struct smb_com_ntransact_req {
1090 struct smb_hdr hdr; /* wct >= 19 */ 1096 struct smb_hdr hdr; /* wct >= 19 */
1091 __u8 MaxSetupCount; 1097 __u8 MaxSetupCount;
1092 __u16 Reserved; 1098 __u16 Reserved;
1093 __le32 TotalParameterCount; 1099 __le32 TotalParameterCount;
1094 __le32 TotalDataCount; 1100 __le32 TotalDataCount;
1095 __le32 MaxParameterCount; 1101 __le32 MaxParameterCount;
1096 __le32 MaxDataCount; 1102 __le32 MaxDataCount;
1097 __le32 ParameterCount; 1103 __le32 ParameterCount;
1098 __le32 ParameterOffset; 1104 __le32 ParameterOffset;
1099 __le32 DataCount; 1105 __le32 DataCount;
1100 __le32 DataOffset; 1106 __le32 DataOffset;
1101 __u8 SetupCount; /* four setup words follow subcommand */ 1107 __u8 SetupCount; /* four setup words follow subcommand */
1102 /* SNIA spec incorrectly included spurious pad here */ 1108 /* SNIA spec incorrectly included spurious pad here */
1103 __le16 SubCommand; /* 2 = IOCTL/FSCTL */ 1109 __le16 SubCommand; /* 2 = IOCTL/FSCTL */
1104 /* SetupCount words follow then */ 1110 /* SetupCount words follow then */
1105 __le16 ByteCount; 1111 __le16 ByteCount;
1106 __u8 Pad[3]; 1112 __u8 Pad[3];
1107 __u8 Parms[0]; 1113 __u8 Parms[0];
1108} __attribute__((packed)) NTRANSACT_REQ; 1114} __attribute__((packed)) NTRANSACT_REQ;
1109 1115
1110typedef struct smb_com_ntransact_rsp { 1116typedef struct smb_com_ntransact_rsp {
@@ -1120,7 +1126,7 @@ typedef struct smb_com_ntransact_rsp {
1120 __le32 DataDisplacement; 1126 __le32 DataDisplacement;
1121 __u8 SetupCount; /* 0 */ 1127 __u8 SetupCount; /* 0 */
1122 __u16 ByteCount; 1128 __u16 ByteCount;
1123 /* __u8 Pad[3]; */ 1129 /* __u8 Pad[3]; */
1124 /* parms and data follow */ 1130 /* parms and data follow */
1125} __attribute__((packed)) NTRANSACT_RSP; 1131} __attribute__((packed)) NTRANSACT_RSP;
1126 1132
@@ -1215,7 +1221,7 @@ typedef struct smb_com_transaction_change_notify_req {
1215/* __u8 Data[1];*/ 1221/* __u8 Data[1];*/
1216} __attribute__((packed)) TRANSACT_CHANGE_NOTIFY_REQ; 1222} __attribute__((packed)) TRANSACT_CHANGE_NOTIFY_REQ;
1217 1223
1218/* BB eventually change to use generic ntransact rsp struct 1224/* BB eventually change to use generic ntransact rsp struct
1219 and validation routine */ 1225 and validation routine */
1220typedef struct smb_com_transaction_change_notify_rsp { 1226typedef struct smb_com_transaction_change_notify_rsp {
1221 struct smb_hdr hdr; /* wct = 18 */ 1227 struct smb_hdr hdr; /* wct = 18 */
@@ -1262,7 +1268,7 @@ struct file_notify_information {
1262 __le32 Action; 1268 __le32 Action;
1263 __le32 FileNameLength; 1269 __le32 FileNameLength;
1264 __u8 FileName[0]; 1270 __u8 FileName[0];
1265} __attribute__((packed)); 1271} __attribute__((packed));
1266 1272
1267struct reparse_data { 1273struct reparse_data {
1268 __u32 ReparseTag; 1274 __u32 ReparseTag;
@@ -1331,7 +1337,7 @@ struct trans2_resp {
1331 __u8 Reserved1; 1337 __u8 Reserved1;
1332 /* SetupWords[SetupCount]; 1338 /* SetupWords[SetupCount];
1333 __u16 ByteCount; 1339 __u16 ByteCount;
1334 __u16 Reserved2;*/ 1340 __u16 Reserved2;*/
1335 /* data area follows */ 1341 /* data area follows */
1336} __attribute__((packed)); 1342} __attribute__((packed));
1337 1343
@@ -1370,9 +1376,9 @@ struct smb_t2_rsp {
1370#define SMB_QUERY_FILE_INTERNAL_INFO 0x3ee 1376#define SMB_QUERY_FILE_INTERNAL_INFO 0x3ee
1371#define SMB_QUERY_FILE_ACCESS_INFO 0x3f0 1377#define SMB_QUERY_FILE_ACCESS_INFO 0x3f0
1372#define SMB_QUERY_FILE_NAME_INFO2 0x3f1 /* 0x30 bytes */ 1378#define SMB_QUERY_FILE_NAME_INFO2 0x3f1 /* 0x30 bytes */
1373#define SMB_QUERY_FILE_POSITION_INFO 0x3f6 1379#define SMB_QUERY_FILE_POSITION_INFO 0x3f6
1374#define SMB_QUERY_FILE_MODE_INFO 0x3f8 1380#define SMB_QUERY_FILE_MODE_INFO 0x3f8
1375#define SMB_QUERY_FILE_ALGN_INFO 0x3f9 1381#define SMB_QUERY_FILE_ALGN_INFO 0x3f9
1376 1382
1377 1383
1378#define SMB_SET_FILE_BASIC_INFO 0x101 1384#define SMB_SET_FILE_BASIC_INFO 0x101
@@ -1506,35 +1512,35 @@ struct smb_com_transaction2_sfi_req {
1506 __u16 Pad1; 1512 __u16 Pad1;
1507 __u16 Fid; 1513 __u16 Fid;
1508 __le16 InformationLevel; 1514 __le16 InformationLevel;
1509 __u16 Reserved4; 1515 __u16 Reserved4;
1510} __attribute__((packed)); 1516} __attribute__((packed));
1511 1517
1512struct smb_com_transaction2_sfi_rsp { 1518struct smb_com_transaction2_sfi_rsp {
1513 struct smb_hdr hdr; /* wct = 10 + SetupCount */ 1519 struct smb_hdr hdr; /* wct = 10 + SetupCount */
1514 struct trans2_resp t2; 1520 struct trans2_resp t2;
1515 __u16 ByteCount; 1521 __u16 ByteCount;
1516 __u16 Reserved2; /* parameter word reserved - 1522 __u16 Reserved2; /* parameter word reserved -
1517 present for infolevels > 100 */ 1523 present for infolevels > 100 */
1518} __attribute__((packed)); 1524} __attribute__((packed));
1519 1525
1520struct smb_t2_qfi_req { 1526struct smb_t2_qfi_req {
1521 struct smb_hdr hdr; 1527 struct smb_hdr hdr;
1522 struct trans2_req t2; 1528 struct trans2_req t2;
1523 __u8 Pad; 1529 __u8 Pad;
1524 __u16 Fid; 1530 __u16 Fid;
1525 __le16 InformationLevel; 1531 __le16 InformationLevel;
1526} __attribute__((packed)); 1532} __attribute__((packed));
1527 1533
1528struct smb_t2_qfi_rsp { 1534struct smb_t2_qfi_rsp {
1529 struct smb_hdr hdr; /* wct = 10 + SetupCount */ 1535 struct smb_hdr hdr; /* wct = 10 + SetupCount */
1530 struct trans2_resp t2; 1536 struct trans2_resp t2;
1531 __u16 ByteCount; 1537 __u16 ByteCount;
1532 __u16 Reserved2; /* parameter word reserved - 1538 __u16 Reserved2; /* parameter word reserved -
1533 present for infolevels > 100 */ 1539 present for infolevels > 100 */
1534} __attribute__((packed)); 1540} __attribute__((packed));
1535 1541
1536/* 1542/*
1537 * Flags on T2 FINDFIRST and FINDNEXT 1543 * Flags on T2 FINDFIRST and FINDNEXT
1538 */ 1544 */
1539#define CIFS_SEARCH_CLOSE_ALWAYS 0x0001 1545#define CIFS_SEARCH_CLOSE_ALWAYS 0x0001
1540#define CIFS_SEARCH_CLOSE_AT_END 0x0002 1546#define CIFS_SEARCH_CLOSE_AT_END 0x0002
@@ -1743,7 +1749,9 @@ typedef struct smb_com_transaction2_get_dfs_refer_req {
1743 __u8 Reserved3; 1749 __u8 Reserved3;
1744 __le16 SubCommand; /* one setup word */ 1750 __le16 SubCommand; /* one setup word */
1745 __le16 ByteCount; 1751 __le16 ByteCount;
1746 __u8 Pad[3]; /* Win2K has sent 0x0F01 (max resp length perhaps?) followed by one byte pad - doesn't seem to matter though */ 1752 __u8 Pad[3]; /* Win2K has sent 0x0F01 (max response length
1753 perhaps?) followed by one byte pad - doesn't
1754 seem to matter though */
1747 __le16 MaxReferralLevel; 1755 __le16 MaxReferralLevel;
1748 char RequestFileName[1]; 1756 char RequestFileName[1];
1749} __attribute__((packed)) TRANSACTION2_GET_DFS_REFER_REQ; 1757} __attribute__((packed)) TRANSACTION2_GET_DFS_REFER_REQ;
@@ -1752,7 +1760,10 @@ typedef struct dfs_referral_level_3 {
1752 __le16 VersionNumber; 1760 __le16 VersionNumber;
1753 __le16 ReferralSize; 1761 __le16 ReferralSize;
1754 __le16 ServerType; /* 0x0001 = CIFS server */ 1762 __le16 ServerType; /* 0x0001 = CIFS server */
1755 __le16 ReferralFlags; /* or proximity - not clear which since always set to zero - SNIA spec says 0x01 means strip off PathConsumed chars before submitting RequestFileName to remote node */ 1763 __le16 ReferralFlags; /* or proximity - not clear which since it is
1764 always set to zero - SNIA spec says 0x01
1765 means strip off PathConsumed chars before
1766 submitting RequestFileName to remote node */
1756 __le16 TimeToLive; 1767 __le16 TimeToLive;
1757 __le16 Proximity; 1768 __le16 Proximity;
1758 __le16 DfsPathOffset; 1769 __le16 DfsPathOffset;
@@ -1778,11 +1789,13 @@ typedef struct smb_com_transaction_get_dfs_refer_rsp {
1778#define DFSREF_STORAGE_SERVER 0x0002 1789#define DFSREF_STORAGE_SERVER 0x0002
1779 1790
1780/* IOCTL information */ 1791/* IOCTL information */
1781/* List of ioctl function codes that look to be of interest to remote clients like this. */ 1792/*
1782/* Need to do some experimentation to make sure they all work remotely. */ 1793 * List of ioctl function codes that look to be of interest to remote clients
1783/* Some of the following such as the encryption/compression ones would be */ 1794 * like this one. Need to do some experimentation to make sure they all work
1784/* invoked from tools via a specialized hook into the VFS rather than via the */ 1795 * remotely. Some of the following, such as the encryption/compression ones
1785/* standard vfs entry points */ 1796 * would be invoked from tools via a specialized hook into the VFS rather
1797 * than via the standard vfs entry points
1798 */
1786#define FSCTL_REQUEST_OPLOCK_LEVEL_1 0x00090000 1799#define FSCTL_REQUEST_OPLOCK_LEVEL_1 0x00090000
1787#define FSCTL_REQUEST_OPLOCK_LEVEL_2 0x00090004 1800#define FSCTL_REQUEST_OPLOCK_LEVEL_2 0x00090004
1788#define FSCTL_REQUEST_BATCH_OPLOCK 0x00090008 1801#define FSCTL_REQUEST_BATCH_OPLOCK 0x00090008
@@ -1811,7 +1824,7 @@ typedef struct smb_com_transaction_get_dfs_refer_rsp {
1811/* 1824/*
1812 ************************************************************************ 1825 ************************************************************************
1813 * All structs for everything above the SMB PDUs themselves 1826 * All structs for everything above the SMB PDUs themselves
1814 * (such as the T2 level specific data) go here 1827 * (such as the T2 level specific data) go here
1815 ************************************************************************ 1828 ************************************************************************
1816 */ 1829 */
1817 1830
@@ -1857,7 +1870,7 @@ typedef struct {
1857 __le64 FreeAllocationUnits; 1870 __le64 FreeAllocationUnits;
1858 __le32 SectorsPerAllocationUnit; 1871 __le32 SectorsPerAllocationUnit;
1859 __le32 BytesPerSector; 1872 __le32 BytesPerSector;
1860} __attribute__((packed)) FILE_SYSTEM_INFO; /* size info, level 0x103 */ 1873} __attribute__((packed)) FILE_SYSTEM_INFO; /* size info, level 0x103 */
1861 1874
1862typedef struct { 1875typedef struct {
1863 __le32 fsid; 1876 __le32 fsid;
@@ -1871,7 +1884,7 @@ typedef struct {
1871 __le16 MajorVersionNumber; 1884 __le16 MajorVersionNumber;
1872 __le16 MinorVersionNumber; 1885 __le16 MinorVersionNumber;
1873 __le64 Capability; 1886 __le64 Capability;
1874} __attribute__((packed)) FILE_SYSTEM_UNIX_INFO; /* Unix extensions info, level 0x200 */ 1887} __attribute__((packed)) FILE_SYSTEM_UNIX_INFO; /* Unix extension level 0x200*/
1875 1888
1876/* Version numbers for CIFS UNIX major and minor. */ 1889/* Version numbers for CIFS UNIX major and minor. */
1877#define CIFS_UNIX_MAJOR_VERSION 1 1890#define CIFS_UNIX_MAJOR_VERSION 1
@@ -1885,16 +1898,20 @@ typedef struct {
1885#define CIFS_UNIX_POSIX_PATHNAMES_CAP 0x00000010 /* Allow POSIX path chars */ 1898#define CIFS_UNIX_POSIX_PATHNAMES_CAP 0x00000010 /* Allow POSIX path chars */
1886#define CIFS_UNIX_POSIX_PATH_OPS_CAP 0x00000020 /* Allow new POSIX path based 1899#define CIFS_UNIX_POSIX_PATH_OPS_CAP 0x00000020 /* Allow new POSIX path based
1887 calls including posix open 1900 calls including posix open
1888 and posix unlink */ 1901 and posix unlink */
1902#define CIFS_UNIX_LARGE_READ_CAP 0x00000040 /* support reads >128K (up
1903 to 0xFFFF00 */
1904#define CIFS_UNIX_LARGE_WRITE_CAP 0x00000080
1905
1889#ifdef CONFIG_CIFS_POSIX 1906#ifdef CONFIG_CIFS_POSIX
1890/* Can not set pathnames cap yet until we send new posix create SMB since 1907/* Can not set pathnames cap yet until we send new posix create SMB since
1891 otherwise server can treat such handles opened with older ntcreatex 1908 otherwise server can treat such handles opened with older ntcreatex
1892 (by a new client which knows how to send posix path ops) 1909 (by a new client which knows how to send posix path ops)
1893 as non-posix handles (can affect write behavior with byte range locks. 1910 as non-posix handles (can affect write behavior with byte range locks.
1894 We can add back in POSIX_PATH_OPS cap when Posix Create/Mkdir finished */ 1911 We can add back in POSIX_PATH_OPS cap when Posix Create/Mkdir finished */
1895/* #define CIFS_UNIX_CAP_MASK 0x0000003b */ 1912/* #define CIFS_UNIX_CAP_MASK 0x000000fb */
1896#define CIFS_UNIX_CAP_MASK 0x0000001b 1913#define CIFS_UNIX_CAP_MASK 0x000000db
1897#else 1914#else
1898#define CIFS_UNIX_CAP_MASK 0x00000013 1915#define CIFS_UNIX_CAP_MASK 0x00000013
1899#endif /* CONFIG_CIFS_POSIX */ 1916#endif /* CONFIG_CIFS_POSIX */
1900 1917
@@ -1904,10 +1921,10 @@ typedef struct {
1904typedef struct { 1921typedef struct {
1905 /* For undefined recommended transfer size return -1 in that field */ 1922 /* For undefined recommended transfer size return -1 in that field */
1906 __le32 OptimalTransferSize; /* bsize on some os, iosize on other os */ 1923 __le32 OptimalTransferSize; /* bsize on some os, iosize on other os */
1907 __le32 BlockSize; 1924 __le32 BlockSize;
1908 /* The next three fields are in terms of the block size. 1925 /* The next three fields are in terms of the block size.
1909 (above). If block size is unknown, 4096 would be a 1926 (above). If block size is unknown, 4096 would be a
1910 reasonable block size for a server to report. 1927 reasonable block size for a server to report.
1911 Note that returning the blocks/blocksavail removes need 1928 Note that returning the blocks/blocksavail removes need
1912 to make a second call (to QFSInfo level 0x103 to get this info. 1929 to make a second call (to QFSInfo level 0x103 to get this info.
1913 UserBlockAvail is typically less than or equal to BlocksAvail, 1930 UserBlockAvail is typically less than or equal to BlocksAvail,
@@ -2062,9 +2079,9 @@ struct file_alt_name_info {
2062 2079
2063struct file_stream_info { 2080struct file_stream_info {
2064 __le32 number_of_streams; /* BB check sizes and verify location */ 2081 __le32 number_of_streams; /* BB check sizes and verify location */
2065 /* followed by info on streams themselves 2082 /* followed by info on streams themselves
2066 u64 size; 2083 u64 size;
2067 u64 allocation_size 2084 u64 allocation_size
2068 stream info */ 2085 stream info */
2069}; /* level 0x109 */ 2086}; /* level 0x109 */
2070 2087
@@ -2083,7 +2100,7 @@ struct cifs_posix_ace { /* access control entry (ACE) */
2083 __u8 cifs_e_tag; 2100 __u8 cifs_e_tag;
2084 __u8 cifs_e_perm; 2101 __u8 cifs_e_perm;
2085 __le64 cifs_uid; /* or gid */ 2102 __le64 cifs_uid; /* or gid */
2086} __attribute__((packed)); 2103} __attribute__((packed));
2087 2104
2088struct cifs_posix_acl { /* access conrol list (ACL) */ 2105struct cifs_posix_acl { /* access conrol list (ACL) */
2089 __le16 version; 2106 __le16 version;
@@ -2138,6 +2155,12 @@ typedef struct {
2138 /* struct following varies based on requested level */ 2155 /* struct following varies based on requested level */
2139} __attribute__((packed)) OPEN_PSX_RSP; /* level 0x209 SetPathInfo data */ 2156} __attribute__((packed)) OPEN_PSX_RSP; /* level 0x209 SetPathInfo data */
2140 2157
2158#define SMB_POSIX_UNLINK_FILE_TARGET 0
2159#define SMB_POSIX_UNLINK_DIRECTORY_TARGET 1
2160
2161struct unlink_psx_rq { /* level 0x20a SetPathInfo */
2162 __le16 type;
2163} __attribute__((packed));
2141 2164
2142struct file_internal_info { 2165struct file_internal_info {
2143 __u64 UniqueId; /* inode number */ 2166 __u64 UniqueId; /* inode number */
@@ -2154,7 +2177,7 @@ struct file_attrib_tag {
2154 2177
2155 2178
2156/********************************************************/ 2179/********************************************************/
2157/* FindFirst/FindNext transact2 data buffer formats */ 2180/* FindFirst/FindNext transact2 data buffer formats */
2158/********************************************************/ 2181/********************************************************/
2159 2182
2160typedef struct { 2183typedef struct {
@@ -2232,7 +2255,7 @@ typedef struct {
2232 __le64 EndOfFile; 2255 __le64 EndOfFile;
2233 __le64 AllocationSize; 2256 __le64 AllocationSize;
2234 __le32 ExtFileAttributes; 2257 __le32 ExtFileAttributes;
2235 __le32 FileNameLength; 2258 __le32 FileNameLength;
2236 __le32 EaSize; /* length of the xattrs */ 2259 __le32 EaSize; /* length of the xattrs */
2237 __u8 ShortNameLength; 2260 __u8 ShortNameLength;
2238 __u8 Reserved; 2261 __u8 Reserved;
@@ -2259,7 +2282,7 @@ typedef struct {
2259struct win_dev { 2282struct win_dev {
2260 unsigned char type[8]; /* IntxCHR or IntxBLK */ 2283 unsigned char type[8]; /* IntxCHR or IntxBLK */
2261 __le64 major; 2284 __le64 major;
2262 __le64 minor; 2285 __le64 minor;
2263} __attribute__((packed)); 2286} __attribute__((packed));
2264 2287
2265struct gea { 2288struct gea {
@@ -2291,36 +2314,36 @@ struct fealist {
2291struct data_blob { 2314struct data_blob {
2292 __u8 *data; 2315 __u8 *data;
2293 size_t length; 2316 size_t length;
2294 void (*free) (struct data_blob * data_blob); 2317 void (*free) (struct data_blob *data_blob);
2295} __attribute__((packed)); 2318} __attribute__((packed));
2296 2319
2297 2320
2298#ifdef CONFIG_CIFS_POSIX 2321#ifdef CONFIG_CIFS_POSIX
2299/* 2322/*
2300 For better POSIX semantics from Linux client, (even better 2323 For better POSIX semantics from Linux client, (even better
2301 than the existing CIFS Unix Extensions) we need updated PDUs for: 2324 than the existing CIFS Unix Extensions) we need updated PDUs for:
2302 2325
2303 1) PosixCreateX - to set and return the mode, inode#, device info and 2326 1) PosixCreateX - to set and return the mode, inode#, device info and
2304 perhaps add a CreateDevice - to create Pipes and other special .inodes 2327 perhaps add a CreateDevice - to create Pipes and other special .inodes
2305 Also note POSIX open flags 2328 Also note POSIX open flags
2306 2) Close - to return the last write time to do cache across close 2329 2) Close - to return the last write time to do cache across close
2307 more safely 2330 more safely
2308 3) FindFirst return unique inode number - what about resume key, two 2331 3) FindFirst return unique inode number - what about resume key, two
2309 forms short (matches readdir) and full (enough info to cache inodes) 2332 forms short (matches readdir) and full (enough info to cache inodes)
2310 4) Mkdir - set mode 2333 4) Mkdir - set mode
2311 2334
2312 And under consideration: 2335 And under consideration:
2313 5) FindClose2 (return nanosecond timestamp ??) 2336 5) FindClose2 (return nanosecond timestamp ??)
2314 6) Use nanosecond timestamps throughout all time fields if 2337 6) Use nanosecond timestamps throughout all time fields if
2315 corresponding attribute flag is set 2338 corresponding attribute flag is set
2316 7) sendfile - handle based copy 2339 7) sendfile - handle based copy
2317 8) Direct i/o 2340 8) Direct i/o
2318 9) Misc fcntls? 2341 9) Misc fcntls?
2319 2342
2320 what about fixing 64 bit alignment 2343 what about fixing 64 bit alignment
2321 2344
2322 There are also various legacy SMB/CIFS requests used as is 2345 There are also various legacy SMB/CIFS requests used as is
2323 2346
2324 From existing Lanman and NTLM dialects: 2347 From existing Lanman and NTLM dialects:
2325 -------------------------------------- 2348 --------------------------------------
2326 NEGOTIATE 2349 NEGOTIATE
@@ -2341,48 +2364,48 @@ struct data_blob {
2341 (BB verify that never need to set allocation size) 2364 (BB verify that never need to set allocation size)
2342 SMB_SET_FILE_BASIC_INFO2 (setting times - BB can it be done via 2365 SMB_SET_FILE_BASIC_INFO2 (setting times - BB can it be done via
2343 Unix ext?) 2366 Unix ext?)
2344 2367
2345 COPY (note support for copy across directories) - FUTURE, OPTIONAL 2368 COPY (note support for copy across directories) - FUTURE, OPTIONAL
2346 setting/getting OS/2 EAs - FUTURE (BB can this handle 2369 setting/getting OS/2 EAs - FUTURE (BB can this handle
2347 setting Linux xattrs perfectly) - OPTIONAL 2370 setting Linux xattrs perfectly) - OPTIONAL
2348 dnotify - FUTURE, OPTIONAL 2371 dnotify - FUTURE, OPTIONAL
2349 quota - FUTURE, OPTIONAL 2372 quota - FUTURE, OPTIONAL
2350 2373
2351 Note that various requests implemented for NT interop such as 2374 Note that various requests implemented for NT interop such as
2352 NT_TRANSACT (IOCTL) QueryReparseInfo 2375 NT_TRANSACT (IOCTL) QueryReparseInfo
2353 are unneeded to servers compliant with the CIFS POSIX extensions 2376 are unneeded to servers compliant with the CIFS POSIX extensions
2354 2377
2355 From CIFS Unix Extensions: 2378 From CIFS Unix Extensions:
2356 ------------------------- 2379 -------------------------
2357 T2 SET_PATH_INFO (SMB_SET_FILE_UNIX_LINK) for symlinks 2380 T2 SET_PATH_INFO (SMB_SET_FILE_UNIX_LINK) for symlinks
2358 T2 SET_PATH_INFO (SMB_SET_FILE_BASIC_INFO2) 2381 T2 SET_PATH_INFO (SMB_SET_FILE_BASIC_INFO2)
2359 T2 QUERY_PATH_INFO (SMB_QUERY_FILE_UNIX_LINK) 2382 T2 QUERY_PATH_INFO (SMB_QUERY_FILE_UNIX_LINK)
2360 T2 QUERY_PATH_INFO (SMB_QUERY_FILE_UNIX_BASIC) - BB check for missing inode fields 2383 T2 QUERY_PATH_INFO (SMB_QUERY_FILE_UNIX_BASIC) BB check for missing
2361 Actually need QUERY_FILE_UNIX_INFO since has inode num 2384 inode fields
2362 BB what about a) blksize/blkbits/blocks 2385 Actually a need QUERY_FILE_UNIX_INFO
2386 since has inode num
2387 BB what about a) blksize/blkbits/blocks
2363 b) i_version 2388 b) i_version
2364 c) i_rdev 2389 c) i_rdev
2365 d) notify mask? 2390 d) notify mask?
2366 e) generation 2391 e) generation
2367 f) size_seqcount 2392 f) size_seqcount
2368 T2 FIND_FIRST/FIND_NEXT FIND_FILE_UNIX 2393 T2 FIND_FIRST/FIND_NEXT FIND_FILE_UNIX
2369 TRANS2_GET_DFS_REFERRAL - OPTIONAL but recommended 2394 TRANS2_GET_DFS_REFERRAL - OPTIONAL but recommended
2370 T2_QFS_INFO QueryDevice/AttributeInfo - OPTIONAL 2395 T2_QFS_INFO QueryDevice/AttributeInfo - OPTIONAL
2371
2372
2373 */ 2396 */
2374 2397
2375/* xsymlink is a symlink format (used by MacOS) that can be used 2398/* xsymlink is a symlink format (used by MacOS) that can be used
2376 to save symlink info in a regular file when 2399 to save symlink info in a regular file when
2377 mounted to operating systems that do not 2400 mounted to operating systems that do not
2378 support the cifs Unix extensions or EAs (for xattr 2401 support the cifs Unix extensions or EAs (for xattr
2379 based symlinks). For such a file to be recognized 2402 based symlinks). For such a file to be recognized
2380 as containing symlink data: 2403 as containing symlink data:
2381 2404
2382 1) file size must be 1067, 2405 1) file size must be 1067,
2383 2) signature must begin file data, 2406 2) signature must begin file data,
2384 3) length field must be set to ASCII representation 2407 3) length field must be set to ASCII representation
2385 of a number which is less than or equal to 1024, 2408 of a number which is less than or equal to 1024,
2386 4) md5 must match that of the path data */ 2409 4) md5 must match that of the path data */
2387 2410
2388struct xsymlink { 2411struct xsymlink {
@@ -2393,10 +2416,10 @@ struct xsymlink {
2393 char length[4]; 2416 char length[4];
2394 char cr1; /* \n */ 2417 char cr1; /* \n */
2395/* md5 of valid subset of path ie path[0] through path[length-1] */ 2418/* md5 of valid subset of path ie path[0] through path[length-1] */
2396 __u8 md5[32]; 2419 __u8 md5[32];
2397 char cr2; /* \n */ 2420 char cr2; /* \n */
2398/* if room left, then end with \n then 0x20s by convention but not required */ 2421/* if room left, then end with \n then 0x20s by convention but not required */
2399 char path[1024]; 2422 char path[1024];
2400} __attribute__((packed)); 2423} __attribute__((packed));
2401 2424
2402typedef struct file_xattr_info { 2425typedef struct file_xattr_info {
@@ -2405,7 +2428,8 @@ typedef struct file_xattr_info {
2405 __u32 xattr_value_len; 2428 __u32 xattr_value_len;
2406 char xattr_name[0]; 2429 char xattr_name[0];
2407 /* followed by xattr_value[xattr_value_len], no pad */ 2430 /* followed by xattr_value[xattr_value_len], no pad */
2408} __attribute__((packed)) FILE_XATTR_INFO; /* extended attribute, info level 0x205 */ 2431} __attribute__((packed)) FILE_XATTR_INFO; /* extended attribute info
2432 level 0x205 */
2409 2433
2410 2434
2411/* flags for chattr command */ 2435/* flags for chattr command */
@@ -2431,8 +2455,9 @@ typedef struct file_xattr_info {
2431typedef struct file_chattr_info { 2455typedef struct file_chattr_info {
2432 __le64 mask; /* list of all possible attribute bits */ 2456 __le64 mask; /* list of all possible attribute bits */
2433 __le64 mode; /* list of actual attribute bits on this inode */ 2457 __le64 mode; /* list of actual attribute bits on this inode */
2434} __attribute__((packed)) FILE_CHATTR_INFO; /* ext attributes (chattr, chflags) level 0x206 */ 2458} __attribute__((packed)) FILE_CHATTR_INFO; /* ext attributes
2459 (chattr, chflags) level 0x206 */
2435 2460
2436#endif 2461#endif
2437 2462
2438#endif /* _CIFSPDU_H */ 2463#endif /* _CIFSPDU_H */
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 5d163e2b6143..04a69dafedba 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -16,7 +16,7 @@
16 * 16 *
17 * You should have received a copy of the GNU Lesser General Public License 17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software 18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21#ifndef _CIFSPROTO_H 21#ifndef _CIFSPROTO_H
22#define _CIFSPROTO_H 22#define _CIFSPROTO_H
@@ -49,9 +49,9 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *,
49 struct smb_hdr * /* out */ , 49 struct smb_hdr * /* out */ ,
50 int * /* bytes returned */ , const int long_op); 50 int * /* bytes returned */ , const int long_op);
51extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *, 51extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *,
52 struct kvec *, int /* nvec to send */, 52 struct kvec *, int /* nvec to send */,
53 int * /* type of buf returned */ , const int long_op); 53 int * /* type of buf returned */ , const int long_op);
54extern int SendReceiveBlockingLock(const unsigned int /* xid */ , 54extern int SendReceiveBlockingLock(const unsigned int /* xid */ ,
55 struct cifsTconInfo *, 55 struct cifsTconInfo *,
56 struct smb_hdr * /* input */ , 56 struct smb_hdr * /* input */ ,
57 struct smb_hdr * /* out */ , 57 struct smb_hdr * /* out */ ,
@@ -64,19 +64,19 @@ extern unsigned int smbCalcSize(struct smb_hdr *ptr);
64extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr); 64extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr);
65extern int decode_negTokenInit(unsigned char *security_blob, int length, 65extern int decode_negTokenInit(unsigned char *security_blob, int length,
66 enum securityEnum *secType); 66 enum securityEnum *secType);
67extern int cifs_inet_pton(int, char * source, void *dst); 67extern int cifs_inet_pton(int, char *source, void *dst);
68extern int map_smb_to_linux_error(struct smb_hdr *smb); 68extern int map_smb_to_linux_error(struct smb_hdr *smb);
69extern void header_assemble(struct smb_hdr *, char /* command */ , 69extern void header_assemble(struct smb_hdr *, char /* command */ ,
70 const struct cifsTconInfo *, int /* length of 70 const struct cifsTconInfo *, int /* length of
71 fixed section (word count) in two byte units */); 71 fixed section (word count) in two byte units */);
72extern int small_smb_init_no_tc(const int smb_cmd, const int wct, 72extern int small_smb_init_no_tc(const int smb_cmd, const int wct,
73 struct cifsSesInfo *ses, 73 struct cifsSesInfo *ses,
74 void ** request_buf); 74 void **request_buf);
75extern int CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, 75extern int CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
76 const int stage, 76 const int stage,
77 const struct nls_table *nls_cp); 77 const struct nls_table *nls_cp);
78extern __u16 GetNextMid(struct TCP_Server_Info *server); 78extern __u16 GetNextMid(struct TCP_Server_Info *server);
79extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16, 79extern struct oplock_q_entry *AllocOplockQEntry(struct inode *, u16,
80 struct cifsTconInfo *); 80 struct cifsTconInfo *);
81extern void DeleteOplockQEntry(struct oplock_q_entry *); 81extern void DeleteOplockQEntry(struct oplock_q_entry *);
82extern struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ ); 82extern struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ );
@@ -85,12 +85,12 @@ extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time);
85extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time); 85extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time);
86 86
87extern int cifs_get_inode_info(struct inode **pinode, 87extern int cifs_get_inode_info(struct inode **pinode,
88 const unsigned char *search_path, 88 const unsigned char *search_path,
89 FILE_ALL_INFO * pfile_info, 89 FILE_ALL_INFO * pfile_info,
90 struct super_block *sb, int xid); 90 struct super_block *sb, int xid);
91extern int cifs_get_inode_info_unix(struct inode **pinode, 91extern int cifs_get_inode_info_unix(struct inode **pinode,
92 const unsigned char *search_path, 92 const unsigned char *search_path,
93 struct super_block *sb,int xid); 93 struct super_block *sb, int xid);
94 94
95extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *, 95extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *,
96 const char *); 96 const char *);
@@ -98,8 +98,8 @@ extern int cifs_umount(struct super_block *, struct cifs_sb_info *);
98void cifs_proc_init(void); 98void cifs_proc_init(void);
99void cifs_proc_clean(void); 99void cifs_proc_clean(void);
100 100
101extern int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, 101extern int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
102 struct nls_table * nls_info); 102 struct nls_table *nls_info);
103extern int CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses); 103extern int CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses);
104 104
105extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, 105extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
@@ -108,11 +108,11 @@ extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
108 108
109extern int CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, 109extern int CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
110 const char *searchName, const struct nls_table *nls_codepage, 110 const char *searchName, const struct nls_table *nls_codepage,
111 __u16 *searchHandle, struct cifs_search_info * psrch_inf, 111 __u16 *searchHandle, struct cifs_search_info *psrch_inf,
112 int map, const char dirsep); 112 int map, const char dirsep);
113 113
114extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, 114extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
115 __u16 searchHandle, struct cifs_search_info * psrch_inf); 115 __u16 searchHandle, struct cifs_search_info *psrch_inf);
116 116
117extern int CIFSFindClose(const int, struct cifsTconInfo *tcon, 117extern int CIFSFindClose(const int, struct cifsTconInfo *tcon,
118 const __u16 search_handle); 118 const __u16 search_handle);
@@ -123,9 +123,9 @@ extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
123 int legacy /* whether to use old info level */, 123 int legacy /* whether to use old info level */,
124 const struct nls_table *nls_codepage, int remap); 124 const struct nls_table *nls_codepage, int remap);
125extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, 125extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
126 const unsigned char *searchName, 126 const unsigned char *searchName,
127 FILE_ALL_INFO * findData, 127 FILE_ALL_INFO *findData,
128 const struct nls_table *nls_codepage, int remap); 128 const struct nls_table *nls_codepage, int remap);
129 129
130extern int CIFSSMBUnixQPathInfo(const int xid, 130extern int CIFSSMBUnixQPathInfo(const int xid,
131 struct cifsTconInfo *tcon, 131 struct cifsTconInfo *tcon,
@@ -143,13 +143,13 @@ extern int connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
143 const char *old_path, 143 const char *old_path,
144 const struct nls_table *nls_codepage, int remap); 144 const struct nls_table *nls_codepage, int remap);
145extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, 145extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
146 const char *old_path, 146 const char *old_path,
147 const struct nls_table *nls_codepage, 147 const struct nls_table *nls_codepage,
148 unsigned int *pnum_referrals, 148 unsigned int *pnum_referrals,
149 unsigned char ** preferrals, 149 unsigned char **preferrals,
150 int remap); 150 int remap);
151extern void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, 151extern void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
152 struct super_block * sb, struct smb_vol * vol); 152 struct super_block *sb, struct smb_vol *vol);
153extern int CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, 153extern int CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon,
154 struct kstatfs *FSData); 154 struct kstatfs *FSData);
155extern int SMBOldQFSInfo(const int xid, struct cifsTconInfo *tcon, 155extern int SMBOldQFSInfo(const int xid, struct cifsTconInfo *tcon,
@@ -181,11 +181,11 @@ extern int CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon,
181 const struct nls_table *nls_codepage, 181 const struct nls_table *nls_codepage,
182 int remap_special_chars); 182 int remap_special_chars);
183extern int CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, 183extern int CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon,
184 __u64 size, __u16 fileHandle,__u32 opener_pid, 184 __u64 size, __u16 fileHandle, __u32 opener_pid,
185 int AllocSizeFlag); 185 int AllocSizeFlag);
186extern int CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *pTcon, 186extern int CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *pTcon,
187 char *full_path, __u64 mode, __u64 uid, 187 char *full_path, __u64 mode, __u64 uid,
188 __u64 gid, dev_t dev, 188 __u64 gid, dev_t dev,
189 const struct nls_table *nls_codepage, 189 const struct nls_table *nls_codepage,
190 int remap_special_chars); 190 int remap_special_chars);
191 191
@@ -196,7 +196,10 @@ extern int CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon,
196extern int CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon, 196extern int CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon,
197 const char *name, const struct nls_table *nls_codepage, 197 const char *name, const struct nls_table *nls_codepage,
198 int remap_special_chars); 198 int remap_special_chars);
199 199extern int CIFSPOSIXDelFile(const int xid, struct cifsTconInfo *tcon,
200 const char *name, __u16 type,
201 const struct nls_table *nls_codepage,
202 int remap_special_chars);
200extern int CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon, 203extern int CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon,
201 const char *name, 204 const char *name,
202 const struct nls_table *nls_codepage, 205 const struct nls_table *nls_codepage,
@@ -205,8 +208,8 @@ extern int CIFSSMBRename(const int xid, struct cifsTconInfo *tcon,
205 const char *fromName, const char *toName, 208 const char *fromName, const char *toName,
206 const struct nls_table *nls_codepage, 209 const struct nls_table *nls_codepage,
207 int remap_special_chars); 210 int remap_special_chars);
208extern int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon, 211extern int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon,
209 int netfid, char * target_name, 212 int netfid, char *target_name,
210 const struct nls_table *nls_codepage, 213 const struct nls_table *nls_codepage,
211 int remap_special_chars); 214 int remap_special_chars);
212extern int CIFSCreateHardLink(const int xid, 215extern int CIFSCreateHardLink(const int xid,
@@ -217,7 +220,7 @@ extern int CIFSCreateHardLink(const int xid,
217extern int CIFSUnixCreateHardLink(const int xid, 220extern int CIFSUnixCreateHardLink(const int xid,
218 struct cifsTconInfo *tcon, 221 struct cifsTconInfo *tcon,
219 const char *fromName, const char *toName, 222 const char *fromName, const char *toName,
220 const struct nls_table *nls_codepage, 223 const struct nls_table *nls_codepage,
221 int remap_special_chars); 224 int remap_special_chars);
222extern int CIFSUnixCreateSymLink(const int xid, 225extern int CIFSUnixCreateSymLink(const int xid,
223 struct cifsTconInfo *tcon, 226 struct cifsTconInfo *tcon,
@@ -228,7 +231,7 @@ extern int CIFSSMBUnixQuerySymLink(const int xid,
228 const unsigned char *searchName, 231 const unsigned char *searchName,
229 char *syminfo, const int buflen, 232 char *syminfo, const int buflen,
230 const struct nls_table *nls_codepage); 233 const struct nls_table *nls_codepage);
231extern int CIFSSMBQueryReparseLinkInfo(const int xid, 234extern int CIFSSMBQueryReparseLinkInfo(const int xid,
232 struct cifsTconInfo *tcon, 235 struct cifsTconInfo *tcon,
233 const unsigned char *searchName, 236 const unsigned char *searchName,
234 char *symlinkinfo, const int buflen, __u16 fid, 237 char *symlinkinfo, const int buflen, __u16 fid,
@@ -244,35 +247,35 @@ extern int SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon,
244 const int access_flags, const int omode, 247 const int access_flags, const int omode,
245 __u16 * netfid, int *pOplock, FILE_ALL_INFO *, 248 __u16 * netfid, int *pOplock, FILE_ALL_INFO *,
246 const struct nls_table *nls_codepage, int remap); 249 const struct nls_table *nls_codepage, int remap);
247extern int CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, 250extern int CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon,
248 u32 posix_flags, __u64 mode, __u16 * netfid, 251 u32 posix_flags, __u64 mode, __u16 * netfid,
249 FILE_UNIX_BASIC_INFO *pRetData, 252 FILE_UNIX_BASIC_INFO *pRetData,
250 __u32 *pOplock, const char *name, 253 __u32 *pOplock, const char *name,
251 const struct nls_table *nls_codepage, int remap); 254 const struct nls_table *nls_codepage, int remap);
252extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, 255extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon,
253 const int smb_file_id); 256 const int smb_file_id);
254 257
255extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, 258extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
256 const int netfid, unsigned int count, 259 const int netfid, unsigned int count,
257 const __u64 lseek, unsigned int *nbytes, char **buf, 260 const __u64 lseek, unsigned int *nbytes, char **buf,
258 int * return_buf_type); 261 int *return_buf_type);
259extern int CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, 262extern int CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
260 const int netfid, const unsigned int count, 263 const int netfid, const unsigned int count,
261 const __u64 lseek, unsigned int *nbytes, 264 const __u64 lseek, unsigned int *nbytes,
262 const char *buf, const char __user *ubuf, 265 const char *buf, const char __user *ubuf,
263 const int long_op); 266 const int long_op);
264extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, 267extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
265 const int netfid, const unsigned int count, 268 const int netfid, const unsigned int count,
266 const __u64 offset, unsigned int *nbytes, 269 const __u64 offset, unsigned int *nbytes,
267 struct kvec *iov, const int nvec, const int long_op); 270 struct kvec *iov, const int nvec, const int long_op);
268extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, 271extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
269 const unsigned char *searchName, __u64 * inode_number, 272 const unsigned char *searchName, __u64 * inode_number,
270 const struct nls_table *nls_codepage, 273 const struct nls_table *nls_codepage,
271 int remap_special_chars); 274 int remap_special_chars);
272extern int cifs_convertUCSpath(char *target, const __le16 *source, int maxlen, 275extern int cifs_convertUCSpath(char *target, const __le16 *source, int maxlen,
273 const struct nls_table * codepage); 276 const struct nls_table *codepage);
274extern int cifsConvertToUCS(__le16 * target, const char *source, int maxlen, 277extern int cifsConvertToUCS(__le16 *target, const char *source, int maxlen,
275 const struct nls_table * cp, int mapChars); 278 const struct nls_table *cp, int mapChars);
276 279
277extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, 280extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
278 const __u16 netfid, const __u64 len, 281 const __u16 netfid, const __u64 len,
@@ -281,7 +284,7 @@ extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
281 const int waitFlag); 284 const int waitFlag);
282extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, 285extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
283 const __u16 smb_file_id, const int get_flag, 286 const __u16 smb_file_id, const int get_flag,
284 const __u64 len, struct file_lock *, 287 const __u64 len, struct file_lock *,
285 const __u16 lock_type, const int waitFlag); 288 const __u16 lock_type, const int waitFlag);
286extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon); 289extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon);
287extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses); 290extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses);
@@ -291,54 +294,56 @@ extern void sesInfoFree(struct cifsSesInfo *);
291extern struct cifsTconInfo *tconInfoAlloc(void); 294extern struct cifsTconInfo *tconInfoAlloc(void);
292extern void tconInfoFree(struct cifsTconInfo *); 295extern void tconInfoFree(struct cifsTconInfo *);
293 296
294extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *,__u32 *); 297extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *, __u32 *);
295extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *, 298extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
296 __u32 *); 299 __u32 *);
297extern int cifs_verify_signature(struct smb_hdr *, const char * mac_key, 300extern int cifs_verify_signature(struct smb_hdr *,
298 __u32 expected_sequence_number); 301 const struct mac_key *mac_key,
299extern int cifs_calculate_mac_key(char * key,const char * rn,const char * pass); 302 __u32 expected_sequence_number);
300extern int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *, 303extern int cifs_calculate_mac_key(struct mac_key *key, const char *rn,
304 const char *pass);
305extern int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *,
301 const struct nls_table *); 306 const struct nls_table *);
302extern void CalcNTLMv2_response(const struct cifsSesInfo *, char * ); 307extern void CalcNTLMv2_response(const struct cifsSesInfo *, char * );
303extern void setup_ntlmv2_rsp(struct cifsSesInfo *, char *, 308extern void setup_ntlmv2_rsp(struct cifsSesInfo *, char *,
304 const struct nls_table *); 309 const struct nls_table *);
305#ifdef CONFIG_CIFS_WEAK_PW_HASH 310#ifdef CONFIG_CIFS_WEAK_PW_HASH
306extern void calc_lanman_hash(struct cifsSesInfo * ses, char * lnm_session_key); 311extern void calc_lanman_hash(struct cifsSesInfo *ses, char *lnm_session_key);
307#endif /* CIFS_WEAK_PW_HASH */ 312#endif /* CIFS_WEAK_PW_HASH */
308extern int CIFSSMBCopy(int xid, 313extern int CIFSSMBCopy(int xid,
309 struct cifsTconInfo *source_tcon, 314 struct cifsTconInfo *source_tcon,
310 const char *fromName, 315 const char *fromName,
311 const __u16 target_tid, 316 const __u16 target_tid,
312 const char *toName, const int flags, 317 const char *toName, const int flags,
313 const struct nls_table *nls_codepage, 318 const struct nls_table *nls_codepage,
314 int remap_special_chars); 319 int remap_special_chars);
315extern int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, 320extern int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
316 const int notify_subdirs,const __u16 netfid, 321 const int notify_subdirs, const __u16 netfid,
317 __u32 filter, struct file * file, int multishot, 322 __u32 filter, struct file *file, int multishot,
318 const struct nls_table *nls_codepage); 323 const struct nls_table *nls_codepage);
319extern ssize_t CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, 324extern ssize_t CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
320 const unsigned char *searchName, char * EAData, 325 const unsigned char *searchName, char *EAData,
321 size_t bufsize, const struct nls_table *nls_codepage, 326 size_t bufsize, const struct nls_table *nls_codepage,
322 int remap_special_chars); 327 int remap_special_chars);
323extern ssize_t CIFSSMBQueryEA(const int xid,struct cifsTconInfo * tcon, 328extern ssize_t CIFSSMBQueryEA(const int xid, struct cifsTconInfo *tcon,
324 const unsigned char * searchName,const unsigned char * ea_name, 329 const unsigned char *searchName, const unsigned char *ea_name,
325 unsigned char * ea_value, size_t buf_size, 330 unsigned char *ea_value, size_t buf_size,
326 const struct nls_table *nls_codepage, int remap_special_chars); 331 const struct nls_table *nls_codepage, int remap_special_chars);
327extern int CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, 332extern int CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon,
328 const char *fileName, const char * ea_name, 333 const char *fileName, const char *ea_name,
329 const void * ea_value, const __u16 ea_value_len, 334 const void *ea_value, const __u16 ea_value_len,
330 const struct nls_table *nls_codepage, int remap_special_chars); 335 const struct nls_table *nls_codepage, int remap_special_chars);
331extern int CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, 336extern int CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon,
332 __u16 fid, char *acl_inf, const int buflen, 337 __u16 fid, char *acl_inf, const int buflen,
333 const int acl_type /* ACCESS vs. DEFAULT */); 338 const int acl_type /* ACCESS vs. DEFAULT */);
334extern int CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon, 339extern int CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon,
335 const unsigned char *searchName, 340 const unsigned char *searchName,
336 char *acl_inf, const int buflen,const int acl_type, 341 char *acl_inf, const int buflen, const int acl_type,
337 const struct nls_table *nls_codepage, int remap_special_chars); 342 const struct nls_table *nls_codepage, int remap_special_chars);
338extern int CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon, 343extern int CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
339 const unsigned char *fileName, 344 const unsigned char *fileName,
340 const char *local_acl, const int buflen, const int acl_type, 345 const char *local_acl, const int buflen, const int acl_type,
341 const struct nls_table *nls_codepage, int remap_special_chars); 346 const struct nls_table *nls_codepage, int remap_special_chars);
342extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon, 347extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
343 const int netfid, __u64 * pExtAttrBits, __u64 *pMask); 348 const int netfid, __u64 * pExtAttrBits, __u64 *pMask);
344#endif /* _CIFSPROTO_H */ 349#endif /* _CIFSPROTO_H */
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 57419a176688..8eb102f940d4 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -48,7 +48,7 @@ static struct {
48 {LANMAN_PROT, "\2LM1.2X002"}, 48 {LANMAN_PROT, "\2LM1.2X002"},
49 {LANMAN2_PROT, "\2LANMAN2.1"}, 49 {LANMAN2_PROT, "\2LANMAN2.1"},
50#endif /* weak password hashing for legacy clients */ 50#endif /* weak password hashing for legacy clients */
51 {CIFS_PROT, "\2NT LM 0.12"}, 51 {CIFS_PROT, "\2NT LM 0.12"},
52 {POSIX_PROT, "\2POSIX 2"}, 52 {POSIX_PROT, "\2POSIX 2"},
53 {BAD_PROT, "\2"} 53 {BAD_PROT, "\2"}
54}; 54};
@@ -61,7 +61,7 @@ static struct {
61 {LANMAN_PROT, "\2LM1.2X002"}, 61 {LANMAN_PROT, "\2LM1.2X002"},
62 {LANMAN2_PROT, "\2LANMAN2.1"}, 62 {LANMAN2_PROT, "\2LANMAN2.1"},
63#endif /* weak password hashing for legacy clients */ 63#endif /* weak password hashing for legacy clients */
64 {CIFS_PROT, "\2NT LM 0.12"}, 64 {CIFS_PROT, "\2NT LM 0.12"},
65 {BAD_PROT, "\2"} 65 {BAD_PROT, "\2"}
66}; 66};
67#endif 67#endif
@@ -84,17 +84,17 @@ static struct {
84 84
85/* Mark as invalid, all open files on tree connections since they 85/* Mark as invalid, all open files on tree connections since they
86 were closed when session to server was lost */ 86 were closed when session to server was lost */
87static void mark_open_files_invalid(struct cifsTconInfo * pTcon) 87static void mark_open_files_invalid(struct cifsTconInfo *pTcon)
88{ 88{
89 struct cifsFileInfo *open_file = NULL; 89 struct cifsFileInfo *open_file = NULL;
90 struct list_head * tmp; 90 struct list_head *tmp;
91 struct list_head * tmp1; 91 struct list_head *tmp1;
92 92
93/* list all files open on tree connection and mark them invalid */ 93/* list all files open on tree connection and mark them invalid */
94 write_lock(&GlobalSMBSeslock); 94 write_lock(&GlobalSMBSeslock);
95 list_for_each_safe(tmp, tmp1, &pTcon->openFileList) { 95 list_for_each_safe(tmp, tmp1, &pTcon->openFileList) {
96 open_file = list_entry(tmp,struct cifsFileInfo, tlist); 96 open_file = list_entry(tmp, struct cifsFileInfo, tlist);
97 if(open_file) { 97 if (open_file) {
98 open_file->invalidHandle = TRUE; 98 open_file->invalidHandle = TRUE;
99 } 99 }
100 } 100 }
@@ -113,75 +113,78 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
113 /* SMBs NegProt, SessSetup, uLogoff do not have tcon yet so 113 /* SMBs NegProt, SessSetup, uLogoff do not have tcon yet so
114 check for tcp and smb session status done differently 114 check for tcp and smb session status done differently
115 for those three - in the calling routine */ 115 for those three - in the calling routine */
116 if(tcon) { 116 if (tcon) {
117 if(tcon->tidStatus == CifsExiting) { 117 if (tcon->tidStatus == CifsExiting) {
118 /* only tree disconnect, open, and write, 118 /* only tree disconnect, open, and write,
119 (and ulogoff which does not have tcon) 119 (and ulogoff which does not have tcon)
120 are allowed as we start force umount */ 120 are allowed as we start force umount */
121 if((smb_command != SMB_COM_WRITE_ANDX) && 121 if ((smb_command != SMB_COM_WRITE_ANDX) &&
122 (smb_command != SMB_COM_OPEN_ANDX) && 122 (smb_command != SMB_COM_OPEN_ANDX) &&
123 (smb_command != SMB_COM_TREE_DISCONNECT)) { 123 (smb_command != SMB_COM_TREE_DISCONNECT)) {
124 cFYI(1,("can not send cmd %d while umounting", 124 cFYI(1, ("can not send cmd %d while umounting",
125 smb_command)); 125 smb_command));
126 return -ENODEV; 126 return -ENODEV;
127 } 127 }
128 } 128 }
129 if((tcon->ses) && (tcon->ses->status != CifsExiting) && 129 if ((tcon->ses) && (tcon->ses->status != CifsExiting) &&
130 (tcon->ses->server)){ 130 (tcon->ses->server)) {
131 struct nls_table *nls_codepage; 131 struct nls_table *nls_codepage;
132 /* Give Demultiplex thread up to 10 seconds to 132 /* Give Demultiplex thread up to 10 seconds to
133 reconnect, should be greater than cifs socket 133 reconnect, should be greater than cifs socket
134 timeout which is 7 seconds */ 134 timeout which is 7 seconds */
135 while(tcon->ses->server->tcpStatus == CifsNeedReconnect) { 135 while (tcon->ses->server->tcpStatus ==
136 CifsNeedReconnect) {
136 wait_event_interruptible_timeout(tcon->ses->server->response_q, 137 wait_event_interruptible_timeout(tcon->ses->server->response_q,
137 (tcon->ses->server->tcpStatus == CifsGood), 10 * HZ); 138 (tcon->ses->server->tcpStatus ==
138 if(tcon->ses->server->tcpStatus == CifsNeedReconnect) { 139 CifsGood), 10 * HZ);
140 if (tcon->ses->server->tcpStatus ==
141 CifsNeedReconnect) {
139 /* on "soft" mounts we wait once */ 142 /* on "soft" mounts we wait once */
140 if((tcon->retry == FALSE) || 143 if ((tcon->retry == FALSE) ||
141 (tcon->ses->status == CifsExiting)) { 144 (tcon->ses->status == CifsExiting)) {
142 cFYI(1,("gave up waiting on reconnect in smb_init")); 145 cFYI(1, ("gave up waiting on "
146 "reconnect in smb_init"));
143 return -EHOSTDOWN; 147 return -EHOSTDOWN;
144 } /* else "hard" mount - keep retrying 148 } /* else "hard" mount - keep retrying
145 until process is killed or server 149 until process is killed or server
146 comes back on-line */ 150 comes back on-line */
147 } else /* TCP session is reestablished now */ 151 } else /* TCP session is reestablished now */
148 break; 152 break;
149
150 } 153 }
151 154
152 nls_codepage = load_nls_default(); 155 nls_codepage = load_nls_default();
153 /* need to prevent multiple threads trying to 156 /* need to prevent multiple threads trying to
154 simultaneously reconnect the same SMB session */ 157 simultaneously reconnect the same SMB session */
155 down(&tcon->ses->sesSem); 158 down(&tcon->ses->sesSem);
156 if(tcon->ses->status == CifsNeedReconnect) 159 if (tcon->ses->status == CifsNeedReconnect)
157 rc = cifs_setup_session(0, tcon->ses, 160 rc = cifs_setup_session(0, tcon->ses,
158 nls_codepage); 161 nls_codepage);
159 if(!rc && (tcon->tidStatus == CifsNeedReconnect)) { 162 if (!rc && (tcon->tidStatus == CifsNeedReconnect)) {
160 mark_open_files_invalid(tcon); 163 mark_open_files_invalid(tcon);
161 rc = CIFSTCon(0, tcon->ses, tcon->treeName, 164 rc = CIFSTCon(0, tcon->ses, tcon->treeName,
162 tcon, nls_codepage); 165 tcon, nls_codepage);
163 up(&tcon->ses->sesSem); 166 up(&tcon->ses->sesSem);
164 /* tell server which Unix caps we support */ 167 /* tell server which Unix caps we support */
165 if (tcon->ses->capabilities & CAP_UNIX) 168 if (tcon->ses->capabilities & CAP_UNIX)
166 reset_cifs_unix_caps(0 /* no xid */, 169 reset_cifs_unix_caps(0 /* no xid */,
167 tcon, 170 tcon,
168 NULL /* we do not know sb */, 171 NULL /* we do not know sb */,
169 NULL /* no vol info */); 172 NULL /* no vol info */);
170 /* BB FIXME add code to check if wsize needs 173 /* BB FIXME add code to check if wsize needs
171 update due to negotiated smb buffer size 174 update due to negotiated smb buffer size
172 shrinking */ 175 shrinking */
173 if(rc == 0) 176 if (rc == 0)
174 atomic_inc(&tconInfoReconnectCount); 177 atomic_inc(&tconInfoReconnectCount);
175 178
176 cFYI(1, ("reconnect tcon rc = %d", rc)); 179 cFYI(1, ("reconnect tcon rc = %d", rc));
177 /* Removed call to reopen open files here - 180 /* Removed call to reopen open files here.
178 it is safer (and faster) to reopen files 181 It is safer (and faster) to reopen files
179 one at a time as needed in read and write */ 182 one at a time as needed in read and write */
180 183
181 /* Check if handle based operation so we 184 /* Check if handle based operation so we
182 know whether we can continue or not without 185 know whether we can continue or not without
183 returning to caller to reset file handle */ 186 returning to caller to reset file handle */
184 switch(smb_command) { 187 switch (smb_command) {
185 case SMB_COM_READ_ANDX: 188 case SMB_COM_READ_ANDX:
186 case SMB_COM_WRITE_ANDX: 189 case SMB_COM_WRITE_ANDX:
187 case SMB_COM_CLOSE: 190 case SMB_COM_CLOSE:
@@ -200,7 +203,7 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
200 return -EIO; 203 return -EIO;
201 } 204 }
202 } 205 }
203 if(rc) 206 if (rc)
204 return rc; 207 return rc;
205 208
206 *request_buf = cifs_small_buf_get(); 209 *request_buf = cifs_small_buf_get();
@@ -209,23 +212,24 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
209 return -ENOMEM; 212 return -ENOMEM;
210 } 213 }
211 214
212 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,wct); 215 header_assemble((struct smb_hdr *) *request_buf, smb_command,
216 tcon, wct);
213 217
214 if(tcon != NULL) 218 if (tcon != NULL)
215 cifs_stats_inc(&tcon->num_smbs_sent); 219 cifs_stats_inc(&tcon->num_smbs_sent);
216 220
217 return rc; 221 return rc;
218} 222}
219 223
220int 224int
221small_smb_init_no_tc(const int smb_command, const int wct, 225small_smb_init_no_tc(const int smb_command, const int wct,
222 struct cifsSesInfo *ses, void **request_buf) 226 struct cifsSesInfo *ses, void **request_buf)
223{ 227{
224 int rc; 228 int rc;
225 struct smb_hdr * buffer; 229 struct smb_hdr *buffer;
226 230
227 rc = small_smb_init(smb_command, wct, NULL, request_buf); 231 rc = small_smb_init(smb_command, wct, NULL, request_buf);
228 if(rc) 232 if (rc)
229 return rc; 233 return rc;
230 234
231 buffer = (struct smb_hdr *)*request_buf; 235 buffer = (struct smb_hdr *)*request_buf;
@@ -237,7 +241,7 @@ small_smb_init_no_tc(const int smb_command, const int wct,
237 241
238 /* uid, tid can stay at zero as set in header assemble */ 242 /* uid, tid can stay at zero as set in header assemble */
239 243
240 /* BB add support for turning on the signing when 244 /* BB add support for turning on the signing when
241 this function is used after 1st of session setup requests */ 245 this function is used after 1st of session setup requests */
242 246
243 return rc; 247 return rc;
@@ -254,52 +258,53 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
254 /* SMBs NegProt, SessSetup, uLogoff do not have tcon yet so 258 /* SMBs NegProt, SessSetup, uLogoff do not have tcon yet so
255 check for tcp and smb session status done differently 259 check for tcp and smb session status done differently
256 for those three - in the calling routine */ 260 for those three - in the calling routine */
257 if(tcon) { 261 if (tcon) {
258 if(tcon->tidStatus == CifsExiting) { 262 if (tcon->tidStatus == CifsExiting) {
259 /* only tree disconnect, open, and write, 263 /* only tree disconnect, open, and write,
260 (and ulogoff which does not have tcon) 264 (and ulogoff which does not have tcon)
261 are allowed as we start force umount */ 265 are allowed as we start force umount */
262 if((smb_command != SMB_COM_WRITE_ANDX) && 266 if ((smb_command != SMB_COM_WRITE_ANDX) &&
263 (smb_command != SMB_COM_OPEN_ANDX) && 267 (smb_command != SMB_COM_OPEN_ANDX) &&
264 (smb_command != SMB_COM_TREE_DISCONNECT)) { 268 (smb_command != SMB_COM_TREE_DISCONNECT)) {
265 cFYI(1,("can not send cmd %d while umounting", 269 cFYI(1, ("can not send cmd %d while umounting",
266 smb_command)); 270 smb_command));
267 return -ENODEV; 271 return -ENODEV;
268 } 272 }
269 } 273 }
270 274
271 if((tcon->ses) && (tcon->ses->status != CifsExiting) && 275 if ((tcon->ses) && (tcon->ses->status != CifsExiting) &&
272 (tcon->ses->server)){ 276 (tcon->ses->server)) {
273 struct nls_table *nls_codepage; 277 struct nls_table *nls_codepage;
274 /* Give Demultiplex thread up to 10 seconds to 278 /* Give Demultiplex thread up to 10 seconds to
275 reconnect, should be greater than cifs socket 279 reconnect, should be greater than cifs socket
276 timeout which is 7 seconds */ 280 timeout which is 7 seconds */
277 while(tcon->ses->server->tcpStatus == CifsNeedReconnect) { 281 while (tcon->ses->server->tcpStatus ==
282 CifsNeedReconnect) {
278 wait_event_interruptible_timeout(tcon->ses->server->response_q, 283 wait_event_interruptible_timeout(tcon->ses->server->response_q,
279 (tcon->ses->server->tcpStatus == CifsGood), 10 * HZ); 284 (tcon->ses->server->tcpStatus ==
280 if(tcon->ses->server->tcpStatus == 285 CifsGood), 10 * HZ);
286 if (tcon->ses->server->tcpStatus ==
281 CifsNeedReconnect) { 287 CifsNeedReconnect) {
282 /* on "soft" mounts we wait once */ 288 /* on "soft" mounts we wait once */
283 if((tcon->retry == FALSE) || 289 if ((tcon->retry == FALSE) ||
284 (tcon->ses->status == CifsExiting)) { 290 (tcon->ses->status == CifsExiting)) {
285 cFYI(1,("gave up waiting on reconnect in smb_init")); 291 cFYI(1, ("gave up waiting on "
292 "reconnect in smb_init"));
286 return -EHOSTDOWN; 293 return -EHOSTDOWN;
287 } /* else "hard" mount - keep retrying 294 } /* else "hard" mount - keep retrying
288 until process is killed or server 295 until process is killed or server
289 comes on-line */ 296 comes on-line */
290 } else /* TCP session is reestablished now */ 297 } else /* TCP session is reestablished now */
291 break; 298 break;
292
293 } 299 }
294
295 nls_codepage = load_nls_default(); 300 nls_codepage = load_nls_default();
296 /* need to prevent multiple threads trying to 301 /* need to prevent multiple threads trying to
297 simultaneously reconnect the same SMB session */ 302 simultaneously reconnect the same SMB session */
298 down(&tcon->ses->sesSem); 303 down(&tcon->ses->sesSem);
299 if(tcon->ses->status == CifsNeedReconnect) 304 if (tcon->ses->status == CifsNeedReconnect)
300 rc = cifs_setup_session(0, tcon->ses, 305 rc = cifs_setup_session(0, tcon->ses,
301 nls_codepage); 306 nls_codepage);
302 if(!rc && (tcon->tidStatus == CifsNeedReconnect)) { 307 if (!rc && (tcon->tidStatus == CifsNeedReconnect)) {
303 mark_open_files_invalid(tcon); 308 mark_open_files_invalid(tcon);
304 rc = CIFSTCon(0, tcon->ses, tcon->treeName, 309 rc = CIFSTCon(0, tcon->ses, tcon->treeName,
305 tcon, nls_codepage); 310 tcon, nls_codepage);
@@ -307,24 +312,24 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
307 /* tell server which Unix caps we support */ 312 /* tell server which Unix caps we support */
308 if (tcon->ses->capabilities & CAP_UNIX) 313 if (tcon->ses->capabilities & CAP_UNIX)
309 reset_cifs_unix_caps(0 /* no xid */, 314 reset_cifs_unix_caps(0 /* no xid */,
310 tcon, 315 tcon,
311 NULL /* do not know sb */, 316 NULL /* do not know sb */,
312 NULL /* no vol info */); 317 NULL /* no vol info */);
313 /* BB FIXME add code to check if wsize needs 318 /* BB FIXME add code to check if wsize needs
314 update due to negotiated smb buffer size 319 update due to negotiated smb buffer size
315 shrinking */ 320 shrinking */
316 if(rc == 0) 321 if (rc == 0)
317 atomic_inc(&tconInfoReconnectCount); 322 atomic_inc(&tconInfoReconnectCount);
318 323
319 cFYI(1, ("reconnect tcon rc = %d", rc)); 324 cFYI(1, ("reconnect tcon rc = %d", rc));
320 /* Removed call to reopen open files here - 325 /* Removed call to reopen open files here.
321 it is safer (and faster) to reopen files 326 It is safer (and faster) to reopen files
322 one at a time as needed in read and write */ 327 one at a time as needed in read and write */
323 328
324 /* Check if handle based operation so we 329 /* Check if handle based operation so we
325 know whether we can continue or not without 330 know whether we can continue or not without
326 returning to caller to reset file handle */ 331 returning to caller to reset file handle */
327 switch(smb_command) { 332 switch (smb_command) {
328 case SMB_COM_READ_ANDX: 333 case SMB_COM_READ_ANDX:
329 case SMB_COM_WRITE_ANDX: 334 case SMB_COM_WRITE_ANDX:
330 case SMB_COM_CLOSE: 335 case SMB_COM_CLOSE:
@@ -343,7 +348,7 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
343 return -EIO; 348 return -EIO;
344 } 349 }
345 } 350 }
346 if(rc) 351 if (rc)
347 return rc; 352 return rc;
348 353
349 *request_buf = cifs_buf_get(); 354 *request_buf = cifs_buf_get();
@@ -355,48 +360,48 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
355 /* potential retries of smb operations it turns out we can determine */ 360 /* potential retries of smb operations it turns out we can determine */
356 /* from the mid flags when the request buffer can be resent without */ 361 /* from the mid flags when the request buffer can be resent without */
357 /* having to use a second distinct buffer for the response */ 362 /* having to use a second distinct buffer for the response */
358 if(response_buf) 363 if (response_buf)
359 *response_buf = *request_buf; 364 *response_buf = *request_buf;
360 365
361 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon, 366 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
362 wct /*wct */ ); 367 wct /*wct */ );
363 368
364 if(tcon != NULL) 369 if (tcon != NULL)
365 cifs_stats_inc(&tcon->num_smbs_sent); 370 cifs_stats_inc(&tcon->num_smbs_sent);
366 371
367 return rc; 372 return rc;
368} 373}
369 374
370static int validate_t2(struct smb_t2_rsp * pSMB) 375static int validate_t2(struct smb_t2_rsp *pSMB)
371{ 376{
372 int rc = -EINVAL; 377 int rc = -EINVAL;
373 int total_size; 378 int total_size;
374 char * pBCC; 379 char *pBCC;
375 380
376 /* check for plausible wct, bcc and t2 data and parm sizes */ 381 /* check for plausible wct, bcc and t2 data and parm sizes */
377 /* check for parm and data offset going beyond end of smb */ 382 /* check for parm and data offset going beyond end of smb */
378 if(pSMB->hdr.WordCount >= 10) { 383 if (pSMB->hdr.WordCount >= 10) {
379 if((le16_to_cpu(pSMB->t2_rsp.ParameterOffset) <= 1024) && 384 if ((le16_to_cpu(pSMB->t2_rsp.ParameterOffset) <= 1024) &&
380 (le16_to_cpu(pSMB->t2_rsp.DataOffset) <= 1024)) { 385 (le16_to_cpu(pSMB->t2_rsp.DataOffset) <= 1024)) {
381 /* check that bcc is at least as big as parms + data */ 386 /* check that bcc is at least as big as parms + data */
382 /* check that bcc is less than negotiated smb buffer */ 387 /* check that bcc is less than negotiated smb buffer */
383 total_size = le16_to_cpu(pSMB->t2_rsp.ParameterCount); 388 total_size = le16_to_cpu(pSMB->t2_rsp.ParameterCount);
384 if(total_size < 512) { 389 if (total_size < 512) {
385 total_size+=le16_to_cpu(pSMB->t2_rsp.DataCount); 390 total_size +=
391 le16_to_cpu(pSMB->t2_rsp.DataCount);
386 /* BCC le converted in SendReceive */ 392 /* BCC le converted in SendReceive */
387 pBCC = (pSMB->hdr.WordCount * 2) + 393 pBCC = (pSMB->hdr.WordCount * 2) +
388 sizeof(struct smb_hdr) + 394 sizeof(struct smb_hdr) +
389 (char *)pSMB; 395 (char *)pSMB;
390 if((total_size <= (*(u16 *)pBCC)) && 396 if ((total_size <= (*(u16 *)pBCC)) &&
391 (total_size < 397 (total_size <
392 CIFSMaxBufSize+MAX_CIFS_HDR_SIZE)) { 398 CIFSMaxBufSize+MAX_CIFS_HDR_SIZE)) {
393 return 0; 399 return 0;
394 } 400 }
395
396 } 401 }
397 } 402 }
398 } 403 }
399 cifs_dump_mem("Invalid transact2 SMB: ",(char *)pSMB, 404 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
400 sizeof(struct smb_t2_rsp) + 16); 405 sizeof(struct smb_t2_rsp) + 16);
401 return rc; 406 return rc;
402} 407}
@@ -408,12 +413,12 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
408 int rc = 0; 413 int rc = 0;
409 int bytes_returned; 414 int bytes_returned;
410 int i; 415 int i;
411 struct TCP_Server_Info * server; 416 struct TCP_Server_Info *server;
412 u16 count; 417 u16 count;
413 unsigned int secFlags; 418 unsigned int secFlags;
414 u16 dialect; 419 u16 dialect;
415 420
416 if(ses->server) 421 if (ses->server)
417 server = ses->server; 422 server = ses->server;
418 else { 423 else {
419 rc = -EIO; 424 rc = -EIO;
@@ -425,20 +430,20 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
425 return rc; 430 return rc;
426 431
427 /* if any of auth flags (ie not sign or seal) are overriden use them */ 432 /* if any of auth flags (ie not sign or seal) are overriden use them */
428 if(ses->overrideSecFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL))) 433 if (ses->overrideSecFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL)))
429 secFlags = ses->overrideSecFlg; 434 secFlags = ses->overrideSecFlg; /* BB FIXME fix sign flags? */
430 else /* if override flags set only sign/seal OR them with global auth */ 435 else /* if override flags set only sign/seal OR them with global auth */
431 secFlags = extended_security | ses->overrideSecFlg; 436 secFlags = extended_security | ses->overrideSecFlg;
432 437
433 cFYI(1,("secFlags 0x%x",secFlags)); 438 cFYI(1, ("secFlags 0x%x", secFlags));
434 439
435 pSMB->hdr.Mid = GetNextMid(server); 440 pSMB->hdr.Mid = GetNextMid(server);
436 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS); 441 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
437 if ((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5) 442 if ((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5)
438 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; 443 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
439 444
440 count = 0; 445 count = 0;
441 for(i=0;i<CIFS_NUM_PROT;i++) { 446 for (i = 0; i < CIFS_NUM_PROT; i++) {
442 strncpy(pSMB->DialectsArray+count, protocols[i].name, 16); 447 strncpy(pSMB->DialectsArray+count, protocols[i].name, 16);
443 count += strlen(protocols[i].name) + 1; 448 count += strlen(protocols[i].name) + 1;
444 /* null at end of source and target buffers anyway */ 449 /* null at end of source and target buffers anyway */
@@ -448,26 +453,26 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
448 453
449 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, 454 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
450 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 455 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
451 if (rc != 0) 456 if (rc != 0)
452 goto neg_err_exit; 457 goto neg_err_exit;
453 458
454 dialect = le16_to_cpu(pSMBr->DialectIndex); 459 dialect = le16_to_cpu(pSMBr->DialectIndex);
455 cFYI(1,("Dialect: %d", dialect)); 460 cFYI(1, ("Dialect: %d", dialect));
456 /* Check wct = 1 error case */ 461 /* Check wct = 1 error case */
457 if((pSMBr->hdr.WordCount < 13) || (dialect == BAD_PROT)) { 462 if ((pSMBr->hdr.WordCount < 13) || (dialect == BAD_PROT)) {
458 /* core returns wct = 1, but we do not ask for core - otherwise 463 /* core returns wct = 1, but we do not ask for core - otherwise
459 small wct just comes when dialect index is -1 indicating we 464 small wct just comes when dialect index is -1 indicating we
460 could not negotiate a common dialect */ 465 could not negotiate a common dialect */
461 rc = -EOPNOTSUPP; 466 rc = -EOPNOTSUPP;
462 goto neg_err_exit; 467 goto neg_err_exit;
463#ifdef CONFIG_CIFS_WEAK_PW_HASH 468#ifdef CONFIG_CIFS_WEAK_PW_HASH
464 } else if((pSMBr->hdr.WordCount == 13) 469 } else if ((pSMBr->hdr.WordCount == 13)
465 && ((dialect == LANMAN_PROT) 470 && ((dialect == LANMAN_PROT)
466 || (dialect == LANMAN2_PROT))) { 471 || (dialect == LANMAN2_PROT))) {
467 __s16 tmp; 472 __s16 tmp;
468 struct lanman_neg_rsp * rsp = (struct lanman_neg_rsp *)pSMBr; 473 struct lanman_neg_rsp *rsp = (struct lanman_neg_rsp *)pSMBr;
469 474
470 if((secFlags & CIFSSEC_MAY_LANMAN) || 475 if ((secFlags & CIFSSEC_MAY_LANMAN) ||
471 (secFlags & CIFSSEC_MAY_PLNTXT)) 476 (secFlags & CIFSSEC_MAY_PLNTXT))
472 server->secType = LANMAN; 477 server->secType = LANMAN;
473 else { 478 else {
@@ -475,7 +480,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
475 " in /proc/fs/cifs/SecurityFlags")); 480 " in /proc/fs/cifs/SecurityFlags"));
476 rc = -EOPNOTSUPP; 481 rc = -EOPNOTSUPP;
477 goto neg_err_exit; 482 goto neg_err_exit;
478 } 483 }
479 server->secMode = (__u8)le16_to_cpu(rsp->SecurityMode); 484 server->secMode = (__u8)le16_to_cpu(rsp->SecurityMode);
480 server->maxReq = le16_to_cpu(rsp->MaxMpxCount); 485 server->maxReq = le16_to_cpu(rsp->MaxMpxCount);
481 server->maxBuf = min((__u32)le16_to_cpu(rsp->MaxBufSize), 486 server->maxBuf = min((__u32)le16_to_cpu(rsp->MaxBufSize),
@@ -483,7 +488,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
483 GETU32(server->sessid) = le32_to_cpu(rsp->SessionKey); 488 GETU32(server->sessid) = le32_to_cpu(rsp->SessionKey);
484 /* even though we do not use raw we might as well set this 489 /* even though we do not use raw we might as well set this
485 accurately, in case we ever find a need for it */ 490 accurately, in case we ever find a need for it */
486 if((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) { 491 if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) {
487 server->maxRw = 0xFF00; 492 server->maxRw = 0xFF00;
488 server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE; 493 server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE;
489 } else { 494 } else {
@@ -504,29 +509,29 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
504 utc = CURRENT_TIME; 509 utc = CURRENT_TIME;
505 ts = cnvrtDosUnixTm(le16_to_cpu(rsp->SrvTime.Date), 510 ts = cnvrtDosUnixTm(le16_to_cpu(rsp->SrvTime.Date),
506 le16_to_cpu(rsp->SrvTime.Time)); 511 le16_to_cpu(rsp->SrvTime.Time));
507 cFYI(1,("SrvTime: %d sec since 1970 (utc: %d) diff: %d", 512 cFYI(1, ("SrvTime %d sec since 1970 (utc: %d) diff: %d",
508 (int)ts.tv_sec, (int)utc.tv_sec, 513 (int)ts.tv_sec, (int)utc.tv_sec,
509 (int)(utc.tv_sec - ts.tv_sec))); 514 (int)(utc.tv_sec - ts.tv_sec)));
510 val = (int)(utc.tv_sec - ts.tv_sec); 515 val = (int)(utc.tv_sec - ts.tv_sec);
511 seconds = val < 0 ? -val : val; 516 seconds = val < 0 ? -val : val;
512 result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ; 517 result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
513 remain = seconds % MIN_TZ_ADJ; 518 remain = seconds % MIN_TZ_ADJ;
514 if(remain >= (MIN_TZ_ADJ / 2)) 519 if (remain >= (MIN_TZ_ADJ / 2))
515 result += MIN_TZ_ADJ; 520 result += MIN_TZ_ADJ;
516 if(val < 0) 521 if (val < 0)
517 result = - result; 522 result = - result;
518 server->timeAdj = result; 523 server->timeAdj = result;
519 } else { 524 } else {
520 server->timeAdj = (int)tmp; 525 server->timeAdj = (int)tmp;
521 server->timeAdj *= 60; /* also in seconds */ 526 server->timeAdj *= 60; /* also in seconds */
522 } 527 }
523 cFYI(1,("server->timeAdj: %d seconds", server->timeAdj)); 528 cFYI(1, ("server->timeAdj: %d seconds", server->timeAdj));
524 529
525 530
526 /* BB get server time for time conversions and add 531 /* BB get server time for time conversions and add
527 code to use it and timezone since this is not UTC */ 532 code to use it and timezone since this is not UTC */
528 533
529 if (rsp->EncryptionKeyLength == 534 if (rsp->EncryptionKeyLength ==
530 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) { 535 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
531 memcpy(server->cryptKey, rsp->EncryptionKey, 536 memcpy(server->cryptKey, rsp->EncryptionKey,
532 CIFS_CRYPTO_KEY_SIZE); 537 CIFS_CRYPTO_KEY_SIZE);
@@ -535,39 +540,39 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
535 goto neg_err_exit; 540 goto neg_err_exit;
536 } 541 }
537 542
538 cFYI(1,("LANMAN negotiated")); 543 cFYI(1, ("LANMAN negotiated"));
539 /* we will not end up setting signing flags - as no signing 544 /* we will not end up setting signing flags - as no signing
540 was in LANMAN and server did not return the flags on */ 545 was in LANMAN and server did not return the flags on */
541 goto signing_check; 546 goto signing_check;
542#else /* weak security disabled */ 547#else /* weak security disabled */
543 } else if(pSMBr->hdr.WordCount == 13) { 548 } else if (pSMBr->hdr.WordCount == 13) {
544 cERROR(1,("mount failed, cifs module not built " 549 cERROR(1, ("mount failed, cifs module not built "
545 "with CIFS_WEAK_PW_HASH support")); 550 "with CIFS_WEAK_PW_HASH support"));
546 rc = -EOPNOTSUPP; 551 rc = -EOPNOTSUPP;
547#endif /* WEAK_PW_HASH */ 552#endif /* WEAK_PW_HASH */
548 goto neg_err_exit; 553 goto neg_err_exit;
549 } else if(pSMBr->hdr.WordCount != 17) { 554 } else if (pSMBr->hdr.WordCount != 17) {
550 /* unknown wct */ 555 /* unknown wct */
551 rc = -EOPNOTSUPP; 556 rc = -EOPNOTSUPP;
552 goto neg_err_exit; 557 goto neg_err_exit;
553 } 558 }
554 /* else wct == 17 NTLM */ 559 /* else wct == 17 NTLM */
555 server->secMode = pSMBr->SecurityMode; 560 server->secMode = pSMBr->SecurityMode;
556 if((server->secMode & SECMODE_USER) == 0) 561 if ((server->secMode & SECMODE_USER) == 0)
557 cFYI(1,("share mode security")); 562 cFYI(1, ("share mode security"));
558 563
559 if((server->secMode & SECMODE_PW_ENCRYPT) == 0) 564 if ((server->secMode & SECMODE_PW_ENCRYPT) == 0)
560#ifdef CONFIG_CIFS_WEAK_PW_HASH 565#ifdef CONFIG_CIFS_WEAK_PW_HASH
561 if ((secFlags & CIFSSEC_MAY_PLNTXT) == 0) 566 if ((secFlags & CIFSSEC_MAY_PLNTXT) == 0)
562#endif /* CIFS_WEAK_PW_HASH */ 567#endif /* CIFS_WEAK_PW_HASH */
563 cERROR(1,("Server requests plain text password" 568 cERROR(1, ("Server requests plain text password"
564 " but client support disabled")); 569 " but client support disabled"));
565 570
566 if((secFlags & CIFSSEC_MUST_NTLMV2) == CIFSSEC_MUST_NTLMV2) 571 if ((secFlags & CIFSSEC_MUST_NTLMV2) == CIFSSEC_MUST_NTLMV2)
567 server->secType = NTLMv2; 572 server->secType = NTLMv2;
568 else if(secFlags & CIFSSEC_MAY_NTLM) 573 else if (secFlags & CIFSSEC_MAY_NTLM)
569 server->secType = NTLM; 574 server->secType = NTLM;
570 else if(secFlags & CIFSSEC_MAY_NTLMV2) 575 else if (secFlags & CIFSSEC_MAY_NTLMV2)
571 server->secType = NTLMv2; 576 server->secType = NTLMv2;
572 /* else krb5 ... any others ... */ 577 /* else krb5 ... any others ... */
573 578
@@ -596,7 +601,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
596 601
597 /* BB might be helpful to save off the domain of server here */ 602 /* BB might be helpful to save off the domain of server here */
598 603
599 if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) && 604 if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) &&
600 (server->capabilities & CAP_EXTENDED_SECURITY)) { 605 (server->capabilities & CAP_EXTENDED_SECURITY)) {
601 count = pSMBr->ByteCount; 606 count = pSMBr->ByteCount;
602 if (count < 16) 607 if (count < 16)
@@ -620,7 +625,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
620 SecurityBlob, 625 SecurityBlob,
621 count - 16, 626 count - 16,
622 &server->secType); 627 &server->secType);
623 if(rc == 1) { 628 if (rc == 1) {
624 /* BB Need to fill struct for sessetup here */ 629 /* BB Need to fill struct for sessetup here */
625 rc = -EOPNOTSUPP; 630 rc = -EOPNOTSUPP;
626 } else { 631 } else {
@@ -633,26 +638,37 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
633#ifdef CONFIG_CIFS_WEAK_PW_HASH 638#ifdef CONFIG_CIFS_WEAK_PW_HASH
634signing_check: 639signing_check:
635#endif 640#endif
636 if(sign_CIFS_PDUs == FALSE) { 641 if ((secFlags & CIFSSEC_MAY_SIGN) == 0) {
637 if(server->secMode & SECMODE_SIGN_REQUIRED) 642 /* MUST_SIGN already includes the MAY_SIGN FLAG
638 cERROR(1,("Server requires " 643 so if this is zero it means that signing is disabled */
639 "/proc/fs/cifs/PacketSigningEnabled to be on")); 644 cFYI(1, ("Signing disabled"));
640 server->secMode &= 645 if (server->secMode & SECMODE_SIGN_REQUIRED)
646 cERROR(1, ("Server requires "
647 "/proc/fs/cifs/PacketSigningEnabled "
648 "to be on"));
649 server->secMode &=
641 ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); 650 ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
642 } else if(sign_CIFS_PDUs == 1) { 651 } else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) {
643 if((server->secMode & SECMODE_SIGN_REQUIRED) == 0) 652 /* signing required */
644 server->secMode &= 653 cFYI(1, ("Must sign - secFlags 0x%x", secFlags));
645 ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); 654 if ((server->secMode &
646 } else if(sign_CIFS_PDUs == 2) {
647 if((server->secMode &
648 (SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) { 655 (SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) {
649 cERROR(1,("signing required but server lacks support")); 656 cERROR(1,
650 } 657 ("signing required but server lacks support"));
658 rc = -EOPNOTSUPP;
659 } else
660 server->secMode |= SECMODE_SIGN_REQUIRED;
661 } else {
662 /* signing optional ie CIFSSEC_MAY_SIGN */
663 if ((server->secMode & SECMODE_SIGN_REQUIRED) == 0)
664 server->secMode &=
665 ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
651 } 666 }
652neg_err_exit: 667
668neg_err_exit:
653 cifs_buf_release(pSMB); 669 cifs_buf_release(pSMB);
654 670
655 cFYI(1,("negprot rc %d",rc)); 671 cFYI(1, ("negprot rc %d", rc));
656 return rc; 672 return rc;
657} 673}
658 674
@@ -669,7 +685,7 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
669 * If last user of the connection and 685 * If last user of the connection and
670 * connection alive - disconnect it 686 * connection alive - disconnect it
671 * If this is the last connection on the server session disconnect it 687 * If this is the last connection on the server session disconnect it
672 * (and inside session disconnect we should check if tcp socket needs 688 * (and inside session disconnect we should check if tcp socket needs
673 * to be freed and kernel thread woken up). 689 * to be freed and kernel thread woken up).
674 */ 690 */
675 if (tcon) 691 if (tcon)
@@ -683,18 +699,18 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
683 return -EBUSY; 699 return -EBUSY;
684 } 700 }
685 701
686 /* No need to return error on this operation if tid invalidated and 702 /* No need to return error on this operation if tid invalidated and
687 closed on server already e.g. due to tcp session crashing */ 703 closed on server already e.g. due to tcp session crashing */
688 if(tcon->tidStatus == CifsNeedReconnect) { 704 if (tcon->tidStatus == CifsNeedReconnect) {
689 up(&tcon->tconSem); 705 up(&tcon->tconSem);
690 return 0; 706 return 0;
691 } 707 }
692 708
693 if((tcon->ses == NULL) || (tcon->ses->server == NULL)) { 709 if ((tcon->ses == NULL) || (tcon->ses->server == NULL)) {
694 up(&tcon->tconSem); 710 up(&tcon->tconSem);
695 return -EIO; 711 return -EIO;
696 } 712 }
697 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon, 713 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
698 (void **)&smb_buffer); 714 (void **)&smb_buffer);
699 if (rc) { 715 if (rc) {
700 up(&tcon->tconSem); 716 up(&tcon->tconSem);
@@ -711,7 +727,7 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
711 cifs_small_buf_release(smb_buffer); 727 cifs_small_buf_release(smb_buffer);
712 up(&tcon->tconSem); 728 up(&tcon->tconSem);
713 729
714 /* No need to return error on this operation if tid invalidated and 730 /* No need to return error on this operation if tid invalidated and
715 closed on server already e.g. due to tcp session crashing */ 731 closed on server already e.g. due to tcp session crashing */
716 if (rc == -EAGAIN) 732 if (rc == -EAGAIN)
717 rc = 0; 733 rc = 0;
@@ -745,11 +761,11 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
745 } 761 }
746 762
747 smb_buffer_response = (struct smb_hdr *)pSMB; /* BB removeme BB */ 763 smb_buffer_response = (struct smb_hdr *)pSMB; /* BB removeme BB */
748 764
749 if(ses->server) { 765 if (ses->server) {
750 pSMB->hdr.Mid = GetNextMid(ses->server); 766 pSMB->hdr.Mid = GetNextMid(ses->server);
751 767
752 if(ses->server->secMode & 768 if (ses->server->secMode &
753 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 769 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
754 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 770 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
755 } 771 }
@@ -772,7 +788,7 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
772 cifs_small_buf_release(pSMB); 788 cifs_small_buf_release(pSMB);
773 789
774 /* if session dead then we do not need to do ulogoff, 790 /* if session dead then we do not need to do ulogoff,
775 since server closed smb session, no sense reporting 791 since server closed smb session, no sense reporting
776 error */ 792 error */
777 if (rc == -EAGAIN) 793 if (rc == -EAGAIN)
778 rc = 0; 794 rc = 0;
@@ -780,6 +796,82 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
780} 796}
781 797
782int 798int
799CIFSPOSIXDelFile(const int xid, struct cifsTconInfo *tcon, const char *fileName,
800 __u16 type, const struct nls_table *nls_codepage, int remap)
801{
802 TRANSACTION2_SPI_REQ *pSMB = NULL;
803 TRANSACTION2_SPI_RSP *pSMBr = NULL;
804 struct unlink_psx_rq *pRqD;
805 int name_len;
806 int rc = 0;
807 int bytes_returned = 0;
808 __u16 params, param_offset, offset, byte_count;
809
810 cFYI(1, ("In POSIX delete"));
811PsxDelete:
812 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
813 (void **) &pSMBr);
814 if (rc)
815 return rc;
816
817 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
818 name_len =
819 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
820 PATH_MAX, nls_codepage, remap);
821 name_len++; /* trailing null */
822 name_len *= 2;
823 } else { /* BB add path length overrun check */
824 name_len = strnlen(fileName, PATH_MAX);
825 name_len++; /* trailing null */
826 strncpy(pSMB->FileName, fileName, name_len);
827 }
828
829 params = 6 + name_len;
830 pSMB->MaxParameterCount = cpu_to_le16(2);
831 pSMB->MaxDataCount = 0; /* BB double check this with jra */
832 pSMB->MaxSetupCount = 0;
833 pSMB->Reserved = 0;
834 pSMB->Flags = 0;
835 pSMB->Timeout = 0;
836 pSMB->Reserved2 = 0;
837 param_offset = offsetof(struct smb_com_transaction2_spi_req,
838 InformationLevel) - 4;
839 offset = param_offset + params;
840
841 /* Setup pointer to Request Data (inode type) */
842 pRqD = (struct unlink_psx_rq *)(((char *)&pSMB->hdr.Protocol) + offset);
843 pRqD->type = cpu_to_le16(type);
844 pSMB->ParameterOffset = cpu_to_le16(param_offset);
845 pSMB->DataOffset = cpu_to_le16(offset);
846 pSMB->SetupCount = 1;
847 pSMB->Reserved3 = 0;
848 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
849 byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq);
850
851 pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
852 pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
853 pSMB->ParameterCount = cpu_to_le16(params);
854 pSMB->TotalParameterCount = pSMB->ParameterCount;
855 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
856 pSMB->Reserved4 = 0;
857 pSMB->hdr.smb_buf_length += byte_count;
858 pSMB->ByteCount = cpu_to_le16(byte_count);
859 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
860 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
861 if (rc) {
862 cFYI(1, ("Posix delete returned %d", rc));
863 }
864 cifs_buf_release(pSMB);
865
866 cifs_stats_inc(&tcon->num_deletes);
867
868 if (rc == -EAGAIN)
869 goto PsxDelete;
870
871 return rc;
872}
873
874int
783CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon, const char *fileName, 875CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon, const char *fileName,
784 const struct nls_table *nls_codepage, int remap) 876 const struct nls_table *nls_codepage, int remap)
785{ 877{
@@ -797,7 +889,7 @@ DelFileRetry:
797 889
798 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 890 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
799 name_len = 891 name_len =
800 cifsConvertToUCS((__le16 *) pSMB->fileName, fileName, 892 cifsConvertToUCS((__le16 *) pSMB->fileName, fileName,
801 PATH_MAX, nls_codepage, remap); 893 PATH_MAX, nls_codepage, remap);
802 name_len++; /* trailing null */ 894 name_len++; /* trailing null */
803 name_len *= 2; 895 name_len *= 2;
@@ -816,7 +908,7 @@ DelFileRetry:
816 cifs_stats_inc(&tcon->num_deletes); 908 cifs_stats_inc(&tcon->num_deletes);
817 if (rc) { 909 if (rc) {
818 cFYI(1, ("Error in RMFile = %d", rc)); 910 cFYI(1, ("Error in RMFile = %d", rc));
819 } 911 }
820 912
821 cifs_buf_release(pSMB); 913 cifs_buf_release(pSMB);
822 if (rc == -EAGAIN) 914 if (rc == -EAGAIN)
@@ -826,7 +918,7 @@ DelFileRetry:
826} 918}
827 919
828int 920int
829CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon, const char *dirName, 921CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon, const char *dirName,
830 const struct nls_table *nls_codepage, int remap) 922 const struct nls_table *nls_codepage, int remap)
831{ 923{
832 DELETE_DIRECTORY_REQ *pSMB = NULL; 924 DELETE_DIRECTORY_REQ *pSMB = NULL;
@@ -887,7 +979,7 @@ MkDirRetry:
887 return rc; 979 return rc;
888 980
889 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 981 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
890 name_len = cifsConvertToUCS((__le16 *) pSMB->DirName, name, 982 name_len = cifsConvertToUCS((__le16 *) pSMB->DirName, name,
891 PATH_MAX, nls_codepage, remap); 983 PATH_MAX, nls_codepage, remap);
892 name_len++; /* trailing null */ 984 name_len++; /* trailing null */
893 name_len *= 2; 985 name_len *= 2;
@@ -916,7 +1008,7 @@ MkDirRetry:
916int 1008int
917CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, __u32 posix_flags, 1009CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, __u32 posix_flags,
918 __u64 mode, __u16 * netfid, FILE_UNIX_BASIC_INFO *pRetData, 1010 __u64 mode, __u16 * netfid, FILE_UNIX_BASIC_INFO *pRetData,
919 __u32 *pOplock, const char *name, 1011 __u32 *pOplock, const char *name,
920 const struct nls_table *nls_codepage, int remap) 1012 const struct nls_table *nls_codepage, int remap)
921{ 1013{
922 TRANSACTION2_SPI_REQ *pSMB = NULL; 1014 TRANSACTION2_SPI_REQ *pSMB = NULL;
@@ -924,7 +1016,6 @@ CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, __u32 posix_flags,
924 int name_len; 1016 int name_len;
925 int rc = 0; 1017 int rc = 0;
926 int bytes_returned = 0; 1018 int bytes_returned = 0;
927 char *data_offset;
928 __u16 params, param_offset, offset, byte_count, count; 1019 __u16 params, param_offset, offset, byte_count, count;
929 OPEN_PSX_REQ * pdata; 1020 OPEN_PSX_REQ * pdata;
930 OPEN_PSX_RSP * psx_rsp; 1021 OPEN_PSX_RSP * psx_rsp;
@@ -958,13 +1049,12 @@ PsxCreat:
958 pSMB->Timeout = 0; 1049 pSMB->Timeout = 0;
959 pSMB->Reserved2 = 0; 1050 pSMB->Reserved2 = 0;
960 param_offset = offsetof(struct smb_com_transaction2_spi_req, 1051 param_offset = offsetof(struct smb_com_transaction2_spi_req,
961 InformationLevel) - 4; 1052 InformationLevel) - 4;
962 offset = param_offset + params; 1053 offset = param_offset + params;
963 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
964 pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset); 1054 pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset);
965 pdata->Level = SMB_QUERY_FILE_UNIX_BASIC; 1055 pdata->Level = SMB_QUERY_FILE_UNIX_BASIC;
966 pdata->Permissions = cpu_to_le64(mode); 1056 pdata->Permissions = cpu_to_le64(mode);
967 pdata->PosixOpenFlags = cpu_to_le32(posix_flags); 1057 pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
968 pdata->OpenFlags = cpu_to_le32(*pOplock); 1058 pdata->OpenFlags = cpu_to_le32(*pOplock);
969 pSMB->ParameterOffset = cpu_to_le16(param_offset); 1059 pSMB->ParameterOffset = cpu_to_le16(param_offset);
970 pSMB->DataOffset = cpu_to_le16(offset); 1060 pSMB->DataOffset = cpu_to_le16(offset);
@@ -979,7 +1069,7 @@ PsxCreat:
979 pSMB->TotalParameterCount = pSMB->ParameterCount; 1069 pSMB->TotalParameterCount = pSMB->ParameterCount;
980 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN); 1070 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
981 pSMB->Reserved4 = 0; 1071 pSMB->Reserved4 = 0;
982 pSMB->hdr.smb_buf_length += byte_count; 1072 pSMB->hdr.smb_buf_length += byte_count;
983 pSMB->ByteCount = cpu_to_le16(byte_count); 1073 pSMB->ByteCount = cpu_to_le16(byte_count);
984 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1074 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
985 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1075 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -988,7 +1078,7 @@ PsxCreat:
988 goto psx_create_err; 1078 goto psx_create_err;
989 } 1079 }
990 1080
991 cFYI(1,("copying inode info")); 1081 cFYI(1, ("copying inode info"));
992 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 1082 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
993 1083
994 if (rc || (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP))) { 1084 if (rc || (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP))) {
@@ -997,34 +1087,33 @@ PsxCreat:
997 } 1087 }
998 1088
999 /* copy return information to pRetData */ 1089 /* copy return information to pRetData */
1000 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol 1090 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
1001 + le16_to_cpu(pSMBr->t2.DataOffset)); 1091 + le16_to_cpu(pSMBr->t2.DataOffset));
1002 1092
1003 *pOplock = le16_to_cpu(psx_rsp->OplockFlags); 1093 *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
1004 if(netfid) 1094 if (netfid)
1005 *netfid = psx_rsp->Fid; /* cifs fid stays in le */ 1095 *netfid = psx_rsp->Fid; /* cifs fid stays in le */
1006 /* Let caller know file was created so we can set the mode. */ 1096 /* Let caller know file was created so we can set the mode. */
1007 /* Do we care about the CreateAction in any other cases? */ 1097 /* Do we care about the CreateAction in any other cases? */
1008 if(cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction) 1098 if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
1009 *pOplock |= CIFS_CREATE_ACTION; 1099 *pOplock |= CIFS_CREATE_ACTION;
1010 /* check to make sure response data is there */ 1100 /* check to make sure response data is there */
1011 if(psx_rsp->ReturnedLevel != SMB_QUERY_FILE_UNIX_BASIC) { 1101 if (psx_rsp->ReturnedLevel != SMB_QUERY_FILE_UNIX_BASIC) {
1012 pRetData->Type = -1; /* unknown */ 1102 pRetData->Type = -1; /* unknown */
1013#ifdef CONFIG_CIFS_DEBUG2 1103#ifdef CONFIG_CIFS_DEBUG2
1014 cFYI(1,("unknown type")); 1104 cFYI(1, ("unknown type"));
1015#endif 1105#endif
1016 } else { 1106 } else {
1017 if(pSMBr->ByteCount < sizeof(OPEN_PSX_RSP) 1107 if (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP)
1018 + sizeof(FILE_UNIX_BASIC_INFO)) { 1108 + sizeof(FILE_UNIX_BASIC_INFO)) {
1019 cERROR(1,("Open response data too small")); 1109 cERROR(1, ("Open response data too small"));
1020 pRetData->Type = -1; 1110 pRetData->Type = -1;
1021 goto psx_create_err; 1111 goto psx_create_err;
1022 } 1112 }
1023 memcpy((char *) pRetData, 1113 memcpy((char *) pRetData,
1024 (char *)psx_rsp + sizeof(OPEN_PSX_RSP), 1114 (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
1025 sizeof (FILE_UNIX_BASIC_INFO)); 1115 sizeof (FILE_UNIX_BASIC_INFO));
1026 } 1116 }
1027
1028 1117
1029psx_create_err: 1118psx_create_err:
1030 cifs_buf_release(pSMB); 1119 cifs_buf_release(pSMB);
@@ -1034,7 +1123,7 @@ psx_create_err:
1034 if (rc == -EAGAIN) 1123 if (rc == -EAGAIN)
1035 goto PsxCreat; 1124 goto PsxCreat;
1036 1125
1037 return rc; 1126 return rc;
1038} 1127}
1039 1128
1040static __u16 convert_disposition(int disposition) 1129static __u16 convert_disposition(int disposition)
@@ -1061,7 +1150,7 @@ static __u16 convert_disposition(int disposition)
1061 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC; 1150 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1062 break; 1151 break;
1063 default: 1152 default:
1064 cFYI(1,("unknown disposition %d",disposition)); 1153 cFYI(1, ("unknown disposition %d", disposition));
1065 ofun = SMBOPEN_OAPPEND; /* regular open */ 1154 ofun = SMBOPEN_OAPPEND; /* regular open */
1066 } 1155 }
1067 return ofun; 1156 return ofun;
@@ -1071,7 +1160,7 @@ int
1071SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon, 1160SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon,
1072 const char *fileName, const int openDisposition, 1161 const char *fileName, const int openDisposition,
1073 const int access_flags, const int create_options, __u16 * netfid, 1162 const int access_flags, const int create_options, __u16 * netfid,
1074 int *pOplock, FILE_ALL_INFO * pfile_info, 1163 int *pOplock, FILE_ALL_INFO * pfile_info,
1075 const struct nls_table *nls_codepage, int remap) 1164 const struct nls_table *nls_codepage, int remap)
1076{ 1165{
1077 int rc = -EACCES; 1166 int rc = -EACCES;
@@ -1113,16 +1202,16 @@ OldOpenRetry:
1113 1 = write 1202 1 = write
1114 2 = rw 1203 2 = rw
1115 3 = execute 1204 3 = execute
1116 */ 1205 */
1117 pSMB->Mode = cpu_to_le16(2); 1206 pSMB->Mode = cpu_to_le16(2);
1118 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */ 1207 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1119 /* set file as system file if special file such 1208 /* set file as system file if special file such
1120 as fifo and server expecting SFU style and 1209 as fifo and server expecting SFU style and
1121 no Unix extensions */ 1210 no Unix extensions */
1122 1211
1123 if(create_options & CREATE_OPTION_SPECIAL) 1212 if (create_options & CREATE_OPTION_SPECIAL)
1124 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM); 1213 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1125 else 1214 else
1126 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/); /* BB FIXME */ 1215 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/); /* BB FIXME */
1127 1216
1128 /* if ((omode & S_IWUGO) == 0) 1217 /* if ((omode & S_IWUGO) == 0)
@@ -1132,7 +1221,8 @@ OldOpenRetry:
1132 being created */ 1221 being created */
1133 1222
1134 /* BB FIXME BB */ 1223 /* BB FIXME BB */
1135/* pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK); */ 1224/* pSMB->CreateOptions = cpu_to_le32(create_options &
1225 CREATE_OPTIONS_MASK); */
1136 /* BB FIXME END BB */ 1226 /* BB FIXME END BB */
1137 1227
1138 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY); 1228 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
@@ -1143,7 +1233,7 @@ OldOpenRetry:
1143 pSMB->ByteCount = cpu_to_le16(count); 1233 pSMB->ByteCount = cpu_to_le16(count);
1144 /* long_op set to 1 to allow for oplock break timeouts */ 1234 /* long_op set to 1 to allow for oplock break timeouts */
1145 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1235 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1146 (struct smb_hdr *) pSMBr, &bytes_returned, 1); 1236 (struct smb_hdr *) pSMBr, &bytes_returned, 1);
1147 cifs_stats_inc(&tcon->num_opens); 1237 cifs_stats_inc(&tcon->num_opens);
1148 if (rc) { 1238 if (rc) {
1149 cFYI(1, ("Error in Open = %d", rc)); 1239 cFYI(1, ("Error in Open = %d", rc));
@@ -1156,17 +1246,17 @@ OldOpenRetry:
1156 /* Let caller know file was created so we can set the mode. */ 1246 /* Let caller know file was created so we can set the mode. */
1157 /* Do we care about the CreateAction in any other cases? */ 1247 /* Do we care about the CreateAction in any other cases? */
1158 /* BB FIXME BB */ 1248 /* BB FIXME BB */
1159/* if(cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction) 1249/* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1160 *pOplock |= CIFS_CREATE_ACTION; */ 1250 *pOplock |= CIFS_CREATE_ACTION; */
1161 /* BB FIXME END */ 1251 /* BB FIXME END */
1162 1252
1163 if(pfile_info) { 1253 if (pfile_info) {
1164 pfile_info->CreationTime = 0; /* BB convert CreateTime*/ 1254 pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1165 pfile_info->LastAccessTime = 0; /* BB fixme */ 1255 pfile_info->LastAccessTime = 0; /* BB fixme */
1166 pfile_info->LastWriteTime = 0; /* BB fixme */ 1256 pfile_info->LastWriteTime = 0; /* BB fixme */
1167 pfile_info->ChangeTime = 0; /* BB fixme */ 1257 pfile_info->ChangeTime = 0; /* BB fixme */
1168 pfile_info->Attributes = 1258 pfile_info->Attributes =
1169 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes)); 1259 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1170 /* the file_info buf is endian converted by caller */ 1260 /* the file_info buf is endian converted by caller */
1171 pfile_info->AllocationSize = 1261 pfile_info->AllocationSize =
1172 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile)); 1262 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
@@ -1185,7 +1275,7 @@ int
1185CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, 1275CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
1186 const char *fileName, const int openDisposition, 1276 const char *fileName, const int openDisposition,
1187 const int access_flags, const int create_options, __u16 * netfid, 1277 const int access_flags, const int create_options, __u16 * netfid,
1188 int *pOplock, FILE_ALL_INFO * pfile_info, 1278 int *pOplock, FILE_ALL_INFO * pfile_info,
1189 const struct nls_table *nls_codepage, int remap) 1279 const struct nls_table *nls_codepage, int remap)
1190{ 1280{
1191 int rc = -EACCES; 1281 int rc = -EACCES;
@@ -1228,7 +1318,7 @@ openRetry:
1228 /* set file as system file if special file such 1318 /* set file as system file if special file such
1229 as fifo and server expecting SFU style and 1319 as fifo and server expecting SFU style and
1230 no Unix extensions */ 1320 no Unix extensions */
1231 if(create_options & CREATE_OPTION_SPECIAL) 1321 if (create_options & CREATE_OPTION_SPECIAL)
1232 pSMB->FileAttributes = cpu_to_le32(ATTR_SYSTEM); 1322 pSMB->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1233 else 1323 else
1234 pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL); 1324 pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL);
@@ -1266,10 +1356,10 @@ openRetry:
1266 *netfid = pSMBr->Fid; /* cifs fid stays in le */ 1356 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1267 /* Let caller know file was created so we can set the mode. */ 1357 /* Let caller know file was created so we can set the mode. */
1268 /* Do we care about the CreateAction in any other cases? */ 1358 /* Do we care about the CreateAction in any other cases? */
1269 if(cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction) 1359 if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1270 *pOplock |= CIFS_CREATE_ACTION; 1360 *pOplock |= CIFS_CREATE_ACTION;
1271 if(pfile_info) { 1361 if (pfile_info) {
1272 memcpy((char *)pfile_info,(char *)&pSMBr->CreationTime, 1362 memcpy((char *)pfile_info, (char *)&pSMBr->CreationTime,
1273 36 /* CreationTime to Attributes */); 1363 36 /* CreationTime to Attributes */);
1274 /* the file_info buf is endian converted by caller */ 1364 /* the file_info buf is endian converted by caller */
1275 pfile_info->AllocationSize = pSMBr->AllocationSize; 1365 pfile_info->AllocationSize = pSMBr->AllocationSize;
@@ -1285,10 +1375,9 @@ openRetry:
1285} 1375}
1286 1376
1287int 1377int
1288CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, 1378CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
1289 const int netfid, const unsigned int count, 1379 const unsigned int count, const __u64 lseek, unsigned int *nbytes,
1290 const __u64 lseek, unsigned int *nbytes, char **buf, 1380 char **buf, int *pbuf_type)
1291 int * pbuf_type)
1292{ 1381{
1293 int rc = -EACCES; 1382 int rc = -EACCES;
1294 READ_REQ *pSMB = NULL; 1383 READ_REQ *pSMB = NULL;
@@ -1298,8 +1387,8 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
1298 int resp_buf_type = 0; 1387 int resp_buf_type = 0;
1299 struct kvec iov[1]; 1388 struct kvec iov[1];
1300 1389
1301 cFYI(1,("Reading %d bytes on fid %d",count,netfid)); 1390 cFYI(1, ("Reading %d bytes on fid %d", count, netfid));
1302 if(tcon->ses->capabilities & CAP_LARGE_FILES) 1391 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1303 wct = 12; 1392 wct = 12;
1304 else 1393 else
1305 wct = 10; /* old style read */ 1394 wct = 10; /* old style read */
@@ -1316,28 +1405,28 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
1316 pSMB->AndXCommand = 0xFF; /* none */ 1405 pSMB->AndXCommand = 0xFF; /* none */
1317 pSMB->Fid = netfid; 1406 pSMB->Fid = netfid;
1318 pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF); 1407 pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF);
1319 if(wct == 12) 1408 if (wct == 12)
1320 pSMB->OffsetHigh = cpu_to_le32(lseek >> 32); 1409 pSMB->OffsetHigh = cpu_to_le32(lseek >> 32);
1321 else if((lseek >> 32) > 0) /* can not handle this big offset for old */ 1410 else if ((lseek >> 32) > 0) /* can not handle this big offset for old */
1322 return -EIO; 1411 return -EIO;
1323 1412
1324 pSMB->Remaining = 0; 1413 pSMB->Remaining = 0;
1325 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF); 1414 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1326 pSMB->MaxCountHigh = cpu_to_le32(count >> 16); 1415 pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1327 if(wct == 12) 1416 if (wct == 12)
1328 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */ 1417 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
1329 else { 1418 else {
1330 /* old style read */ 1419 /* old style read */
1331 struct smb_com_readx_req * pSMBW = 1420 struct smb_com_readx_req *pSMBW =
1332 (struct smb_com_readx_req *)pSMB; 1421 (struct smb_com_readx_req *)pSMB;
1333 pSMBW->ByteCount = 0; 1422 pSMBW->ByteCount = 0;
1334 } 1423 }
1335 1424
1336 iov[0].iov_base = (char *)pSMB; 1425 iov[0].iov_base = (char *)pSMB;
1337 iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; 1426 iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
1338 rc = SendReceive2(xid, tcon->ses, iov, 1427 rc = SendReceive2(xid, tcon->ses, iov,
1339 1 /* num iovecs */, 1428 1 /* num iovecs */,
1340 &resp_buf_type, 0); 1429 &resp_buf_type, 0);
1341 cifs_stats_inc(&tcon->num_reads); 1430 cifs_stats_inc(&tcon->num_reads);
1342 pSMBr = (READ_RSP *)iov[0].iov_base; 1431 pSMBr = (READ_RSP *)iov[0].iov_base;
1343 if (rc) { 1432 if (rc) {
@@ -1351,33 +1440,34 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
1351 /*check that DataLength would not go beyond end of SMB */ 1440 /*check that DataLength would not go beyond end of SMB */
1352 if ((data_length > CIFSMaxBufSize) 1441 if ((data_length > CIFSMaxBufSize)
1353 || (data_length > count)) { 1442 || (data_length > count)) {
1354 cFYI(1,("bad length %d for count %d",data_length,count)); 1443 cFYI(1, ("bad length %d for count %d",
1444 data_length, count));
1355 rc = -EIO; 1445 rc = -EIO;
1356 *nbytes = 0; 1446 *nbytes = 0;
1357 } else { 1447 } else {
1358 pReadData = (char *) (&pSMBr->hdr.Protocol) + 1448 pReadData = (char *) (&pSMBr->hdr.Protocol) +
1359 le16_to_cpu(pSMBr->DataOffset); 1449 le16_to_cpu(pSMBr->DataOffset);
1360/* if(rc = copy_to_user(buf, pReadData, data_length)) { 1450/* if (rc = copy_to_user(buf, pReadData, data_length)) {
1361 cERROR(1,("Faulting on read rc = %d",rc)); 1451 cERROR(1,("Faulting on read rc = %d",rc));
1362 rc = -EFAULT; 1452 rc = -EFAULT;
1363 }*/ /* can not use copy_to_user when using page cache*/ 1453 }*/ /* can not use copy_to_user when using page cache*/
1364 if(*buf) 1454 if (*buf)
1365 memcpy(*buf,pReadData,data_length); 1455 memcpy(*buf, pReadData, data_length);
1366 } 1456 }
1367 } 1457 }
1368 1458
1369/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */ 1459/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
1370 if(*buf) { 1460 if (*buf) {
1371 if(resp_buf_type == CIFS_SMALL_BUFFER) 1461 if (resp_buf_type == CIFS_SMALL_BUFFER)
1372 cifs_small_buf_release(iov[0].iov_base); 1462 cifs_small_buf_release(iov[0].iov_base);
1373 else if(resp_buf_type == CIFS_LARGE_BUFFER) 1463 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1374 cifs_buf_release(iov[0].iov_base); 1464 cifs_buf_release(iov[0].iov_base);
1375 } else if(resp_buf_type != CIFS_NO_BUFFER) { 1465 } else if (resp_buf_type != CIFS_NO_BUFFER) {
1376 /* return buffer to caller to free */ 1466 /* return buffer to caller to free */
1377 *buf = iov[0].iov_base; 1467 *buf = iov[0].iov_base;
1378 if(resp_buf_type == CIFS_SMALL_BUFFER) 1468 if (resp_buf_type == CIFS_SMALL_BUFFER)
1379 *pbuf_type = CIFS_SMALL_BUFFER; 1469 *pbuf_type = CIFS_SMALL_BUFFER;
1380 else if(resp_buf_type == CIFS_LARGE_BUFFER) 1470 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1381 *pbuf_type = CIFS_LARGE_BUFFER; 1471 *pbuf_type = CIFS_LARGE_BUFFER;
1382 } /* else no valid buffer on return - leave as null */ 1472 } /* else no valid buffer on return - leave as null */
1383 1473
@@ -1391,7 +1481,7 @@ int
1391CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, 1481CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
1392 const int netfid, const unsigned int count, 1482 const int netfid, const unsigned int count,
1393 const __u64 offset, unsigned int *nbytes, const char *buf, 1483 const __u64 offset, unsigned int *nbytes, const char *buf,
1394 const char __user * ubuf, const int long_op) 1484 const char __user *ubuf, const int long_op)
1395{ 1485{
1396 int rc = -EACCES; 1486 int rc = -EACCES;
1397 WRITE_REQ *pSMB = NULL; 1487 WRITE_REQ *pSMB = NULL;
@@ -1401,10 +1491,10 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
1401 __u16 byte_count; 1491 __u16 byte_count;
1402 1492
1403 /* cFYI(1,("write at %lld %d bytes",offset,count));*/ 1493 /* cFYI(1,("write at %lld %d bytes",offset,count));*/
1404 if(tcon->ses == NULL) 1494 if (tcon->ses == NULL)
1405 return -ECONNABORTED; 1495 return -ECONNABORTED;
1406 1496
1407 if(tcon->ses->capabilities & CAP_LARGE_FILES) 1497 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1408 wct = 14; 1498 wct = 14;
1409 else 1499 else
1410 wct = 12; 1500 wct = 12;
@@ -1420,20 +1510,20 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
1420 pSMB->AndXCommand = 0xFF; /* none */ 1510 pSMB->AndXCommand = 0xFF; /* none */
1421 pSMB->Fid = netfid; 1511 pSMB->Fid = netfid;
1422 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); 1512 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1423 if(wct == 14) 1513 if (wct == 14)
1424 pSMB->OffsetHigh = cpu_to_le32(offset >> 32); 1514 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1425 else if((offset >> 32) > 0) /* can not handle this big offset for old */ 1515 else if ((offset >> 32) > 0) /* can not handle big offset for old srv */
1426 return -EIO; 1516 return -EIO;
1427 1517
1428 pSMB->Reserved = 0xFFFFFFFF; 1518 pSMB->Reserved = 0xFFFFFFFF;
1429 pSMB->WriteMode = 0; 1519 pSMB->WriteMode = 0;
1430 pSMB->Remaining = 0; 1520 pSMB->Remaining = 0;
1431 1521
1432 /* Can increase buffer size if buffer is big enough in some cases - ie we 1522 /* Can increase buffer size if buffer is big enough in some cases ie we
1433 can send more if LARGE_WRITE_X capability returned by the server and if 1523 can send more if LARGE_WRITE_X capability returned by the server and if
1434 our buffer is big enough or if we convert to iovecs on socket writes 1524 our buffer is big enough or if we convert to iovecs on socket writes
1435 and eliminate the copy to the CIFS buffer */ 1525 and eliminate the copy to the CIFS buffer */
1436 if(tcon->ses->capabilities & CAP_LARGE_WRITE_X) { 1526 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1437 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count); 1527 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1438 } else { 1528 } else {
1439 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) 1529 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
@@ -1443,11 +1533,11 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
1443 if (bytes_sent > count) 1533 if (bytes_sent > count)
1444 bytes_sent = count; 1534 bytes_sent = count;
1445 pSMB->DataOffset = 1535 pSMB->DataOffset =
1446 cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4); 1536 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1447 if(buf) 1537 if (buf)
1448 memcpy(pSMB->Data,buf,bytes_sent); 1538 memcpy(pSMB->Data, buf, bytes_sent);
1449 else if(ubuf) { 1539 else if (ubuf) {
1450 if(copy_from_user(pSMB->Data,ubuf,bytes_sent)) { 1540 if (copy_from_user(pSMB->Data, ubuf, bytes_sent)) {
1451 cifs_buf_release(pSMB); 1541 cifs_buf_release(pSMB);
1452 return -EFAULT; 1542 return -EFAULT;
1453 } 1543 }
@@ -1456,7 +1546,7 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
1456 cifs_buf_release(pSMB); 1546 cifs_buf_release(pSMB);
1457 return -EINVAL; 1547 return -EINVAL;
1458 } /* else setting file size with write of zero bytes */ 1548 } /* else setting file size with write of zero bytes */
1459 if(wct == 14) 1549 if (wct == 14)
1460 byte_count = bytes_sent + 1; /* pad */ 1550 byte_count = bytes_sent + 1; /* pad */
1461 else /* wct == 12 */ { 1551 else /* wct == 12 */ {
1462 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */ 1552 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
@@ -1465,10 +1555,11 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
1465 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16); 1555 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1466 pSMB->hdr.smb_buf_length += byte_count; 1556 pSMB->hdr.smb_buf_length += byte_count;
1467 1557
1468 if(wct == 14) 1558 if (wct == 14)
1469 pSMB->ByteCount = cpu_to_le16(byte_count); 1559 pSMB->ByteCount = cpu_to_le16(byte_count);
1470 else { /* old style write has byte count 4 bytes earlier so 4 bytes pad */ 1560 else { /* old style write has byte count 4 bytes earlier
1471 struct smb_com_writex_req * pSMBW = 1561 so 4 bytes pad */
1562 struct smb_com_writex_req *pSMBW =
1472 (struct smb_com_writex_req *)pSMB; 1563 (struct smb_com_writex_req *)pSMB;
1473 pSMBW->ByteCount = cpu_to_le16(byte_count); 1564 pSMBW->ByteCount = cpu_to_le16(byte_count);
1474 } 1565 }
@@ -1487,7 +1578,7 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
1487 1578
1488 cifs_buf_release(pSMB); 1579 cifs_buf_release(pSMB);
1489 1580
1490 /* Note: On -EAGAIN error only caller can retry on handle based calls 1581 /* Note: On -EAGAIN error only caller can retry on handle based calls
1491 since file handle passed in no longer valid */ 1582 since file handle passed in no longer valid */
1492 1583
1493 return rc; 1584 return rc;
@@ -1505,9 +1596,9 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
1505 int smb_hdr_len; 1596 int smb_hdr_len;
1506 int resp_buf_type = 0; 1597 int resp_buf_type = 0;
1507 1598
1508 cFYI(1,("write2 at %lld %d bytes", (long long)offset, count)); 1599 cFYI(1, ("write2 at %lld %d bytes", (long long)offset, count));
1509 1600
1510 if(tcon->ses->capabilities & CAP_LARGE_FILES) 1601 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1511 wct = 14; 1602 wct = 14;
1512 else 1603 else
1513 wct = 12; 1604 wct = 12;
@@ -1521,37 +1612,37 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
1521 pSMB->AndXCommand = 0xFF; /* none */ 1612 pSMB->AndXCommand = 0xFF; /* none */
1522 pSMB->Fid = netfid; 1613 pSMB->Fid = netfid;
1523 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); 1614 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1524 if(wct == 14) 1615 if (wct == 14)
1525 pSMB->OffsetHigh = cpu_to_le32(offset >> 32); 1616 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1526 else if((offset >> 32) > 0) /* can not handle this big offset for old */ 1617 else if ((offset >> 32) > 0) /* can not handle big offset for old srv */
1527 return -EIO; 1618 return -EIO;
1528 pSMB->Reserved = 0xFFFFFFFF; 1619 pSMB->Reserved = 0xFFFFFFFF;
1529 pSMB->WriteMode = 0; 1620 pSMB->WriteMode = 0;
1530 pSMB->Remaining = 0; 1621 pSMB->Remaining = 0;
1531 1622
1532 pSMB->DataOffset = 1623 pSMB->DataOffset =
1533 cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4); 1624 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1534 1625
1535 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF); 1626 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
1536 pSMB->DataLengthHigh = cpu_to_le16(count >> 16); 1627 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
1537 smb_hdr_len = pSMB->hdr.smb_buf_length + 1; /* hdr + 1 byte pad */ 1628 smb_hdr_len = pSMB->hdr.smb_buf_length + 1; /* hdr + 1 byte pad */
1538 if(wct == 14) 1629 if (wct == 14)
1539 pSMB->hdr.smb_buf_length += count+1; 1630 pSMB->hdr.smb_buf_length += count+1;
1540 else /* wct == 12 */ 1631 else /* wct == 12 */
1541 pSMB->hdr.smb_buf_length += count+5; /* smb data starts later */ 1632 pSMB->hdr.smb_buf_length += count+5; /* smb data starts later */
1542 if(wct == 14) 1633 if (wct == 14)
1543 pSMB->ByteCount = cpu_to_le16(count + 1); 1634 pSMB->ByteCount = cpu_to_le16(count + 1);
1544 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ { 1635 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
1545 struct smb_com_writex_req * pSMBW = 1636 struct smb_com_writex_req *pSMBW =
1546 (struct smb_com_writex_req *)pSMB; 1637 (struct smb_com_writex_req *)pSMB;
1547 pSMBW->ByteCount = cpu_to_le16(count + 5); 1638 pSMBW->ByteCount = cpu_to_le16(count + 5);
1548 } 1639 }
1549 iov[0].iov_base = pSMB; 1640 iov[0].iov_base = pSMB;
1550 if(wct == 14) 1641 if (wct == 14)
1551 iov[0].iov_len = smb_hdr_len + 4; 1642 iov[0].iov_len = smb_hdr_len + 4;
1552 else /* wct == 12 pad bigger by four bytes */ 1643 else /* wct == 12 pad bigger by four bytes */
1553 iov[0].iov_len = smb_hdr_len + 8; 1644 iov[0].iov_len = smb_hdr_len + 8;
1554 1645
1555 1646
1556 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 1647 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type,
1557 long_op); 1648 long_op);
@@ -1559,7 +1650,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
1559 if (rc) { 1650 if (rc) {
1560 cFYI(1, ("Send error Write2 = %d", rc)); 1651 cFYI(1, ("Send error Write2 = %d", rc));
1561 *nbytes = 0; 1652 *nbytes = 0;
1562 } else if(resp_buf_type == 0) { 1653 } else if (resp_buf_type == 0) {
1563 /* presumably this can not happen, but best to be safe */ 1654 /* presumably this can not happen, but best to be safe */
1564 rc = -EIO; 1655 rc = -EIO;
1565 *nbytes = 0; 1656 *nbytes = 0;
@@ -1568,15 +1659,15 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
1568 *nbytes = le16_to_cpu(pSMBr->CountHigh); 1659 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1569 *nbytes = (*nbytes) << 16; 1660 *nbytes = (*nbytes) << 16;
1570 *nbytes += le16_to_cpu(pSMBr->Count); 1661 *nbytes += le16_to_cpu(pSMBr->Count);
1571 } 1662 }
1572 1663
1573/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */ 1664/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
1574 if(resp_buf_type == CIFS_SMALL_BUFFER) 1665 if (resp_buf_type == CIFS_SMALL_BUFFER)
1575 cifs_small_buf_release(iov[0].iov_base); 1666 cifs_small_buf_release(iov[0].iov_base);
1576 else if(resp_buf_type == CIFS_LARGE_BUFFER) 1667 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1577 cifs_buf_release(iov[0].iov_base); 1668 cifs_buf_release(iov[0].iov_base);
1578 1669
1579 /* Note: On -EAGAIN error only caller can retry on handle based calls 1670 /* Note: On -EAGAIN error only caller can retry on handle based calls
1580 since file handle passed in no longer valid */ 1671 since file handle passed in no longer valid */
1581 1672
1582 return rc; 1673 return rc;
@@ -1596,7 +1687,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1596 int timeout = 0; 1687 int timeout = 0;
1597 __u16 count; 1688 __u16 count;
1598 1689
1599 cFYI(1, ("In CIFSSMBLock - timeout %d numLock %d",waitFlag,numLock)); 1690 cFYI(1, ("In CIFSSMBLock - timeout %d numLock %d", waitFlag, numLock));
1600 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB); 1691 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
1601 1692
1602 if (rc) 1693 if (rc)
@@ -1604,7 +1695,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1604 1695
1605 pSMBr = (LOCK_RSP *)pSMB; /* BB removeme BB */ 1696 pSMBr = (LOCK_RSP *)pSMB; /* BB removeme BB */
1606 1697
1607 if(lockType == LOCKING_ANDX_OPLOCK_RELEASE) { 1698 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
1608 timeout = -1; /* no response expected */ 1699 timeout = -1; /* no response expected */
1609 pSMB->Timeout = 0; 1700 pSMB->Timeout = 0;
1610 } else if (waitFlag == TRUE) { 1701 } else if (waitFlag == TRUE) {
@@ -1620,7 +1711,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1620 pSMB->AndXCommand = 0xFF; /* none */ 1711 pSMB->AndXCommand = 0xFF; /* none */
1621 pSMB->Fid = smb_file_id; /* netfid stays le */ 1712 pSMB->Fid = smb_file_id; /* netfid stays le */
1622 1713
1623 if((numLock != 0) || (numUnlock != 0)) { 1714 if ((numLock != 0) || (numUnlock != 0)) {
1624 pSMB->Locks[0].Pid = cpu_to_le16(current->tgid); 1715 pSMB->Locks[0].Pid = cpu_to_le16(current->tgid);
1625 /* BB where to store pid high? */ 1716 /* BB where to store pid high? */
1626 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len); 1717 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
@@ -1648,7 +1739,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1648 } 1739 }
1649 cifs_small_buf_release(pSMB); 1740 cifs_small_buf_release(pSMB);
1650 1741
1651 /* Note: On -EAGAIN error only caller can retry on handle based calls 1742 /* Note: On -EAGAIN error only caller can retry on handle based calls
1652 since file handle passed in no longer valid */ 1743 since file handle passed in no longer valid */
1653 return rc; 1744 return rc;
1654} 1745}
@@ -1656,12 +1747,11 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1656int 1747int
1657CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, 1748CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1658 const __u16 smb_file_id, const int get_flag, const __u64 len, 1749 const __u16 smb_file_id, const int get_flag, const __u64 len,
1659 struct file_lock *pLockData, const __u16 lock_type, 1750 struct file_lock *pLockData, const __u16 lock_type,
1660 const int waitFlag) 1751 const int waitFlag)
1661{ 1752{
1662 struct smb_com_transaction2_sfi_req *pSMB = NULL; 1753 struct smb_com_transaction2_sfi_req *pSMB = NULL;
1663 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; 1754 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
1664 char *data_offset;
1665 struct cifs_posix_lock *parm_data; 1755 struct cifs_posix_lock *parm_data;
1666 int rc = 0; 1756 int rc = 0;
1667 int timeout = 0; 1757 int timeout = 0;
@@ -1670,7 +1760,7 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1670 1760
1671 cFYI(1, ("Posix Lock")); 1761 cFYI(1, ("Posix Lock"));
1672 1762
1673 if(pLockData == NULL) 1763 if (pLockData == NULL)
1674 return EINVAL; 1764 return EINVAL;
1675 1765
1676 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 1766 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
@@ -1680,7 +1770,7 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1680 1770
1681 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB; 1771 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
1682 1772
1683 params = 6; 1773 params = 6;
1684 pSMB->MaxSetupCount = 0; 1774 pSMB->MaxSetupCount = 0;
1685 pSMB->Reserved = 0; 1775 pSMB->Reserved = 0;
1686 pSMB->Flags = 0; 1776 pSMB->Flags = 0;
@@ -1688,14 +1778,12 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1688 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 1778 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
1689 offset = param_offset + params; 1779 offset = param_offset + params;
1690 1780
1691 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
1692
1693 count = sizeof(struct cifs_posix_lock); 1781 count = sizeof(struct cifs_posix_lock);
1694 pSMB->MaxParameterCount = cpu_to_le16(2); 1782 pSMB->MaxParameterCount = cpu_to_le16(2);
1695 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */ 1783 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */
1696 pSMB->SetupCount = 1; 1784 pSMB->SetupCount = 1;
1697 pSMB->Reserved3 = 0; 1785 pSMB->Reserved3 = 0;
1698 if(get_flag) 1786 if (get_flag)
1699 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); 1787 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
1700 else 1788 else
1701 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 1789 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
@@ -1705,11 +1793,11 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1705 pSMB->TotalDataCount = pSMB->DataCount; 1793 pSMB->TotalDataCount = pSMB->DataCount;
1706 pSMB->TotalParameterCount = pSMB->ParameterCount; 1794 pSMB->TotalParameterCount = pSMB->ParameterCount;
1707 pSMB->ParameterOffset = cpu_to_le16(param_offset); 1795 pSMB->ParameterOffset = cpu_to_le16(param_offset);
1708 parm_data = (struct cifs_posix_lock *) 1796 parm_data = (struct cifs_posix_lock *)
1709 (((char *) &pSMB->hdr.Protocol) + offset); 1797 (((char *) &pSMB->hdr.Protocol) + offset);
1710 1798
1711 parm_data->lock_type = cpu_to_le16(lock_type); 1799 parm_data->lock_type = cpu_to_le16(lock_type);
1712 if(waitFlag) { 1800 if (waitFlag) {
1713 timeout = 3; /* blocking operation, no timeout */ 1801 timeout = 3; /* blocking operation, no timeout */
1714 parm_data->lock_flags = cpu_to_le16(1); 1802 parm_data->lock_flags = cpu_to_le16(1);
1715 pSMB->Timeout = cpu_to_le32(-1); 1803 pSMB->Timeout = cpu_to_le32(-1);
@@ -1746,22 +1834,22 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1746 rc = -EIO; /* bad smb */ 1834 rc = -EIO; /* bad smb */
1747 goto plk_err_exit; 1835 goto plk_err_exit;
1748 } 1836 }
1749 if(pLockData == NULL) { 1837 if (pLockData == NULL) {
1750 rc = -EINVAL; 1838 rc = -EINVAL;
1751 goto plk_err_exit; 1839 goto plk_err_exit;
1752 } 1840 }
1753 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 1841 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
1754 data_count = le16_to_cpu(pSMBr->t2.DataCount); 1842 data_count = le16_to_cpu(pSMBr->t2.DataCount);
1755 if(data_count < sizeof(struct cifs_posix_lock)) { 1843 if (data_count < sizeof(struct cifs_posix_lock)) {
1756 rc = -EIO; 1844 rc = -EIO;
1757 goto plk_err_exit; 1845 goto plk_err_exit;
1758 } 1846 }
1759 parm_data = (struct cifs_posix_lock *) 1847 parm_data = (struct cifs_posix_lock *)
1760 ((char *)&pSMBr->hdr.Protocol + data_offset); 1848 ((char *)&pSMBr->hdr.Protocol + data_offset);
1761 if(parm_data->lock_type == cpu_to_le16(CIFS_UNLCK)) 1849 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
1762 pLockData->fl_type = F_UNLCK; 1850 pLockData->fl_type = F_UNLCK;
1763 } 1851 }
1764 1852
1765plk_err_exit: 1853plk_err_exit:
1766 if (pSMB) 1854 if (pSMB)
1767 cifs_small_buf_release(pSMB); 1855 cifs_small_buf_release(pSMB);
@@ -1784,7 +1872,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
1784 1872
1785/* do not retry on dead session on close */ 1873/* do not retry on dead session on close */
1786 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB); 1874 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
1787 if(rc == -EAGAIN) 1875 if (rc == -EAGAIN)
1788 return 0; 1876 return 0;
1789 if (rc) 1877 if (rc)
1790 return rc; 1878 return rc;
@@ -1798,7 +1886,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
1798 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1886 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1799 cifs_stats_inc(&tcon->num_closes); 1887 cifs_stats_inc(&tcon->num_closes);
1800 if (rc) { 1888 if (rc) {
1801 if(rc!=-EINTR) { 1889 if (rc != -EINTR) {
1802 /* EINTR is expected when user ctl-c to kill app */ 1890 /* EINTR is expected when user ctl-c to kill app */
1803 cERROR(1, ("Send error in Close = %d", rc)); 1891 cERROR(1, ("Send error in Close = %d", rc));
1804 } 1892 }
@@ -1807,7 +1895,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
1807 cifs_small_buf_release(pSMB); 1895 cifs_small_buf_release(pSMB);
1808 1896
1809 /* Since session is dead, file will be closed on server already */ 1897 /* Since session is dead, file will be closed on server already */
1810 if(rc == -EAGAIN) 1898 if (rc == -EAGAIN)
1811 rc = 0; 1899 rc = 0;
1812 1900
1813 return rc; 1901 return rc;
@@ -1839,7 +1927,7 @@ renameRetry:
1839 1927
1840 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 1928 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1841 name_len = 1929 name_len =
1842 cifsConvertToUCS((__le16 *) pSMB->OldFileName, fromName, 1930 cifsConvertToUCS((__le16 *) pSMB->OldFileName, fromName,
1843 PATH_MAX, nls_codepage, remap); 1931 PATH_MAX, nls_codepage, remap);
1844 name_len++; /* trailing null */ 1932 name_len++; /* trailing null */
1845 name_len *= 2; 1933 name_len *= 2;
@@ -1851,7 +1939,7 @@ renameRetry:
1851 toName, PATH_MAX, nls_codepage, remap); 1939 toName, PATH_MAX, nls_codepage, remap);
1852 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; 1940 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
1853 name_len2 *= 2; /* convert to bytes */ 1941 name_len2 *= 2; /* convert to bytes */
1854 } else { /* BB improve the check for buffer overruns BB */ 1942 } else { /* BB improve the check for buffer overruns BB */
1855 name_len = strnlen(fromName, PATH_MAX); 1943 name_len = strnlen(fromName, PATH_MAX);
1856 name_len++; /* trailing null */ 1944 name_len++; /* trailing null */
1857 strncpy(pSMB->OldFileName, fromName, name_len); 1945 strncpy(pSMB->OldFileName, fromName, name_len);
@@ -1872,7 +1960,7 @@ renameRetry:
1872 cifs_stats_inc(&tcon->num_renames); 1960 cifs_stats_inc(&tcon->num_renames);
1873 if (rc) { 1961 if (rc) {
1874 cFYI(1, ("Send error in rename = %d", rc)); 1962 cFYI(1, ("Send error in rename = %d", rc));
1875 } 1963 }
1876 1964
1877 cifs_buf_release(pSMB); 1965 cifs_buf_release(pSMB);
1878 1966
@@ -1882,13 +1970,13 @@ renameRetry:
1882 return rc; 1970 return rc;
1883} 1971}
1884 1972
1885int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon, 1973int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon,
1886 int netfid, char * target_name, 1974 int netfid, char *target_name,
1887 const struct nls_table * nls_codepage, int remap) 1975 const struct nls_table *nls_codepage, int remap)
1888{ 1976{
1889 struct smb_com_transaction2_sfi_req *pSMB = NULL; 1977 struct smb_com_transaction2_sfi_req *pSMB = NULL;
1890 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; 1978 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
1891 struct set_file_rename * rename_info; 1979 struct set_file_rename *rename_info;
1892 char *data_offset; 1980 char *data_offset;
1893 char dummy_string[30]; 1981 char dummy_string[30];
1894 int rc = 0; 1982 int rc = 0;
@@ -1927,13 +2015,14 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
1927 rename_info->overwrite = cpu_to_le32(1); 2015 rename_info->overwrite = cpu_to_le32(1);
1928 rename_info->root_fid = 0; 2016 rename_info->root_fid = 0;
1929 /* unicode only call */ 2017 /* unicode only call */
1930 if(target_name == NULL) { 2018 if (target_name == NULL) {
1931 sprintf(dummy_string,"cifs%x",pSMB->hdr.Mid); 2019 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
1932 len_of_str = cifsConvertToUCS((__le16 *)rename_info->target_name, 2020 len_of_str = cifsConvertToUCS((__le16 *)rename_info->target_name,
1933 dummy_string, 24, nls_codepage, remap); 2021 dummy_string, 24, nls_codepage, remap);
1934 } else { 2022 } else {
1935 len_of_str = cifsConvertToUCS((__le16 *)rename_info->target_name, 2023 len_of_str = cifsConvertToUCS((__le16 *)rename_info->target_name,
1936 target_name, PATH_MAX, nls_codepage, remap); 2024 target_name, PATH_MAX, nls_codepage,
2025 remap);
1937 } 2026 }
1938 rename_info->target_name_len = cpu_to_le32(2 * len_of_str); 2027 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
1939 count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str) + 2; 2028 count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str) + 2;
@@ -1947,10 +2036,10 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
1947 pSMB->hdr.smb_buf_length += byte_count; 2036 pSMB->hdr.smb_buf_length += byte_count;
1948 pSMB->ByteCount = cpu_to_le16(byte_count); 2037 pSMB->ByteCount = cpu_to_le16(byte_count);
1949 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB, 2038 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
1950 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2039 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1951 cifs_stats_inc(&pTcon->num_t2renames); 2040 cifs_stats_inc(&pTcon->num_t2renames);
1952 if (rc) { 2041 if (rc) {
1953 cFYI(1,("Send error in Rename (by file handle) = %d", rc)); 2042 cFYI(1, ("Send error in Rename (by file handle) = %d", rc));
1954 } 2043 }
1955 2044
1956 cifs_buf_release(pSMB); 2045 cifs_buf_release(pSMB);
@@ -1962,9 +2051,9 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
1962} 2051}
1963 2052
1964int 2053int
1965CIFSSMBCopy(const int xid, struct cifsTconInfo *tcon, const char * fromName, 2054CIFSSMBCopy(const int xid, struct cifsTconInfo *tcon, const char *fromName,
1966 const __u16 target_tid, const char *toName, const int flags, 2055 const __u16 target_tid, const char *toName, const int flags,
1967 const struct nls_table *nls_codepage, int remap) 2056 const struct nls_table *nls_codepage, int remap)
1968{ 2057{
1969 int rc = 0; 2058 int rc = 0;
1970 COPY_REQ *pSMB = NULL; 2059 COPY_REQ *pSMB = NULL;
@@ -1986,7 +2075,7 @@ copyRetry:
1986 pSMB->Flags = cpu_to_le16(flags & COPY_TREE); 2075 pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
1987 2076
1988 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2077 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1989 name_len = cifsConvertToUCS((__le16 *) pSMB->OldFileName, 2078 name_len = cifsConvertToUCS((__le16 *) pSMB->OldFileName,
1990 fromName, PATH_MAX, nls_codepage, 2079 fromName, PATH_MAX, nls_codepage,
1991 remap); 2080 remap);
1992 name_len++; /* trailing null */ 2081 name_len++; /* trailing null */
@@ -1994,11 +2083,12 @@ copyRetry:
1994 pSMB->OldFileName[name_len] = 0x04; /* pad */ 2083 pSMB->OldFileName[name_len] = 0x04; /* pad */
1995 /* protocol requires ASCII signature byte on Unicode string */ 2084 /* protocol requires ASCII signature byte on Unicode string */
1996 pSMB->OldFileName[name_len + 1] = 0x00; 2085 pSMB->OldFileName[name_len + 1] = 0x00;
1997 name_len2 = cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2], 2086 name_len2 =
2087 cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2],
1998 toName, PATH_MAX, nls_codepage, remap); 2088 toName, PATH_MAX, nls_codepage, remap);
1999 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; 2089 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2000 name_len2 *= 2; /* convert to bytes */ 2090 name_len2 *= 2; /* convert to bytes */
2001 } else { /* BB improve the check for buffer overruns BB */ 2091 } else { /* BB improve the check for buffer overruns BB */
2002 name_len = strnlen(fromName, PATH_MAX); 2092 name_len = strnlen(fromName, PATH_MAX);
2003 name_len++; /* trailing null */ 2093 name_len++; /* trailing null */
2004 strncpy(pSMB->OldFileName, fromName, name_len); 2094 strncpy(pSMB->OldFileName, fromName, name_len);
@@ -2058,7 +2148,7 @@ createSymLinkRetry:
2058 name_len++; /* trailing null */ 2148 name_len++; /* trailing null */
2059 name_len *= 2; 2149 name_len *= 2;
2060 2150
2061 } else { /* BB improve the check for buffer overruns BB */ 2151 } else { /* BB improve the check for buffer overruns BB */
2062 name_len = strnlen(fromName, PATH_MAX); 2152 name_len = strnlen(fromName, PATH_MAX);
2063 name_len++; /* trailing null */ 2153 name_len++; /* trailing null */
2064 strncpy(pSMB->FileName, fromName, name_len); 2154 strncpy(pSMB->FileName, fromName, name_len);
@@ -2070,7 +2160,7 @@ createSymLinkRetry:
2070 pSMB->Timeout = 0; 2160 pSMB->Timeout = 0;
2071 pSMB->Reserved2 = 0; 2161 pSMB->Reserved2 = 0;
2072 param_offset = offsetof(struct smb_com_transaction2_spi_req, 2162 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2073 InformationLevel) - 4; 2163 InformationLevel) - 4;
2074 offset = param_offset + params; 2164 offset = param_offset + params;
2075 2165
2076 data_offset = (char *) (&pSMB->hdr.Protocol) + offset; 2166 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
@@ -2081,7 +2171,7 @@ createSymLinkRetry:
2081 , nls_codepage); 2171 , nls_codepage);
2082 name_len_target++; /* trailing null */ 2172 name_len_target++; /* trailing null */
2083 name_len_target *= 2; 2173 name_len_target *= 2;
2084 } else { /* BB improve the check for buffer overruns BB */ 2174 } else { /* BB improve the check for buffer overruns BB */
2085 name_len_target = strnlen(toName, PATH_MAX); 2175 name_len_target = strnlen(toName, PATH_MAX);
2086 name_len_target++; /* trailing null */ 2176 name_len_target++; /* trailing null */
2087 strncpy(data_offset, toName, name_len_target); 2177 strncpy(data_offset, toName, name_len_target);
@@ -2108,9 +2198,7 @@ createSymLinkRetry:
2108 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2198 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2109 cifs_stats_inc(&tcon->num_symlinks); 2199 cifs_stats_inc(&tcon->num_symlinks);
2110 if (rc) { 2200 if (rc) {
2111 cFYI(1, 2201 cFYI(1, ("Send error in SetPathInfo create symlink = %d", rc));
2112 ("Send error in SetPathInfo (create symlink) = %d",
2113 rc));
2114 } 2202 }
2115 2203
2116 if (pSMB) 2204 if (pSMB)
@@ -2149,7 +2237,7 @@ createHardLinkRetry:
2149 name_len++; /* trailing null */ 2237 name_len++; /* trailing null */
2150 name_len *= 2; 2238 name_len *= 2;
2151 2239
2152 } else { /* BB improve the check for buffer overruns BB */ 2240 } else { /* BB improve the check for buffer overruns BB */
2153 name_len = strnlen(toName, PATH_MAX); 2241 name_len = strnlen(toName, PATH_MAX);
2154 name_len++; /* trailing null */ 2242 name_len++; /* trailing null */
2155 strncpy(pSMB->FileName, toName, name_len); 2243 strncpy(pSMB->FileName, toName, name_len);
@@ -2161,7 +2249,7 @@ createHardLinkRetry:
2161 pSMB->Timeout = 0; 2249 pSMB->Timeout = 0;
2162 pSMB->Reserved2 = 0; 2250 pSMB->Reserved2 = 0;
2163 param_offset = offsetof(struct smb_com_transaction2_spi_req, 2251 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2164 InformationLevel) - 4; 2252 InformationLevel) - 4;
2165 offset = param_offset + params; 2253 offset = param_offset + params;
2166 2254
2167 data_offset = (char *) (&pSMB->hdr.Protocol) + offset; 2255 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
@@ -2171,7 +2259,7 @@ createHardLinkRetry:
2171 nls_codepage, remap); 2259 nls_codepage, remap);
2172 name_len_target++; /* trailing null */ 2260 name_len_target++; /* trailing null */
2173 name_len_target *= 2; 2261 name_len_target *= 2;
2174 } else { /* BB improve the check for buffer overruns BB */ 2262 } else { /* BB improve the check for buffer overruns BB */
2175 name_len_target = strnlen(fromName, PATH_MAX); 2263 name_len_target = strnlen(fromName, PATH_MAX);
2176 name_len_target++; /* trailing null */ 2264 name_len_target++; /* trailing null */
2177 strncpy(data_offset, fromName, name_len_target); 2265 strncpy(data_offset, fromName, name_len_target);
@@ -2243,13 +2331,13 @@ winCreateHardLinkRetry:
2243 name_len++; /* trailing null */ 2331 name_len++; /* trailing null */
2244 name_len *= 2; 2332 name_len *= 2;
2245 pSMB->OldFileName[name_len] = 0; /* pad */ 2333 pSMB->OldFileName[name_len] = 0; /* pad */
2246 pSMB->OldFileName[name_len + 1] = 0x04; 2334 pSMB->OldFileName[name_len + 1] = 0x04;
2247 name_len2 = 2335 name_len2 =
2248 cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2], 2336 cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2],
2249 toName, PATH_MAX, nls_codepage, remap); 2337 toName, PATH_MAX, nls_codepage, remap);
2250 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; 2338 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2251 name_len2 *= 2; /* convert to bytes */ 2339 name_len2 *= 2; /* convert to bytes */
2252 } else { /* BB improve the check for buffer overruns BB */ 2340 } else { /* BB improve the check for buffer overruns BB */
2253 name_len = strnlen(fromName, PATH_MAX); 2341 name_len = strnlen(fromName, PATH_MAX);
2254 name_len++; /* trailing null */ 2342 name_len++; /* trailing null */
2255 strncpy(pSMB->OldFileName, fromName, name_len); 2343 strncpy(pSMB->OldFileName, fromName, name_len);
@@ -2302,12 +2390,11 @@ querySymLinkRetry:
2302 2390
2303 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2391 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2304 name_len = 2392 name_len =
2305 cifs_strtoUCS((__le16 *) pSMB->FileName, searchName, PATH_MAX 2393 cifs_strtoUCS((__le16 *) pSMB->FileName, searchName,
2306 /* find define for this maxpathcomponent */ 2394 PATH_MAX, nls_codepage);
2307 , nls_codepage);
2308 name_len++; /* trailing null */ 2395 name_len++; /* trailing null */
2309 name_len *= 2; 2396 name_len *= 2;
2310 } else { /* BB improve the check for buffer overruns BB */ 2397 } else { /* BB improve the check for buffer overruns BB */
2311 name_len = strnlen(searchName, PATH_MAX); 2398 name_len = strnlen(searchName, PATH_MAX);
2312 name_len++; /* trailing null */ 2399 name_len++; /* trailing null */
2313 strncpy(pSMB->FileName, searchName, name_len); 2400 strncpy(pSMB->FileName, searchName, name_len);
@@ -2324,7 +2411,7 @@ querySymLinkRetry:
2324 pSMB->Timeout = 0; 2411 pSMB->Timeout = 0;
2325 pSMB->Reserved2 = 0; 2412 pSMB->Reserved2 = 0;
2326 pSMB->ParameterOffset = cpu_to_le16(offsetof( 2413 pSMB->ParameterOffset = cpu_to_le16(offsetof(
2327 struct smb_com_transaction2_qpi_req ,InformationLevel) - 4); 2414 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
2328 pSMB->DataCount = 0; 2415 pSMB->DataCount = 0;
2329 pSMB->DataOffset = 0; 2416 pSMB->DataOffset = 0;
2330 pSMB->SetupCount = 1; 2417 pSMB->SetupCount = 1;
@@ -2355,16 +2442,16 @@ querySymLinkRetry:
2355 2442
2356 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) { 2443 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
2357 name_len = UniStrnlen((wchar_t *) ((char *) 2444 name_len = UniStrnlen((wchar_t *) ((char *)
2358 &pSMBr->hdr.Protocol +data_offset), 2445 &pSMBr->hdr.Protocol + data_offset),
2359 min_t(const int, buflen,count) / 2); 2446 min_t(const int, buflen, count) / 2);
2360 /* BB FIXME investigate remapping reserved chars here */ 2447 /* BB FIXME investigate remapping reserved chars here */
2361 cifs_strfromUCS_le(symlinkinfo, 2448 cifs_strfromUCS_le(symlinkinfo,
2362 (__le16 *) ((char *)&pSMBr->hdr.Protocol + 2449 (__le16 *) ((char *)&pSMBr->hdr.Protocol
2363 data_offset), 2450 + data_offset),
2364 name_len, nls_codepage); 2451 name_len, nls_codepage);
2365 } else { 2452 } else {
2366 strncpy(symlinkinfo, 2453 strncpy(symlinkinfo,
2367 (char *) &pSMBr->hdr.Protocol + 2454 (char *) &pSMBr->hdr.Protocol +
2368 data_offset, 2455 data_offset,
2369 min_t(const int, buflen, count)); 2456 min_t(const int, buflen, count));
2370 } 2457 }
@@ -2385,14 +2472,14 @@ querySymLinkRetry:
2385 Setup words themselves and ByteCount 2472 Setup words themselves and ByteCount
2386 MaxSetupCount (size of returned setup area) and 2473 MaxSetupCount (size of returned setup area) and
2387 MaxParameterCount (returned parms size) must be set by caller */ 2474 MaxParameterCount (returned parms size) must be set by caller */
2388static int 2475static int
2389smb_init_ntransact(const __u16 sub_command, const int setup_count, 2476smb_init_ntransact(const __u16 sub_command, const int setup_count,
2390 const int parm_len, struct cifsTconInfo *tcon, 2477 const int parm_len, struct cifsTconInfo *tcon,
2391 void ** ret_buf) 2478 void **ret_buf)
2392{ 2479{
2393 int rc; 2480 int rc;
2394 __u32 temp_offset; 2481 __u32 temp_offset;
2395 struct smb_com_ntransact_req * pSMB; 2482 struct smb_com_ntransact_req *pSMB;
2396 2483
2397 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon, 2484 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
2398 (void **)&pSMB); 2485 (void **)&pSMB);
@@ -2416,47 +2503,47 @@ smb_init_ntransact(const __u16 sub_command, const int setup_count,
2416} 2503}
2417 2504
2418static int 2505static int
2419validate_ntransact(char * buf, char ** ppparm, char ** ppdata, 2506validate_ntransact(char *buf, char **ppparm, char **ppdata,
2420 int * pdatalen, int * pparmlen) 2507 int *pdatalen, int *pparmlen)
2421{ 2508{
2422 char * end_of_smb; 2509 char *end_of_smb;
2423 __u32 data_count, data_offset, parm_count, parm_offset; 2510 __u32 data_count, data_offset, parm_count, parm_offset;
2424 struct smb_com_ntransact_rsp * pSMBr; 2511 struct smb_com_ntransact_rsp *pSMBr;
2425 2512
2426 if(buf == NULL) 2513 if (buf == NULL)
2427 return -EINVAL; 2514 return -EINVAL;
2428 2515
2429 pSMBr = (struct smb_com_ntransact_rsp *)buf; 2516 pSMBr = (struct smb_com_ntransact_rsp *)buf;
2430 2517
2431 /* ByteCount was converted from little endian in SendReceive */ 2518 /* ByteCount was converted from little endian in SendReceive */
2432 end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount + 2519 end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount +
2433 (char *)&pSMBr->ByteCount; 2520 (char *)&pSMBr->ByteCount;
2434 2521
2435
2436 data_offset = le32_to_cpu(pSMBr->DataOffset); 2522 data_offset = le32_to_cpu(pSMBr->DataOffset);
2437 data_count = le32_to_cpu(pSMBr->DataCount); 2523 data_count = le32_to_cpu(pSMBr->DataCount);
2438 parm_offset = le32_to_cpu(pSMBr->ParameterOffset); 2524 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
2439 parm_count = le32_to_cpu(pSMBr->ParameterCount); 2525 parm_count = le32_to_cpu(pSMBr->ParameterCount);
2440 2526
2441 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset; 2527 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
2442 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset; 2528 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
2443 2529
2444 /* should we also check that parm and data areas do not overlap? */ 2530 /* should we also check that parm and data areas do not overlap? */
2445 if(*ppparm > end_of_smb) { 2531 if (*ppparm > end_of_smb) {
2446 cFYI(1,("parms start after end of smb")); 2532 cFYI(1, ("parms start after end of smb"));
2447 return -EINVAL; 2533 return -EINVAL;
2448 } else if(parm_count + *ppparm > end_of_smb) { 2534 } else if (parm_count + *ppparm > end_of_smb) {
2449 cFYI(1,("parm end after end of smb")); 2535 cFYI(1, ("parm end after end of smb"));
2450 return -EINVAL; 2536 return -EINVAL;
2451 } else if(*ppdata > end_of_smb) { 2537 } else if (*ppdata > end_of_smb) {
2452 cFYI(1,("data starts after end of smb")); 2538 cFYI(1, ("data starts after end of smb"));
2453 return -EINVAL; 2539 return -EINVAL;
2454 } else if(data_count + *ppdata > end_of_smb) { 2540 } else if (data_count + *ppdata > end_of_smb) {
2455 cFYI(1,("data %p + count %d (%p) ends after end of smb %p start %p", 2541 cFYI(1,("data %p + count %d (%p) ends after end of smb %p start %p",
2456 *ppdata, data_count, (data_count + *ppdata), end_of_smb, pSMBr)); /* BB FIXME */ 2542 *ppdata, data_count, (data_count + *ppdata),
2543 end_of_smb, pSMBr));
2457 return -EINVAL; 2544 return -EINVAL;
2458 } else if(parm_count + data_count > pSMBr->ByteCount) { 2545 } else if (parm_count + data_count > pSMBr->ByteCount) {
2459 cFYI(1,("parm count and data count larger than SMB")); 2546 cFYI(1, ("parm count and data count larger than SMB"));
2460 return -EINVAL; 2547 return -EINVAL;
2461 } 2548 }
2462 return 0; 2549 return 0;
@@ -2465,14 +2552,14 @@ validate_ntransact(char * buf, char ** ppparm, char ** ppdata,
2465int 2552int
2466CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, 2553CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
2467 const unsigned char *searchName, 2554 const unsigned char *searchName,
2468 char *symlinkinfo, const int buflen,__u16 fid, 2555 char *symlinkinfo, const int buflen, __u16 fid,
2469 const struct nls_table *nls_codepage) 2556 const struct nls_table *nls_codepage)
2470{ 2557{
2471 int rc = 0; 2558 int rc = 0;
2472 int bytes_returned; 2559 int bytes_returned;
2473 int name_len; 2560 int name_len;
2474 struct smb_com_transaction_ioctl_req * pSMB; 2561 struct smb_com_transaction_ioctl_req *pSMB;
2475 struct smb_com_transaction_ioctl_rsp * pSMBr; 2562 struct smb_com_transaction_ioctl_rsp *pSMBr;
2476 2563
2477 cFYI(1, ("In Windows reparse style QueryLink for path %s", searchName)); 2564 cFYI(1, ("In Windows reparse style QueryLink for path %s", searchName));
2478 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB, 2565 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
@@ -2511,47 +2598,53 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
2511 /* BB also check enough total bytes returned */ 2598 /* BB also check enough total bytes returned */
2512 rc = -EIO; /* bad smb */ 2599 rc = -EIO; /* bad smb */
2513 else { 2600 else {
2514 if(data_count && (data_count < 2048)) { 2601 if (data_count && (data_count < 2048)) {
2515 char * end_of_smb = 2 /* sizeof byte count */ + 2602 char *end_of_smb = 2 /* sizeof byte count */ +
2516 pSMBr->ByteCount + 2603 pSMBr->ByteCount +
2517 (char *)&pSMBr->ByteCount; 2604 (char *)&pSMBr->ByteCount;
2518 2605
2519 struct reparse_data * reparse_buf = (struct reparse_data *) 2606 struct reparse_data *reparse_buf =
2520 ((char *)&pSMBr->hdr.Protocol + data_offset); 2607 (struct reparse_data *)
2521 if((char*)reparse_buf >= end_of_smb) { 2608 ((char *)&pSMBr->hdr.Protocol
2609 + data_offset);
2610 if ((char *)reparse_buf >= end_of_smb) {
2522 rc = -EIO; 2611 rc = -EIO;
2523 goto qreparse_out; 2612 goto qreparse_out;
2524 } 2613 }
2525 if((reparse_buf->LinkNamesBuf + 2614 if ((reparse_buf->LinkNamesBuf +
2526 reparse_buf->TargetNameOffset + 2615 reparse_buf->TargetNameOffset +
2527 reparse_buf->TargetNameLen) > 2616 reparse_buf->TargetNameLen) >
2528 end_of_smb) { 2617 end_of_smb) {
2529 cFYI(1,("reparse buf extended beyond SMB")); 2618 cFYI(1,("reparse buf goes beyond SMB"));
2530 rc = -EIO; 2619 rc = -EIO;
2531 goto qreparse_out; 2620 goto qreparse_out;
2532 } 2621 }
2533 2622
2534 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) { 2623 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
2535 name_len = UniStrnlen((wchar_t *) 2624 name_len = UniStrnlen((wchar_t *)
2536 (reparse_buf->LinkNamesBuf + 2625 (reparse_buf->LinkNamesBuf +
2537 reparse_buf->TargetNameOffset), 2626 reparse_buf->TargetNameOffset),
2538 min(buflen/2, reparse_buf->TargetNameLen / 2)); 2627 min(buflen/2,
2628 reparse_buf->TargetNameLen / 2));
2539 cifs_strfromUCS_le(symlinkinfo, 2629 cifs_strfromUCS_le(symlinkinfo,
2540 (__le16 *) (reparse_buf->LinkNamesBuf + 2630 (__le16 *) (reparse_buf->LinkNamesBuf +
2541 reparse_buf->TargetNameOffset), 2631 reparse_buf->TargetNameOffset),
2542 name_len, nls_codepage); 2632 name_len, nls_codepage);
2543 } else { /* ASCII names */ 2633 } else { /* ASCII names */
2544 strncpy(symlinkinfo,reparse_buf->LinkNamesBuf + 2634 strncpy(symlinkinfo,
2545 reparse_buf->TargetNameOffset, 2635 reparse_buf->LinkNamesBuf +
2546 min_t(const int, buflen, reparse_buf->TargetNameLen)); 2636 reparse_buf->TargetNameOffset,
2637 min_t(const int, buflen,
2638 reparse_buf->TargetNameLen));
2547 } 2639 }
2548 } else { 2640 } else {
2549 rc = -EIO; 2641 rc = -EIO;
2550 cFYI(1,("Invalid return data count on get reparse info ioctl")); 2642 cFYI(1, ("Invalid return data count on "
2643 "get reparse info ioctl"));
2551 } 2644 }
2552 symlinkinfo[buflen] = 0; /* just in case so the caller 2645 symlinkinfo[buflen] = 0; /* just in case so the caller
2553 does not go off the end of the buffer */ 2646 does not go off the end of the buffer */
2554 cFYI(1,("readlink result - %s",symlinkinfo)); 2647 cFYI(1, ("readlink result - %s", symlinkinfo));
2555 } 2648 }
2556 } 2649 }
2557qreparse_out: 2650qreparse_out:
@@ -2566,7 +2659,8 @@ qreparse_out:
2566#ifdef CONFIG_CIFS_POSIX 2659#ifdef CONFIG_CIFS_POSIX
2567 2660
2568/*Convert an Access Control Entry from wire format to local POSIX xattr format*/ 2661/*Convert an Access Control Entry from wire format to local POSIX xattr format*/
2569static void cifs_convert_ace(posix_acl_xattr_entry * ace, struct cifs_posix_ace * cifs_ace) 2662static void cifs_convert_ace(posix_acl_xattr_entry *ace,
2663 struct cifs_posix_ace *cifs_ace)
2570{ 2664{
2571 /* u8 cifs fields do not need le conversion */ 2665 /* u8 cifs fields do not need le conversion */
2572 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm); 2666 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
@@ -2578,30 +2672,31 @@ static void cifs_convert_ace(posix_acl_xattr_entry * ace, struct cifs_posix_ace
2578} 2672}
2579 2673
2580/* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */ 2674/* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
2581static int cifs_copy_posix_acl(char * trgt,char * src, const int buflen, 2675static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
2582 const int acl_type,const int size_of_data_area) 2676 const int acl_type, const int size_of_data_area)
2583{ 2677{
2584 int size = 0; 2678 int size = 0;
2585 int i; 2679 int i;
2586 __u16 count; 2680 __u16 count;
2587 struct cifs_posix_ace * pACE; 2681 struct cifs_posix_ace *pACE;
2588 struct cifs_posix_acl * cifs_acl = (struct cifs_posix_acl *)src; 2682 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
2589 posix_acl_xattr_header * local_acl = (posix_acl_xattr_header *)trgt; 2683 posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)trgt;
2590 2684
2591 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION) 2685 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
2592 return -EOPNOTSUPP; 2686 return -EOPNOTSUPP;
2593 2687
2594 if(acl_type & ACL_TYPE_ACCESS) { 2688 if (acl_type & ACL_TYPE_ACCESS) {
2595 count = le16_to_cpu(cifs_acl->access_entry_count); 2689 count = le16_to_cpu(cifs_acl->access_entry_count);
2596 pACE = &cifs_acl->ace_array[0]; 2690 pACE = &cifs_acl->ace_array[0];
2597 size = sizeof(struct cifs_posix_acl); 2691 size = sizeof(struct cifs_posix_acl);
2598 size += sizeof(struct cifs_posix_ace) * count; 2692 size += sizeof(struct cifs_posix_ace) * count;
2599 /* check if we would go beyond end of SMB */ 2693 /* check if we would go beyond end of SMB */
2600 if(size_of_data_area < size) { 2694 if (size_of_data_area < size) {
2601 cFYI(1,("bad CIFS POSIX ACL size %d vs. %d",size_of_data_area,size)); 2695 cFYI(1, ("bad CIFS POSIX ACL size %d vs. %d",
2696 size_of_data_area, size));
2602 return -EINVAL; 2697 return -EINVAL;
2603 } 2698 }
2604 } else if(acl_type & ACL_TYPE_DEFAULT) { 2699 } else if (acl_type & ACL_TYPE_DEFAULT) {
2605 count = le16_to_cpu(cifs_acl->access_entry_count); 2700 count = le16_to_cpu(cifs_acl->access_entry_count);
2606 size = sizeof(struct cifs_posix_acl); 2701 size = sizeof(struct cifs_posix_acl);
2607 size += sizeof(struct cifs_posix_ace) * count; 2702 size += sizeof(struct cifs_posix_ace) * count;
@@ -2610,7 +2705,7 @@ static int cifs_copy_posix_acl(char * trgt,char * src, const int buflen,
2610 count = le16_to_cpu(cifs_acl->default_entry_count); 2705 count = le16_to_cpu(cifs_acl->default_entry_count);
2611 size += sizeof(struct cifs_posix_ace) * count; 2706 size += sizeof(struct cifs_posix_ace) * count;
2612 /* check if we would go beyond end of SMB */ 2707 /* check if we would go beyond end of SMB */
2613 if(size_of_data_area < size) 2708 if (size_of_data_area < size)
2614 return -EINVAL; 2709 return -EINVAL;
2615 } else { 2710 } else {
2616 /* illegal type */ 2711 /* illegal type */
@@ -2618,76 +2713,77 @@ static int cifs_copy_posix_acl(char * trgt,char * src, const int buflen,
2618 } 2713 }
2619 2714
2620 size = posix_acl_xattr_size(count); 2715 size = posix_acl_xattr_size(count);
2621 if((buflen == 0) || (local_acl == NULL)) { 2716 if ((buflen == 0) || (local_acl == NULL)) {
2622 /* used to query ACL EA size */ 2717 /* used to query ACL EA size */
2623 } else if(size > buflen) { 2718 } else if (size > buflen) {
2624 return -ERANGE; 2719 return -ERANGE;
2625 } else /* buffer big enough */ { 2720 } else /* buffer big enough */ {
2626 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION); 2721 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
2627 for(i = 0;i < count ;i++) { 2722 for (i = 0; i < count ; i++) {
2628 cifs_convert_ace(&local_acl->a_entries[i],pACE); 2723 cifs_convert_ace(&local_acl->a_entries[i], pACE);
2629 pACE ++; 2724 pACE++;
2630 } 2725 }
2631 } 2726 }
2632 return size; 2727 return size;
2633} 2728}
2634 2729
2635static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace * cifs_ace, 2730static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
2636 const posix_acl_xattr_entry * local_ace) 2731 const posix_acl_xattr_entry *local_ace)
2637{ 2732{
2638 __u16 rc = 0; /* 0 = ACL converted ok */ 2733 __u16 rc = 0; /* 0 = ACL converted ok */
2639 2734
2640 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm); 2735 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
2641 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag); 2736 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
2642 /* BB is there a better way to handle the large uid? */ 2737 /* BB is there a better way to handle the large uid? */
2643 if(local_ace->e_id == cpu_to_le32(-1)) { 2738 if (local_ace->e_id == cpu_to_le32(-1)) {
2644 /* Probably no need to le convert -1 on any arch but can not hurt */ 2739 /* Probably no need to le convert -1 on any arch but can not hurt */
2645 cifs_ace->cifs_uid = cpu_to_le64(-1); 2740 cifs_ace->cifs_uid = cpu_to_le64(-1);
2646 } else 2741 } else
2647 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id)); 2742 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
2648 /*cFYI(1,("perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id));*/ 2743 /*cFYI(1,("perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id));*/
2649 return rc; 2744 return rc;
2650} 2745}
2651 2746
2652/* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */ 2747/* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
2653static __u16 ACL_to_cifs_posix(char * parm_data,const char * pACL,const int buflen, 2748static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
2654 const int acl_type) 2749 const int buflen, const int acl_type)
2655{ 2750{
2656 __u16 rc = 0; 2751 __u16 rc = 0;
2657 struct cifs_posix_acl * cifs_acl = (struct cifs_posix_acl *)parm_data; 2752 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
2658 posix_acl_xattr_header * local_acl = (posix_acl_xattr_header *)pACL; 2753 posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)pACL;
2659 int count; 2754 int count;
2660 int i; 2755 int i;
2661 2756
2662 if((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL)) 2757 if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
2663 return 0; 2758 return 0;
2664 2759
2665 count = posix_acl_xattr_count((size_t)buflen); 2760 count = posix_acl_xattr_count((size_t)buflen);
2666 cFYI(1,("setting acl with %d entries from buf of length %d and version of %d", 2761 cFYI(1, ("setting acl with %d entries from buf of length %d and "
2762 "version of %d",
2667 count, buflen, le32_to_cpu(local_acl->a_version))); 2763 count, buflen, le32_to_cpu(local_acl->a_version)));
2668 if(le32_to_cpu(local_acl->a_version) != 2) { 2764 if (le32_to_cpu(local_acl->a_version) != 2) {
2669 cFYI(1,("unknown POSIX ACL version %d", 2765 cFYI(1, ("unknown POSIX ACL version %d",
2670 le32_to_cpu(local_acl->a_version))); 2766 le32_to_cpu(local_acl->a_version)));
2671 return 0; 2767 return 0;
2672 } 2768 }
2673 cifs_acl->version = cpu_to_le16(1); 2769 cifs_acl->version = cpu_to_le16(1);
2674 if(acl_type == ACL_TYPE_ACCESS) 2770 if (acl_type == ACL_TYPE_ACCESS)
2675 cifs_acl->access_entry_count = cpu_to_le16(count); 2771 cifs_acl->access_entry_count = cpu_to_le16(count);
2676 else if(acl_type == ACL_TYPE_DEFAULT) 2772 else if (acl_type == ACL_TYPE_DEFAULT)
2677 cifs_acl->default_entry_count = cpu_to_le16(count); 2773 cifs_acl->default_entry_count = cpu_to_le16(count);
2678 else { 2774 else {
2679 cFYI(1,("unknown ACL type %d",acl_type)); 2775 cFYI(1, ("unknown ACL type %d", acl_type));
2680 return 0; 2776 return 0;
2681 } 2777 }
2682 for(i=0;i<count;i++) { 2778 for (i = 0; i < count; i++) {
2683 rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i], 2779 rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i],
2684 &local_acl->a_entries[i]); 2780 &local_acl->a_entries[i]);
2685 if(rc != 0) { 2781 if (rc != 0) {
2686 /* ACE not converted */ 2782 /* ACE not converted */
2687 break; 2783 break;
2688 } 2784 }
2689 } 2785 }
2690 if(rc == 0) { 2786 if (rc == 0) {
2691 rc = (__u16)(count * sizeof(struct cifs_posix_ace)); 2787 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
2692 rc += sizeof(struct cifs_posix_acl); 2788 rc += sizeof(struct cifs_posix_acl);
2693 /* BB add check to make sure ACL does not overflow SMB */ 2789 /* BB add check to make sure ACL does not overflow SMB */
@@ -2697,9 +2793,9 @@ static __u16 ACL_to_cifs_posix(char * parm_data,const char * pACL,const int bufl
2697 2793
2698int 2794int
2699CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon, 2795CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon,
2700 const unsigned char *searchName, 2796 const unsigned char *searchName,
2701 char *acl_inf, const int buflen, const int acl_type, 2797 char *acl_inf, const int buflen, const int acl_type,
2702 const struct nls_table *nls_codepage, int remap) 2798 const struct nls_table *nls_codepage, int remap)
2703{ 2799{
2704/* SMB_QUERY_POSIX_ACL */ 2800/* SMB_QUERY_POSIX_ACL */
2705 TRANSACTION2_QPI_REQ *pSMB = NULL; 2801 TRANSACTION2_QPI_REQ *pSMB = NULL;
@@ -2708,7 +2804,7 @@ CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon,
2708 int bytes_returned; 2804 int bytes_returned;
2709 int name_len; 2805 int name_len;
2710 __u16 params, byte_count; 2806 __u16 params, byte_count;
2711 2807
2712 cFYI(1, ("In GetPosixACL (Unix) for path %s", searchName)); 2808 cFYI(1, ("In GetPosixACL (Unix) for path %s", searchName));
2713 2809
2714queryAclRetry: 2810queryAclRetry:
@@ -2716,16 +2812,16 @@ queryAclRetry:
2716 (void **) &pSMBr); 2812 (void **) &pSMBr);
2717 if (rc) 2813 if (rc)
2718 return rc; 2814 return rc;
2719 2815
2720 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2816 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2721 name_len = 2817 name_len =
2722 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, 2818 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
2723 PATH_MAX, nls_codepage, remap); 2819 PATH_MAX, nls_codepage, remap);
2724 name_len++; /* trailing null */ 2820 name_len++; /* trailing null */
2725 name_len *= 2; 2821 name_len *= 2;
2726 pSMB->FileName[name_len] = 0; 2822 pSMB->FileName[name_len] = 0;
2727 pSMB->FileName[name_len+1] = 0; 2823 pSMB->FileName[name_len+1] = 0;
2728 } else { /* BB improve the check for buffer overruns BB */ 2824 } else { /* BB improve the check for buffer overruns BB */
2729 name_len = strnlen(searchName, PATH_MAX); 2825 name_len = strnlen(searchName, PATH_MAX);
2730 name_len++; /* trailing null */ 2826 name_len++; /* trailing null */
2731 strncpy(pSMB->FileName, searchName, name_len); 2827 strncpy(pSMB->FileName, searchName, name_len);
@@ -2734,7 +2830,7 @@ queryAclRetry:
2734 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ; 2830 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
2735 pSMB->TotalDataCount = 0; 2831 pSMB->TotalDataCount = 0;
2736 pSMB->MaxParameterCount = cpu_to_le16(2); 2832 pSMB->MaxParameterCount = cpu_to_le16(2);
2737 /* BB find exact max data count below from sess structure BB */ 2833 /* BB find exact max data count below from sess structure BB */
2738 pSMB->MaxDataCount = cpu_to_le16(4000); 2834 pSMB->MaxDataCount = cpu_to_le16(4000);
2739 pSMB->MaxSetupCount = 0; 2835 pSMB->MaxSetupCount = 0;
2740 pSMB->Reserved = 0; 2836 pSMB->Reserved = 0;
@@ -2742,7 +2838,8 @@ queryAclRetry:
2742 pSMB->Timeout = 0; 2838 pSMB->Timeout = 0;
2743 pSMB->Reserved2 = 0; 2839 pSMB->Reserved2 = 0;
2744 pSMB->ParameterOffset = cpu_to_le16( 2840 pSMB->ParameterOffset = cpu_to_le16(
2745 offsetof(struct smb_com_transaction2_qpi_req ,InformationLevel) - 4); 2841 offsetof(struct smb_com_transaction2_qpi_req,
2842 InformationLevel) - 4);
2746 pSMB->DataCount = 0; 2843 pSMB->DataCount = 0;
2747 pSMB->DataOffset = 0; 2844 pSMB->DataOffset = 0;
2748 pSMB->SetupCount = 1; 2845 pSMB->SetupCount = 1;
@@ -2763,7 +2860,7 @@ queryAclRetry:
2763 cFYI(1, ("Send error in Query POSIX ACL = %d", rc)); 2860 cFYI(1, ("Send error in Query POSIX ACL = %d", rc));
2764 } else { 2861 } else {
2765 /* decode response */ 2862 /* decode response */
2766 2863
2767 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 2864 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2768 if (rc || (pSMBr->ByteCount < 2)) 2865 if (rc || (pSMBr->ByteCount < 2))
2769 /* BB also check enough total bytes returned */ 2866 /* BB also check enough total bytes returned */
@@ -2773,7 +2870,7 @@ queryAclRetry:
2773 __u16 count = le16_to_cpu(pSMBr->t2.DataCount); 2870 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
2774 rc = cifs_copy_posix_acl(acl_inf, 2871 rc = cifs_copy_posix_acl(acl_inf,
2775 (char *)&pSMBr->hdr.Protocol+data_offset, 2872 (char *)&pSMBr->hdr.Protocol+data_offset,
2776 buflen,acl_type,count); 2873 buflen, acl_type, count);
2777 } 2874 }
2778 } 2875 }
2779 cifs_buf_release(pSMB); 2876 cifs_buf_release(pSMB);
@@ -2784,10 +2881,10 @@ queryAclRetry:
2784 2881
2785int 2882int
2786CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon, 2883CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
2787 const unsigned char *fileName, 2884 const unsigned char *fileName,
2788 const char *local_acl, const int buflen, 2885 const char *local_acl, const int buflen,
2789 const int acl_type, 2886 const int acl_type,
2790 const struct nls_table *nls_codepage, int remap) 2887 const struct nls_table *nls_codepage, int remap)
2791{ 2888{
2792 struct smb_com_transaction2_spi_req *pSMB = NULL; 2889 struct smb_com_transaction2_spi_req *pSMB = NULL;
2793 struct smb_com_transaction2_spi_rsp *pSMBr = NULL; 2890 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
@@ -2800,16 +2897,16 @@ CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
2800 cFYI(1, ("In SetPosixACL (Unix) for path %s", fileName)); 2897 cFYI(1, ("In SetPosixACL (Unix) for path %s", fileName));
2801setAclRetry: 2898setAclRetry:
2802 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 2899 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2803 (void **) &pSMBr); 2900 (void **) &pSMBr);
2804 if (rc) 2901 if (rc)
2805 return rc; 2902 return rc;
2806 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2903 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2807 name_len = 2904 name_len =
2808 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName, 2905 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
2809 PATH_MAX, nls_codepage, remap); 2906 PATH_MAX, nls_codepage, remap);
2810 name_len++; /* trailing null */ 2907 name_len++; /* trailing null */
2811 name_len *= 2; 2908 name_len *= 2;
2812 } else { /* BB improve the check for buffer overruns BB */ 2909 } else { /* BB improve the check for buffer overruns BB */
2813 name_len = strnlen(fileName, PATH_MAX); 2910 name_len = strnlen(fileName, PATH_MAX);
2814 name_len++; /* trailing null */ 2911 name_len++; /* trailing null */
2815 strncpy(pSMB->FileName, fileName, name_len); 2912 strncpy(pSMB->FileName, fileName, name_len);
@@ -2823,15 +2920,15 @@ setAclRetry:
2823 pSMB->Timeout = 0; 2920 pSMB->Timeout = 0;
2824 pSMB->Reserved2 = 0; 2921 pSMB->Reserved2 = 0;
2825 param_offset = offsetof(struct smb_com_transaction2_spi_req, 2922 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2826 InformationLevel) - 4; 2923 InformationLevel) - 4;
2827 offset = param_offset + params; 2924 offset = param_offset + params;
2828 parm_data = ((char *) &pSMB->hdr.Protocol) + offset; 2925 parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
2829 pSMB->ParameterOffset = cpu_to_le16(param_offset); 2926 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2830 2927
2831 /* convert to on the wire format for POSIX ACL */ 2928 /* convert to on the wire format for POSIX ACL */
2832 data_count = ACL_to_cifs_posix(parm_data,local_acl,buflen,acl_type); 2929 data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
2833 2930
2834 if(data_count == 0) { 2931 if (data_count == 0) {
2835 rc = -EOPNOTSUPP; 2932 rc = -EOPNOTSUPP;
2836 goto setACLerrorExit; 2933 goto setACLerrorExit;
2837 } 2934 }
@@ -2849,7 +2946,7 @@ setAclRetry:
2849 pSMB->hdr.smb_buf_length += byte_count; 2946 pSMB->hdr.smb_buf_length += byte_count;
2850 pSMB->ByteCount = cpu_to_le16(byte_count); 2947 pSMB->ByteCount = cpu_to_le16(byte_count);
2851 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2948 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2852 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2949 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2853 if (rc) { 2950 if (rc) {
2854 cFYI(1, ("Set POSIX ACL returned %d", rc)); 2951 cFYI(1, ("Set POSIX ACL returned %d", rc));
2855 } 2952 }
@@ -2864,86 +2961,85 @@ setACLerrorExit:
2864/* BB fix tabs in this function FIXME BB */ 2961/* BB fix tabs in this function FIXME BB */
2865int 2962int
2866CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon, 2963CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
2867 const int netfid, __u64 * pExtAttrBits, __u64 *pMask) 2964 const int netfid, __u64 * pExtAttrBits, __u64 *pMask)
2868{ 2965{
2869 int rc = 0; 2966 int rc = 0;
2870 struct smb_t2_qfi_req *pSMB = NULL; 2967 struct smb_t2_qfi_req *pSMB = NULL;
2871 struct smb_t2_qfi_rsp *pSMBr = NULL; 2968 struct smb_t2_qfi_rsp *pSMBr = NULL;
2872 int bytes_returned; 2969 int bytes_returned;
2873 __u16 params, byte_count; 2970 __u16 params, byte_count;
2874 2971
2875 cFYI(1,("In GetExtAttr")); 2972 cFYI(1, ("In GetExtAttr"));
2876 if(tcon == NULL) 2973 if (tcon == NULL)
2877 return -ENODEV; 2974 return -ENODEV;
2878 2975
2879GetExtAttrRetry: 2976GetExtAttrRetry:
2880 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 2977 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2881 (void **) &pSMBr); 2978 (void **) &pSMBr);
2882 if (rc) 2979 if (rc)
2883 return rc; 2980 return rc;
2884 2981
2885 params = 2 /* level */ +2 /* fid */; 2982 params = 2 /* level */ +2 /* fid */;
2886 pSMB->t2.TotalDataCount = 0; 2983 pSMB->t2.TotalDataCount = 0;
2887 pSMB->t2.MaxParameterCount = cpu_to_le16(4); 2984 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
2888 /* BB find exact max data count below from sess structure BB */ 2985 /* BB find exact max data count below from sess structure BB */
2889 pSMB->t2.MaxDataCount = cpu_to_le16(4000); 2986 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
2890 pSMB->t2.MaxSetupCount = 0; 2987 pSMB->t2.MaxSetupCount = 0;
2891 pSMB->t2.Reserved = 0; 2988 pSMB->t2.Reserved = 0;
2892 pSMB->t2.Flags = 0; 2989 pSMB->t2.Flags = 0;
2893 pSMB->t2.Timeout = 0; 2990 pSMB->t2.Timeout = 0;
2894 pSMB->t2.Reserved2 = 0; 2991 pSMB->t2.Reserved2 = 0;
2895 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req, 2992 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
2896 Fid) - 4); 2993 Fid) - 4);
2897 pSMB->t2.DataCount = 0; 2994 pSMB->t2.DataCount = 0;
2898 pSMB->t2.DataOffset = 0; 2995 pSMB->t2.DataOffset = 0;
2899 pSMB->t2.SetupCount = 1; 2996 pSMB->t2.SetupCount = 1;
2900 pSMB->t2.Reserved3 = 0; 2997 pSMB->t2.Reserved3 = 0;
2901 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); 2998 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2902 byte_count = params + 1 /* pad */ ; 2999 byte_count = params + 1 /* pad */ ;
2903 pSMB->t2.TotalParameterCount = cpu_to_le16(params); 3000 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
2904 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount; 3001 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
2905 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS); 3002 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
2906 pSMB->Pad = 0; 3003 pSMB->Pad = 0;
2907 pSMB->Fid = netfid; 3004 pSMB->Fid = netfid;
2908 pSMB->hdr.smb_buf_length += byte_count; 3005 pSMB->hdr.smb_buf_length += byte_count;
2909 pSMB->t2.ByteCount = cpu_to_le16(byte_count); 3006 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
2910 3007
2911 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3008 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2912 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3009 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2913 if (rc) { 3010 if (rc) {
2914 cFYI(1, ("error %d in GetExtAttr", rc)); 3011 cFYI(1, ("error %d in GetExtAttr", rc));
2915 } else { 3012 } else {
2916 /* decode response */ 3013 /* decode response */
2917 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3014 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2918 if (rc || (pSMBr->ByteCount < 2)) 3015 if (rc || (pSMBr->ByteCount < 2))
2919 /* BB also check enough total bytes returned */ 3016 /* BB also check enough total bytes returned */
2920 /* If rc should we check for EOPNOSUPP and 3017 /* If rc should we check for EOPNOSUPP and
2921 disable the srvino flag? or in caller? */ 3018 disable the srvino flag? or in caller? */
2922 rc = -EIO; /* bad smb */ 3019 rc = -EIO; /* bad smb */
2923 else { 3020 else {
2924 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3021 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2925 __u16 count = le16_to_cpu(pSMBr->t2.DataCount); 3022 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
2926 struct file_chattr_info * pfinfo; 3023 struct file_chattr_info *pfinfo;
2927 /* BB Do we need a cast or hash here ? */ 3024 /* BB Do we need a cast or hash here ? */
2928 if(count != 16) { 3025 if (count != 16) {
2929 cFYI(1, ("Illegal size ret in GetExtAttr")); 3026 cFYI(1, ("Illegal size ret in GetExtAttr"));
2930 rc = -EIO; 3027 rc = -EIO;
2931 goto GetExtAttrOut; 3028 goto GetExtAttrOut;
2932 } 3029 }
2933 pfinfo = (struct file_chattr_info *) 3030 pfinfo = (struct file_chattr_info *)
2934 (data_offset + (char *) &pSMBr->hdr.Protocol); 3031 (data_offset + (char *) &pSMBr->hdr.Protocol);
2935 *pExtAttrBits = le64_to_cpu(pfinfo->mode); 3032 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
2936 *pMask = le64_to_cpu(pfinfo->mask); 3033 *pMask = le64_to_cpu(pfinfo->mask);
2937 } 3034 }
2938 } 3035 }
2939GetExtAttrOut: 3036GetExtAttrOut:
2940 cifs_buf_release(pSMB); 3037 cifs_buf_release(pSMB);
2941 if (rc == -EAGAIN) 3038 if (rc == -EAGAIN)
2942 goto GetExtAttrRetry; 3039 goto GetExtAttrRetry;
2943 return rc; 3040 return rc;
2944} 3041}
2945 3042
2946
2947#endif /* CONFIG_POSIX */ 3043#endif /* CONFIG_POSIX */
2948 3044
2949 3045
@@ -2955,7 +3051,7 @@ static const struct cifs_sid sid_user =
2955 {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}}; 3051 {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}};
2956 3052
2957/* Convert CIFS ACL to POSIX form */ 3053/* Convert CIFS ACL to POSIX form */
2958static int parse_sec_desc(struct cifs_sid * psec_desc, int acl_len) 3054static int parse_sec_desc(struct cifs_sid *psec_desc, int acl_len)
2959{ 3055{
2960 return 0; 3056 return 0;
2961} 3057}
@@ -2963,7 +3059,7 @@ static int parse_sec_desc(struct cifs_sid * psec_desc, int acl_len)
2963/* Get Security Descriptor (by handle) from remote server for a file or dir */ 3059/* Get Security Descriptor (by handle) from remote server for a file or dir */
2964int 3060int
2965CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, 3061CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
2966 /* BB fix up return info */ char *acl_inf, const int buflen, 3062 /* BB fix up return info */ char *acl_inf, const int buflen,
2967 const int acl_type /* ACCESS/DEFAULT not sure implication */) 3063 const int acl_type /* ACCESS/DEFAULT not sure implication */)
2968{ 3064{
2969 int rc = 0; 3065 int rc = 0;
@@ -2973,7 +3069,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
2973 3069
2974 cFYI(1, ("GetCifsACL")); 3070 cFYI(1, ("GetCifsACL"));
2975 3071
2976 rc = smb_init_ntransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0, 3072 rc = smb_init_ntransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
2977 8 /* parm len */, tcon, (void **) &pSMB); 3073 8 /* parm len */, tcon, (void **) &pSMB);
2978 if (rc) 3074 if (rc)
2979 return rc; 3075 return rc;
@@ -2994,23 +3090,23 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
2994 if (rc) { 3090 if (rc) {
2995 cFYI(1, ("Send error in QuerySecDesc = %d", rc)); 3091 cFYI(1, ("Send error in QuerySecDesc = %d", rc));
2996 } else { /* decode response */ 3092 } else { /* decode response */
2997 struct cifs_sid * psec_desc; 3093 struct cifs_sid *psec_desc;
2998 __le32 * parm; 3094 __le32 * parm;
2999 int parm_len; 3095 int parm_len;
3000 int data_len; 3096 int data_len;
3001 int acl_len; 3097 int acl_len;
3002 struct smb_com_ntransact_rsp * pSMBr; 3098 struct smb_com_ntransact_rsp *pSMBr;
3003 3099
3004/* validate_nttransact */ 3100/* validate_nttransact */
3005 rc = validate_ntransact(iov[0].iov_base, (char **)&parm, 3101 rc = validate_ntransact(iov[0].iov_base, (char **)&parm,
3006 (char **)&psec_desc, 3102 (char **)&psec_desc,
3007 &parm_len, &data_len); 3103 &parm_len, &data_len);
3008 3104 if (rc)
3009 if(rc)
3010 goto qsec_out; 3105 goto qsec_out;
3011 pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base; 3106 pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base;
3012 3107
3013 cERROR(1,("smb %p parm %p data %p",pSMBr,parm,psec_desc)); /* BB removeme BB */ 3108 cERROR(1, ("smb %p parm %p data %p",
3109 pSMBr, parm, psec_desc)); /* BB removeme BB */
3014 3110
3015 if (le32_to_cpu(pSMBr->ParameterCount) != 4) { 3111 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3016 rc = -EIO; /* bad smb */ 3112 rc = -EIO; /* bad smb */
@@ -3020,14 +3116,14 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
3020/* BB check that data area is minimum length and as big as acl_len */ 3116/* BB check that data area is minimum length and as big as acl_len */
3021 3117
3022 acl_len = le32_to_cpu(*(__le32 *)parm); 3118 acl_len = le32_to_cpu(*(__le32 *)parm);
3023 /* BB check if(acl_len > bufsize) */ 3119 /* BB check if (acl_len > bufsize) */
3024 3120
3025 parse_sec_desc(psec_desc, acl_len); 3121 parse_sec_desc(psec_desc, acl_len);
3026 } 3122 }
3027qsec_out: 3123qsec_out:
3028 if(buf_type == CIFS_SMALL_BUFFER) 3124 if (buf_type == CIFS_SMALL_BUFFER)
3029 cifs_small_buf_release(iov[0].iov_base); 3125 cifs_small_buf_release(iov[0].iov_base);
3030 else if(buf_type == CIFS_LARGE_BUFFER) 3126 else if (buf_type == CIFS_LARGE_BUFFER)
3031 cifs_buf_release(iov[0].iov_base); 3127 cifs_buf_release(iov[0].iov_base);
3032/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */ 3128/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
3033 return rc; 3129 return rc;
@@ -3036,9 +3132,9 @@ qsec_out:
3036/* Legacy Query Path Information call for lookup to old servers such 3132/* Legacy Query Path Information call for lookup to old servers such
3037 as Win9x/WinME */ 3133 as Win9x/WinME */
3038int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, 3134int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
3039 const unsigned char *searchName, 3135 const unsigned char *searchName,
3040 FILE_ALL_INFO * pFinfo, 3136 FILE_ALL_INFO *pFinfo,
3041 const struct nls_table *nls_codepage, int remap) 3137 const struct nls_table *nls_codepage, int remap)
3042{ 3138{
3043 QUERY_INFORMATION_REQ * pSMB; 3139 QUERY_INFORMATION_REQ * pSMB;
3044 QUERY_INFORMATION_RSP * pSMBr; 3140 QUERY_INFORMATION_RSP * pSMBr;
@@ -3046,31 +3142,31 @@ int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
3046 int bytes_returned; 3142 int bytes_returned;
3047 int name_len; 3143 int name_len;
3048 3144
3049 cFYI(1, ("In SMBQPath path %s", searchName)); 3145 cFYI(1, ("In SMBQPath path %s", searchName));
3050QInfRetry: 3146QInfRetry:
3051 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB, 3147 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3052 (void **) &pSMBr); 3148 (void **) &pSMBr);
3053 if (rc) 3149 if (rc)
3054 return rc; 3150 return rc;
3055 3151
3056 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3152 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3057 name_len = 3153 name_len =
3058 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, 3154 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
3059 PATH_MAX, nls_codepage, remap); 3155 PATH_MAX, nls_codepage, remap);
3060 name_len++; /* trailing null */ 3156 name_len++; /* trailing null */
3061 name_len *= 2; 3157 name_len *= 2;
3062 } else { 3158 } else {
3063 name_len = strnlen(searchName, PATH_MAX); 3159 name_len = strnlen(searchName, PATH_MAX);
3064 name_len++; /* trailing null */ 3160 name_len++; /* trailing null */
3065 strncpy(pSMB->FileName, searchName, name_len); 3161 strncpy(pSMB->FileName, searchName, name_len);
3066 } 3162 }
3067 pSMB->BufferFormat = 0x04; 3163 pSMB->BufferFormat = 0x04;
3068 name_len++; /* account for buffer type byte */ 3164 name_len++; /* account for buffer type byte */
3069 pSMB->hdr.smb_buf_length += (__u16) name_len; 3165 pSMB->hdr.smb_buf_length += (__u16) name_len;
3070 pSMB->ByteCount = cpu_to_le16(name_len); 3166 pSMB->ByteCount = cpu_to_le16(name_len);
3071 3167
3072 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3168 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3073 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3169 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3074 if (rc) { 3170 if (rc) {
3075 cFYI(1, ("Send error in QueryInfo = %d", rc)); 3171 cFYI(1, ("Send error in QueryInfo = %d", rc));
3076 } else if (pFinfo) { /* decode response */ 3172 } else if (pFinfo) { /* decode response */
@@ -3127,17 +3223,17 @@ QPathInfoRetry:
3127 3223
3128 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3224 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3129 name_len = 3225 name_len =
3130 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, 3226 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
3131 PATH_MAX, nls_codepage, remap); 3227 PATH_MAX, nls_codepage, remap);
3132 name_len++; /* trailing null */ 3228 name_len++; /* trailing null */
3133 name_len *= 2; 3229 name_len *= 2;
3134 } else { /* BB improve the check for buffer overruns BB */ 3230 } else { /* BB improve the check for buffer overruns BB */
3135 name_len = strnlen(searchName, PATH_MAX); 3231 name_len = strnlen(searchName, PATH_MAX);
3136 name_len++; /* trailing null */ 3232 name_len++; /* trailing null */
3137 strncpy(pSMB->FileName, searchName, name_len); 3233 strncpy(pSMB->FileName, searchName, name_len);
3138 } 3234 }
3139 3235
3140 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */ ; 3236 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
3141 pSMB->TotalDataCount = 0; 3237 pSMB->TotalDataCount = 0;
3142 pSMB->MaxParameterCount = cpu_to_le16(2); 3238 pSMB->MaxParameterCount = cpu_to_le16(2);
3143 pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */ 3239 pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */
@@ -3147,7 +3243,7 @@ QPathInfoRetry:
3147 pSMB->Timeout = 0; 3243 pSMB->Timeout = 0;
3148 pSMB->Reserved2 = 0; 3244 pSMB->Reserved2 = 0;
3149 pSMB->ParameterOffset = cpu_to_le16(offsetof( 3245 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3150 struct smb_com_transaction2_qpi_req ,InformationLevel) - 4); 3246 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3151 pSMB->DataCount = 0; 3247 pSMB->DataCount = 0;
3152 pSMB->DataOffset = 0; 3248 pSMB->DataOffset = 0;
3153 pSMB->SetupCount = 1; 3249 pSMB->SetupCount = 1;
@@ -3156,7 +3252,7 @@ QPathInfoRetry:
3156 byte_count = params + 1 /* pad */ ; 3252 byte_count = params + 1 /* pad */ ;
3157 pSMB->TotalParameterCount = cpu_to_le16(params); 3253 pSMB->TotalParameterCount = cpu_to_le16(params);
3158 pSMB->ParameterCount = pSMB->TotalParameterCount; 3254 pSMB->ParameterCount = pSMB->TotalParameterCount;
3159 if(legacy) 3255 if (legacy)
3160 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD); 3256 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
3161 else 3257 else
3162 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO); 3258 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
@@ -3173,16 +3269,18 @@ QPathInfoRetry:
3173 3269
3174 if (rc) /* BB add auto retry on EOPNOTSUPP? */ 3270 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3175 rc = -EIO; 3271 rc = -EIO;
3176 else if (!legacy && (pSMBr->ByteCount < 40)) 3272 else if (!legacy && (pSMBr->ByteCount < 40))
3177 rc = -EIO; /* bad smb */ 3273 rc = -EIO; /* bad smb */
3178 else if(legacy && (pSMBr->ByteCount < 24)) 3274 else if (legacy && (pSMBr->ByteCount < 24))
3179 rc = -EIO; /* 24 or 26 expected but we do not read last field */ 3275 rc = -EIO; /* 24 or 26 expected but we do not read
3180 else if (pFindData){ 3276 last field */
3277 else if (pFindData) {
3181 int size; 3278 int size;
3182 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3279 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3183 if(legacy) /* we do not read the last field, EAsize, fortunately 3280 if (legacy) /* we do not read the last field, EAsize,
3184 since it varies by subdialect and on Set vs. Get, is 3281 fortunately since it varies by subdialect
3185 two bytes or 4 bytes depending but we don't care here */ 3282 and on Set vs. Get, is two bytes or 4
3283 bytes depending but we don't care here */
3186 size = sizeof(FILE_INFO_STANDARD); 3284 size = sizeof(FILE_INFO_STANDARD);
3187 else 3285 else
3188 size = sizeof(FILE_ALL_INFO); 3286 size = sizeof(FILE_ALL_INFO);
@@ -3226,24 +3324,24 @@ UnixQPathInfoRetry:
3226 PATH_MAX, nls_codepage, remap); 3324 PATH_MAX, nls_codepage, remap);
3227 name_len++; /* trailing null */ 3325 name_len++; /* trailing null */
3228 name_len *= 2; 3326 name_len *= 2;
3229 } else { /* BB improve the check for buffer overruns BB */ 3327 } else { /* BB improve the check for buffer overruns BB */
3230 name_len = strnlen(searchName, PATH_MAX); 3328 name_len = strnlen(searchName, PATH_MAX);
3231 name_len++; /* trailing null */ 3329 name_len++; /* trailing null */
3232 strncpy(pSMB->FileName, searchName, name_len); 3330 strncpy(pSMB->FileName, searchName, name_len);
3233 } 3331 }
3234 3332
3235 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */ ; 3333 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
3236 pSMB->TotalDataCount = 0; 3334 pSMB->TotalDataCount = 0;
3237 pSMB->MaxParameterCount = cpu_to_le16(2); 3335 pSMB->MaxParameterCount = cpu_to_le16(2);
3238 /* BB find exact max SMB PDU from sess structure BB */ 3336 /* BB find exact max SMB PDU from sess structure BB */
3239 pSMB->MaxDataCount = cpu_to_le16(4000); 3337 pSMB->MaxDataCount = cpu_to_le16(4000);
3240 pSMB->MaxSetupCount = 0; 3338 pSMB->MaxSetupCount = 0;
3241 pSMB->Reserved = 0; 3339 pSMB->Reserved = 0;
3242 pSMB->Flags = 0; 3340 pSMB->Flags = 0;
3243 pSMB->Timeout = 0; 3341 pSMB->Timeout = 0;
3244 pSMB->Reserved2 = 0; 3342 pSMB->Reserved2 = 0;
3245 pSMB->ParameterOffset = cpu_to_le16(offsetof( 3343 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3246 struct smb_com_transaction2_qpi_req ,InformationLevel) - 4); 3344 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3247 pSMB->DataCount = 0; 3345 pSMB->DataCount = 0;
3248 pSMB->DataOffset = 0; 3346 pSMB->DataOffset = 0;
3249 pSMB->SetupCount = 1; 3347 pSMB->SetupCount = 1;
@@ -3303,12 +3401,11 @@ findUniqueRetry:
3303 3401
3304 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3402 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3305 name_len = 3403 name_len =
3306 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, PATH_MAX 3404 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
3307 /* find define for this maxpathcomponent */ 3405 PATH_MAX, nls_codepage);
3308 , nls_codepage);
3309 name_len++; /* trailing null */ 3406 name_len++; /* trailing null */
3310 name_len *= 2; 3407 name_len *= 2;
3311 } else { /* BB improve the check for buffer overruns BB */ 3408 } else { /* BB improve the check for buffer overruns BB */
3312 name_len = strnlen(searchName, PATH_MAX); 3409 name_len = strnlen(searchName, PATH_MAX);
3313 name_len++; /* trailing null */ 3410 name_len++; /* trailing null */
3314 strncpy(pSMB->FileName, searchName, name_len); 3411 strncpy(pSMB->FileName, searchName, name_len);
@@ -3324,7 +3421,7 @@ findUniqueRetry:
3324 pSMB->Timeout = 0; 3421 pSMB->Timeout = 0;
3325 pSMB->Reserved2 = 0; 3422 pSMB->Reserved2 = 0;
3326 pSMB->ParameterOffset = cpu_to_le16( 3423 pSMB->ParameterOffset = cpu_to_le16(
3327 offsetof(struct smb_com_transaction2_ffirst_req,InformationLevel) - 4); 3424 offsetof(struct smb_com_transaction2_ffirst_req, InformationLevel)-4);
3328 pSMB->DataCount = 0; 3425 pSMB->DataCount = 0;
3329 pSMB->DataOffset = 0; 3426 pSMB->DataOffset = 0;
3330 pSMB->SetupCount = 1; /* one byte, no need to le convert */ 3427 pSMB->SetupCount = 1; /* one byte, no need to le convert */
@@ -3364,10 +3461,10 @@ findUniqueRetry:
3364/* xid, tcon, searchName and codepage are input parms, rest are returned */ 3461/* xid, tcon, searchName and codepage are input parms, rest are returned */
3365int 3462int
3366CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, 3463CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
3367 const char *searchName, 3464 const char *searchName,
3368 const struct nls_table *nls_codepage, 3465 const struct nls_table *nls_codepage,
3369 __u16 * pnetfid, 3466 __u16 *pnetfid,
3370 struct cifs_search_info * psrch_inf, int remap, const char dirsep) 3467 struct cifs_search_info *psrch_inf, int remap, const char dirsep)
3371{ 3468{
3372/* level 257 SMB_ */ 3469/* level 257 SMB_ */
3373 TRANSACTION2_FFIRST_REQ *pSMB = NULL; 3470 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
@@ -3378,7 +3475,7 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
3378 int name_len; 3475 int name_len;
3379 __u16 params, byte_count; 3476 __u16 params, byte_count;
3380 3477
3381 cFYI(1, ("In FindFirst for %s",searchName)); 3478 cFYI(1, ("In FindFirst for %s", searchName));
3382 3479
3383findFirstRetry: 3480findFirstRetry:
3384 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3481 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
@@ -3388,7 +3485,7 @@ findFirstRetry:
3388 3485
3389 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3486 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3390 name_len = 3487 name_len =
3391 cifsConvertToUCS((__le16 *) pSMB->FileName,searchName, 3488 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
3392 PATH_MAX, nls_codepage, remap); 3489 PATH_MAX, nls_codepage, remap);
3393 /* We can not add the asterik earlier in case 3490 /* We can not add the asterik earlier in case
3394 it got remapped to 0xF03A as if it were part of the 3491 it got remapped to 0xF03A as if it were part of the
@@ -3405,7 +3502,7 @@ findFirstRetry:
3405 } else { /* BB add check for overrun of SMB buf BB */ 3502 } else { /* BB add check for overrun of SMB buf BB */
3406 name_len = strnlen(searchName, PATH_MAX); 3503 name_len = strnlen(searchName, PATH_MAX);
3407/* BB fix here and in unicode clause above ie 3504/* BB fix here and in unicode clause above ie
3408 if(name_len > buffersize-header) 3505 if (name_len > buffersize-header)
3409 free buffer exit; BB */ 3506 free buffer exit; BB */
3410 strncpy(pSMB->FileName, searchName, name_len); 3507 strncpy(pSMB->FileName, searchName, name_len);
3411 pSMB->FileName[name_len] = dirsep; 3508 pSMB->FileName[name_len] = dirsep;
@@ -3438,8 +3535,8 @@ findFirstRetry:
3438 pSMB->SearchAttributes = 3535 pSMB->SearchAttributes =
3439 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | 3536 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
3440 ATTR_DIRECTORY); 3537 ATTR_DIRECTORY);
3441 pSMB->SearchCount= cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO)); 3538 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
3442 pSMB->SearchFlags = cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END | 3539 pSMB->SearchFlags = cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END |
3443 CIFS_SEARCH_RETURN_RESUME); 3540 CIFS_SEARCH_RETURN_RESUME);
3444 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level); 3541 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
3445 3542
@@ -3466,7 +3563,7 @@ findFirstRetry:
3466 } else { /* decode response */ 3563 } else { /* decode response */
3467 /* BB remember to free buffer if error BB */ 3564 /* BB remember to free buffer if error BB */
3468 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3565 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3469 if(rc == 0) { 3566 if (rc == 0) {
3470 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) 3567 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3471 psrch_inf->unicode = TRUE; 3568 psrch_inf->unicode = TRUE;
3472 else 3569 else
@@ -3474,18 +3571,19 @@ findFirstRetry:
3474 3571
3475 psrch_inf->ntwrk_buf_start = (char *)pSMBr; 3572 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
3476 psrch_inf->smallBuf = 0; 3573 psrch_inf->smallBuf = 0;
3477 psrch_inf->srch_entries_start = 3574 psrch_inf->srch_entries_start =
3478 (char *) &pSMBr->hdr.Protocol + 3575 (char *) &pSMBr->hdr.Protocol +
3479 le16_to_cpu(pSMBr->t2.DataOffset); 3576 le16_to_cpu(pSMBr->t2.DataOffset);
3480 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol + 3577 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
3481 le16_to_cpu(pSMBr->t2.ParameterOffset)); 3578 le16_to_cpu(pSMBr->t2.ParameterOffset));
3482 3579
3483 if(parms->EndofSearch) 3580 if (parms->EndofSearch)
3484 psrch_inf->endOfSearch = TRUE; 3581 psrch_inf->endOfSearch = TRUE;
3485 else 3582 else
3486 psrch_inf->endOfSearch = FALSE; 3583 psrch_inf->endOfSearch = FALSE;
3487 3584
3488 psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount); 3585 psrch_inf->entries_in_buffer =
3586 le16_to_cpu(parms->SearchCount);
3489 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ + 3587 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
3490 psrch_inf->entries_in_buffer; 3588 psrch_inf->entries_in_buffer;
3491 *pnetfid = parms->SearchHandle; 3589 *pnetfid = parms->SearchHandle;
@@ -3498,7 +3596,7 @@ findFirstRetry:
3498} 3596}
3499 3597
3500int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, 3598int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
3501 __u16 searchHandle, struct cifs_search_info * psrch_inf) 3599 __u16 searchHandle, struct cifs_search_info *psrch_inf)
3502{ 3600{
3503 TRANSACTION2_FNEXT_REQ *pSMB = NULL; 3601 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
3504 TRANSACTION2_FNEXT_RSP *pSMBr = NULL; 3602 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
@@ -3510,7 +3608,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
3510 3608
3511 cFYI(1, ("In FindNext")); 3609 cFYI(1, ("In FindNext"));
3512 3610
3513 if(psrch_inf->endOfSearch == TRUE) 3611 if (psrch_inf->endOfSearch == TRUE)
3514 return -ENOENT; 3612 return -ENOENT;
3515 3613
3516 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3614 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
@@ -3518,12 +3616,13 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
3518 if (rc) 3616 if (rc)
3519 return rc; 3617 return rc;
3520 3618
3521 params = 14; /* includes 2 bytes of null string, converted to LE below */ 3619 params = 14; /* includes 2 bytes of null string, converted to LE below*/
3522 byte_count = 0; 3620 byte_count = 0;
3523 pSMB->TotalDataCount = 0; /* no EAs */ 3621 pSMB->TotalDataCount = 0; /* no EAs */
3524 pSMB->MaxParameterCount = cpu_to_le16(8); 3622 pSMB->MaxParameterCount = cpu_to_le16(8);
3525 pSMB->MaxDataCount = 3623 pSMB->MaxDataCount =
3526 cpu_to_le16((tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFF00); 3624 cpu_to_le16((tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) &
3625 0xFFFFFF00);
3527 pSMB->MaxSetupCount = 0; 3626 pSMB->MaxSetupCount = 0;
3528 pSMB->Reserved = 0; 3627 pSMB->Reserved = 0;
3529 pSMB->Flags = 0; 3628 pSMB->Flags = 0;
@@ -3539,15 +3638,6 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
3539 pSMB->SearchHandle = searchHandle; /* always kept as le */ 3638 pSMB->SearchHandle = searchHandle; /* always kept as le */
3540 pSMB->SearchCount = 3639 pSMB->SearchCount =
3541 cpu_to_le16(CIFSMaxBufSize / sizeof (FILE_UNIX_INFO)); 3640 cpu_to_le16(CIFSMaxBufSize / sizeof (FILE_UNIX_INFO));
3542 /* test for Unix extensions */
3543/* if (tcon->ses->capabilities & CAP_UNIX) {
3544 pSMB->InformationLevel = cpu_to_le16(SMB_FIND_FILE_UNIX);
3545 psrch_inf->info_level = SMB_FIND_FILE_UNIX;
3546 } else {
3547 pSMB->InformationLevel =
3548 cpu_to_le16(SMB_FIND_FILE_DIRECTORY_INFO);
3549 psrch_inf->info_level = SMB_FIND_FILE_DIRECTORY_INFO;
3550 } */
3551 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level); 3641 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
3552 pSMB->ResumeKey = psrch_inf->resume_key; 3642 pSMB->ResumeKey = psrch_inf->resume_key;
3553 pSMB->SearchFlags = 3643 pSMB->SearchFlags =
@@ -3555,7 +3645,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
3555 3645
3556 name_len = psrch_inf->resume_name_len; 3646 name_len = psrch_inf->resume_name_len;
3557 params += name_len; 3647 params += name_len;
3558 if(name_len < PATH_MAX) { 3648 if (name_len < PATH_MAX) {
3559 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len); 3649 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
3560 byte_count += name_len; 3650 byte_count += name_len;
3561 /* 14 byte parm len above enough for 2 byte null terminator */ 3651 /* 14 byte parm len above enough for 2 byte null terminator */
@@ -3570,20 +3660,20 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
3570 pSMB->ParameterCount = pSMB->TotalParameterCount; 3660 pSMB->ParameterCount = pSMB->TotalParameterCount;
3571 pSMB->hdr.smb_buf_length += byte_count; 3661 pSMB->hdr.smb_buf_length += byte_count;
3572 pSMB->ByteCount = cpu_to_le16(byte_count); 3662 pSMB->ByteCount = cpu_to_le16(byte_count);
3573 3663
3574 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3664 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3575 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3665 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3576 cifs_stats_inc(&tcon->num_fnext); 3666 cifs_stats_inc(&tcon->num_fnext);
3577 if (rc) { 3667 if (rc) {
3578 if (rc == -EBADF) { 3668 if (rc == -EBADF) {
3579 psrch_inf->endOfSearch = TRUE; 3669 psrch_inf->endOfSearch = TRUE;
3580 rc = 0; /* search probably was closed at end of search above */ 3670 rc = 0; /* search probably was closed at end of search*/
3581 } else 3671 } else
3582 cFYI(1, ("FindNext returned = %d", rc)); 3672 cFYI(1, ("FindNext returned = %d", rc));
3583 } else { /* decode response */ 3673 } else { /* decode response */
3584 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3674 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3585 3675
3586 if(rc == 0) { 3676 if (rc == 0) {
3587 /* BB fixme add lock for file (srch_info) struct here */ 3677 /* BB fixme add lock for file (srch_info) struct here */
3588 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) 3678 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3589 psrch_inf->unicode = TRUE; 3679 psrch_inf->unicode = TRUE;
@@ -3594,7 +3684,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
3594 parms = (T2_FNEXT_RSP_PARMS *)response_data; 3684 parms = (T2_FNEXT_RSP_PARMS *)response_data;
3595 response_data = (char *)&pSMBr->hdr.Protocol + 3685 response_data = (char *)&pSMBr->hdr.Protocol +
3596 le16_to_cpu(pSMBr->t2.DataOffset); 3686 le16_to_cpu(pSMBr->t2.DataOffset);
3597 if(psrch_inf->smallBuf) 3687 if (psrch_inf->smallBuf)
3598 cifs_small_buf_release( 3688 cifs_small_buf_release(
3599 psrch_inf->ntwrk_buf_start); 3689 psrch_inf->ntwrk_buf_start);
3600 else 3690 else
@@ -3602,15 +3692,16 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
3602 psrch_inf->srch_entries_start = response_data; 3692 psrch_inf->srch_entries_start = response_data;
3603 psrch_inf->ntwrk_buf_start = (char *)pSMB; 3693 psrch_inf->ntwrk_buf_start = (char *)pSMB;
3604 psrch_inf->smallBuf = 0; 3694 psrch_inf->smallBuf = 0;
3605 if(parms->EndofSearch) 3695 if (parms->EndofSearch)
3606 psrch_inf->endOfSearch = TRUE; 3696 psrch_inf->endOfSearch = TRUE;
3607 else 3697 else
3608 psrch_inf->endOfSearch = FALSE; 3698 psrch_inf->endOfSearch = FALSE;
3609 3699 psrch_inf->entries_in_buffer =
3610 psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount); 3700 le16_to_cpu(parms->SearchCount);
3611 psrch_inf->index_of_last_entry += 3701 psrch_inf->index_of_last_entry +=
3612 psrch_inf->entries_in_buffer; 3702 psrch_inf->entries_in_buffer;
3613/* cFYI(1,("fnxt2 entries in buf %d index_of_last %d",psrch_inf->entries_in_buffer,psrch_inf->index_of_last_entry)); */ 3703/* cFYI(1,("fnxt2 entries in buf %d index_of_last %d",
3704 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry)); */
3614 3705
3615 /* BB fixme add unlock here */ 3706 /* BB fixme add unlock here */
3616 } 3707 }
@@ -3625,12 +3716,12 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
3625FNext2_err_exit: 3716FNext2_err_exit:
3626 if (rc != 0) 3717 if (rc != 0)
3627 cifs_buf_release(pSMB); 3718 cifs_buf_release(pSMB);
3628
3629 return rc; 3719 return rc;
3630} 3720}
3631 3721
3632int 3722int
3633CIFSFindClose(const int xid, struct cifsTconInfo *tcon, const __u16 searchHandle) 3723CIFSFindClose(const int xid, struct cifsTconInfo *tcon,
3724 const __u16 searchHandle)
3634{ 3725{
3635 int rc = 0; 3726 int rc = 0;
3636 FINDCLOSE_REQ *pSMB = NULL; 3727 FINDCLOSE_REQ *pSMB = NULL;
@@ -3642,7 +3733,7 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon, const __u16 searchHandle
3642 3733
3643 /* no sense returning error if session restarted 3734 /* no sense returning error if session restarted
3644 as file handle has been closed */ 3735 as file handle has been closed */
3645 if(rc == -EAGAIN) 3736 if (rc == -EAGAIN)
3646 return 0; 3737 return 0;
3647 if (rc) 3738 if (rc)
3648 return rc; 3739 return rc;
@@ -3667,9 +3758,9 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon, const __u16 searchHandle
3667 3758
3668int 3759int
3669CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, 3760CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
3670 const unsigned char *searchName, 3761 const unsigned char *searchName,
3671 __u64 * inode_number, 3762 __u64 * inode_number,
3672 const struct nls_table *nls_codepage, int remap) 3763 const struct nls_table *nls_codepage, int remap)
3673{ 3764{
3674 int rc = 0; 3765 int rc = 0;
3675 TRANSACTION2_QPI_REQ *pSMB = NULL; 3766 TRANSACTION2_QPI_REQ *pSMB = NULL;
@@ -3677,24 +3768,23 @@ CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
3677 int name_len, bytes_returned; 3768 int name_len, bytes_returned;
3678 __u16 params, byte_count; 3769 __u16 params, byte_count;
3679 3770
3680 cFYI(1,("In GetSrvInodeNum for %s",searchName)); 3771 cFYI(1, ("In GetSrvInodeNum for %s", searchName));
3681 if(tcon == NULL) 3772 if (tcon == NULL)
3682 return -ENODEV; 3773 return -ENODEV;
3683 3774
3684GetInodeNumberRetry: 3775GetInodeNumberRetry:
3685 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3776 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3686 (void **) &pSMBr); 3777 (void **) &pSMBr);
3687 if (rc) 3778 if (rc)
3688 return rc; 3779 return rc;
3689 3780
3690
3691 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3781 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3692 name_len = 3782 name_len =
3693 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, 3783 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
3694 PATH_MAX,nls_codepage, remap); 3784 PATH_MAX, nls_codepage, remap);
3695 name_len++; /* trailing null */ 3785 name_len++; /* trailing null */
3696 name_len *= 2; 3786 name_len *= 2;
3697 } else { /* BB improve the check for buffer overruns BB */ 3787 } else { /* BB improve the check for buffer overruns BB */
3698 name_len = strnlen(searchName, PATH_MAX); 3788 name_len = strnlen(searchName, PATH_MAX);
3699 name_len++; /* trailing null */ 3789 name_len++; /* trailing null */
3700 strncpy(pSMB->FileName, searchName, name_len); 3790 strncpy(pSMB->FileName, searchName, name_len);
@@ -3711,7 +3801,7 @@ GetInodeNumberRetry:
3711 pSMB->Timeout = 0; 3801 pSMB->Timeout = 0;
3712 pSMB->Reserved2 = 0; 3802 pSMB->Reserved2 = 0;
3713 pSMB->ParameterOffset = cpu_to_le16(offsetof( 3803 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3714 struct smb_com_transaction2_qpi_req ,InformationLevel) - 4); 3804 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3715 pSMB->DataCount = 0; 3805 pSMB->DataCount = 0;
3716 pSMB->DataOffset = 0; 3806 pSMB->DataOffset = 0;
3717 pSMB->SetupCount = 1; 3807 pSMB->SetupCount = 1;
@@ -3737,12 +3827,12 @@ GetInodeNumberRetry:
3737 /* If rc should we check for EOPNOSUPP and 3827 /* If rc should we check for EOPNOSUPP and
3738 disable the srvino flag? or in caller? */ 3828 disable the srvino flag? or in caller? */
3739 rc = -EIO; /* bad smb */ 3829 rc = -EIO; /* bad smb */
3740 else { 3830 else {
3741 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3831 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3742 __u16 count = le16_to_cpu(pSMBr->t2.DataCount); 3832 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3743 struct file_internal_info * pfinfo; 3833 struct file_internal_info *pfinfo;
3744 /* BB Do we need a cast or hash here ? */ 3834 /* BB Do we need a cast or hash here ? */
3745 if(count < 8) { 3835 if (count < 8) {
3746 cFYI(1, ("Illegal size ret in QryIntrnlInf")); 3836 cFYI(1, ("Illegal size ret in QryIntrnlInf"));
3747 rc = -EIO; 3837 rc = -EIO;
3748 goto GetInodeNumOut; 3838 goto GetInodeNumOut;
@@ -3769,12 +3859,12 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
3769/* TRANS2_GET_DFS_REFERRAL */ 3859/* TRANS2_GET_DFS_REFERRAL */
3770 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL; 3860 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
3771 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL; 3861 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
3772 struct dfs_referral_level_3 * referrals = NULL; 3862 struct dfs_referral_level_3 *referrals = NULL;
3773 int rc = 0; 3863 int rc = 0;
3774 int bytes_returned; 3864 int bytes_returned;
3775 int name_len; 3865 int name_len;
3776 unsigned int i; 3866 unsigned int i;
3777 char * temp; 3867 char *temp;
3778 __u16 params, byte_count; 3868 __u16 params, byte_count;
3779 *number_of_UNC_in_array = 0; 3869 *number_of_UNC_in_array = 0;
3780 *targetUNCs = NULL; 3870 *targetUNCs = NULL;
@@ -3787,8 +3877,8 @@ getDFSRetry:
3787 (void **) &pSMBr); 3877 (void **) &pSMBr);
3788 if (rc) 3878 if (rc)
3789 return rc; 3879 return rc;
3790 3880
3791 /* server pointer checked in called function, 3881 /* server pointer checked in called function,
3792 but should never be null here anyway */ 3882 but should never be null here anyway */
3793 pSMB->hdr.Mid = GetNextMid(ses->server); 3883 pSMB->hdr.Mid = GetNextMid(ses->server);
3794 pSMB->hdr.Tid = ses->ipc_tid; 3884 pSMB->hdr.Tid = ses->ipc_tid;
@@ -3807,19 +3897,19 @@ getDFSRetry:
3807 searchName, PATH_MAX, nls_codepage, remap); 3897 searchName, PATH_MAX, nls_codepage, remap);
3808 name_len++; /* trailing null */ 3898 name_len++; /* trailing null */
3809 name_len *= 2; 3899 name_len *= 2;
3810 } else { /* BB improve the check for buffer overruns BB */ 3900 } else { /* BB improve the check for buffer overruns BB */
3811 name_len = strnlen(searchName, PATH_MAX); 3901 name_len = strnlen(searchName, PATH_MAX);
3812 name_len++; /* trailing null */ 3902 name_len++; /* trailing null */
3813 strncpy(pSMB->RequestFileName, searchName, name_len); 3903 strncpy(pSMB->RequestFileName, searchName, name_len);
3814 } 3904 }
3815 3905
3816 if(ses->server) { 3906 if (ses->server) {
3817 if(ses->server->secMode & 3907 if (ses->server->secMode &
3818 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 3908 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3819 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 3909 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3820 } 3910 }
3821 3911
3822 pSMB->hdr.Uid = ses->Suid; 3912 pSMB->hdr.Uid = ses->Suid;
3823 3913
3824 params = 2 /* level */ + name_len /*includes null */ ; 3914 params = 2 /* level */ + name_len /*includes null */ ;
3825 pSMB->TotalDataCount = 0; 3915 pSMB->TotalDataCount = 0;
@@ -3833,7 +3923,7 @@ getDFSRetry:
3833 pSMB->Timeout = 0; 3923 pSMB->Timeout = 0;
3834 pSMB->Reserved2 = 0; 3924 pSMB->Reserved2 = 0;
3835 pSMB->ParameterOffset = cpu_to_le16(offsetof( 3925 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3836 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4); 3926 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
3837 pSMB->SetupCount = 1; 3927 pSMB->SetupCount = 1;
3838 pSMB->Reserved3 = 0; 3928 pSMB->Reserved3 = 0;
3839 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL); 3929 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
@@ -3852,74 +3942,87 @@ getDFSRetry:
3852/* BB Add logic to parse referrals here */ 3942/* BB Add logic to parse referrals here */
3853 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3943 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3854 3944
3855 if (rc || (pSMBr->ByteCount < 17)) /* BB also check enough total bytes returned */ 3945 /* BB Also check if enough total bytes returned? */
3946 if (rc || (pSMBr->ByteCount < 17))
3856 rc = -EIO; /* bad smb */ 3947 rc = -EIO; /* bad smb */
3857 else { 3948 else {
3858 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3949 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3859 __u16 data_count = le16_to_cpu(pSMBr->t2.DataCount); 3950 __u16 data_count = le16_to_cpu(pSMBr->t2.DataCount);
3860 3951
3861 cFYI(1, 3952 cFYI(1,
3862 ("Decoding GetDFSRefer response. BCC: %d Offset %d", 3953 ("Decoding GetDFSRefer response BCC: %d Offset %d",
3863 pSMBr->ByteCount, data_offset)); 3954 pSMBr->ByteCount, data_offset));
3864 referrals = 3955 referrals =
3865 (struct dfs_referral_level_3 *) 3956 (struct dfs_referral_level_3 *)
3866 (8 /* sizeof start of data block */ + 3957 (8 /* sizeof start of data block */ +
3867 data_offset + 3958 data_offset +
3868 (char *) &pSMBr->hdr.Protocol); 3959 (char *) &pSMBr->hdr.Protocol);
3869 cFYI(1,("num_referrals: %d dfs flags: 0x%x ... \nfor referral one refer size: 0x%x srv type: 0x%x refer flags: 0x%x ttl: 0x%x", 3960 cFYI(1, ("num_referrals: %d dfs flags: 0x%x ... \n"
3870 le16_to_cpu(pSMBr->NumberOfReferrals),le16_to_cpu(pSMBr->DFSFlags), le16_to_cpu(referrals->ReferralSize),le16_to_cpu(referrals->ServerType),le16_to_cpu(referrals->ReferralFlags),le16_to_cpu(referrals->TimeToLive))); 3961 "for referral one refer size: 0x%x srv "
3962 "type: 0x%x refer flags: 0x%x ttl: 0x%x",
3963 le16_to_cpu(pSMBr->NumberOfReferrals),
3964 le16_to_cpu(pSMBr->DFSFlags),
3965 le16_to_cpu(referrals->ReferralSize),
3966 le16_to_cpu(referrals->ServerType),
3967 le16_to_cpu(referrals->ReferralFlags),
3968 le16_to_cpu(referrals->TimeToLive)));
3871 /* BB This field is actually two bytes in from start of 3969 /* BB This field is actually two bytes in from start of
3872 data block so we could do safety check that DataBlock 3970 data block so we could do safety check that DataBlock
3873 begins at address of pSMBr->NumberOfReferrals */ 3971 begins at address of pSMBr->NumberOfReferrals */
3874 *number_of_UNC_in_array = le16_to_cpu(pSMBr->NumberOfReferrals); 3972 *number_of_UNC_in_array =
3973 le16_to_cpu(pSMBr->NumberOfReferrals);
3875 3974
3876 /* BB Fix below so can return more than one referral */ 3975 /* BB Fix below so can return more than one referral */
3877 if(*number_of_UNC_in_array > 1) 3976 if (*number_of_UNC_in_array > 1)
3878 *number_of_UNC_in_array = 1; 3977 *number_of_UNC_in_array = 1;
3879 3978
3880 /* get the length of the strings describing refs */ 3979 /* get the length of the strings describing refs */
3881 name_len = 0; 3980 name_len = 0;
3882 for(i=0;i<*number_of_UNC_in_array;i++) { 3981 for (i = 0; i < *number_of_UNC_in_array; i++) {
3883 /* make sure that DfsPathOffset not past end */ 3982 /* make sure that DfsPathOffset not past end */
3884 __u16 offset = le16_to_cpu(referrals->DfsPathOffset); 3983 __u16 offset =
3984 le16_to_cpu(referrals->DfsPathOffset);
3885 if (offset > data_count) { 3985 if (offset > data_count) {
3886 /* if invalid referral, stop here and do 3986 /* if invalid referral, stop here and do
3887 not try to copy any more */ 3987 not try to copy any more */
3888 *number_of_UNC_in_array = i; 3988 *number_of_UNC_in_array = i;
3889 break; 3989 break;
3890 } 3990 }
3891 temp = ((char *)referrals) + offset; 3991 temp = ((char *)referrals) + offset;
3892 3992
3893 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) { 3993 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
3894 name_len += UniStrnlen((wchar_t *)temp,data_count); 3994 name_len += UniStrnlen((wchar_t *)temp,
3995 data_count);
3895 } else { 3996 } else {
3896 name_len += strnlen(temp,data_count); 3997 name_len += strnlen(temp, data_count);
3897 } 3998 }
3898 referrals++; 3999 referrals++;
3899 /* BB add check that referral pointer does not fall off end PDU */ 4000 /* BB add check that referral pointer does
3900 4001 not fall off end PDU */
3901 } 4002 }
3902 /* BB add check for name_len bigger than bcc */ 4003 /* BB add check for name_len bigger than bcc */
3903 *targetUNCs = 4004 *targetUNCs =
3904 kmalloc(name_len+1+ (*number_of_UNC_in_array),GFP_KERNEL); 4005 kmalloc(name_len+1+(*number_of_UNC_in_array),
3905 if(*targetUNCs == NULL) { 4006 GFP_KERNEL);
4007 if (*targetUNCs == NULL) {
3906 rc = -ENOMEM; 4008 rc = -ENOMEM;
3907 goto GetDFSRefExit; 4009 goto GetDFSRefExit;
3908 } 4010 }
3909 /* copy the ref strings */ 4011 /* copy the ref strings */
3910 referrals = 4012 referrals = (struct dfs_referral_level_3 *)
3911 (struct dfs_referral_level_3 *) 4013 (8 /* sizeof data hdr */ + data_offset +
3912 (8 /* sizeof data hdr */ +
3913 data_offset +
3914 (char *) &pSMBr->hdr.Protocol); 4014 (char *) &pSMBr->hdr.Protocol);
3915 4015
3916 for(i=0;i<*number_of_UNC_in_array;i++) { 4016 for (i = 0; i < *number_of_UNC_in_array; i++) {
3917 temp = ((char *)referrals) + le16_to_cpu(referrals->DfsPathOffset); 4017 temp = ((char *)referrals) +
4018 le16_to_cpu(referrals->DfsPathOffset);
3918 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) { 4019 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
3919 cifs_strfromUCS_le(*targetUNCs, 4020 cifs_strfromUCS_le(*targetUNCs,
3920 (__le16 *) temp, name_len, nls_codepage); 4021 (__le16 *) temp,
4022 name_len,
4023 nls_codepage);
3921 } else { 4024 } else {
3922 strncpy(*targetUNCs,temp,name_len); 4025 strncpy(*targetUNCs, temp, name_len);
3923 } 4026 }
3924 /* BB update target_uncs pointers */ 4027 /* BB update target_uncs pointers */
3925 referrals++; 4028 referrals++;
@@ -3996,18 +4099,17 @@ oldQFSInfoRetry:
3996 rc = -EIO; /* bad smb */ 4099 rc = -EIO; /* bad smb */
3997 else { 4100 else {
3998 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4101 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3999 cFYI(1,("qfsinf resp BCC: %d Offset %d", 4102 cFYI(1, ("qfsinf resp BCC: %d Offset %d",
4000 pSMBr->ByteCount, data_offset)); 4103 pSMBr->ByteCount, data_offset));
4001 4104
4002 response_data = 4105 response_data = (FILE_SYSTEM_ALLOC_INFO *)
4003 (FILE_SYSTEM_ALLOC_INFO *)
4004 (((char *) &pSMBr->hdr.Protocol) + data_offset); 4106 (((char *) &pSMBr->hdr.Protocol) + data_offset);
4005 FSData->f_bsize = 4107 FSData->f_bsize =
4006 le16_to_cpu(response_data->BytesPerSector) * 4108 le16_to_cpu(response_data->BytesPerSector) *
4007 le32_to_cpu(response_data-> 4109 le32_to_cpu(response_data->
4008 SectorsPerAllocationUnit); 4110 SectorsPerAllocationUnit);
4009 FSData->f_blocks = 4111 FSData->f_blocks =
4010 le32_to_cpu(response_data->TotalAllocationUnits); 4112 le32_to_cpu(response_data->TotalAllocationUnits);
4011 FSData->f_bfree = FSData->f_bavail = 4113 FSData->f_bfree = FSData->f_bavail =
4012 le32_to_cpu(response_data->FreeAllocationUnits); 4114 le32_to_cpu(response_data->FreeAllocationUnits);
4013 cFYI(1, 4115 cFYI(1,
@@ -4056,7 +4158,7 @@ QFSInfoRetry:
4056 pSMB->TotalParameterCount = cpu_to_le16(params); 4158 pSMB->TotalParameterCount = cpu_to_le16(params);
4057 pSMB->ParameterCount = pSMB->TotalParameterCount; 4159 pSMB->ParameterCount = pSMB->TotalParameterCount;
4058 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4160 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4059 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4161 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4060 pSMB->DataCount = 0; 4162 pSMB->DataCount = 0;
4061 pSMB->DataOffset = 0; 4163 pSMB->DataOffset = 0;
4062 pSMB->SetupCount = 1; 4164 pSMB->SetupCount = 1;
@@ -4071,7 +4173,7 @@ QFSInfoRetry:
4071 if (rc) { 4173 if (rc) {
4072 cFYI(1, ("Send error in QFSInfo = %d", rc)); 4174 cFYI(1, ("Send error in QFSInfo = %d", rc));
4073 } else { /* decode response */ 4175 } else { /* decode response */
4074 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4176 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4075 4177
4076 if (rc || (pSMBr->ByteCount < 24)) 4178 if (rc || (pSMBr->ByteCount < 24))
4077 rc = -EIO; /* bad smb */ 4179 rc = -EIO; /* bad smb */
@@ -4136,7 +4238,7 @@ QFSAttributeRetry:
4136 pSMB->TotalParameterCount = cpu_to_le16(params); 4238 pSMB->TotalParameterCount = cpu_to_le16(params);
4137 pSMB->ParameterCount = pSMB->TotalParameterCount; 4239 pSMB->ParameterCount = pSMB->TotalParameterCount;
4138 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4240 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4139 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4241 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4140 pSMB->DataCount = 0; 4242 pSMB->DataCount = 0;
4141 pSMB->DataOffset = 0; 4243 pSMB->DataOffset = 0;
4142 pSMB->SetupCount = 1; 4244 pSMB->SetupCount = 1;
@@ -4153,7 +4255,8 @@ QFSAttributeRetry:
4153 } else { /* decode response */ 4255 } else { /* decode response */
4154 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4256 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4155 4257
4156 if (rc || (pSMBr->ByteCount < 13)) { /* BB also check enough bytes returned */ 4258 if (rc || (pSMBr->ByteCount < 13)) {
4259 /* BB also check if enough bytes returned */
4157 rc = -EIO; /* bad smb */ 4260 rc = -EIO; /* bad smb */
4158 } else { 4261 } else {
4159 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4262 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
@@ -4204,7 +4307,7 @@ QFSDeviceRetry:
4204 pSMB->TotalParameterCount = cpu_to_le16(params); 4307 pSMB->TotalParameterCount = cpu_to_le16(params);
4205 pSMB->ParameterCount = pSMB->TotalParameterCount; 4308 pSMB->ParameterCount = pSMB->TotalParameterCount;
4206 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4309 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4207 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4310 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4208 4311
4209 pSMB->DataCount = 0; 4312 pSMB->DataCount = 0;
4210 pSMB->DataOffset = 0; 4313 pSMB->DataOffset = 0;
@@ -4274,8 +4377,8 @@ QFSUnixRetry:
4274 byte_count = params + 1 /* pad */ ; 4377 byte_count = params + 1 /* pad */ ;
4275 pSMB->ParameterCount = cpu_to_le16(params); 4378 pSMB->ParameterCount = cpu_to_le16(params);
4276 pSMB->TotalParameterCount = pSMB->ParameterCount; 4379 pSMB->TotalParameterCount = pSMB->ParameterCount;
4277 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct 4380 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
4278 smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4381 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4279 pSMB->SetupCount = 1; 4382 pSMB->SetupCount = 1;
4280 pSMB->Reserved3 = 0; 4383 pSMB->Reserved3 = 0;
4281 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4384 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
@@ -4335,7 +4438,8 @@ SETFSUnixRetry:
4335 pSMB->Flags = 0; 4438 pSMB->Flags = 0;
4336 pSMB->Timeout = 0; 4439 pSMB->Timeout = 0;
4337 pSMB->Reserved2 = 0; 4440 pSMB->Reserved2 = 0;
4338 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum) - 4; 4441 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
4442 - 4;
4339 offset = param_offset + params; 4443 offset = param_offset + params;
4340 4444
4341 pSMB->MaxParameterCount = cpu_to_le16(4); 4445 pSMB->MaxParameterCount = cpu_to_le16(4);
@@ -4417,8 +4521,8 @@ QFSPosixRetry:
4417 byte_count = params + 1 /* pad */ ; 4521 byte_count = params + 1 /* pad */ ;
4418 pSMB->ParameterCount = cpu_to_le16(params); 4522 pSMB->ParameterCount = cpu_to_le16(params);
4419 pSMB->TotalParameterCount = pSMB->ParameterCount; 4523 pSMB->TotalParameterCount = pSMB->ParameterCount;
4420 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct 4524 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
4421 smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4525 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4422 pSMB->SetupCount = 1; 4526 pSMB->SetupCount = 1;
4423 pSMB->Reserved3 = 0; 4527 pSMB->Reserved3 = 0;
4424 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4528 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
@@ -4447,18 +4551,18 @@ QFSPosixRetry:
4447 le64_to_cpu(response_data->TotalBlocks); 4551 le64_to_cpu(response_data->TotalBlocks);
4448 FSData->f_bfree = 4552 FSData->f_bfree =
4449 le64_to_cpu(response_data->BlocksAvail); 4553 le64_to_cpu(response_data->BlocksAvail);
4450 if(response_data->UserBlocksAvail == cpu_to_le64(-1)) { 4554 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
4451 FSData->f_bavail = FSData->f_bfree; 4555 FSData->f_bavail = FSData->f_bfree;
4452 } else { 4556 } else {
4453 FSData->f_bavail = 4557 FSData->f_bavail =
4454 le64_to_cpu(response_data->UserBlocksAvail); 4558 le64_to_cpu(response_data->UserBlocksAvail);
4455 } 4559 }
4456 if(response_data->TotalFileNodes != cpu_to_le64(-1)) 4560 if (response_data->TotalFileNodes != cpu_to_le64(-1))
4457 FSData->f_files = 4561 FSData->f_files =
4458 le64_to_cpu(response_data->TotalFileNodes); 4562 le64_to_cpu(response_data->TotalFileNodes);
4459 if(response_data->FreeFileNodes != cpu_to_le64(-1)) 4563 if (response_data->FreeFileNodes != cpu_to_le64(-1))
4460 FSData->f_ffree = 4564 FSData->f_ffree =
4461 le64_to_cpu(response_data->FreeFileNodes); 4565 le64_to_cpu(response_data->FreeFileNodes);
4462 } 4566 }
4463 } 4567 }
4464 cifs_buf_release(pSMB); 4568 cifs_buf_release(pSMB);
@@ -4470,15 +4574,15 @@ QFSPosixRetry:
4470} 4574}
4471 4575
4472 4576
4473/* We can not use write of zero bytes trick to 4577/* We can not use write of zero bytes trick to
4474 set file size due to need for large file support. Also note that 4578 set file size due to need for large file support. Also note that
4475 this SetPathInfo is preferred to SetFileInfo based method in next 4579 this SetPathInfo is preferred to SetFileInfo based method in next
4476 routine which is only needed to work around a sharing violation bug 4580 routine which is only needed to work around a sharing violation bug
4477 in Samba which this routine can run into */ 4581 in Samba which this routine can run into */
4478 4582
4479int 4583int
4480CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, const char *fileName, 4584CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, const char *fileName,
4481 __u64 size, int SetAllocation, 4585 __u64 size, int SetAllocation,
4482 const struct nls_table *nls_codepage, int remap) 4586 const struct nls_table *nls_codepage, int remap)
4483{ 4587{
4484 struct smb_com_transaction2_spi_req *pSMB = NULL; 4588 struct smb_com_transaction2_spi_req *pSMB = NULL;
@@ -4517,22 +4621,22 @@ SetEOFRetry:
4517 pSMB->Timeout = 0; 4621 pSMB->Timeout = 0;
4518 pSMB->Reserved2 = 0; 4622 pSMB->Reserved2 = 0;
4519 param_offset = offsetof(struct smb_com_transaction2_spi_req, 4623 param_offset = offsetof(struct smb_com_transaction2_spi_req,
4520 InformationLevel) - 4; 4624 InformationLevel) - 4;
4521 offset = param_offset + params; 4625 offset = param_offset + params;
4522 if(SetAllocation) { 4626 if (SetAllocation) {
4523 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 4627 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
4524 pSMB->InformationLevel = 4628 pSMB->InformationLevel =
4525 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2); 4629 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
4526 else 4630 else
4527 pSMB->InformationLevel = 4631 pSMB->InformationLevel =
4528 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO); 4632 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
4529 } else /* Set File Size */ { 4633 } else /* Set File Size */ {
4530 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 4634 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
4531 pSMB->InformationLevel = 4635 pSMB->InformationLevel =
4532 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2); 4636 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
4533 else 4637 else
4534 pSMB->InformationLevel = 4638 pSMB->InformationLevel =
4535 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO); 4639 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
4536 } 4640 }
4537 4641
4538 parm_data = 4642 parm_data =
@@ -4567,8 +4671,8 @@ SetEOFRetry:
4567} 4671}
4568 4672
4569int 4673int
4570CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size, 4674CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
4571 __u16 fid, __u32 pid_of_opener, int SetAllocation) 4675 __u16 fid, __u32 pid_of_opener, int SetAllocation)
4572{ 4676{
4573 struct smb_com_transaction2_sfi_req *pSMB = NULL; 4677 struct smb_com_transaction2_sfi_req *pSMB = NULL;
4574 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; 4678 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
@@ -4589,7 +4693,7 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
4589 4693
4590 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); 4694 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
4591 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16)); 4695 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
4592 4696
4593 params = 6; 4697 params = 6;
4594 pSMB->MaxSetupCount = 0; 4698 pSMB->MaxSetupCount = 0;
4595 pSMB->Reserved = 0; 4699 pSMB->Reserved = 0;
@@ -4599,7 +4703,7 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
4599 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 4703 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
4600 offset = param_offset + params; 4704 offset = param_offset + params;
4601 4705
4602 data_offset = (char *) (&pSMB->hdr.Protocol) + offset; 4706 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
4603 4707
4604 count = sizeof(struct file_end_of_file_info); 4708 count = sizeof(struct file_end_of_file_info);
4605 pSMB->MaxParameterCount = cpu_to_le16(2); 4709 pSMB->MaxParameterCount = cpu_to_le16(2);
@@ -4614,25 +4718,25 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
4614 pSMB->TotalParameterCount = pSMB->ParameterCount; 4718 pSMB->TotalParameterCount = pSMB->ParameterCount;
4615 pSMB->ParameterOffset = cpu_to_le16(param_offset); 4719 pSMB->ParameterOffset = cpu_to_le16(param_offset);
4616 parm_data = 4720 parm_data =
4617 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) + 4721 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol)
4618 offset); 4722 + offset);
4619 pSMB->DataOffset = cpu_to_le16(offset); 4723 pSMB->DataOffset = cpu_to_le16(offset);
4620 parm_data->FileSize = cpu_to_le64(size); 4724 parm_data->FileSize = cpu_to_le64(size);
4621 pSMB->Fid = fid; 4725 pSMB->Fid = fid;
4622 if(SetAllocation) { 4726 if (SetAllocation) {
4623 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 4727 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
4624 pSMB->InformationLevel = 4728 pSMB->InformationLevel =
4625 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2); 4729 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
4626 else 4730 else
4627 pSMB->InformationLevel = 4731 pSMB->InformationLevel =
4628 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO); 4732 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
4629 } else /* Set File Size */ { 4733 } else /* Set File Size */ {
4630 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 4734 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
4631 pSMB->InformationLevel = 4735 pSMB->InformationLevel =
4632 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2); 4736 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
4633 else 4737 else
4634 pSMB->InformationLevel = 4738 pSMB->InformationLevel =
4635 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO); 4739 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
4636 } 4740 }
4637 pSMB->Reserved4 = 0; 4741 pSMB->Reserved4 = 0;
4638 pSMB->hdr.smb_buf_length += byte_count; 4742 pSMB->hdr.smb_buf_length += byte_count;
@@ -4648,21 +4752,21 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
4648 if (pSMB) 4752 if (pSMB)
4649 cifs_small_buf_release(pSMB); 4753 cifs_small_buf_release(pSMB);
4650 4754
4651 /* Note: On -EAGAIN error only caller can retry on handle based calls 4755 /* Note: On -EAGAIN error only caller can retry on handle based calls
4652 since file handle passed in no longer valid */ 4756 since file handle passed in no longer valid */
4653 4757
4654 return rc; 4758 return rc;
4655} 4759}
4656 4760
4657/* Some legacy servers such as NT4 require that the file times be set on 4761/* Some legacy servers such as NT4 require that the file times be set on
4658 an open handle, rather than by pathname - this is awkward due to 4762 an open handle, rather than by pathname - this is awkward due to
4659 potential access conflicts on the open, but it is unavoidable for these 4763 potential access conflicts on the open, but it is unavoidable for these
4660 old servers since the only other choice is to go from 100 nanosecond DCE 4764 old servers since the only other choice is to go from 100 nanosecond DCE
4661 time and resort to the original setpathinfo level which takes the ancient 4765 time and resort to the original setpathinfo level which takes the ancient
4662 DOS time format with 2 second granularity */ 4766 DOS time format with 2 second granularity */
4663int 4767int
4664CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, const FILE_BASIC_INFO * data, 4768CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon,
4665 __u16 fid) 4769 const FILE_BASIC_INFO *data, __u16 fid)
4666{ 4770{
4667 struct smb_com_transaction2_sfi_req *pSMB = NULL; 4771 struct smb_com_transaction2_sfi_req *pSMB = NULL;
4668 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; 4772 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
@@ -4684,7 +4788,7 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, const FILE_BASIC_I
4684 use an existing handle (rather than opening one on the fly) */ 4788 use an existing handle (rather than opening one on the fly) */
4685 /* pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); 4789 /* pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
4686 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));*/ 4790 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));*/
4687 4791
4688 params = 6; 4792 params = 6;
4689 pSMB->MaxSetupCount = 0; 4793 pSMB->MaxSetupCount = 0;
4690 pSMB->Reserved = 0; 4794 pSMB->Reserved = 0;
@@ -4694,7 +4798,7 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, const FILE_BASIC_I
4694 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 4798 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
4695 offset = param_offset + params; 4799 offset = param_offset + params;
4696 4800
4697 data_offset = (char *) (&pSMB->hdr.Protocol) + offset; 4801 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
4698 4802
4699 count = sizeof (FILE_BASIC_INFO); 4803 count = sizeof (FILE_BASIC_INFO);
4700 pSMB->MaxParameterCount = cpu_to_le16(2); 4804 pSMB->MaxParameterCount = cpu_to_le16(2);
@@ -4717,16 +4821,16 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, const FILE_BASIC_I
4717 pSMB->Reserved4 = 0; 4821 pSMB->Reserved4 = 0;
4718 pSMB->hdr.smb_buf_length += byte_count; 4822 pSMB->hdr.smb_buf_length += byte_count;
4719 pSMB->ByteCount = cpu_to_le16(byte_count); 4823 pSMB->ByteCount = cpu_to_le16(byte_count);
4720 memcpy(data_offset,data,sizeof(FILE_BASIC_INFO)); 4824 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
4721 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4825 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4722 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4826 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4723 if (rc) { 4827 if (rc) {
4724 cFYI(1,("Send error in Set Time (SetFileInfo) = %d",rc)); 4828 cFYI(1, ("Send error in Set Time (SetFileInfo) = %d", rc));
4725 } 4829 }
4726 4830
4727 cifs_small_buf_release(pSMB); 4831 cifs_small_buf_release(pSMB);
4728 4832
4729 /* Note: On -EAGAIN error only caller can retry on handle based calls 4833 /* Note: On -EAGAIN error only caller can retry on handle based calls
4730 since file handle passed in no longer valid */ 4834 since file handle passed in no longer valid */
4731 4835
4732 return rc; 4836 return rc;
@@ -4735,7 +4839,7 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, const FILE_BASIC_I
4735 4839
4736int 4840int
4737CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon, const char *fileName, 4841CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon, const char *fileName,
4738 const FILE_BASIC_INFO * data, 4842 const FILE_BASIC_INFO *data,
4739 const struct nls_table *nls_codepage, int remap) 4843 const struct nls_table *nls_codepage, int remap)
4740{ 4844{
4741 TRANSACTION2_SPI_REQ *pSMB = NULL; 4845 TRANSACTION2_SPI_REQ *pSMB = NULL;
@@ -4760,7 +4864,7 @@ SetTimesRetry:
4760 PATH_MAX, nls_codepage, remap); 4864 PATH_MAX, nls_codepage, remap);
4761 name_len++; /* trailing null */ 4865 name_len++; /* trailing null */
4762 name_len *= 2; 4866 name_len *= 2;
4763 } else { /* BB improve the check for buffer overruns BB */ 4867 } else { /* BB improve the check for buffer overruns BB */
4764 name_len = strnlen(fileName, PATH_MAX); 4868 name_len = strnlen(fileName, PATH_MAX);
4765 name_len++; /* trailing null */ 4869 name_len++; /* trailing null */
4766 strncpy(pSMB->FileName, fileName, name_len); 4870 strncpy(pSMB->FileName, fileName, name_len);
@@ -4776,7 +4880,7 @@ SetTimesRetry:
4776 pSMB->Timeout = 0; 4880 pSMB->Timeout = 0;
4777 pSMB->Reserved2 = 0; 4881 pSMB->Reserved2 = 0;
4778 param_offset = offsetof(struct smb_com_transaction2_spi_req, 4882 param_offset = offsetof(struct smb_com_transaction2_spi_req,
4779 InformationLevel) - 4; 4883 InformationLevel) - 4;
4780 offset = param_offset + params; 4884 offset = param_offset + params;
4781 data_offset = (char *) (&pSMB->hdr.Protocol) + offset; 4885 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
4782 pSMB->ParameterOffset = cpu_to_le16(param_offset); 4886 pSMB->ParameterOffset = cpu_to_le16(param_offset);
@@ -4837,11 +4941,11 @@ SetAttrLgcyRetry:
4837 4941
4838 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 4942 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4839 name_len = 4943 name_len =
4840 ConvertToUCS((__le16 *) pSMB->fileName, fileName, 4944 ConvertToUCS((__le16 *) pSMB->fileName, fileName,
4841 PATH_MAX, nls_codepage); 4945 PATH_MAX, nls_codepage);
4842 name_len++; /* trailing null */ 4946 name_len++; /* trailing null */
4843 name_len *= 2; 4947 name_len *= 2;
4844 } else { /* BB improve the check for buffer overruns BB */ 4948 } else { /* BB improve the check for buffer overruns BB */
4845 name_len = strnlen(fileName, PATH_MAX); 4949 name_len = strnlen(fileName, PATH_MAX);
4846 name_len++; /* trailing null */ 4950 name_len++; /* trailing null */
4847 strncpy(pSMB->fileName, fileName, name_len); 4951 strncpy(pSMB->fileName, fileName, name_len);
@@ -4867,8 +4971,8 @@ SetAttrLgcyRetry:
4867 4971
4868int 4972int
4869CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon, 4973CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon,
4870 char *fileName, __u64 mode, __u64 uid, __u64 gid, 4974 char *fileName, __u64 mode, __u64 uid, __u64 gid,
4871 dev_t device, const struct nls_table *nls_codepage, 4975 dev_t device, const struct nls_table *nls_codepage,
4872 int remap) 4976 int remap)
4873{ 4977{
4874 TRANSACTION2_SPI_REQ *pSMB = NULL; 4978 TRANSACTION2_SPI_REQ *pSMB = NULL;
@@ -4888,7 +4992,7 @@ setPermsRetry:
4888 4992
4889 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 4993 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4890 name_len = 4994 name_len =
4891 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName, 4995 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
4892 PATH_MAX, nls_codepage, remap); 4996 PATH_MAX, nls_codepage, remap);
4893 name_len++; /* trailing null */ 4997 name_len++; /* trailing null */
4894 name_len *= 2; 4998 name_len *= 2;
@@ -4908,7 +5012,7 @@ setPermsRetry:
4908 pSMB->Timeout = 0; 5012 pSMB->Timeout = 0;
4909 pSMB->Reserved2 = 0; 5013 pSMB->Reserved2 = 0;
4910 param_offset = offsetof(struct smb_com_transaction2_spi_req, 5014 param_offset = offsetof(struct smb_com_transaction2_spi_req,
4911 InformationLevel) - 4; 5015 InformationLevel) - 4;
4912 offset = param_offset + params; 5016 offset = param_offset + params;
4913 data_offset = 5017 data_offset =
4914 (FILE_UNIX_BASIC_INFO *) ((char *) &pSMB->hdr.Protocol + 5018 (FILE_UNIX_BASIC_INFO *) ((char *) &pSMB->hdr.Protocol +
@@ -4931,7 +5035,7 @@ setPermsRetry:
4931 older clients, but we should be precise - we use SetFileSize to 5035 older clients, but we should be precise - we use SetFileSize to
4932 set file size and do not want to truncate file size to zero 5036 set file size and do not want to truncate file size to zero
4933 accidently as happened on one Samba server beta by putting 5037 accidently as happened on one Samba server beta by putting
4934 zero instead of -1 here */ 5038 zero instead of -1 here */
4935 data_offset->EndOfFile = NO_CHANGE_64; 5039 data_offset->EndOfFile = NO_CHANGE_64;
4936 data_offset->NumOfBytes = NO_CHANGE_64; 5040 data_offset->NumOfBytes = NO_CHANGE_64;
4937 data_offset->LastStatusChange = NO_CHANGE_64; 5041 data_offset->LastStatusChange = NO_CHANGE_64;
@@ -4943,20 +5047,20 @@ setPermsRetry:
4943 data_offset->DevMajor = cpu_to_le64(MAJOR(device)); 5047 data_offset->DevMajor = cpu_to_le64(MAJOR(device));
4944 data_offset->DevMinor = cpu_to_le64(MINOR(device)); 5048 data_offset->DevMinor = cpu_to_le64(MINOR(device));
4945 data_offset->Permissions = cpu_to_le64(mode); 5049 data_offset->Permissions = cpu_to_le64(mode);
4946 5050
4947 if(S_ISREG(mode)) 5051 if (S_ISREG(mode))
4948 data_offset->Type = cpu_to_le32(UNIX_FILE); 5052 data_offset->Type = cpu_to_le32(UNIX_FILE);
4949 else if(S_ISDIR(mode)) 5053 else if (S_ISDIR(mode))
4950 data_offset->Type = cpu_to_le32(UNIX_DIR); 5054 data_offset->Type = cpu_to_le32(UNIX_DIR);
4951 else if(S_ISLNK(mode)) 5055 else if (S_ISLNK(mode))
4952 data_offset->Type = cpu_to_le32(UNIX_SYMLINK); 5056 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
4953 else if(S_ISCHR(mode)) 5057 else if (S_ISCHR(mode))
4954 data_offset->Type = cpu_to_le32(UNIX_CHARDEV); 5058 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
4955 else if(S_ISBLK(mode)) 5059 else if (S_ISBLK(mode))
4956 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV); 5060 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
4957 else if(S_ISFIFO(mode)) 5061 else if (S_ISFIFO(mode))
4958 data_offset->Type = cpu_to_le32(UNIX_FIFO); 5062 data_offset->Type = cpu_to_le32(UNIX_FIFO);
4959 else if(S_ISSOCK(mode)) 5063 else if (S_ISSOCK(mode))
4960 data_offset->Type = cpu_to_le32(UNIX_SOCKET); 5064 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
4961 5065
4962 5066
@@ -4974,20 +5078,20 @@ setPermsRetry:
4974 return rc; 5078 return rc;
4975} 5079}
4976 5080
4977int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, 5081int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
4978 const int notify_subdirs, const __u16 netfid, 5082 const int notify_subdirs, const __u16 netfid,
4979 __u32 filter, struct file * pfile, int multishot, 5083 __u32 filter, struct file *pfile, int multishot,
4980 const struct nls_table *nls_codepage) 5084 const struct nls_table *nls_codepage)
4981{ 5085{
4982 int rc = 0; 5086 int rc = 0;
4983 struct smb_com_transaction_change_notify_req * pSMB = NULL; 5087 struct smb_com_transaction_change_notify_req *pSMB = NULL;
4984 struct smb_com_ntransaction_change_notify_rsp * pSMBr = NULL; 5088 struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
4985 struct dir_notify_req *dnotify_req; 5089 struct dir_notify_req *dnotify_req;
4986 int bytes_returned; 5090 int bytes_returned;
4987 5091
4988 cFYI(1, ("In CIFSSMBNotify for file handle %d",(int)netfid)); 5092 cFYI(1, ("In CIFSSMBNotify for file handle %d", (int)netfid));
4989 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB, 5093 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
4990 (void **) &pSMBr); 5094 (void **) &pSMBr);
4991 if (rc) 5095 if (rc)
4992 return rc; 5096 return rc;
4993 5097
@@ -5008,7 +5112,7 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
5008 pSMB->SetupCount = 4; /* single byte does not need le conversion */ 5112 pSMB->SetupCount = 4; /* single byte does not need le conversion */
5009 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE); 5113 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
5010 pSMB->ParameterCount = pSMB->TotalParameterCount; 5114 pSMB->ParameterCount = pSMB->TotalParameterCount;
5011 if(notify_subdirs) 5115 if (notify_subdirs)
5012 pSMB->WatchTree = 1; /* one byte - no le conversion needed */ 5116 pSMB->WatchTree = 1; /* one byte - no le conversion needed */
5013 pSMB->Reserved2 = 0; 5117 pSMB->Reserved2 = 0;
5014 pSMB->CompletionFilter = cpu_to_le32(filter); 5118 pSMB->CompletionFilter = cpu_to_le32(filter);
@@ -5021,11 +5125,11 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
5021 cFYI(1, ("Error in Notify = %d", rc)); 5125 cFYI(1, ("Error in Notify = %d", rc));
5022 } else { 5126 } else {
5023 /* Add file to outstanding requests */ 5127 /* Add file to outstanding requests */
5024 /* BB change to kmem cache alloc */ 5128 /* BB change to kmem cache alloc */
5025 dnotify_req = kmalloc( 5129 dnotify_req = kmalloc(
5026 sizeof(struct dir_notify_req), 5130 sizeof(struct dir_notify_req),
5027 GFP_KERNEL); 5131 GFP_KERNEL);
5028 if(dnotify_req) { 5132 if (dnotify_req) {
5029 dnotify_req->Pid = pSMB->hdr.Pid; 5133 dnotify_req->Pid = pSMB->hdr.Pid;
5030 dnotify_req->PidHigh = pSMB->hdr.PidHigh; 5134 dnotify_req->PidHigh = pSMB->hdr.PidHigh;
5031 dnotify_req->Mid = pSMB->hdr.Mid; 5135 dnotify_req->Mid = pSMB->hdr.Mid;
@@ -5036,20 +5140,20 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
5036 dnotify_req->filter = filter; 5140 dnotify_req->filter = filter;
5037 dnotify_req->multishot = multishot; 5141 dnotify_req->multishot = multishot;
5038 spin_lock(&GlobalMid_Lock); 5142 spin_lock(&GlobalMid_Lock);
5039 list_add_tail(&dnotify_req->lhead, 5143 list_add_tail(&dnotify_req->lhead,
5040 &GlobalDnotifyReqList); 5144 &GlobalDnotifyReqList);
5041 spin_unlock(&GlobalMid_Lock); 5145 spin_unlock(&GlobalMid_Lock);
5042 } else 5146 } else
5043 rc = -ENOMEM; 5147 rc = -ENOMEM;
5044 } 5148 }
5045 cifs_buf_release(pSMB); 5149 cifs_buf_release(pSMB);
5046 return rc; 5150 return rc;
5047} 5151}
5048#ifdef CONFIG_CIFS_XATTR 5152#ifdef CONFIG_CIFS_XATTR
5049ssize_t 5153ssize_t
5050CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, 5154CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
5051 const unsigned char *searchName, 5155 const unsigned char *searchName,
5052 char * EAData, size_t buf_size, 5156 char *EAData, size_t buf_size,
5053 const struct nls_table *nls_codepage, int remap) 5157 const struct nls_table *nls_codepage, int remap)
5054{ 5158{
5055 /* BB assumes one setup word */ 5159 /* BB assumes one setup word */
@@ -5058,8 +5162,8 @@ CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
5058 int rc = 0; 5162 int rc = 0;
5059 int bytes_returned; 5163 int bytes_returned;
5060 int name_len; 5164 int name_len;
5061 struct fea * temp_fea; 5165 struct fea *temp_fea;
5062 char * temp_ptr; 5166 char *temp_ptr;
5063 __u16 params, byte_count; 5167 __u16 params, byte_count;
5064 5168
5065 cFYI(1, ("In Query All EAs path %s", searchName)); 5169 cFYI(1, ("In Query All EAs path %s", searchName));
@@ -5071,7 +5175,7 @@ QAllEAsRetry:
5071 5175
5072 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5176 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5073 name_len = 5177 name_len =
5074 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, 5178 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
5075 PATH_MAX, nls_codepage, remap); 5179 PATH_MAX, nls_codepage, remap);
5076 name_len++; /* trailing null */ 5180 name_len++; /* trailing null */
5077 name_len *= 2; 5181 name_len *= 2;
@@ -5081,7 +5185,7 @@ QAllEAsRetry:
5081 strncpy(pSMB->FileName, searchName, name_len); 5185 strncpy(pSMB->FileName, searchName, name_len);
5082 } 5186 }
5083 5187
5084 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */ ; 5188 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
5085 pSMB->TotalDataCount = 0; 5189 pSMB->TotalDataCount = 0;
5086 pSMB->MaxParameterCount = cpu_to_le16(2); 5190 pSMB->MaxParameterCount = cpu_to_le16(2);
5087 pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */ 5191 pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */
@@ -5091,7 +5195,7 @@ QAllEAsRetry:
5091 pSMB->Timeout = 0; 5195 pSMB->Timeout = 0;
5092 pSMB->Reserved2 = 0; 5196 pSMB->Reserved2 = 0;
5093 pSMB->ParameterOffset = cpu_to_le16(offsetof( 5197 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5094 struct smb_com_transaction2_qpi_req ,InformationLevel) - 4); 5198 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
5095 pSMB->DataCount = 0; 5199 pSMB->DataCount = 0;
5096 pSMB->DataOffset = 0; 5200 pSMB->DataOffset = 0;
5097 pSMB->SetupCount = 1; 5201 pSMB->SetupCount = 1;
@@ -5115,7 +5219,7 @@ QAllEAsRetry:
5115 /* BB also check enough total bytes returned */ 5219 /* BB also check enough total bytes returned */
5116 /* BB we need to improve the validity checking 5220 /* BB we need to improve the validity checking
5117 of these trans2 responses */ 5221 of these trans2 responses */
5118 if (rc || (pSMBr->ByteCount < 4)) 5222 if (rc || (pSMBr->ByteCount < 4))
5119 rc = -EIO; /* bad smb */ 5223 rc = -EIO; /* bad smb */
5120 /* else if (pFindData){ 5224 /* else if (pFindData){
5121 memcpy((char *) pFindData, 5225 memcpy((char *) pFindData,
@@ -5128,39 +5232,40 @@ QAllEAsRetry:
5128 /* check that each element of each entry does not 5232 /* check that each element of each entry does not
5129 go beyond end of list */ 5233 go beyond end of list */
5130 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 5234 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5131 struct fealist * ea_response_data; 5235 struct fealist *ea_response_data;
5132 rc = 0; 5236 rc = 0;
5133 /* validate_trans2_offsets() */ 5237 /* validate_trans2_offsets() */
5134 /* BB to check if(start of smb + data_offset > &bcc+ bcc)*/ 5238 /* BB check if start of smb + data_offset > &bcc+ bcc */
5135 ea_response_data = (struct fealist *) 5239 ea_response_data = (struct fealist *)
5136 (((char *) &pSMBr->hdr.Protocol) + 5240 (((char *) &pSMBr->hdr.Protocol) +
5137 data_offset); 5241 data_offset);
5138 name_len = le32_to_cpu(ea_response_data->list_len); 5242 name_len = le32_to_cpu(ea_response_data->list_len);
5139 cFYI(1,("ea length %d", name_len)); 5243 cFYI(1, ("ea length %d", name_len));
5140 if(name_len <= 8) { 5244 if (name_len <= 8) {
5141 /* returned EA size zeroed at top of function */ 5245 /* returned EA size zeroed at top of function */
5142 cFYI(1,("empty EA list returned from server")); 5246 cFYI(1, ("empty EA list returned from server"));
5143 } else { 5247 } else {
5144 /* account for ea list len */ 5248 /* account for ea list len */
5145 name_len -= 4; 5249 name_len -= 4;
5146 temp_fea = ea_response_data->list; 5250 temp_fea = ea_response_data->list;
5147 temp_ptr = (char *)temp_fea; 5251 temp_ptr = (char *)temp_fea;
5148 while(name_len > 0) { 5252 while (name_len > 0) {
5149 __u16 value_len; 5253 __u16 value_len;
5150 name_len -= 4; 5254 name_len -= 4;
5151 temp_ptr += 4; 5255 temp_ptr += 4;
5152 rc += temp_fea->name_len; 5256 rc += temp_fea->name_len;
5153 /* account for prefix user. and trailing null */ 5257 /* account for prefix user. and trailing null */
5154 rc = rc + 5 + 1; 5258 rc = rc + 5 + 1;
5155 if(rc<(int)buf_size) { 5259 if (rc < (int)buf_size) {
5156 memcpy(EAData,"user.",5); 5260 memcpy(EAData, "user.", 5);
5157 EAData+=5; 5261 EAData += 5;
5158 memcpy(EAData,temp_ptr,temp_fea->name_len); 5262 memcpy(EAData, temp_ptr,
5159 EAData+=temp_fea->name_len; 5263 temp_fea->name_len);
5264 EAData += temp_fea->name_len;
5160 /* null terminate name */ 5265 /* null terminate name */
5161 *EAData = 0; 5266 *EAData = 0;
5162 EAData = EAData + 1; 5267 EAData = EAData + 1;
5163 } else if(buf_size == 0) { 5268 } else if (buf_size == 0) {
5164 /* skip copy - calc size only */ 5269 /* skip copy - calc size only */
5165 } else { 5270 } else {
5166 /* stop before overrun buffer */ 5271 /* stop before overrun buffer */
@@ -5172,11 +5277,15 @@ QAllEAsRetry:
5172 /* account for trailing null */ 5277 /* account for trailing null */
5173 name_len--; 5278 name_len--;
5174 temp_ptr++; 5279 temp_ptr++;
5175 value_len = le16_to_cpu(temp_fea->value_len); 5280 value_len =
5281 le16_to_cpu(temp_fea->value_len);
5176 name_len -= value_len; 5282 name_len -= value_len;
5177 temp_ptr += value_len; 5283 temp_ptr += value_len;
5178 /* BB check that temp_ptr is still within smb BB*/ 5284 /* BB check that temp_ptr is still
5179 /* no trailing null to account for in value len */ 5285 within the SMB BB*/
5286
5287 /* no trailing null to account for
5288 in value len */
5180 /* go on to next EA */ 5289 /* go on to next EA */
5181 temp_fea = (struct fea *)temp_ptr; 5290 temp_fea = (struct fea *)temp_ptr;
5182 } 5291 }
@@ -5191,9 +5300,9 @@ QAllEAsRetry:
5191 return (ssize_t)rc; 5300 return (ssize_t)rc;
5192} 5301}
5193 5302
5194ssize_t CIFSSMBQueryEA(const int xid,struct cifsTconInfo * tcon, 5303ssize_t CIFSSMBQueryEA(const int xid, struct cifsTconInfo *tcon,
5195 const unsigned char * searchName,const unsigned char * ea_name, 5304 const unsigned char *searchName, const unsigned char *ea_name,
5196 unsigned char * ea_value, size_t buf_size, 5305 unsigned char *ea_value, size_t buf_size,
5197 const struct nls_table *nls_codepage, int remap) 5306 const struct nls_table *nls_codepage, int remap)
5198{ 5307{
5199 TRANSACTION2_QPI_REQ *pSMB = NULL; 5308 TRANSACTION2_QPI_REQ *pSMB = NULL;
@@ -5201,8 +5310,8 @@ ssize_t CIFSSMBQueryEA(const int xid,struct cifsTconInfo * tcon,
5201 int rc = 0; 5310 int rc = 0;
5202 int bytes_returned; 5311 int bytes_returned;
5203 int name_len; 5312 int name_len;
5204 struct fea * temp_fea; 5313 struct fea *temp_fea;
5205 char * temp_ptr; 5314 char *temp_ptr;
5206 __u16 params, byte_count; 5315 __u16 params, byte_count;
5207 5316
5208 cFYI(1, ("In Query EA path %s", searchName)); 5317 cFYI(1, ("In Query EA path %s", searchName));
@@ -5214,7 +5323,7 @@ QEARetry:
5214 5323
5215 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5324 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5216 name_len = 5325 name_len =
5217 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, 5326 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
5218 PATH_MAX, nls_codepage, remap); 5327 PATH_MAX, nls_codepage, remap);
5219 name_len++; /* trailing null */ 5328 name_len++; /* trailing null */
5220 name_len *= 2; 5329 name_len *= 2;
@@ -5224,7 +5333,7 @@ QEARetry:
5224 strncpy(pSMB->FileName, searchName, name_len); 5333 strncpy(pSMB->FileName, searchName, name_len);
5225 } 5334 }
5226 5335
5227 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */ ; 5336 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
5228 pSMB->TotalDataCount = 0; 5337 pSMB->TotalDataCount = 0;
5229 pSMB->MaxParameterCount = cpu_to_le16(2); 5338 pSMB->MaxParameterCount = cpu_to_le16(2);
5230 pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */ 5339 pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */
@@ -5234,7 +5343,7 @@ QEARetry:
5234 pSMB->Timeout = 0; 5343 pSMB->Timeout = 0;
5235 pSMB->Reserved2 = 0; 5344 pSMB->Reserved2 = 0;
5236 pSMB->ParameterOffset = cpu_to_le16(offsetof( 5345 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5237 struct smb_com_transaction2_qpi_req ,InformationLevel) - 4); 5346 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
5238 pSMB->DataCount = 0; 5347 pSMB->DataCount = 0;
5239 pSMB->DataOffset = 0; 5348 pSMB->DataOffset = 0;
5240 pSMB->SetupCount = 1; 5349 pSMB->SetupCount = 1;
@@ -5258,7 +5367,7 @@ QEARetry:
5258 /* BB also check enough total bytes returned */ 5367 /* BB also check enough total bytes returned */
5259 /* BB we need to improve the validity checking 5368 /* BB we need to improve the validity checking
5260 of these trans2 responses */ 5369 of these trans2 responses */
5261 if (rc || (pSMBr->ByteCount < 4)) 5370 if (rc || (pSMBr->ByteCount < 4))
5262 rc = -EIO; /* bad smb */ 5371 rc = -EIO; /* bad smb */
5263 /* else if (pFindData){ 5372 /* else if (pFindData){
5264 memcpy((char *) pFindData, 5373 memcpy((char *) pFindData,
@@ -5271,18 +5380,18 @@ QEARetry:
5271 /* check that each element of each entry does not 5380 /* check that each element of each entry does not
5272 go beyond end of list */ 5381 go beyond end of list */
5273 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 5382 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5274 struct fealist * ea_response_data; 5383 struct fealist *ea_response_data;
5275 rc = -ENODATA; 5384 rc = -ENODATA;
5276 /* validate_trans2_offsets() */ 5385 /* validate_trans2_offsets() */
5277 /* BB to check if(start of smb + data_offset > &bcc+ bcc)*/ 5386 /* BB check if start of smb + data_offset > &bcc+ bcc*/
5278 ea_response_data = (struct fealist *) 5387 ea_response_data = (struct fealist *)
5279 (((char *) &pSMBr->hdr.Protocol) + 5388 (((char *) &pSMBr->hdr.Protocol) +
5280 data_offset); 5389 data_offset);
5281 name_len = le32_to_cpu(ea_response_data->list_len); 5390 name_len = le32_to_cpu(ea_response_data->list_len);
5282 cFYI(1,("ea length %d", name_len)); 5391 cFYI(1, ("ea length %d", name_len));
5283 if(name_len <= 8) { 5392 if (name_len <= 8) {
5284 /* returned EA size zeroed at top of function */ 5393 /* returned EA size zeroed at top of function */
5285 cFYI(1,("empty EA list returned from server")); 5394 cFYI(1, ("empty EA list returned from server"));
5286 } else { 5395 } else {
5287 /* account for ea list len */ 5396 /* account for ea list len */
5288 name_len -= 4; 5397 name_len -= 4;
@@ -5290,28 +5399,30 @@ QEARetry:
5290 temp_ptr = (char *)temp_fea; 5399 temp_ptr = (char *)temp_fea;
5291 /* loop through checking if we have a matching 5400 /* loop through checking if we have a matching
5292 name and then return the associated value */ 5401 name and then return the associated value */
5293 while(name_len > 0) { 5402 while (name_len > 0) {
5294 __u16 value_len; 5403 __u16 value_len;
5295 name_len -= 4; 5404 name_len -= 4;
5296 temp_ptr += 4; 5405 temp_ptr += 4;
5297 value_len = le16_to_cpu(temp_fea->value_len); 5406 value_len =
5298 /* BB validate that value_len falls within SMB, 5407 le16_to_cpu(temp_fea->value_len);
5299 even though maximum for name_len is 255 */ 5408 /* BB validate that value_len falls within SMB,
5300 if(memcmp(temp_fea->name,ea_name, 5409 even though maximum for name_len is 255 */
5410 if (memcmp(temp_fea->name, ea_name,
5301 temp_fea->name_len) == 0) { 5411 temp_fea->name_len) == 0) {
5302 /* found a match */ 5412 /* found a match */
5303 rc = value_len; 5413 rc = value_len;
5304 /* account for prefix user. and trailing null */ 5414 /* account for prefix user. and trailing null */
5305 if(rc<=(int)buf_size) { 5415 if (rc <= (int)buf_size) {
5306 memcpy(ea_value, 5416 memcpy(ea_value,
5307 temp_fea->name+temp_fea->name_len+1, 5417 temp_fea->name+temp_fea->name_len+1,
5308 rc); 5418 rc);
5309 /* ea values, unlike ea names, 5419 /* ea values, unlike ea
5310 are not null terminated */ 5420 names, are not null
5311 } else if(buf_size == 0) { 5421 terminated */
5422 } else if (buf_size == 0) {
5312 /* skip copy - calc size only */ 5423 /* skip copy - calc size only */
5313 } else { 5424 } else {
5314 /* stop before overrun buffer */ 5425 /* stop before overrun buffer */
5315 rc = -ERANGE; 5426 rc = -ERANGE;
5316 } 5427 }
5317 break; 5428 break;
@@ -5323,11 +5434,11 @@ QEARetry:
5323 temp_ptr++; 5434 temp_ptr++;
5324 name_len -= value_len; 5435 name_len -= value_len;
5325 temp_ptr += value_len; 5436 temp_ptr += value_len;
5326 /* no trailing null to account for in value len */ 5437 /* No trailing null to account for in
5327 /* go on to next EA */ 5438 value_len. Go on to next EA */
5328 temp_fea = (struct fea *)temp_ptr; 5439 temp_fea = (struct fea *)temp_ptr;
5329 } 5440 }
5330 } 5441 }
5331 } 5442 }
5332 } 5443 }
5333 if (pSMB) 5444 if (pSMB)
@@ -5340,9 +5451,9 @@ QEARetry:
5340 5451
5341int 5452int
5342CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, const char *fileName, 5453CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, const char *fileName,
5343 const char * ea_name, const void * ea_value, 5454 const char *ea_name, const void *ea_value,
5344 const __u16 ea_value_len, const struct nls_table *nls_codepage, 5455 const __u16 ea_value_len, const struct nls_table *nls_codepage,
5345 int remap) 5456 int remap)
5346{ 5457{
5347 struct smb_com_transaction2_spi_req *pSMB = NULL; 5458 struct smb_com_transaction2_spi_req *pSMB = NULL;
5348 struct smb_com_transaction2_spi_rsp *pSMBr = NULL; 5459 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
@@ -5361,11 +5472,11 @@ SetEARetry:
5361 5472
5362 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5473 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5363 name_len = 5474 name_len =
5364 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName, 5475 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
5365 PATH_MAX, nls_codepage, remap); 5476 PATH_MAX, nls_codepage, remap);
5366 name_len++; /* trailing null */ 5477 name_len++; /* trailing null */
5367 name_len *= 2; 5478 name_len *= 2;
5368 } else { /* BB improve the check for buffer overruns BB */ 5479 } else { /* BB improve the check for buffer overruns BB */
5369 name_len = strnlen(fileName, PATH_MAX); 5480 name_len = strnlen(fileName, PATH_MAX);
5370 name_len++; /* trailing null */ 5481 name_len++; /* trailing null */
5371 strncpy(pSMB->FileName, fileName, name_len); 5482 strncpy(pSMB->FileName, fileName, name_len);
@@ -5376,10 +5487,10 @@ SetEARetry:
5376 /* done calculating parms using name_len of file name, 5487 /* done calculating parms using name_len of file name,
5377 now use name_len to calculate length of ea name 5488 now use name_len to calculate length of ea name
5378 we are going to create in the inode xattrs */ 5489 we are going to create in the inode xattrs */
5379 if(ea_name == NULL) 5490 if (ea_name == NULL)
5380 name_len = 0; 5491 name_len = 0;
5381 else 5492 else
5382 name_len = strnlen(ea_name,255); 5493 name_len = strnlen(ea_name, 255);
5383 5494
5384 count = sizeof(*parm_data) + ea_value_len + name_len + 1; 5495 count = sizeof(*parm_data) + ea_value_len + name_len + 1;
5385 pSMB->MaxParameterCount = cpu_to_le16(2); 5496 pSMB->MaxParameterCount = cpu_to_le16(2);
@@ -5390,7 +5501,7 @@ SetEARetry:
5390 pSMB->Timeout = 0; 5501 pSMB->Timeout = 0;
5391 pSMB->Reserved2 = 0; 5502 pSMB->Reserved2 = 0;
5392 param_offset = offsetof(struct smb_com_transaction2_spi_req, 5503 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5393 InformationLevel) - 4; 5504 InformationLevel) - 4;
5394 offset = param_offset + params; 5505 offset = param_offset + params;
5395 pSMB->InformationLevel = 5506 pSMB->InformationLevel =
5396 cpu_to_le16(SMB_SET_FILE_EA); 5507 cpu_to_le16(SMB_SET_FILE_EA);
@@ -5410,17 +5521,19 @@ SetEARetry:
5410 /* we checked above that name len is less than 255 */ 5521 /* we checked above that name len is less than 255 */
5411 parm_data->list[0].name_len = (__u8)name_len; 5522 parm_data->list[0].name_len = (__u8)name_len;
5412 /* EA names are always ASCII */ 5523 /* EA names are always ASCII */
5413 if(ea_name) 5524 if (ea_name)
5414 strncpy(parm_data->list[0].name,ea_name,name_len); 5525 strncpy(parm_data->list[0].name, ea_name, name_len);
5415 parm_data->list[0].name[name_len] = 0; 5526 parm_data->list[0].name[name_len] = 0;
5416 parm_data->list[0].value_len = cpu_to_le16(ea_value_len); 5527 parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
5417 /* caller ensures that ea_value_len is less than 64K but 5528 /* caller ensures that ea_value_len is less than 64K but
5418 we need to ensure that it fits within the smb */ 5529 we need to ensure that it fits within the smb */
5419 5530
5420 /*BB add length check that it would fit in negotiated SMB buffer size BB */ 5531 /*BB add length check to see if it would fit in
5421 /* if(ea_value_len > buffer_size - 512 (enough for header)) */ 5532 negotiated SMB buffer size BB */
5422 if(ea_value_len) 5533 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
5423 memcpy(parm_data->list[0].name+name_len+1,ea_value,ea_value_len); 5534 if (ea_value_len)
5535 memcpy(parm_data->list[0].name+name_len+1,
5536 ea_value, ea_value_len);
5424 5537
5425 pSMB->TotalDataCount = pSMB->DataCount; 5538 pSMB->TotalDataCount = pSMB->DataCount;
5426 pSMB->ParameterCount = cpu_to_le16(params); 5539 pSMB->ParameterCount = cpu_to_le16(params);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 0a1b8bd1dfcb..4af3588c1a96 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/connect.c 2 * fs/cifs/connect.c
3 * 3 *
4 * Copyright (C) International Business Machines Corp., 2002,2006 4 * Copyright (C) International Business Machines Corp., 2002,2007
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This library is free software; you can redistribute it and/or modify 7 * This library is free software; you can redistribute it and/or modify
@@ -16,7 +16,7 @@
16 * 16 *
17 * You should have received a copy of the GNU Lesser General Public License 17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software 18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21#include <linux/fs.h> 21#include <linux/fs.h>
22#include <linux/net.h> 22#include <linux/net.h>
@@ -85,6 +85,7 @@ struct smb_vol {
85 unsigned direct_io:1; 85 unsigned direct_io:1;
86 unsigned remap:1; /* set to remap seven reserved chars in filenames */ 86 unsigned remap:1; /* set to remap seven reserved chars in filenames */
87 unsigned posix_paths:1; /* unset to not ask for posix pathnames. */ 87 unsigned posix_paths:1; /* unset to not ask for posix pathnames. */
88 unsigned no_linux_ext:1;
88 unsigned sfu_emul:1; 89 unsigned sfu_emul:1;
89 unsigned nullauth:1; /* attempt to authenticate with null user */ 90 unsigned nullauth:1; /* attempt to authenticate with null user */
90 unsigned nocase; /* request case insensitive filenames */ 91 unsigned nocase; /* request case insensitive filenames */
@@ -93,20 +94,20 @@ struct smb_vol {
93 unsigned int wsize; 94 unsigned int wsize;
94 unsigned int sockopt; 95 unsigned int sockopt;
95 unsigned short int port; 96 unsigned short int port;
96 char * prepath; 97 char *prepath;
97}; 98};
98 99
99static int ipv4_connect(struct sockaddr_in *psin_server, 100static int ipv4_connect(struct sockaddr_in *psin_server,
100 struct socket **csocket, 101 struct socket **csocket,
101 char * netb_name, 102 char *netb_name,
102 char * server_netb_name); 103 char *server_netb_name);
103static int ipv6_connect(struct sockaddr_in6 *psin_server, 104static int ipv6_connect(struct sockaddr_in6 *psin_server,
104 struct socket **csocket); 105 struct socket **csocket);
105 106
106 107
107 /* 108 /*
108 * cifs tcp session reconnection 109 * cifs tcp session reconnection
109 * 110 *
110 * mark tcp session as reconnecting so temporarily locked 111 * mark tcp session as reconnecting so temporarily locked
111 * mark all smb sessions as reconnecting for tcp session 112 * mark all smb sessions as reconnecting for tcp session
112 * reconnect tcp session 113 * reconnect tcp session
@@ -120,11 +121,11 @@ cifs_reconnect(struct TCP_Server_Info *server)
120 struct list_head *tmp; 121 struct list_head *tmp;
121 struct cifsSesInfo *ses; 122 struct cifsSesInfo *ses;
122 struct cifsTconInfo *tcon; 123 struct cifsTconInfo *tcon;
123 struct mid_q_entry * mid_entry; 124 struct mid_q_entry *mid_entry;
124 125
125 spin_lock(&GlobalMid_Lock); 126 spin_lock(&GlobalMid_Lock);
126 if( kthread_should_stop() ) { 127 if ( kthread_should_stop() ) {
127 /* the demux thread will exit normally 128 /* the demux thread will exit normally
128 next time through the loop */ 129 next time through the loop */
129 spin_unlock(&GlobalMid_Lock); 130 spin_unlock(&GlobalMid_Lock);
130 return rc; 131 return rc;
@@ -150,18 +151,19 @@ cifs_reconnect(struct TCP_Server_Info *server)
150 } 151 }
151 list_for_each(tmp, &GlobalTreeConnectionList) { 152 list_for_each(tmp, &GlobalTreeConnectionList) {
152 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); 153 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
153 if((tcon) && (tcon->ses) && (tcon->ses->server == server)) { 154 if ((tcon) && (tcon->ses) && (tcon->ses->server == server)) {
154 tcon->tidStatus = CifsNeedReconnect; 155 tcon->tidStatus = CifsNeedReconnect;
155 } 156 }
156 } 157 }
157 read_unlock(&GlobalSMBSeslock); 158 read_unlock(&GlobalSMBSeslock);
158 /* do not want to be sending data on a socket we are freeing */ 159 /* do not want to be sending data on a socket we are freeing */
159 down(&server->tcpSem); 160 down(&server->tcpSem);
160 if(server->ssocket) { 161 if (server->ssocket) {
161 cFYI(1,("State: 0x%x Flags: 0x%lx", server->ssocket->state, 162 cFYI(1, ("State: 0x%x Flags: 0x%lx", server->ssocket->state,
162 server->ssocket->flags)); 163 server->ssocket->flags));
163 server->ssocket->ops->shutdown(server->ssocket,SEND_SHUTDOWN); 164 server->ssocket->ops->shutdown(server->ssocket, SEND_SHUTDOWN);
164 cFYI(1,("Post shutdown state: 0x%x Flags: 0x%lx", server->ssocket->state, 165 cFYI(1, ("Post shutdown state: 0x%x Flags: 0x%lx",
166 server->ssocket->state,
165 server->ssocket->flags)); 167 server->ssocket->flags));
166 sock_release(server->ssocket); 168 sock_release(server->ssocket);
167 server->ssocket = NULL; 169 server->ssocket = NULL;
@@ -172,8 +174,8 @@ cifs_reconnect(struct TCP_Server_Info *server)
172 mid_entry = list_entry(tmp, struct 174 mid_entry = list_entry(tmp, struct
173 mid_q_entry, 175 mid_q_entry,
174 qhead); 176 qhead);
175 if(mid_entry) { 177 if (mid_entry) {
176 if(mid_entry->midState == MID_REQUEST_SUBMITTED) { 178 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
177 /* Mark other intransit requests as needing 179 /* Mark other intransit requests as needing
178 retry so we do not immediately mark the 180 retry so we do not immediately mark the
179 session bad again (ie after we reconnect 181 session bad again (ie after we reconnect
@@ -183,29 +185,29 @@ cifs_reconnect(struct TCP_Server_Info *server)
183 } 185 }
184 } 186 }
185 spin_unlock(&GlobalMid_Lock); 187 spin_unlock(&GlobalMid_Lock);
186 up(&server->tcpSem); 188 up(&server->tcpSem);
187 189
188 while ( (!kthread_should_stop()) && (server->tcpStatus != CifsGood)) 190 while ( (!kthread_should_stop()) && (server->tcpStatus != CifsGood)) {
189 {
190 try_to_freeze(); 191 try_to_freeze();
191 if(server->protocolType == IPV6) { 192 if (server->protocolType == IPV6) {
192 rc = ipv6_connect(&server->addr.sockAddr6,&server->ssocket); 193 rc = ipv6_connect(&server->addr.sockAddr6,
194 &server->ssocket);
193 } else { 195 } else {
194 rc = ipv4_connect(&server->addr.sockAddr, 196 rc = ipv4_connect(&server->addr.sockAddr,
195 &server->ssocket, 197 &server->ssocket,
196 server->workstation_RFC1001_name, 198 server->workstation_RFC1001_name,
197 server->server_RFC1001_name); 199 server->server_RFC1001_name);
198 } 200 }
199 if(rc) { 201 if (rc) {
200 cFYI(1,("reconnect error %d",rc)); 202 cFYI(1, ("reconnect error %d", rc));
201 msleep(3000); 203 msleep(3000);
202 } else { 204 } else {
203 atomic_inc(&tcpSesReconnectCount); 205 atomic_inc(&tcpSesReconnectCount);
204 spin_lock(&GlobalMid_Lock); 206 spin_lock(&GlobalMid_Lock);
205 if( !kthread_should_stop() ) 207 if ( !kthread_should_stop() )
206 server->tcpStatus = CifsGood; 208 server->tcpStatus = CifsGood;
207 server->sequence_number = 0; 209 server->sequence_number = 0;
208 spin_unlock(&GlobalMid_Lock); 210 spin_unlock(&GlobalMid_Lock);
209 /* atomic_set(&server->inFlight,0);*/ 211 /* atomic_set(&server->inFlight,0);*/
210 wake_up(&server->response_q); 212 wake_up(&server->response_q);
211 } 213 }
@@ -213,27 +215,27 @@ cifs_reconnect(struct TCP_Server_Info *server)
213 return rc; 215 return rc;
214} 216}
215 217
216/* 218/*
217 return codes: 219 return codes:
218 0 not a transact2, or all data present 220 0 not a transact2, or all data present
219 >0 transact2 with that much data missing 221 >0 transact2 with that much data missing
220 -EINVAL = invalid transact2 222 -EINVAL = invalid transact2
221 223
222 */ 224 */
223static int check2ndT2(struct smb_hdr * pSMB, unsigned int maxBufSize) 225static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize)
224{ 226{
225 struct smb_t2_rsp * pSMBt; 227 struct smb_t2_rsp *pSMBt;
226 int total_data_size; 228 int total_data_size;
227 int data_in_this_rsp; 229 int data_in_this_rsp;
228 int remaining; 230 int remaining;
229 231
230 if(pSMB->Command != SMB_COM_TRANSACTION2) 232 if (pSMB->Command != SMB_COM_TRANSACTION2)
231 return 0; 233 return 0;
232 234
233 /* check for plausible wct, bcc and t2 data and parm sizes */ 235 /* check for plausible wct, bcc and t2 data and parm sizes */
234 /* check for parm and data offset going beyond end of smb */ 236 /* check for parm and data offset going beyond end of smb */
235 if(pSMB->WordCount != 10) { /* coalesce_t2 depends on this */ 237 if (pSMB->WordCount != 10) { /* coalesce_t2 depends on this */
236 cFYI(1,("invalid transact2 word count")); 238 cFYI(1, ("invalid transact2 word count"));
237 return -EINVAL; 239 return -EINVAL;
238 } 240 }
239 241
@@ -244,25 +246,25 @@ static int check2ndT2(struct smb_hdr * pSMB, unsigned int maxBufSize)
244 246
245 remaining = total_data_size - data_in_this_rsp; 247 remaining = total_data_size - data_in_this_rsp;
246 248
247 if(remaining == 0) 249 if (remaining == 0)
248 return 0; 250 return 0;
249 else if(remaining < 0) { 251 else if (remaining < 0) {
250 cFYI(1,("total data %d smaller than data in frame %d", 252 cFYI(1, ("total data %d smaller than data in frame %d",
251 total_data_size, data_in_this_rsp)); 253 total_data_size, data_in_this_rsp));
252 return -EINVAL; 254 return -EINVAL;
253 } else { 255 } else {
254 cFYI(1,("missing %d bytes from transact2, check next response", 256 cFYI(1, ("missing %d bytes from transact2, check next response",
255 remaining)); 257 remaining));
256 if(total_data_size > maxBufSize) { 258 if (total_data_size > maxBufSize) {
257 cERROR(1,("TotalDataSize %d is over maximum buffer %d", 259 cERROR(1, ("TotalDataSize %d is over maximum buffer %d",
258 total_data_size,maxBufSize)); 260 total_data_size, maxBufSize));
259 return -EINVAL; 261 return -EINVAL;
260 } 262 }
261 return remaining; 263 return remaining;
262 } 264 }
263} 265}
264 266
265static int coalesce_t2(struct smb_hdr * psecond, struct smb_hdr *pTargetSMB) 267static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
266{ 268{
267 struct smb_t2_rsp *pSMB2 = (struct smb_t2_rsp *)psecond; 269 struct smb_t2_rsp *pSMB2 = (struct smb_t2_rsp *)psecond;
268 struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB; 270 struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB;
@@ -270,43 +272,43 @@ static int coalesce_t2(struct smb_hdr * psecond, struct smb_hdr *pTargetSMB)
270 int total_in_buf; 272 int total_in_buf;
271 int remaining; 273 int remaining;
272 int total_in_buf2; 274 int total_in_buf2;
273 char * data_area_of_target; 275 char *data_area_of_target;
274 char * data_area_of_buf2; 276 char *data_area_of_buf2;
275 __u16 byte_count; 277 __u16 byte_count;
276 278
277 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount); 279 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
278 280
279 if(total_data_size != le16_to_cpu(pSMB2->t2_rsp.TotalDataCount)) { 281 if (total_data_size != le16_to_cpu(pSMB2->t2_rsp.TotalDataCount)) {
280 cFYI(1,("total data sizes of primary and secondary t2 differ")); 282 cFYI(1, ("total data size of primary and secondary t2 differ"));
281 } 283 }
282 284
283 total_in_buf = le16_to_cpu(pSMBt->t2_rsp.DataCount); 285 total_in_buf = le16_to_cpu(pSMBt->t2_rsp.DataCount);
284 286
285 remaining = total_data_size - total_in_buf; 287 remaining = total_data_size - total_in_buf;
286 288
287 if(remaining < 0) 289 if (remaining < 0)
288 return -EINVAL; 290 return -EINVAL;
289 291
290 if(remaining == 0) /* nothing to do, ignore */ 292 if (remaining == 0) /* nothing to do, ignore */
291 return 0; 293 return 0;
292 294
293 total_in_buf2 = le16_to_cpu(pSMB2->t2_rsp.DataCount); 295 total_in_buf2 = le16_to_cpu(pSMB2->t2_rsp.DataCount);
294 if(remaining < total_in_buf2) { 296 if (remaining < total_in_buf2) {
295 cFYI(1,("transact2 2nd response contains too much data")); 297 cFYI(1, ("transact2 2nd response contains too much data"));
296 } 298 }
297 299
298 /* find end of first SMB data area */ 300 /* find end of first SMB data area */
299 data_area_of_target = (char *)&pSMBt->hdr.Protocol + 301 data_area_of_target = (char *)&pSMBt->hdr.Protocol +
300 le16_to_cpu(pSMBt->t2_rsp.DataOffset); 302 le16_to_cpu(pSMBt->t2_rsp.DataOffset);
301 /* validate target area */ 303 /* validate target area */
302 304
303 data_area_of_buf2 = (char *) &pSMB2->hdr.Protocol + 305 data_area_of_buf2 = (char *) &pSMB2->hdr.Protocol +
304 le16_to_cpu(pSMB2->t2_rsp.DataOffset); 306 le16_to_cpu(pSMB2->t2_rsp.DataOffset);
305 307
306 data_area_of_target += total_in_buf; 308 data_area_of_target += total_in_buf;
307 309
308 /* copy second buffer into end of first buffer */ 310 /* copy second buffer into end of first buffer */
309 memcpy(data_area_of_target,data_area_of_buf2,total_in_buf2); 311 memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2);
310 total_in_buf += total_in_buf2; 312 total_in_buf += total_in_buf2;
311 pSMBt->t2_rsp.DataCount = cpu_to_le16(total_in_buf); 313 pSMBt->t2_rsp.DataCount = cpu_to_le16(total_in_buf);
312 byte_count = le16_to_cpu(BCC_LE(pTargetSMB)); 314 byte_count = le16_to_cpu(BCC_LE(pTargetSMB));
@@ -317,11 +319,11 @@ static int coalesce_t2(struct smb_hdr * psecond, struct smb_hdr *pTargetSMB)
317 byte_count += total_in_buf2; 319 byte_count += total_in_buf2;
318 320
319 /* BB also add check that we are not beyond maximum buffer size */ 321 /* BB also add check that we are not beyond maximum buffer size */
320 322
321 pTargetSMB->smb_buf_length = byte_count; 323 pTargetSMB->smb_buf_length = byte_count;
322 324
323 if(remaining == total_in_buf2) { 325 if (remaining == total_in_buf2) {
324 cFYI(1,("found the last secondary response")); 326 cFYI(1, ("found the last secondary response"));
325 return 0; /* we are done */ 327 return 0; /* we are done */
326 } else /* more responses to go */ 328 } else /* more responses to go */
327 return 1; 329 return 1;
@@ -348,16 +350,15 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
348 int isMultiRsp; 350 int isMultiRsp;
349 int reconnect; 351 int reconnect;
350 352
351 allow_signal(SIGKILL);
352 current->flags |= PF_MEMALLOC; 353 current->flags |= PF_MEMALLOC;
353 server->tsk = current; /* save process info to wake at shutdown */ 354 server->tsk = current; /* save process info to wake at shutdown */
354 cFYI(1, ("Demultiplex PID: %d", current->pid)); 355 cFYI(1, ("Demultiplex PID: %d", current->pid));
355 write_lock(&GlobalSMBSeslock); 356 write_lock(&GlobalSMBSeslock);
356 atomic_inc(&tcpSesAllocCount); 357 atomic_inc(&tcpSesAllocCount);
357 length = tcpSesAllocCount.counter; 358 length = tcpSesAllocCount.counter;
358 write_unlock(&GlobalSMBSeslock); 359 write_unlock(&GlobalSMBSeslock);
359 complete(&cifsd_complete); 360 complete(&cifsd_complete);
360 if(length > 1) { 361 if (length > 1) {
361 mempool_resize(cifs_req_poolp, 362 mempool_resize(cifs_req_poolp,
362 length + cifs_min_rcv, 363 length + cifs_min_rcv,
363 GFP_KERNEL); 364 GFP_KERNEL);
@@ -426,10 +427,10 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
426 break; 427 break;
427 } 428 }
428 if (!try_to_freeze() && (length == -EINTR)) { 429 if (!try_to_freeze() && (length == -EINTR)) {
429 cFYI(1,("cifsd thread killed")); 430 cFYI(1, ("cifsd thread killed"));
430 break; 431 break;
431 } 432 }
432 cFYI(1,("Reconnect after unexpected peek error %d", 433 cFYI(1, ("Reconnect after unexpected peek error %d",
433 length)); 434 length));
434 cifs_reconnect(server); 435 cifs_reconnect(server);
435 csocket = server->ssocket; 436 csocket = server->ssocket;
@@ -453,26 +454,26 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
453 with the most common, zero, as regular data */ 454 with the most common, zero, as regular data */
454 temp = *((char *) smb_buffer); 455 temp = *((char *) smb_buffer);
455 456
456 /* Note that FC 1001 length is big endian on the wire, 457 /* Note that FC 1001 length is big endian on the wire,
457 but we convert it here so it is always manipulated 458 but we convert it here so it is always manipulated
458 as host byte order */ 459 as host byte order */
459 pdu_length = ntohl(smb_buffer->smb_buf_length); 460 pdu_length = ntohl(smb_buffer->smb_buf_length);
460 smb_buffer->smb_buf_length = pdu_length; 461 smb_buffer->smb_buf_length = pdu_length;
461 462
462 cFYI(1,("rfc1002 length 0x%x)", pdu_length+4)); 463 cFYI(1, ("rfc1002 length 0x%x", pdu_length+4));
463 464
464 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) { 465 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
465 continue; 466 continue;
466 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) { 467 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
467 cFYI(1,("Good RFC 1002 session rsp")); 468 cFYI(1, ("Good RFC 1002 session rsp"));
468 continue; 469 continue;
469 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) { 470 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
470 /* we get this from Windows 98 instead of 471 /* we get this from Windows 98 instead of
471 an error on SMB negprot response */ 472 an error on SMB negprot response */
472 cFYI(1,("Negative RFC1002 Session Response Error 0x%x)", 473 cFYI(1, ("Negative RFC1002 Session Response Error 0x%x)",
473 pdu_length)); 474 pdu_length));
474 if(server->tcpStatus == CifsNew) { 475 if (server->tcpStatus == CifsNew) {
475 /* if nack on negprot (rather than 476 /* if nack on negprot (rather than
476 ret of smb negprot error) reconnecting 477 ret of smb negprot error) reconnecting
477 not going to help, ret error to mount */ 478 not going to help, ret error to mount */
478 break; 479 break;
@@ -482,10 +483,10 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
482 msleep(1000); 483 msleep(1000);
483 /* always try 445 first on reconnect 484 /* always try 445 first on reconnect
484 since we get NACK on some if we ever 485 since we get NACK on some if we ever
485 connected to port 139 (the NACK is 486 connected to port 139 (the NACK is
486 since we do not begin with RFC1001 487 since we do not begin with RFC1001
487 session initialize frame) */ 488 session initialize frame) */
488 server->addr.sockAddr.sin_port = 489 server->addr.sockAddr.sin_port =
489 htons(CIFS_PORT); 490 htons(CIFS_PORT);
490 cifs_reconnect(server); 491 cifs_reconnect(server);
491 csocket = server->ssocket; 492 csocket = server->ssocket;
@@ -493,7 +494,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
493 continue; 494 continue;
494 } 495 }
495 } else if (temp != (char) 0) { 496 } else if (temp != (char) 0) {
496 cERROR(1,("Unknown RFC 1002 frame")); 497 cERROR(1, ("Unknown RFC 1002 frame"));
497 cifs_dump_mem(" Received Data: ", (char *)smb_buffer, 498 cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
498 length); 499 length);
499 cifs_reconnect(server); 500 cifs_reconnect(server);
@@ -502,7 +503,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
502 } 503 }
503 504
504 /* else we have an SMB response */ 505 /* else we have an SMB response */
505 if((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) || 506 if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
506 (pdu_length < sizeof (struct smb_hdr) - 1 - 4)) { 507 (pdu_length < sizeof (struct smb_hdr) - 1 - 4)) {
507 cERROR(1, ("Invalid size SMB length %d pdu_length %d", 508 cERROR(1, ("Invalid size SMB length %d pdu_length %d",
508 length, pdu_length+4)); 509 length, pdu_length+4));
@@ -510,12 +511,12 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
510 csocket = server->ssocket; 511 csocket = server->ssocket;
511 wake_up(&server->response_q); 512 wake_up(&server->response_q);
512 continue; 513 continue;
513 } 514 }
514 515
515 /* else length ok */ 516 /* else length ok */
516 reconnect = 0; 517 reconnect = 0;
517 518
518 if(pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) { 519 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
519 isLargeBuf = TRUE; 520 isLargeBuf = TRUE;
520 memcpy(bigbuf, smallbuf, 4); 521 memcpy(bigbuf, smallbuf, 4);
521 smb_buffer = bigbuf; 522 smb_buffer = bigbuf;
@@ -523,11 +524,11 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
523 length = 0; 524 length = 0;
524 iov.iov_base = 4 + (char *)smb_buffer; 525 iov.iov_base = 4 + (char *)smb_buffer;
525 iov.iov_len = pdu_length; 526 iov.iov_len = pdu_length;
526 for (total_read = 0; total_read < pdu_length; 527 for (total_read = 0; total_read < pdu_length;
527 total_read += length) { 528 total_read += length) {
528 length = kernel_recvmsg(csocket, &smb_msg, &iov, 1, 529 length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
529 pdu_length - total_read, 0); 530 pdu_length - total_read, 0);
530 if( kthread_should_stop() || 531 if ( kthread_should_stop() ||
531 (length == -EINTR)) { 532 (length == -EINTR)) {
532 /* then will exit */ 533 /* then will exit */
533 reconnect = 2; 534 reconnect = 2;
@@ -535,19 +536,19 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
535 } else if (server->tcpStatus == CifsNeedReconnect) { 536 } else if (server->tcpStatus == CifsNeedReconnect) {
536 cifs_reconnect(server); 537 cifs_reconnect(server);
537 csocket = server->ssocket; 538 csocket = server->ssocket;
538 /* Reconnect wakes up rspns q */ 539 /* Reconnect wakes up rspns q */
539 /* Now we will reread sock */ 540 /* Now we will reread sock */
540 reconnect = 1; 541 reconnect = 1;
541 break; 542 break;
542 } else if ((length == -ERESTARTSYS) || 543 } else if ((length == -ERESTARTSYS) ||
543 (length == -EAGAIN)) { 544 (length == -EAGAIN)) {
544 msleep(1); /* minimum sleep to prevent looping, 545 msleep(1); /* minimum sleep to prevent looping,
545 allowing socket to clear and app 546 allowing socket to clear and app
546 threads to set tcpStatus 547 threads to set tcpStatus
547 CifsNeedReconnect if server hung*/ 548 CifsNeedReconnect if server hung*/
548 continue; 549 continue;
549 } else if (length <= 0) { 550 } else if (length <= 0) {
550 cERROR(1,("Received no data, expecting %d", 551 cERROR(1, ("Received no data, expecting %d",
551 pdu_length - total_read)); 552 pdu_length - total_read));
552 cifs_reconnect(server); 553 cifs_reconnect(server);
553 csocket = server->ssocket; 554 csocket = server->ssocket;
@@ -555,13 +556,13 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
555 break; 556 break;
556 } 557 }
557 } 558 }
558 if(reconnect == 2) 559 if (reconnect == 2)
559 break; 560 break;
560 else if(reconnect == 1) 561 else if (reconnect == 1)
561 continue; 562 continue;
562 563
563 length += 4; /* account for rfc1002 hdr */ 564 length += 4; /* account for rfc1002 hdr */
564 565
565 566
566 dump_smb(smb_buffer, length); 567 dump_smb(smb_buffer, length);
567 if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) { 568 if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) {
@@ -575,28 +576,28 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
575 list_for_each(tmp, &server->pending_mid_q) { 576 list_for_each(tmp, &server->pending_mid_q) {
576 mid_entry = list_entry(tmp, struct mid_q_entry, qhead); 577 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
577 578
578 if ((mid_entry->mid == smb_buffer->Mid) && 579 if ((mid_entry->mid == smb_buffer->Mid) &&
579 (mid_entry->midState == MID_REQUEST_SUBMITTED) && 580 (mid_entry->midState == MID_REQUEST_SUBMITTED) &&
580 (mid_entry->command == smb_buffer->Command)) { 581 (mid_entry->command == smb_buffer->Command)) {
581 if(check2ndT2(smb_buffer,server->maxBuf) > 0) { 582 if (check2ndT2(smb_buffer,server->maxBuf) > 0) {
582 /* We have a multipart transact2 resp */ 583 /* We have a multipart transact2 resp */
583 isMultiRsp = TRUE; 584 isMultiRsp = TRUE;
584 if(mid_entry->resp_buf) { 585 if (mid_entry->resp_buf) {
585 /* merge response - fix up 1st*/ 586 /* merge response - fix up 1st*/
586 if(coalesce_t2(smb_buffer, 587 if (coalesce_t2(smb_buffer,
587 mid_entry->resp_buf)) { 588 mid_entry->resp_buf)) {
588 mid_entry->multiRsp = 1; 589 mid_entry->multiRsp = 1;
589 break; 590 break;
590 } else { 591 } else {
591 /* all parts received */ 592 /* all parts received */
592 mid_entry->multiEnd = 1; 593 mid_entry->multiEnd = 1;
593 goto multi_t2_fnd; 594 goto multi_t2_fnd;
594 } 595 }
595 } else { 596 } else {
596 if(!isLargeBuf) { 597 if (!isLargeBuf) {
597 cERROR(1,("1st trans2 resp needs bigbuf")); 598 cERROR(1,("1st trans2 resp needs bigbuf"));
598 /* BB maybe we can fix this up, switch 599 /* BB maybe we can fix this up, switch
599 to already allocated large buffer? */ 600 to already allocated large buffer? */
600 } else { 601 } else {
601 /* Have first buffer */ 602 /* Have first buffer */
602 mid_entry->resp_buf = 603 mid_entry->resp_buf =
@@ -606,9 +607,9 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
606 } 607 }
607 } 608 }
608 break; 609 break;
609 } 610 }
610 mid_entry->resp_buf = smb_buffer; 611 mid_entry->resp_buf = smb_buffer;
611 if(isLargeBuf) 612 if (isLargeBuf)
612 mid_entry->largeBuf = 1; 613 mid_entry->largeBuf = 1;
613 else 614 else
614 mid_entry->largeBuf = 0; 615 mid_entry->largeBuf = 0;
@@ -628,24 +629,25 @@ multi_t2_fnd:
628 spin_unlock(&GlobalMid_Lock); 629 spin_unlock(&GlobalMid_Lock);
629 if (task_to_wake) { 630 if (task_to_wake) {
630 /* Was previous buf put in mpx struct for multi-rsp? */ 631 /* Was previous buf put in mpx struct for multi-rsp? */
631 if(!isMultiRsp) { 632 if (!isMultiRsp) {
632 /* smb buffer will be freed by user thread */ 633 /* smb buffer will be freed by user thread */
633 if(isLargeBuf) { 634 if (isLargeBuf) {
634 bigbuf = NULL; 635 bigbuf = NULL;
635 } else 636 } else
636 smallbuf = NULL; 637 smallbuf = NULL;
637 } 638 }
638 wake_up_process(task_to_wake); 639 wake_up_process(task_to_wake);
639 } else if ((is_valid_oplock_break(smb_buffer, server) == FALSE) 640 } else if ((is_valid_oplock_break(smb_buffer, server) == FALSE)
640 && (isMultiRsp == FALSE)) { 641 && (isMultiRsp == FALSE)) {
641 cERROR(1, ("No task to wake, unknown frame rcvd! NumMids %d", midCount.counter)); 642 cERROR(1, ("No task to wake, unknown frame received! "
642 cifs_dump_mem("Received Data is: ",(char *)smb_buffer, 643 "NumMids %d", midCount.counter));
644 cifs_dump_mem("Received Data is: ", (char *)smb_buffer,
643 sizeof(struct smb_hdr)); 645 sizeof(struct smb_hdr));
644#ifdef CONFIG_CIFS_DEBUG2 646#ifdef CONFIG_CIFS_DEBUG2
645 cifs_dump_detail(smb_buffer); 647 cifs_dump_detail(smb_buffer);
646 cifs_dump_mids(server); 648 cifs_dump_mids(server);
647#endif /* CIFS_DEBUG2 */ 649#endif /* CIFS_DEBUG2 */
648 650
649 } 651 }
650 } /* end while !EXITING */ 652 } /* end while !EXITING */
651 653
@@ -655,12 +657,12 @@ multi_t2_fnd:
655 /* check if we have blocked requests that need to free */ 657 /* check if we have blocked requests that need to free */
656 /* Note that cifs_max_pending is normally 50, but 658 /* Note that cifs_max_pending is normally 50, but
657 can be set at module install time to as little as two */ 659 can be set at module install time to as little as two */
658 if(atomic_read(&server->inFlight) >= cifs_max_pending) 660 if (atomic_read(&server->inFlight) >= cifs_max_pending)
659 atomic_set(&server->inFlight, cifs_max_pending - 1); 661 atomic_set(&server->inFlight, cifs_max_pending - 1);
660 /* We do not want to set the max_pending too low or we 662 /* We do not want to set the max_pending too low or we
661 could end up with the counter going negative */ 663 could end up with the counter going negative */
662 spin_unlock(&GlobalMid_Lock); 664 spin_unlock(&GlobalMid_Lock);
663 /* Although there should not be any requests blocked on 665 /* Although there should not be any requests blocked on
664 this queue it can not hurt to be paranoid and try to wake up requests 666 this queue it can not hurt to be paranoid and try to wake up requests
665 that may haven been blocked when more than 50 at time were on the wire 667 that may haven been blocked when more than 50 at time were on the wire
666 to the same server - they now will see the session is in exit state 668 to the same server - they now will see the session is in exit state
@@ -668,8 +670,8 @@ multi_t2_fnd:
668 wake_up_all(&server->request_q); 670 wake_up_all(&server->request_q);
669 /* give those requests time to exit */ 671 /* give those requests time to exit */
670 msleep(125); 672 msleep(125);
671 673
672 if(server->ssocket) { 674 if (server->ssocket) {
673 sock_release(csocket); 675 sock_release(csocket);
674 server->ssocket = NULL; 676 server->ssocket = NULL;
675 } 677 }
@@ -709,10 +711,10 @@ multi_t2_fnd:
709 list_for_each(tmp, &server->pending_mid_q) { 711 list_for_each(tmp, &server->pending_mid_q) {
710 mid_entry = list_entry(tmp, struct mid_q_entry, qhead); 712 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
711 if (mid_entry->midState == MID_REQUEST_SUBMITTED) { 713 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
712 cFYI(1, 714 cFYI(1, ("Clearing Mid 0x%x - waking up ",
713 ("Clearing Mid 0x%x - waking up ",mid_entry->mid)); 715 mid_entry->mid));
714 task_to_wake = mid_entry->tsk; 716 task_to_wake = mid_entry->tsk;
715 if(task_to_wake) { 717 if (task_to_wake) {
716 wake_up_process(task_to_wake); 718 wake_up_process(task_to_wake);
717 } 719 }
718 } 720 }
@@ -724,7 +726,7 @@ multi_t2_fnd:
724 } 726 }
725 727
726 if (!list_empty(&server->pending_mid_q)) { 728 if (!list_empty(&server->pending_mid_q)) {
727 /* mpx threads have not exited yet give them 729 /* mpx threads have not exited yet give them
728 at least the smb send timeout time for long ops */ 730 at least the smb send timeout time for long ops */
729 /* due to delays on oplock break requests, we need 731 /* due to delays on oplock break requests, we need
730 to wait at least 45 seconds before giving up 732 to wait at least 45 seconds before giving up
@@ -742,7 +744,7 @@ multi_t2_fnd:
742 744
743 /* last chance to mark ses pointers invalid 745 /* last chance to mark ses pointers invalid
744 if there are any pointing to this (e.g 746 if there are any pointing to this (e.g
745 if a crazy root user tried to kill cifsd 747 if a crazy root user tried to kill cifsd
746 kernel thread explicitly this might happen) */ 748 kernel thread explicitly this might happen) */
747 list_for_each(tmp, &GlobalSMBSessionList) { 749 list_for_each(tmp, &GlobalSMBSessionList) {
748 ses = list_entry(tmp, struct cifsSesInfo, 750 ses = list_entry(tmp, struct cifsSesInfo,
@@ -754,17 +756,18 @@ multi_t2_fnd:
754 write_unlock(&GlobalSMBSeslock); 756 write_unlock(&GlobalSMBSeslock);
755 757
756 kfree(server); 758 kfree(server);
757 if(length > 0) { 759 if (length > 0) {
758 mempool_resize(cifs_req_poolp, 760 mempool_resize(cifs_req_poolp,
759 length + cifs_min_rcv, 761 length + cifs_min_rcv,
760 GFP_KERNEL); 762 GFP_KERNEL);
761 } 763 }
762 764
763 return 0; 765 return 0;
764} 766}
765 767
766static int 768static int
767cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) 769cifs_parse_mount_options(char *options, const char *devname,
770 struct smb_vol *vol)
768{ 771{
769 char *value; 772 char *value;
770 char *data; 773 char *data;
@@ -772,15 +775,15 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
772 char separator[2]; 775 char separator[2];
773 776
774 separator[0] = ','; 777 separator[0] = ',';
775 separator[1] = 0; 778 separator[1] = 0;
776 779
777 if (Local_System_Name[0] != 0) 780 if (Local_System_Name[0] != 0)
778 memcpy(vol->source_rfc1001_name, Local_System_Name,15); 781 memcpy(vol->source_rfc1001_name, Local_System_Name, 15);
779 else { 782 else {
780 char *nodename = utsname()->nodename; 783 char *nodename = utsname()->nodename;
781 int n = strnlen(nodename,15); 784 int n = strnlen(nodename, 15);
782 memset(vol->source_rfc1001_name,0x20,15); 785 memset(vol->source_rfc1001_name, 0x20, 15);
783 for(i=0 ; i < n ; i++) { 786 for (i = 0; i < n; i++) {
784 /* does not have to be perfect mapping since field is 787 /* does not have to be perfect mapping since field is
785 informational, only used for servers that do not support 788 informational, only used for servers that do not support
786 port 445 and it can be overridden at mount time */ 789 port 445 and it can be overridden at mount time */
@@ -805,31 +808,32 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
805 if (!options) 808 if (!options)
806 return 1; 809 return 1;
807 810
808 if(strncmp(options,"sep=",4) == 0) { 811 if (strncmp(options, "sep=", 4) == 0) {
809 if(options[4] != 0) { 812 if (options[4] != 0) {
810 separator[0] = options[4]; 813 separator[0] = options[4];
811 options += 5; 814 options += 5;
812 } else { 815 } else {
813 cFYI(1,("Null separator not allowed")); 816 cFYI(1, ("Null separator not allowed"));
814 } 817 }
815 } 818 }
816 819
817 while ((data = strsep(&options, separator)) != NULL) { 820 while ((data = strsep(&options, separator)) != NULL) {
818 if (!*data) 821 if (!*data)
819 continue; 822 continue;
820 if ((value = strchr(data, '=')) != NULL) 823 if ((value = strchr(data, '=')) != NULL)
821 *value++ = '\0'; 824 *value++ = '\0';
822 825
823 if (strnicmp(data, "user_xattr",10) == 0) {/*parse before user*/ 826 /* Have to parse this before we parse for "user" */
827 if (strnicmp(data, "user_xattr", 10) == 0) {
824 vol->no_xattr = 0; 828 vol->no_xattr = 0;
825 } else if (strnicmp(data, "nouser_xattr",12) == 0) { 829 } else if (strnicmp(data, "nouser_xattr", 12) == 0) {
826 vol->no_xattr = 1; 830 vol->no_xattr = 1;
827 } else if (strnicmp(data, "user", 4) == 0) { 831 } else if (strnicmp(data, "user", 4) == 0) {
828 if (!value) { 832 if (!value) {
829 printk(KERN_WARNING 833 printk(KERN_WARNING
830 "CIFS: invalid or missing username\n"); 834 "CIFS: invalid or missing username\n");
831 return 1; /* needs_arg; */ 835 return 1; /* needs_arg; */
832 } else if(!*value) { 836 } else if (!*value) {
833 /* null user, ie anonymous, authentication */ 837 /* null user, ie anonymous, authentication */
834 vol->nullauth = 1; 838 vol->nullauth = 1;
835 } 839 }
@@ -843,12 +847,12 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
843 if (!value) { 847 if (!value) {
844 vol->password = NULL; 848 vol->password = NULL;
845 continue; 849 continue;
846 } else if(value[0] == 0) { 850 } else if (value[0] == 0) {
847 /* check if string begins with double comma 851 /* check if string begins with double comma
848 since that would mean the password really 852 since that would mean the password really
849 does start with a comma, and would not 853 does start with a comma, and would not
850 indicate an empty string */ 854 indicate an empty string */
851 if(value[1] != separator[0]) { 855 if (value[1] != separator[0]) {
852 vol->password = NULL; 856 vol->password = NULL;
853 continue; 857 continue;
854 } 858 }
@@ -857,7 +861,7 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
857 /* removed password length check, NTLM passwords 861 /* removed password length check, NTLM passwords
858 can be arbitrarily long */ 862 can be arbitrarily long */
859 863
860 /* if comma in password, the string will be 864 /* if comma in password, the string will be
861 prematurely null terminated. Commas in password are 865 prematurely null terminated. Commas in password are
862 specified across the cifs mount interface by a double 866 specified across the cifs mount interface by a double
863 comma ie ,, and a comma used as in other cases ie ',' 867 comma ie ,, and a comma used as in other cases ie ','
@@ -867,18 +871,18 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
867 /* NB: password legally can have multiple commas and 871 /* NB: password legally can have multiple commas and
868 the only illegal character in a password is null */ 872 the only illegal character in a password is null */
869 873
870 if ((value[temp_len] == 0) && 874 if ((value[temp_len] == 0) &&
871 (value[temp_len+1] == separator[0])) { 875 (value[temp_len+1] == separator[0])) {
872 /* reinsert comma */ 876 /* reinsert comma */
873 value[temp_len] = separator[0]; 877 value[temp_len] = separator[0];
874 temp_len+=2; /* move after the second comma */ 878 temp_len += 2; /* move after second comma */
875 while(value[temp_len] != 0) { 879 while (value[temp_len] != 0) {
876 if (value[temp_len] == separator[0]) { 880 if (value[temp_len] == separator[0]) {
877 if (value[temp_len+1] == 881 if (value[temp_len+1] ==
878 separator[0]) { 882 separator[0]) {
879 /* skip second comma */ 883 /* skip second comma */
880 temp_len++; 884 temp_len++;
881 } else { 885 } else {
882 /* single comma indicating start 886 /* single comma indicating start
883 of next parm */ 887 of next parm */
884 break; 888 break;
@@ -886,24 +890,25 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
886 } 890 }
887 temp_len++; 891 temp_len++;
888 } 892 }
889 if(value[temp_len] == 0) { 893 if (value[temp_len] == 0) {
890 options = NULL; 894 options = NULL;
891 } else { 895 } else {
892 value[temp_len] = 0; 896 value[temp_len] = 0;
893 /* point option to start of next parm */ 897 /* point option to start of next parm */
894 options = value + temp_len + 1; 898 options = value + temp_len + 1;
895 } 899 }
896 /* go from value to value + temp_len condensing 900 /* go from value to value + temp_len condensing
897 double commas to singles. Note that this ends up 901 double commas to singles. Note that this ends up
898 allocating a few bytes too many, which is ok */ 902 allocating a few bytes too many, which is ok */
899 vol->password = kzalloc(temp_len, GFP_KERNEL); 903 vol->password = kzalloc(temp_len, GFP_KERNEL);
900 if(vol->password == NULL) { 904 if (vol->password == NULL) {
901 printk("CIFS: no memory for pass\n"); 905 printk(KERN_WARNING "CIFS: no memory "
906 "for password\n");
902 return 1; 907 return 1;
903 } 908 }
904 for(i=0,j=0;i<temp_len;i++,j++) { 909 for (i = 0, j = 0; i < temp_len; i++, j++) {
905 vol->password[j] = value[i]; 910 vol->password[j] = value[i];
906 if(value[i] == separator[0] 911 if (value[i] == separator[0]
907 && value[i+1] == separator[0]) { 912 && value[i+1] == separator[0]) {
908 /* skip second comma */ 913 /* skip second comma */
909 i++; 914 i++;
@@ -912,8 +917,9 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
912 vol->password[j] = 0; 917 vol->password[j] = 0;
913 } else { 918 } else {
914 vol->password = kzalloc(temp_len+1, GFP_KERNEL); 919 vol->password = kzalloc(temp_len+1, GFP_KERNEL);
915 if(vol->password == NULL) { 920 if (vol->password == NULL) {
916 printk("CIFS: no memory for pass\n"); 921 printk(KERN_WARNING "CIFS: no memory "
922 "for password\n");
917 return 1; 923 return 1;
918 } 924 }
919 strcpy(vol->password, value); 925 strcpy(vol->password, value);
@@ -924,20 +930,21 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
924 } else if (strnlen(value, 35) < 35) { 930 } else if (strnlen(value, 35) < 35) {
925 vol->UNCip = value; 931 vol->UNCip = value;
926 } else { 932 } else {
927 printk(KERN_WARNING "CIFS: ip address too long\n"); 933 printk(KERN_WARNING "CIFS: ip address "
934 "too long\n");
928 return 1; 935 return 1;
929 } 936 }
930 } else if (strnicmp(data, "sec", 3) == 0) { 937 } else if (strnicmp(data, "sec", 3) == 0) {
931 if (!value || !*value) { 938 if (!value || !*value) {
932 cERROR(1,("no security value specified")); 939 cERROR(1, ("no security value specified"));
933 continue; 940 continue;
934 } else if (strnicmp(value, "krb5i", 5) == 0) { 941 } else if (strnicmp(value, "krb5i", 5) == 0) {
935 vol->secFlg |= CIFSSEC_MAY_KRB5 | 942 vol->secFlg |= CIFSSEC_MAY_KRB5 |
936 CIFSSEC_MUST_SIGN; 943 CIFSSEC_MUST_SIGN;
937 } else if (strnicmp(value, "krb5p", 5) == 0) { 944 } else if (strnicmp(value, "krb5p", 5) == 0) {
938 /* vol->secFlg |= CIFSSEC_MUST_SEAL | 945 /* vol->secFlg |= CIFSSEC_MUST_SEAL |
939 CIFSSEC_MAY_KRB5; */ 946 CIFSSEC_MAY_KRB5; */
940 cERROR(1,("Krb5 cifs privacy not supported")); 947 cERROR(1, ("Krb5 cifs privacy not supported"));
941 return 1; 948 return 1;
942 } else if (strnicmp(value, "krb5", 4) == 0) { 949 } else if (strnicmp(value, "krb5", 4) == 0) {
943 vol->secFlg |= CIFSSEC_MAY_KRB5; 950 vol->secFlg |= CIFSSEC_MAY_KRB5;
@@ -957,33 +964,34 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
957 vol->secFlg |= CIFSSEC_MAY_NTLMV2; 964 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
958#ifdef CONFIG_CIFS_WEAK_PW_HASH 965#ifdef CONFIG_CIFS_WEAK_PW_HASH
959 } else if (strnicmp(value, "lanman", 6) == 0) { 966 } else if (strnicmp(value, "lanman", 6) == 0) {
960 vol->secFlg |= CIFSSEC_MAY_LANMAN; 967 vol->secFlg |= CIFSSEC_MAY_LANMAN;
961#endif 968#endif
962 } else if (strnicmp(value, "none", 4) == 0) { 969 } else if (strnicmp(value, "none", 4) == 0) {
963 vol->nullauth = 1; 970 vol->nullauth = 1;
964 } else { 971 } else {
965 cERROR(1,("bad security option: %s", value)); 972 cERROR(1, ("bad security option: %s", value));
966 return 1; 973 return 1;
967 } 974 }
968 } else if ((strnicmp(data, "unc", 3) == 0) 975 } else if ((strnicmp(data, "unc", 3) == 0)
969 || (strnicmp(data, "target", 6) == 0) 976 || (strnicmp(data, "target", 6) == 0)
970 || (strnicmp(data, "path", 4) == 0)) { 977 || (strnicmp(data, "path", 4) == 0)) {
971 if (!value || !*value) { 978 if (!value || !*value) {
972 printk(KERN_WARNING 979 printk(KERN_WARNING "CIFS: invalid path to "
973 "CIFS: invalid path to network resource\n"); 980 "network resource\n");
974 return 1; /* needs_arg; */ 981 return 1; /* needs_arg; */
975 } 982 }
976 if ((temp_len = strnlen(value, 300)) < 300) { 983 if ((temp_len = strnlen(value, 300)) < 300) {
977 vol->UNC = kmalloc(temp_len+1,GFP_KERNEL); 984 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
978 if (vol->UNC == NULL) 985 if (vol->UNC == NULL)
979 return 1; 986 return 1;
980 strcpy(vol->UNC,value); 987 strcpy(vol->UNC, value);
981 if (strncmp(vol->UNC, "//", 2) == 0) { 988 if (strncmp(vol->UNC, "//", 2) == 0) {
982 vol->UNC[0] = '\\'; 989 vol->UNC[0] = '\\';
983 vol->UNC[1] = '\\'; 990 vol->UNC[1] = '\\';
984 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) { 991 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
985 printk(KERN_WARNING 992 printk(KERN_WARNING
986 "CIFS: UNC Path does not begin with // or \\\\ \n"); 993 "CIFS: UNC Path does not begin "
994 "with // or \\\\ \n");
987 return 1; 995 return 1;
988 } 996 }
989 } else { 997 } else {
@@ -1002,43 +1010,47 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
1002 vol->domainname = value; 1010 vol->domainname = value;
1003 cFYI(1, ("Domain name set")); 1011 cFYI(1, ("Domain name set"));
1004 } else { 1012 } else {
1005 printk(KERN_WARNING "CIFS: domain name too long\n"); 1013 printk(KERN_WARNING "CIFS: domain name too "
1014 "long\n");
1006 return 1; 1015 return 1;
1007 } 1016 }
1008 } else if (strnicmp(data, "prefixpath", 10) == 0) { 1017 } else if (strnicmp(data, "prefixpath", 10) == 0) {
1009 if (!value || !*value) { 1018 if (!value || !*value) {
1010 printk(KERN_WARNING 1019 printk(KERN_WARNING
1011 "CIFS: invalid path prefix\n"); 1020 "CIFS: invalid path prefix\n");
1012 return 1; /* needs_arg; */ 1021 return 1; /* needs_argument */
1013 } 1022 }
1014 if ((temp_len = strnlen(value, 1024)) < 1024) { 1023 if ((temp_len = strnlen(value, 1024)) < 1024) {
1015 if (value[0] != '/') 1024 if (value[0] != '/')
1016 temp_len++; /* missing leading slash */ 1025 temp_len++; /* missing leading slash */
1017 vol->prepath = kmalloc(temp_len+1,GFP_KERNEL); 1026 vol->prepath = kmalloc(temp_len+1, GFP_KERNEL);
1018 if (vol->prepath == NULL) 1027 if (vol->prepath == NULL)
1019 return 1; 1028 return 1;
1020 if (value[0] != '/') { 1029 if (value[0] != '/') {
1021 vol->prepath[0] = '/'; 1030 vol->prepath[0] = '/';
1022 strcpy(vol->prepath+1,value); 1031 strcpy(vol->prepath+1, value);
1023 } else 1032 } else
1024 strcpy(vol->prepath,value); 1033 strcpy(vol->prepath, value);
1025 cFYI(1,("prefix path %s",vol->prepath)); 1034 cFYI(1, ("prefix path %s", vol->prepath));
1026 } else { 1035 } else {
1027 printk(KERN_WARNING "CIFS: prefix too long\n"); 1036 printk(KERN_WARNING "CIFS: prefix too long\n");
1028 return 1; 1037 return 1;
1029 } 1038 }
1030 } else if (strnicmp(data, "iocharset", 9) == 0) { 1039 } else if (strnicmp(data, "iocharset", 9) == 0) {
1031 if (!value || !*value) { 1040 if (!value || !*value) {
1032 printk(KERN_WARNING "CIFS: invalid iocharset specified\n"); 1041 printk(KERN_WARNING "CIFS: invalid iocharset "
1042 "specified\n");
1033 return 1; /* needs_arg; */ 1043 return 1; /* needs_arg; */
1034 } 1044 }
1035 if (strnlen(value, 65) < 65) { 1045 if (strnlen(value, 65) < 65) {
1036 if (strnicmp(value,"default",7)) 1046 if (strnicmp(value, "default", 7))
1037 vol->iocharset = value; 1047 vol->iocharset = value;
1038 /* if iocharset not set load_nls_default used by caller */ 1048 /* if iocharset not set then load_nls_default
1039 cFYI(1, ("iocharset set to %s",value)); 1049 is used by caller */
1050 cFYI(1, ("iocharset set to %s", value));
1040 } else { 1051 } else {
1041 printk(KERN_WARNING "CIFS: iocharset name too long.\n"); 1052 printk(KERN_WARNING "CIFS: iocharset name "
1053 "too long.\n");
1042 return 1; 1054 return 1;
1043 } 1055 }
1044 } else if (strnicmp(data, "uid", 3) == 0) { 1056 } else if (strnicmp(data, "uid", 3) == 0) {
@@ -1090,54 +1102,59 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
1090 } 1102 }
1091 } else if (strnicmp(data, "netbiosname", 4) == 0) { 1103 } else if (strnicmp(data, "netbiosname", 4) == 0) {
1092 if (!value || !*value || (*value == ' ')) { 1104 if (!value || !*value || (*value == ' ')) {
1093 cFYI(1,("invalid (empty) netbiosname specified")); 1105 cFYI(1, ("invalid (empty) netbiosname"));
1094 } else { 1106 } else {
1095 memset(vol->source_rfc1001_name,0x20,15); 1107 memset(vol->source_rfc1001_name, 0x20, 15);
1096 for(i=0;i<15;i++) { 1108 for (i = 0; i < 15; i++) {
1097 /* BB are there cases in which a comma can be 1109 /* BB are there cases in which a comma can be
1098 valid in this workstation netbios name (and need 1110 valid in this workstation netbios name (and need
1099 special handling)? */ 1111 special handling)? */
1100 1112
1101 /* We do not uppercase netbiosname for user */ 1113 /* We do not uppercase netbiosname for user */
1102 if (value[i]==0) 1114 if (value[i] == 0)
1103 break; 1115 break;
1104 else 1116 else
1105 vol->source_rfc1001_name[i] = value[i]; 1117 vol->source_rfc1001_name[i] =
1118 value[i];
1106 } 1119 }
1107 /* The string has 16th byte zero still from 1120 /* The string has 16th byte zero still from
1108 set at top of the function */ 1121 set at top of the function */
1109 if ((i==15) && (value[i] != 0)) 1122 if ((i == 15) && (value[i] != 0))
1110 printk(KERN_WARNING "CIFS: netbiosname longer than 15 truncated.\n"); 1123 printk(KERN_WARNING "CIFS: netbiosname"
1124 " longer than 15 truncated.\n");
1111 } 1125 }
1112 } else if (strnicmp(data, "servern", 7) == 0) { 1126 } else if (strnicmp(data, "servern", 7) == 0) {
1113 /* servernetbiosname specified override *SMBSERVER */ 1127 /* servernetbiosname specified override *SMBSERVER */
1114 if (!value || !*value || (*value == ' ')) { 1128 if (!value || !*value || (*value == ' ')) {
1115 cFYI(1,("empty server netbiosname specified")); 1129 cFYI(1, ("empty server netbiosname specified"));
1116 } else { 1130 } else {
1117 /* last byte, type, is 0x20 for servr type */ 1131 /* last byte, type, is 0x20 for servr type */
1118 memset(vol->target_rfc1001_name,0x20,16); 1132 memset(vol->target_rfc1001_name, 0x20, 16);
1119 1133
1120 for(i=0;i<15;i++) { 1134 for (i = 0; i < 15; i++) {
1121 /* BB are there cases in which a comma can be 1135 /* BB are there cases in which a comma can be
1122 valid in this workstation netbios name (and need 1136 valid in this workstation netbios name
1123 special handling)? */ 1137 (and need special handling)? */
1124 1138
1125 /* user or mount helper must uppercase netbiosname */ 1139 /* user or mount helper must uppercase
1126 if (value[i]==0) 1140 the netbiosname */
1141 if (value[i] == 0)
1127 break; 1142 break;
1128 else 1143 else
1129 vol->target_rfc1001_name[i] = value[i]; 1144 vol->target_rfc1001_name[i] =
1145 value[i];
1130 } 1146 }
1131 /* The string has 16th byte zero still from 1147 /* The string has 16th byte zero still from
1132 set at top of the function */ 1148 set at top of the function */
1133 if ((i==15) && (value[i] != 0)) 1149 if ((i == 15) && (value[i] != 0))
1134 printk(KERN_WARNING "CIFS: server netbiosname longer than 15 truncated.\n"); 1150 printk(KERN_WARNING "CIFS: server net"
1151 "biosname longer than 15 truncated.\n");
1135 } 1152 }
1136 } else if (strnicmp(data, "credentials", 4) == 0) { 1153 } else if (strnicmp(data, "credentials", 4) == 0) {
1137 /* ignore */ 1154 /* ignore */
1138 } else if (strnicmp(data, "version", 3) == 0) { 1155 } else if (strnicmp(data, "version", 3) == 0) {
1139 /* ignore */ 1156 /* ignore */
1140 } else if (strnicmp(data, "guest",5) == 0) { 1157 } else if (strnicmp(data, "guest", 5) == 0) {
1141 /* ignore */ 1158 /* ignore */
1142 } else if (strnicmp(data, "rw", 2) == 0) { 1159 } else if (strnicmp(data, "rw", 2) == 0) {
1143 vol->rw = TRUE; 1160 vol->rw = TRUE;
@@ -1149,11 +1166,11 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
1149 (strnicmp(data, "noauto", 6) == 0) || 1166 (strnicmp(data, "noauto", 6) == 0) ||
1150 (strnicmp(data, "dev", 3) == 0)) { 1167 (strnicmp(data, "dev", 3) == 0)) {
1151 /* The mount tool or mount.cifs helper (if present) 1168 /* The mount tool or mount.cifs helper (if present)
1152 uses these opts to set flags, and the flags are read 1169 uses these opts to set flags, and the flags are read
1153 by the kernel vfs layer before we get here (ie 1170 by the kernel vfs layer before we get here (ie
1154 before read super) so there is no point trying to 1171 before read super) so there is no point trying to
1155 parse these options again and set anything and it 1172 parse these options again and set anything and it
1156 is ok to just ignore them */ 1173 is ok to just ignore them */
1157 continue; 1174 continue;
1158 } else if (strnicmp(data, "ro", 2) == 0) { 1175 } else if (strnicmp(data, "ro", 2) == 0) {
1159 vol->rw = FALSE; 1176 vol->rw = FALSE;
@@ -1169,26 +1186,31 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
1169 vol->remap = 1; 1186 vol->remap = 1;
1170 } else if (strnicmp(data, "nomapchars", 10) == 0) { 1187 } else if (strnicmp(data, "nomapchars", 10) == 0) {
1171 vol->remap = 0; 1188 vol->remap = 0;
1172 } else if (strnicmp(data, "sfu", 3) == 0) { 1189 } else if (strnicmp(data, "sfu", 3) == 0) {
1173 vol->sfu_emul = 1; 1190 vol->sfu_emul = 1;
1174 } else if (strnicmp(data, "nosfu", 5) == 0) { 1191 } else if (strnicmp(data, "nosfu", 5) == 0) {
1175 vol->sfu_emul = 0; 1192 vol->sfu_emul = 0;
1176 } else if (strnicmp(data, "posixpaths", 10) == 0) { 1193 } else if (strnicmp(data, "posixpaths", 10) == 0) {
1177 vol->posix_paths = 1; 1194 vol->posix_paths = 1;
1178 } else if (strnicmp(data, "noposixpaths", 12) == 0) { 1195 } else if (strnicmp(data, "noposixpaths", 12) == 0) {
1179 vol->posix_paths = 0; 1196 vol->posix_paths = 0;
1180 } else if ((strnicmp(data, "nocase", 6) == 0) || 1197 } else if (strnicmp(data, "nounix", 6) == 0) {
1198 vol->no_linux_ext = 1;
1199 } else if (strnicmp(data, "nolinux", 7) == 0) {
1200 vol->no_linux_ext = 1;
1201 } else if ((strnicmp(data, "nocase", 6) == 0) ||
1181 (strnicmp(data, "ignorecase", 10) == 0)) { 1202 (strnicmp(data, "ignorecase", 10) == 0)) {
1182 vol->nocase = 1; 1203 vol->nocase = 1;
1183 } else if (strnicmp(data, "brl", 3) == 0) { 1204 } else if (strnicmp(data, "brl", 3) == 0) {
1184 vol->nobrl = 0; 1205 vol->nobrl = 0;
1185 } else if ((strnicmp(data, "nobrl", 5) == 0) || 1206 } else if ((strnicmp(data, "nobrl", 5) == 0) ||
1186 (strnicmp(data, "nolock", 6) == 0)) { 1207 (strnicmp(data, "nolock", 6) == 0)) {
1187 vol->nobrl = 1; 1208 vol->nobrl = 1;
1188 /* turn off mandatory locking in mode 1209 /* turn off mandatory locking in mode
1189 if remote locking is turned off since the 1210 if remote locking is turned off since the
1190 local vfs will do advisory */ 1211 local vfs will do advisory */
1191 if(vol->file_mode == (S_IALLUGO & ~(S_ISUID | S_IXGRP))) 1212 if (vol->file_mode ==
1213 (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
1192 vol->file_mode = S_IALLUGO; 1214 vol->file_mode = S_IALLUGO;
1193 } else if (strnicmp(data, "setuids", 7) == 0) { 1215 } else if (strnicmp(data, "setuids", 7) == 0) {
1194 vol->setuids = 1; 1216 vol->setuids = 1;
@@ -1202,55 +1224,61 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
1202 vol->intr = 0; 1224 vol->intr = 0;
1203 } else if (strnicmp(data, "intr", 4) == 0) { 1225 } else if (strnicmp(data, "intr", 4) == 0) {
1204 vol->intr = 1; 1226 vol->intr = 1;
1205 } else if (strnicmp(data, "serverino",7) == 0) { 1227 } else if (strnicmp(data, "serverino", 7) == 0) {
1206 vol->server_ino = 1; 1228 vol->server_ino = 1;
1207 } else if (strnicmp(data, "noserverino",9) == 0) { 1229 } else if (strnicmp(data, "noserverino", 9) == 0) {
1208 vol->server_ino = 0; 1230 vol->server_ino = 0;
1209 } else if (strnicmp(data, "cifsacl",7) == 0) { 1231 } else if (strnicmp(data, "cifsacl", 7) == 0) {
1210 vol->cifs_acl = 1; 1232 vol->cifs_acl = 1;
1211 } else if (strnicmp(data, "nocifsacl", 9) == 0) { 1233 } else if (strnicmp(data, "nocifsacl", 9) == 0) {
1212 vol->cifs_acl = 0; 1234 vol->cifs_acl = 0;
1213 } else if (strnicmp(data, "acl",3) == 0) { 1235 } else if (strnicmp(data, "acl", 3) == 0) {
1214 vol->no_psx_acl = 0; 1236 vol->no_psx_acl = 0;
1215 } else if (strnicmp(data, "noacl",5) == 0) { 1237 } else if (strnicmp(data, "noacl", 5) == 0) {
1216 vol->no_psx_acl = 1; 1238 vol->no_psx_acl = 1;
1217 } else if (strnicmp(data, "sign",4) == 0) { 1239 } else if (strnicmp(data, "sign", 4) == 0) {
1218 vol->secFlg |= CIFSSEC_MUST_SIGN; 1240 vol->secFlg |= CIFSSEC_MUST_SIGN;
1219/* } else if (strnicmp(data, "seal",4) == 0) { 1241/* } else if (strnicmp(data, "seal",4) == 0) {
1220 vol->secFlg |= CIFSSEC_MUST_SEAL; */ 1242 vol->secFlg |= CIFSSEC_MUST_SEAL; */
1221 } else if (strnicmp(data, "direct",6) == 0) { 1243 } else if (strnicmp(data, "direct", 6) == 0) {
1222 vol->direct_io = 1; 1244 vol->direct_io = 1;
1223 } else if (strnicmp(data, "forcedirectio",13) == 0) { 1245 } else if (strnicmp(data, "forcedirectio", 13) == 0) {
1224 vol->direct_io = 1; 1246 vol->direct_io = 1;
1225 } else if (strnicmp(data, "in6_addr",8) == 0) { 1247 } else if (strnicmp(data, "in6_addr", 8) == 0) {
1226 if (!value || !*value) { 1248 if (!value || !*value) {
1227 vol->in6_addr = NULL; 1249 vol->in6_addr = NULL;
1228 } else if (strnlen(value, 49) == 48) { 1250 } else if (strnlen(value, 49) == 48) {
1229 vol->in6_addr = value; 1251 vol->in6_addr = value;
1230 } else { 1252 } else {
1231 printk(KERN_WARNING "CIFS: ip v6 address not 48 characters long\n"); 1253 printk(KERN_WARNING "CIFS: ip v6 address not "
1254 "48 characters long\n");
1232 return 1; 1255 return 1;
1233 } 1256 }
1234 } else if (strnicmp(data, "noac", 4) == 0) { 1257 } else if (strnicmp(data, "noac", 4) == 0) {
1235 printk(KERN_WARNING "CIFS: Mount option noac not supported. Instead set /proc/fs/cifs/LookupCacheEnabled to 0\n"); 1258 printk(KERN_WARNING "CIFS: Mount option noac not "
1259 "supported. Instead set "
1260 "/proc/fs/cifs/LookupCacheEnabled to 0\n");
1236 } else 1261 } else
1237 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",data); 1262 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
1263 data);
1238 } 1264 }
1239 if (vol->UNC == NULL) { 1265 if (vol->UNC == NULL) {
1240 if (devname == NULL) { 1266 if (devname == NULL) {
1241 printk(KERN_WARNING "CIFS: Missing UNC name for mount target\n"); 1267 printk(KERN_WARNING "CIFS: Missing UNC name for mount "
1268 "target\n");
1242 return 1; 1269 return 1;
1243 } 1270 }
1244 if ((temp_len = strnlen(devname, 300)) < 300) { 1271 if ((temp_len = strnlen(devname, 300)) < 300) {
1245 vol->UNC = kmalloc(temp_len+1,GFP_KERNEL); 1272 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
1246 if (vol->UNC == NULL) 1273 if (vol->UNC == NULL)
1247 return 1; 1274 return 1;
1248 strcpy(vol->UNC,devname); 1275 strcpy(vol->UNC, devname);
1249 if (strncmp(vol->UNC, "//", 2) == 0) { 1276 if (strncmp(vol->UNC, "//", 2) == 0) {
1250 vol->UNC[0] = '\\'; 1277 vol->UNC[0] = '\\';
1251 vol->UNC[1] = '\\'; 1278 vol->UNC[1] = '\\';
1252 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) { 1279 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1253 printk(KERN_WARNING "CIFS: UNC Path does not begin with // or \\\\ \n"); 1280 printk(KERN_WARNING "CIFS: UNC Path does not "
1281 "begin with // or \\\\ \n");
1254 return 1; 1282 return 1;
1255 } 1283 }
1256 } else { 1284 } else {
@@ -1258,14 +1286,14 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
1258 return 1; 1286 return 1;
1259 } 1287 }
1260 } 1288 }
1261 if(vol->UNCip == NULL) 1289 if (vol->UNCip == NULL)
1262 vol->UNCip = &vol->UNC[2]; 1290 vol->UNCip = &vol->UNC[2];
1263 1291
1264 return 0; 1292 return 0;
1265} 1293}
1266 1294
1267static struct cifsSesInfo * 1295static struct cifsSesInfo *
1268cifs_find_tcp_session(struct in_addr * target_ip_addr, 1296cifs_find_tcp_session(struct in_addr *target_ip_addr,
1269 struct in6_addr *target_ip6_addr, 1297 struct in6_addr *target_ip6_addr,
1270 char *userName, struct TCP_Server_Info **psrvTcp) 1298 char *userName, struct TCP_Server_Info **psrvTcp)
1271{ 1299{
@@ -1277,19 +1305,25 @@ cifs_find_tcp_session(struct in_addr * target_ip_addr,
1277 list_for_each(tmp, &GlobalSMBSessionList) { 1305 list_for_each(tmp, &GlobalSMBSessionList) {
1278 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList); 1306 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
1279 if (ses->server) { 1307 if (ses->server) {
1280 if((target_ip_addr && 1308 if ((target_ip_addr &&
1281 (ses->server->addr.sockAddr.sin_addr.s_addr 1309 (ses->server->addr.sockAddr.sin_addr.s_addr
1282 == target_ip_addr->s_addr)) || (target_ip6_addr 1310 == target_ip_addr->s_addr)) || (target_ip6_addr
1283 && memcmp(&ses->server->addr.sockAddr6.sin6_addr, 1311 && memcmp(&ses->server->addr.sockAddr6.sin6_addr,
1284 target_ip6_addr,sizeof(*target_ip6_addr)))){ 1312 target_ip6_addr, sizeof(*target_ip6_addr)))) {
1285 /* BB lock server and tcp session and increment use count here?? */ 1313 /* BB lock server and tcp session and increment
1286 *psrvTcp = ses->server; /* found a match on the TCP session */ 1314 use count here?? */
1315
1316 /* found a match on the TCP session */
1317 *psrvTcp = ses->server;
1318
1287 /* BB check if reconnection needed */ 1319 /* BB check if reconnection needed */
1288 if (strncmp 1320 if (strncmp
1289 (ses->userName, userName, 1321 (ses->userName, userName,
1290 MAX_USERNAME_SIZE) == 0){ 1322 MAX_USERNAME_SIZE) == 0){
1291 read_unlock(&GlobalSMBSeslock); 1323 read_unlock(&GlobalSMBSeslock);
1292 return ses; /* found exact match on both tcp and SMB sessions */ 1324 /* Found exact match on both TCP and
1325 SMB sessions */
1326 return ses;
1293 } 1327 }
1294 } 1328 }
1295 } 1329 }
@@ -1320,7 +1354,8 @@ find_unc(__be32 new_target_ip_addr, char *uncName, char *userName)
1320 /* BB lock tcon, server and tcp session and increment use count here? */ 1354 /* BB lock tcon, server and tcp session and increment use count here? */
1321 /* found a match on the TCP session */ 1355 /* found a match on the TCP session */
1322 /* BB check if reconnection needed */ 1356 /* BB check if reconnection needed */
1323 cFYI(1,("IP match, old UNC: %s new: %s", 1357 cFYI(1,
1358 ("IP match, old UNC: %s new: %s",
1324 tcon->treeName, uncName)); 1359 tcon->treeName, uncName));
1325 if (strncmp 1360 if (strncmp
1326 (tcon->treeName, uncName, 1361 (tcon->treeName, uncName,
@@ -1355,11 +1390,11 @@ connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
1355 unsigned int num_referrals; 1390 unsigned int num_referrals;
1356 int rc = 0; 1391 int rc = 0;
1357 1392
1358 rc = get_dfs_path(xid, pSesInfo,old_path, nls_codepage, 1393 rc = get_dfs_path(xid, pSesInfo, old_path, nls_codepage,
1359 &num_referrals, &referrals, remap); 1394 &num_referrals, &referrals, remap);
1360 1395
1361 /* BB Add in code to: if valid refrl, if not ip address contact 1396 /* BB Add in code to: if valid refrl, if not ip address contact
1362 the helper that resolves tcp names, mount to it, try to 1397 the helper that resolves tcp names, mount to it, try to
1363 tcon to it unmount it if fail */ 1398 tcon to it unmount it if fail */
1364 1399
1365 kfree(referrals); 1400 kfree(referrals);
@@ -1368,10 +1403,9 @@ connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
1368} 1403}
1369 1404
1370int 1405int
1371get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, 1406get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
1372 const char *old_path, const struct nls_table *nls_codepage, 1407 const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
1373 unsigned int *pnum_referrals, 1408 unsigned char **preferrals, int remap)
1374 unsigned char ** preferrals, int remap)
1375{ 1409{
1376 char *temp_unc; 1410 char *temp_unc;
1377 int rc = 0; 1411 int rc = 0;
@@ -1380,7 +1414,8 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
1380 1414
1381 if (pSesInfo->ipc_tid == 0) { 1415 if (pSesInfo->ipc_tid == 0) {
1382 temp_unc = kmalloc(2 /* for slashes */ + 1416 temp_unc = kmalloc(2 /* for slashes */ +
1383 strnlen(pSesInfo->serverName,SERVER_NAME_LEN_WITH_NULL * 2) 1417 strnlen(pSesInfo->serverName,
1418 SERVER_NAME_LEN_WITH_NULL * 2)
1384 + 1 + 4 /* slash IPC$ */ + 2, 1419 + 1 + 4 /* slash IPC$ */ + 2,
1385 GFP_KERNEL); 1420 GFP_KERNEL);
1386 if (temp_unc == NULL) 1421 if (temp_unc == NULL)
@@ -1391,7 +1426,7 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
1391 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$"); 1426 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");
1392 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage); 1427 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
1393 cFYI(1, 1428 cFYI(1,
1394 ("CIFS Tcon rc = %d ipc_tid = %d", rc,pSesInfo->ipc_tid)); 1429 ("CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid));
1395 kfree(temp_unc); 1430 kfree(temp_unc);
1396 } 1431 }
1397 if (rc == 0) 1432 if (rc == 0)
@@ -1402,62 +1437,63 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
1402} 1437}
1403 1438
1404/* See RFC1001 section 14 on representation of Netbios names */ 1439/* See RFC1001 section 14 on representation of Netbios names */
1405static void rfc1002mangle(char * target,char * source, unsigned int length) 1440static void rfc1002mangle(char *target, char *source, unsigned int length)
1406{ 1441{
1407 unsigned int i,j; 1442 unsigned int i, j;
1408 1443
1409 for(i=0,j=0;i<(length);i++) { 1444 for (i = 0, j = 0; i < (length); i++) {
1410 /* mask a nibble at a time and encode */ 1445 /* mask a nibble at a time and encode */
1411 target[j] = 'A' + (0x0F & (source[i] >> 4)); 1446 target[j] = 'A' + (0x0F & (source[i] >> 4));
1412 target[j+1] = 'A' + (0x0F & source[i]); 1447 target[j+1] = 'A' + (0x0F & source[i]);
1413 j+=2; 1448 j += 2;
1414 } 1449 }
1415 1450
1416} 1451}
1417 1452
1418 1453
1419static int 1454static int
1420ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, 1455ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1421 char * netbios_name, char * target_name) 1456 char *netbios_name, char *target_name)
1422{ 1457{
1423 int rc = 0; 1458 int rc = 0;
1424 int connected = 0; 1459 int connected = 0;
1425 __be16 orig_port = 0; 1460 __be16 orig_port = 0;
1426 1461
1427 if(*csocket == NULL) { 1462 if (*csocket == NULL) {
1428 rc = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, csocket); 1463 rc = sock_create_kern(PF_INET, SOCK_STREAM,
1464 IPPROTO_TCP, csocket);
1429 if (rc < 0) { 1465 if (rc < 0) {
1430 cERROR(1, ("Error %d creating socket",rc)); 1466 cERROR(1, ("Error %d creating socket", rc));
1431 *csocket = NULL; 1467 *csocket = NULL;
1432 return rc; 1468 return rc;
1433 } else { 1469 } else {
1434 /* BB other socket options to set KEEPALIVE, NODELAY? */ 1470 /* BB other socket options to set KEEPALIVE, NODELAY? */
1435 cFYI(1,("Socket created")); 1471 cFYI(1, ("Socket created"));
1436 (*csocket)->sk->sk_allocation = GFP_NOFS; 1472 (*csocket)->sk->sk_allocation = GFP_NOFS;
1437 } 1473 }
1438 } 1474 }
1439 1475
1440 psin_server->sin_family = AF_INET; 1476 psin_server->sin_family = AF_INET;
1441 if(psin_server->sin_port) { /* user overrode default port */ 1477 if (psin_server->sin_port) { /* user overrode default port */
1442 rc = (*csocket)->ops->connect(*csocket, 1478 rc = (*csocket)->ops->connect(*csocket,
1443 (struct sockaddr *) psin_server, 1479 (struct sockaddr *) psin_server,
1444 sizeof (struct sockaddr_in),0); 1480 sizeof (struct sockaddr_in), 0);
1445 if (rc >= 0) 1481 if (rc >= 0)
1446 connected = 1; 1482 connected = 1;
1447 } 1483 }
1448 1484
1449 if(!connected) { 1485 if (!connected) {
1450 /* save original port so we can retry user specified port 1486 /* save original port so we can retry user specified port
1451 later if fall back ports fail this time */ 1487 later if fall back ports fail this time */
1452 orig_port = psin_server->sin_port; 1488 orig_port = psin_server->sin_port;
1453 1489
1454 /* do not retry on the same port we just failed on */ 1490 /* do not retry on the same port we just failed on */
1455 if(psin_server->sin_port != htons(CIFS_PORT)) { 1491 if (psin_server->sin_port != htons(CIFS_PORT)) {
1456 psin_server->sin_port = htons(CIFS_PORT); 1492 psin_server->sin_port = htons(CIFS_PORT);
1457 1493
1458 rc = (*csocket)->ops->connect(*csocket, 1494 rc = (*csocket)->ops->connect(*csocket,
1459 (struct sockaddr *) psin_server, 1495 (struct sockaddr *) psin_server,
1460 sizeof (struct sockaddr_in),0); 1496 sizeof (struct sockaddr_in), 0);
1461 if (rc >= 0) 1497 if (rc >= 0)
1462 connected = 1; 1498 connected = 1;
1463 } 1499 }
@@ -1465,60 +1501,63 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1465 if (!connected) { 1501 if (!connected) {
1466 psin_server->sin_port = htons(RFC1001_PORT); 1502 psin_server->sin_port = htons(RFC1001_PORT);
1467 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *) 1503 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1468 psin_server, sizeof (struct sockaddr_in),0); 1504 psin_server,
1469 if (rc >= 0) 1505 sizeof (struct sockaddr_in), 0);
1506 if (rc >= 0)
1470 connected = 1; 1507 connected = 1;
1471 } 1508 }
1472 1509
1473 /* give up here - unless we want to retry on different 1510 /* give up here - unless we want to retry on different
1474 protocol families some day */ 1511 protocol families some day */
1475 if (!connected) { 1512 if (!connected) {
1476 if(orig_port) 1513 if (orig_port)
1477 psin_server->sin_port = orig_port; 1514 psin_server->sin_port = orig_port;
1478 cFYI(1,("Error %d connecting to server via ipv4",rc)); 1515 cFYI(1, ("Error %d connecting to server via ipv4", rc));
1479 sock_release(*csocket); 1516 sock_release(*csocket);
1480 *csocket = NULL; 1517 *csocket = NULL;
1481 return rc; 1518 return rc;
1482 } 1519 }
1483 /* Eventually check for other socket options to change from 1520 /* Eventually check for other socket options to change from
1484 the default. sock_setsockopt not used because it expects 1521 the default. sock_setsockopt not used because it expects
1485 user space buffer */ 1522 user space buffer */
1486 cFYI(1,("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",(*csocket)->sk->sk_sndbuf, 1523 cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
1524 (*csocket)->sk->sk_sndbuf,
1487 (*csocket)->sk->sk_rcvbuf, (*csocket)->sk->sk_rcvtimeo)); 1525 (*csocket)->sk->sk_rcvbuf, (*csocket)->sk->sk_rcvtimeo));
1488 (*csocket)->sk->sk_rcvtimeo = 7 * HZ; 1526 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1489 /* make the bufsizes depend on wsize/rsize and max requests */ 1527 /* make the bufsizes depend on wsize/rsize and max requests */
1490 if((*csocket)->sk->sk_sndbuf < (200 * 1024)) 1528 if ((*csocket)->sk->sk_sndbuf < (200 * 1024))
1491 (*csocket)->sk->sk_sndbuf = 200 * 1024; 1529 (*csocket)->sk->sk_sndbuf = 200 * 1024;
1492 if((*csocket)->sk->sk_rcvbuf < (140 * 1024)) 1530 if ((*csocket)->sk->sk_rcvbuf < (140 * 1024))
1493 (*csocket)->sk->sk_rcvbuf = 140 * 1024; 1531 (*csocket)->sk->sk_rcvbuf = 140 * 1024;
1494 1532
1495 /* send RFC1001 sessinit */ 1533 /* send RFC1001 sessinit */
1496 if(psin_server->sin_port == htons(RFC1001_PORT)) { 1534 if (psin_server->sin_port == htons(RFC1001_PORT)) {
1497 /* some servers require RFC1001 sessinit before sending 1535 /* some servers require RFC1001 sessinit before sending
1498 negprot - BB check reconnection in case where second 1536 negprot - BB check reconnection in case where second
1499 sessinit is sent but no second negprot */ 1537 sessinit is sent but no second negprot */
1500 struct rfc1002_session_packet * ses_init_buf; 1538 struct rfc1002_session_packet *ses_init_buf;
1501 struct smb_hdr * smb_buf; 1539 struct smb_hdr *smb_buf;
1502 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet), GFP_KERNEL); 1540 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
1503 if(ses_init_buf) { 1541 GFP_KERNEL);
1542 if (ses_init_buf) {
1504 ses_init_buf->trailer.session_req.called_len = 32; 1543 ses_init_buf->trailer.session_req.called_len = 32;
1505 if(target_name && (target_name[0] != 0)) { 1544 if (target_name && (target_name[0] != 0)) {
1506 rfc1002mangle(ses_init_buf->trailer.session_req.called_name, 1545 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1507 target_name, 16); 1546 target_name, 16);
1508 } else { 1547 } else {
1509 rfc1002mangle(ses_init_buf->trailer.session_req.called_name, 1548 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1510 DEFAULT_CIFS_CALLED_NAME,16); 1549 DEFAULT_CIFS_CALLED_NAME, 16);
1511 } 1550 }
1512 1551
1513 ses_init_buf->trailer.session_req.calling_len = 32; 1552 ses_init_buf->trailer.session_req.calling_len = 32;
1514 /* calling name ends in null (byte 16) from old smb 1553 /* calling name ends in null (byte 16) from old smb
1515 convention. */ 1554 convention. */
1516 if(netbios_name && (netbios_name[0] !=0)) { 1555 if (netbios_name && (netbios_name[0] != 0)) {
1517 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name, 1556 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1518 netbios_name,16); 1557 netbios_name, 16);
1519 } else { 1558 } else {
1520 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name, 1559 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1521 "LINUX_CIFS_CLNT",16); 1560 "LINUX_CIFS_CLNT", 16);
1522 } 1561 }
1523 ses_init_buf->trailer.session_req.scope1 = 0; 1562 ses_init_buf->trailer.session_req.scope1 = 0;
1524 ses_init_buf->trailer.session_req.scope2 = 0; 1563 ses_init_buf->trailer.session_req.scope2 = 0;
@@ -1528,20 +1567,20 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1528 rc = smb_send(*csocket, smb_buf, 0x44, 1567 rc = smb_send(*csocket, smb_buf, 0x44,
1529 (struct sockaddr *)psin_server); 1568 (struct sockaddr *)psin_server);
1530 kfree(ses_init_buf); 1569 kfree(ses_init_buf);
1531 msleep(1); /* RFC1001 layer in at least one server 1570 msleep(1); /* RFC1001 layer in at least one server
1532 requires very short break before negprot 1571 requires very short break before negprot
1533 presumably because not expecting negprot 1572 presumably because not expecting negprot
1534 to follow so fast. This is a simple 1573 to follow so fast. This is a simple
1535 solution that works without 1574 solution that works without
1536 complicating the code and causes no 1575 complicating the code and causes no
1537 significant slowing down on mount 1576 significant slowing down on mount
1538 for everyone else */ 1577 for everyone else */
1539 } 1578 }
1540 /* else the negprot may still work without this 1579 /* else the negprot may still work without this
1541 even though malloc failed */ 1580 even though malloc failed */
1542 1581
1543 } 1582 }
1544 1583
1545 return rc; 1584 return rc;
1546} 1585}
1547 1586
@@ -1552,41 +1591,42 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
1552 int connected = 0; 1591 int connected = 0;
1553 __be16 orig_port = 0; 1592 __be16 orig_port = 0;
1554 1593
1555 if(*csocket == NULL) { 1594 if (*csocket == NULL) {
1556 rc = sock_create_kern(PF_INET6, SOCK_STREAM, IPPROTO_TCP, csocket); 1595 rc = sock_create_kern(PF_INET6, SOCK_STREAM,
1596 IPPROTO_TCP, csocket);
1557 if (rc < 0) { 1597 if (rc < 0) {
1558 cERROR(1, ("Error %d creating ipv6 socket",rc)); 1598 cERROR(1, ("Error %d creating ipv6 socket", rc));
1559 *csocket = NULL; 1599 *csocket = NULL;
1560 return rc; 1600 return rc;
1561 } else { 1601 } else {
1562 /* BB other socket options to set KEEPALIVE, NODELAY? */ 1602 /* BB other socket options to set KEEPALIVE, NODELAY? */
1563 cFYI(1,("ipv6 Socket created")); 1603 cFYI(1, ("ipv6 Socket created"));
1564 (*csocket)->sk->sk_allocation = GFP_NOFS; 1604 (*csocket)->sk->sk_allocation = GFP_NOFS;
1565 } 1605 }
1566 } 1606 }
1567 1607
1568 psin_server->sin6_family = AF_INET6; 1608 psin_server->sin6_family = AF_INET6;
1569 1609
1570 if(psin_server->sin6_port) { /* user overrode default port */ 1610 if (psin_server->sin6_port) { /* user overrode default port */
1571 rc = (*csocket)->ops->connect(*csocket, 1611 rc = (*csocket)->ops->connect(*csocket,
1572 (struct sockaddr *) psin_server, 1612 (struct sockaddr *) psin_server,
1573 sizeof (struct sockaddr_in6),0); 1613 sizeof (struct sockaddr_in6), 0);
1574 if (rc >= 0) 1614 if (rc >= 0)
1575 connected = 1; 1615 connected = 1;
1576 } 1616 }
1577 1617
1578 if(!connected) { 1618 if (!connected) {
1579 /* save original port so we can retry user specified port 1619 /* save original port so we can retry user specified port
1580 later if fall back ports fail this time */ 1620 later if fall back ports fail this time */
1581 1621
1582 orig_port = psin_server->sin6_port; 1622 orig_port = psin_server->sin6_port;
1583 /* do not retry on the same port we just failed on */ 1623 /* do not retry on the same port we just failed on */
1584 if(psin_server->sin6_port != htons(CIFS_PORT)) { 1624 if (psin_server->sin6_port != htons(CIFS_PORT)) {
1585 psin_server->sin6_port = htons(CIFS_PORT); 1625 psin_server->sin6_port = htons(CIFS_PORT);
1586 1626
1587 rc = (*csocket)->ops->connect(*csocket, 1627 rc = (*csocket)->ops->connect(*csocket,
1588 (struct sockaddr *) psin_server, 1628 (struct sockaddr *) psin_server,
1589 sizeof (struct sockaddr_in6),0); 1629 sizeof (struct sockaddr_in6), 0);
1590 if (rc >= 0) 1630 if (rc >= 0)
1591 connected = 1; 1631 connected = 1;
1592 } 1632 }
@@ -1594,31 +1634,31 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
1594 if (!connected) { 1634 if (!connected) {
1595 psin_server->sin6_port = htons(RFC1001_PORT); 1635 psin_server->sin6_port = htons(RFC1001_PORT);
1596 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *) 1636 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1597 psin_server, sizeof (struct sockaddr_in6),0); 1637 psin_server, sizeof (struct sockaddr_in6), 0);
1598 if (rc >= 0) 1638 if (rc >= 0)
1599 connected = 1; 1639 connected = 1;
1600 } 1640 }
1601 1641
1602 /* give up here - unless we want to retry on different 1642 /* give up here - unless we want to retry on different
1603 protocol families some day */ 1643 protocol families some day */
1604 if (!connected) { 1644 if (!connected) {
1605 if(orig_port) 1645 if (orig_port)
1606 psin_server->sin6_port = orig_port; 1646 psin_server->sin6_port = orig_port;
1607 cFYI(1,("Error %d connecting to server via ipv6",rc)); 1647 cFYI(1, ("Error %d connecting to server via ipv6", rc));
1608 sock_release(*csocket); 1648 sock_release(*csocket);
1609 *csocket = NULL; 1649 *csocket = NULL;
1610 return rc; 1650 return rc;
1611 } 1651 }
1612 /* Eventually check for other socket options to change from 1652 /* Eventually check for other socket options to change from
1613 the default. sock_setsockopt not used because it expects 1653 the default. sock_setsockopt not used because it expects
1614 user space buffer */ 1654 user space buffer */
1615 (*csocket)->sk->sk_rcvtimeo = 7 * HZ; 1655 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1616 1656
1617 return rc; 1657 return rc;
1618} 1658}
1619 1659
1620void reset_cifs_unix_caps(int xid, struct cifsTconInfo * tcon, 1660void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
1621 struct super_block * sb, struct smb_vol * vol_info) 1661 struct super_block *sb, struct smb_vol *vol_info)
1622{ 1662{
1623 /* if we are reconnecting then should we check to see if 1663 /* if we are reconnecting then should we check to see if
1624 * any requested capabilities changed locally e.g. via 1664 * any requested capabilities changed locally e.g. via
@@ -1630,65 +1670,87 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo * tcon,
1630 * What if we wanted to mount the server share twice once with 1670 * What if we wanted to mount the server share twice once with
1631 * and once without posixacls or posix paths? */ 1671 * and once without posixacls or posix paths? */
1632 __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability); 1672 __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
1633 1673
1634 1674 if (vol_info && vol_info->no_linux_ext) {
1635 if(!CIFSSMBQFSUnixInfo(xid, tcon)) { 1675 tcon->fsUnixInfo.Capability = 0;
1676 tcon->unix_ext = 0; /* Unix Extensions disabled */
1677 cFYI(1, ("Linux protocol extensions disabled"));
1678 return;
1679 } else if (vol_info)
1680 tcon->unix_ext = 1; /* Unix Extensions supported */
1681
1682 if (tcon->unix_ext == 0) {
1683 cFYI(1, ("Unix extensions disabled so not set on reconnect"));
1684 return;
1685 }
1686
1687 if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
1636 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability); 1688 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
1637 1689
1638 /* check for reconnect case in which we do not 1690 /* check for reconnect case in which we do not
1639 want to change the mount behavior if we can avoid it */ 1691 want to change the mount behavior if we can avoid it */
1640 if(vol_info == NULL) { 1692 if (vol_info == NULL) {
1641 /* turn off POSIX ACL and PATHNAMES if not set 1693 /* turn off POSIX ACL and PATHNAMES if not set
1642 originally at mount time */ 1694 originally at mount time */
1643 if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0) 1695 if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
1644 cap &= ~CIFS_UNIX_POSIX_ACL_CAP; 1696 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
1645 if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) 1697 if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0)
1646 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP; 1698 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
1647
1648
1649
1650
1651 } 1699 }
1652 1700
1653 cap &= CIFS_UNIX_CAP_MASK; 1701 cap &= CIFS_UNIX_CAP_MASK;
1654 if(vol_info && vol_info->no_psx_acl) 1702 if (vol_info && vol_info->no_psx_acl)
1655 cap &= ~CIFS_UNIX_POSIX_ACL_CAP; 1703 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
1656 else if(CIFS_UNIX_POSIX_ACL_CAP & cap) { 1704 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
1657 cFYI(1,("negotiated posix acl support")); 1705 cFYI(1, ("negotiated posix acl support"));
1658 if(sb) 1706 if (sb)
1659 sb->s_flags |= MS_POSIXACL; 1707 sb->s_flags |= MS_POSIXACL;
1660 } 1708 }
1661 1709
1662 if(vol_info && vol_info->posix_paths == 0) 1710 if (vol_info && vol_info->posix_paths == 0)
1663 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP; 1711 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
1664 else if(cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) { 1712 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
1665 cFYI(1,("negotiate posix pathnames")); 1713 cFYI(1, ("negotiate posix pathnames"));
1666 if(sb) 1714 if (sb)
1667 CIFS_SB(sb)->mnt_cifs_flags |= 1715 CIFS_SB(sb)->mnt_cifs_flags |=
1668 CIFS_MOUNT_POSIX_PATHS; 1716 CIFS_MOUNT_POSIX_PATHS;
1669 } 1717 }
1670 1718
1671 /* We might be setting the path sep back to a different 1719 /* We might be setting the path sep back to a different
1672 form if we are reconnecting and the server switched its 1720 form if we are reconnecting and the server switched its
1673 posix path capability for this share */ 1721 posix path capability for this share */
1674 if(sb && (CIFS_SB(sb)->prepathlen > 0)) 1722 if (sb && (CIFS_SB(sb)->prepathlen > 0))
1675 CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb)); 1723 CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb));
1676 1724
1677 cFYI(1,("Negotiate caps 0x%x",(int)cap)); 1725 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
1726 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
1727 CIFS_SB(sb)->rsize = 127 * 1024;
1728#ifdef CONFIG_CIFS_DEBUG2
1729 cFYI(1, ("larger reads not supported by srv"));
1730#endif
1731 }
1732 }
1733
1734
1735 cFYI(1, ("Negotiate caps 0x%x", (int)cap));
1678#ifdef CONFIG_CIFS_DEBUG2 1736#ifdef CONFIG_CIFS_DEBUG2
1679 if(cap & CIFS_UNIX_FCNTL_CAP) 1737 if (cap & CIFS_UNIX_FCNTL_CAP)
1680 cFYI(1,("FCNTL cap")); 1738 cFYI(1, ("FCNTL cap"));
1681 if(cap & CIFS_UNIX_EXTATTR_CAP) 1739 if (cap & CIFS_UNIX_EXTATTR_CAP)
1682 cFYI(1,("EXTATTR cap")); 1740 cFYI(1, ("EXTATTR cap"));
1683 if(cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) 1741 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
1684 cFYI(1,("POSIX path cap")); 1742 cFYI(1, ("POSIX path cap"));
1685 if(cap & CIFS_UNIX_XATTR_CAP) 1743 if (cap & CIFS_UNIX_XATTR_CAP)
1686 cFYI(1,("XATTR cap")); 1744 cFYI(1, ("XATTR cap"));
1687 if(cap & CIFS_UNIX_POSIX_ACL_CAP) 1745 if (cap & CIFS_UNIX_POSIX_ACL_CAP)
1688 cFYI(1,("POSIX ACL cap")); 1746 cFYI(1, ("POSIX ACL cap"));
1747 if (cap & CIFS_UNIX_LARGE_READ_CAP)
1748 cFYI(1, ("very large read cap"));
1749 if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
1750 cFYI(1, ("very large write cap"));
1689#endif /* CIFS_DEBUG2 */ 1751#endif /* CIFS_DEBUG2 */
1690 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) { 1752 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
1691 cFYI(1,("setting capabilities failed")); 1753 cFYI(1, ("setting capabilities failed"));
1692 } 1754 }
1693 } 1755 }
1694} 1756}
@@ -1712,8 +1774,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1712 xid = GetXid(); 1774 xid = GetXid();
1713 1775
1714/* cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); */ 1776/* cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); */
1715 1777
1716 memset(&volume_info,0,sizeof(struct smb_vol)); 1778 memset(&volume_info, 0, sizeof(struct smb_vol));
1717 if (cifs_parse_mount_options(mount_data, devname, &volume_info)) { 1779 if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
1718 kfree(volume_info.UNC); 1780 kfree(volume_info.UNC);
1719 kfree(volume_info.password); 1781 kfree(volume_info.password);
@@ -1723,15 +1785,15 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1723 } 1785 }
1724 1786
1725 if (volume_info.nullauth) { 1787 if (volume_info.nullauth) {
1726 cFYI(1,("null user")); 1788 cFYI(1, ("null user"));
1727 volume_info.username = NULL; 1789 volume_info.username = NULL;
1728 } else if (volume_info.username) { 1790 } else if (volume_info.username) {
1729 /* BB fixme parse for domain name here */ 1791 /* BB fixme parse for domain name here */
1730 cFYI(1, ("Username: %s ", volume_info.username)); 1792 cFYI(1, ("Username: %s", volume_info.username));
1731 } else { 1793 } else {
1732 cifserror("No username specified"); 1794 cifserror("No username specified");
1733 /* In userspace mount helper we can get user name from alternate 1795 /* In userspace mount helper we can get user name from alternate
1734 locations such as env variables and files on disk */ 1796 locations such as env variables and files on disk */
1735 kfree(volume_info.UNC); 1797 kfree(volume_info.UNC);
1736 kfree(volume_info.password); 1798 kfree(volume_info.password);
1737 kfree(volume_info.prepath); 1799 kfree(volume_info.prepath);
@@ -1740,18 +1802,20 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1740 } 1802 }
1741 1803
1742 if (volume_info.UNCip && volume_info.UNC) { 1804 if (volume_info.UNCip && volume_info.UNC) {
1743 rc = cifs_inet_pton(AF_INET, volume_info.UNCip,&sin_server.sin_addr.s_addr); 1805 rc = cifs_inet_pton(AF_INET, volume_info.UNCip,
1806 &sin_server.sin_addr.s_addr);
1744 1807
1745 if(rc <= 0) { 1808 if (rc <= 0) {
1746 /* not ipv4 address, try ipv6 */ 1809 /* not ipv4 address, try ipv6 */
1747 rc = cifs_inet_pton(AF_INET6,volume_info.UNCip,&sin_server6.sin6_addr.in6_u); 1810 rc = cifs_inet_pton(AF_INET6, volume_info.UNCip,
1748 if(rc > 0) 1811 &sin_server6.sin6_addr.in6_u);
1812 if (rc > 0)
1749 address_type = AF_INET6; 1813 address_type = AF_INET6;
1750 } else { 1814 } else {
1751 address_type = AF_INET; 1815 address_type = AF_INET;
1752 } 1816 }
1753 1817
1754 if(rc <= 0) { 1818 if (rc <= 0) {
1755 /* we failed translating address */ 1819 /* we failed translating address */
1756 kfree(volume_info.UNC); 1820 kfree(volume_info.UNC);
1757 kfree(volume_info.password); 1821 kfree(volume_info.password);
@@ -1763,9 +1827,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1763 cFYI(1, ("UNC: %s ip: %s", volume_info.UNC, volume_info.UNCip)); 1827 cFYI(1, ("UNC: %s ip: %s", volume_info.UNC, volume_info.UNCip));
1764 /* success */ 1828 /* success */
1765 rc = 0; 1829 rc = 0;
1766 } else if (volume_info.UNCip){ 1830 } else if (volume_info.UNCip) {
1767 /* BB using ip addr as server name connect to the DFS root below */ 1831 /* BB using ip addr as server name to connect to the
1768 cERROR(1,("Connecting to DFS root not implemented yet")); 1832 DFS root below */
1833 cERROR(1, ("Connecting to DFS root not implemented yet"));
1769 kfree(volume_info.UNC); 1834 kfree(volume_info.UNC);
1770 kfree(volume_info.password); 1835 kfree(volume_info.password);
1771 kfree(volume_info.prepath); 1836 kfree(volume_info.prepath);
@@ -1773,7 +1838,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1773 return -EINVAL; 1838 return -EINVAL;
1774 } else /* which servers DFS root would we conect to */ { 1839 } else /* which servers DFS root would we conect to */ {
1775 cERROR(1, 1840 cERROR(1,
1776 ("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified")); 1841 ("CIFS mount error: No UNC path (e.g. -o "
1842 "unc=//192.168.1.100/public) specified"));
1777 kfree(volume_info.UNC); 1843 kfree(volume_info.UNC);
1778 kfree(volume_info.password); 1844 kfree(volume_info.password);
1779 kfree(volume_info.prepath); 1845 kfree(volume_info.prepath);
@@ -1782,13 +1848,14 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1782 } 1848 }
1783 1849
1784 /* this is needed for ASCII cp to Unicode converts */ 1850 /* this is needed for ASCII cp to Unicode converts */
1785 if(volume_info.iocharset == NULL) { 1851 if (volume_info.iocharset == NULL) {
1786 cifs_sb->local_nls = load_nls_default(); 1852 cifs_sb->local_nls = load_nls_default();
1787 /* load_nls_default can not return null */ 1853 /* load_nls_default can not return null */
1788 } else { 1854 } else {
1789 cifs_sb->local_nls = load_nls(volume_info.iocharset); 1855 cifs_sb->local_nls = load_nls(volume_info.iocharset);
1790 if(cifs_sb->local_nls == NULL) { 1856 if (cifs_sb->local_nls == NULL) {
1791 cERROR(1,("CIFS mount error: iocharset %s not found",volume_info.iocharset)); 1857 cERROR(1, ("CIFS mount error: iocharset %s not found",
1858 volume_info.iocharset));
1792 kfree(volume_info.UNC); 1859 kfree(volume_info.UNC);
1793 kfree(volume_info.password); 1860 kfree(volume_info.password);
1794 kfree(volume_info.prepath); 1861 kfree(volume_info.prepath);
@@ -1797,12 +1864,12 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1797 } 1864 }
1798 } 1865 }
1799 1866
1800 if(address_type == AF_INET) 1867 if (address_type == AF_INET)
1801 existingCifsSes = cifs_find_tcp_session(&sin_server.sin_addr, 1868 existingCifsSes = cifs_find_tcp_session(&sin_server.sin_addr,
1802 NULL /* no ipv6 addr */, 1869 NULL /* no ipv6 addr */,
1803 volume_info.username, &srvTcp); 1870 volume_info.username, &srvTcp);
1804 else if(address_type == AF_INET6) { 1871 else if (address_type == AF_INET6) {
1805 cFYI(1,("looking for ipv6 address")); 1872 cFYI(1, ("looking for ipv6 address"));
1806 existingCifsSes = cifs_find_tcp_session(NULL /* no ipv4 addr */, 1873 existingCifsSes = cifs_find_tcp_session(NULL /* no ipv4 addr */,
1807 &sin_server6.sin6_addr, 1874 &sin_server6.sin6_addr,
1808 volume_info.username, &srvTcp); 1875 volume_info.username, &srvTcp);
@@ -1814,26 +1881,25 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1814 return -EINVAL; 1881 return -EINVAL;
1815 } 1882 }
1816 1883
1817
1818 if (srvTcp) { 1884 if (srvTcp) {
1819 cFYI(1, ("Existing tcp session with server found")); 1885 cFYI(1, ("Existing tcp session with server found"));
1820 } else { /* create socket */ 1886 } else { /* create socket */
1821 if (volume_info.port) 1887 if (volume_info.port)
1822 sin_server.sin_port = htons(volume_info.port); 1888 sin_server.sin_port = htons(volume_info.port);
1823 else 1889 else
1824 sin_server.sin_port = 0; 1890 sin_server.sin_port = 0;
1825 if (address_type == AF_INET6) { 1891 if (address_type == AF_INET6) {
1826 cFYI(1,("attempting ipv6 connect")); 1892 cFYI(1, ("attempting ipv6 connect"));
1827 /* BB should we allow ipv6 on port 139? */ 1893 /* BB should we allow ipv6 on port 139? */
1828 /* other OS never observed in Wild doing 139 with v6 */ 1894 /* other OS never observed in Wild doing 139 with v6 */
1829 rc = ipv6_connect(&sin_server6,&csocket); 1895 rc = ipv6_connect(&sin_server6, &csocket);
1830 } else 1896 } else
1831 rc = ipv4_connect(&sin_server,&csocket, 1897 rc = ipv4_connect(&sin_server, &csocket,
1832 volume_info.source_rfc1001_name, 1898 volume_info.source_rfc1001_name,
1833 volume_info.target_rfc1001_name); 1899 volume_info.target_rfc1001_name);
1834 if (rc < 0) { 1900 if (rc < 0) {
1835 cERROR(1, 1901 cERROR(1, ("Error connecting to IPv4 socket. "
1836 ("Error connecting to IPv4 socket. Aborting operation")); 1902 "Aborting operation"));
1837 if (csocket != NULL) 1903 if (csocket != NULL)
1838 sock_release(csocket); 1904 sock_release(csocket);
1839 kfree(volume_info.UNC); 1905 kfree(volume_info.UNC);
@@ -1854,8 +1920,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1854 return rc; 1920 return rc;
1855 } else { 1921 } else {
1856 memset(srvTcp, 0, sizeof (struct TCP_Server_Info)); 1922 memset(srvTcp, 0, sizeof (struct TCP_Server_Info));
1857 memcpy(&srvTcp->addr.sockAddr, &sin_server, sizeof (struct sockaddr_in)); 1923 memcpy(&srvTcp->addr.sockAddr, &sin_server,
1858 atomic_set(&srvTcp->inFlight,0); 1924 sizeof (struct sockaddr_in));
1925 atomic_set(&srvTcp->inFlight, 0);
1859 /* BB Add code for ipv6 case too */ 1926 /* BB Add code for ipv6 case too */
1860 srvTcp->ssocket = csocket; 1927 srvTcp->ssocket = csocket;
1861 srvTcp->protocolType = IPV4; 1928 srvTcp->protocolType = IPV4;
@@ -1870,7 +1937,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1870 srvTcp->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread, srvTcp, "cifsd"); 1937 srvTcp->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread, srvTcp, "cifsd");
1871 if ( IS_ERR(srvTcp->tsk) ) { 1938 if ( IS_ERR(srvTcp->tsk) ) {
1872 rc = PTR_ERR(srvTcp->tsk); 1939 rc = PTR_ERR(srvTcp->tsk);
1873 cERROR(1,("error %d create cifsd thread", rc)); 1940 cERROR(1, ("error %d create cifsd thread", rc));
1874 srvTcp->tsk = NULL; 1941 srvTcp->tsk = NULL;
1875 sock_release(csocket); 1942 sock_release(csocket);
1876 kfree(volume_info.UNC); 1943 kfree(volume_info.UNC);
@@ -1881,8 +1948,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1881 } 1948 }
1882 wait_for_completion(&cifsd_complete); 1949 wait_for_completion(&cifsd_complete);
1883 rc = 0; 1950 rc = 0;
1884 memcpy(srvTcp->workstation_RFC1001_name, volume_info.source_rfc1001_name,16); 1951 memcpy(srvTcp->workstation_RFC1001_name,
1885 memcpy(srvTcp->server_RFC1001_name, volume_info.target_rfc1001_name,16); 1952 volume_info.source_rfc1001_name, 16);
1953 memcpy(srvTcp->server_RFC1001_name,
1954 volume_info.target_rfc1001_name, 16);
1886 srvTcp->sequence_number = 0; 1955 srvTcp->sequence_number = 0;
1887 } 1956 }
1888 } 1957 }
@@ -1903,16 +1972,17 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1903 NIPQUAD(sin_server.sin_addr.s_addr)); 1972 NIPQUAD(sin_server.sin_addr.s_addr));
1904 } 1973 }
1905 1974
1906 if (!rc){ 1975 if (!rc) {
1907 /* volume_info.password freed at unmount */ 1976 /* volume_info.password freed at unmount */
1908 if (volume_info.password) 1977 if (volume_info.password)
1909 pSesInfo->password = volume_info.password; 1978 pSesInfo->password = volume_info.password;
1910 if (volume_info.username) 1979 if (volume_info.username)
1911 strncpy(pSesInfo->userName, 1980 strncpy(pSesInfo->userName,
1912 volume_info.username,MAX_USERNAME_SIZE); 1981 volume_info.username,
1982 MAX_USERNAME_SIZE);
1913 if (volume_info.domainname) { 1983 if (volume_info.domainname) {
1914 int len = strlen(volume_info.domainname); 1984 int len = strlen(volume_info.domainname);
1915 pSesInfo->domainName = 1985 pSesInfo->domainName =
1916 kmalloc(len + 1, GFP_KERNEL); 1986 kmalloc(len + 1, GFP_KERNEL);
1917 if (pSesInfo->domainName) 1987 if (pSesInfo->domainName)
1918 strcpy(pSesInfo->domainName, 1988 strcpy(pSesInfo->domainName,
@@ -1922,46 +1992,48 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1922 pSesInfo->overrideSecFlg = volume_info.secFlg; 1992 pSesInfo->overrideSecFlg = volume_info.secFlg;
1923 down(&pSesInfo->sesSem); 1993 down(&pSesInfo->sesSem);
1924 /* BB FIXME need to pass vol->secFlgs BB */ 1994 /* BB FIXME need to pass vol->secFlgs BB */
1925 rc = cifs_setup_session(xid,pSesInfo, cifs_sb->local_nls); 1995 rc = cifs_setup_session(xid, pSesInfo,
1996 cifs_sb->local_nls);
1926 up(&pSesInfo->sesSem); 1997 up(&pSesInfo->sesSem);
1927 if (!rc) 1998 if (!rc)
1928 atomic_inc(&srvTcp->socketUseCount); 1999 atomic_inc(&srvTcp->socketUseCount);
1929 } else 2000 } else
1930 kfree(volume_info.password); 2001 kfree(volume_info.password);
1931 } 2002 }
1932 2003
1933 /* search for existing tcon to this server share */ 2004 /* search for existing tcon to this server share */
1934 if (!rc) { 2005 if (!rc) {
1935 if (volume_info.rsize > CIFSMaxBufSize) { 2006 if (volume_info.rsize > CIFSMaxBufSize) {
1936 cERROR(1,("rsize %d too large, using MaxBufSize", 2007 cERROR(1, ("rsize %d too large, using MaxBufSize",
1937 volume_info.rsize)); 2008 volume_info.rsize));
1938 cifs_sb->rsize = CIFSMaxBufSize; 2009 cifs_sb->rsize = CIFSMaxBufSize;
1939 } else if((volume_info.rsize) && (volume_info.rsize <= CIFSMaxBufSize)) 2010 } else if ((volume_info.rsize) &&
2011 (volume_info.rsize <= CIFSMaxBufSize))
1940 cifs_sb->rsize = volume_info.rsize; 2012 cifs_sb->rsize = volume_info.rsize;
1941 else /* default */ 2013 else /* default */
1942 cifs_sb->rsize = CIFSMaxBufSize; 2014 cifs_sb->rsize = CIFSMaxBufSize;
1943 2015
1944 if (volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) { 2016 if (volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
1945 cERROR(1,("wsize %d too large using 4096 instead", 2017 cERROR(1, ("wsize %d too large, using 4096 instead",
1946 volume_info.wsize)); 2018 volume_info.wsize));
1947 cifs_sb->wsize = 4096; 2019 cifs_sb->wsize = 4096;
1948 } else if (volume_info.wsize) 2020 } else if (volume_info.wsize)
1949 cifs_sb->wsize = volume_info.wsize; 2021 cifs_sb->wsize = volume_info.wsize;
1950 else 2022 else
1951 cifs_sb->wsize = 2023 cifs_sb->wsize =
1952 min_t(const int, PAGEVEC_SIZE * PAGE_CACHE_SIZE, 2024 min_t(const int, PAGEVEC_SIZE * PAGE_CACHE_SIZE,
1953 127*1024); 2025 127*1024);
1954 /* old default of CIFSMaxBufSize was too small now 2026 /* old default of CIFSMaxBufSize was too small now
1955 that SMB Write2 can send multiple pages in kvec. 2027 that SMB Write2 can send multiple pages in kvec.
1956 RFC1001 does not describe what happens when frame 2028 RFC1001 does not describe what happens when frame
1957 bigger than 128K is sent so use that as max in 2029 bigger than 128K is sent so use that as max in
1958 conjunction with 52K kvec constraint on arch with 4K 2030 conjunction with 52K kvec constraint on arch with 4K
1959 page size */ 2031 page size */
1960 2032
1961 if (cifs_sb->rsize < 2048) { 2033 if (cifs_sb->rsize < 2048) {
1962 cifs_sb->rsize = 2048; 2034 cifs_sb->rsize = 2048;
1963 /* Windows ME may prefer this */ 2035 /* Windows ME may prefer this */
1964 cFYI(1,("readsize set to minimum 2048")); 2036 cFYI(1, ("readsize set to minimum: 2048"));
1965 } 2037 }
1966 /* calculate prepath */ 2038 /* calculate prepath */
1967 cifs_sb->prepath = volume_info.prepath; 2039 cifs_sb->prepath = volume_info.prepath;
@@ -1969,14 +2041,14 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1969 cifs_sb->prepathlen = strlen(cifs_sb->prepath); 2041 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
1970 cifs_sb->prepath[0] = CIFS_DIR_SEP(cifs_sb); 2042 cifs_sb->prepath[0] = CIFS_DIR_SEP(cifs_sb);
1971 volume_info.prepath = NULL; 2043 volume_info.prepath = NULL;
1972 } else 2044 } else
1973 cifs_sb->prepathlen = 0; 2045 cifs_sb->prepathlen = 0;
1974 cifs_sb->mnt_uid = volume_info.linux_uid; 2046 cifs_sb->mnt_uid = volume_info.linux_uid;
1975 cifs_sb->mnt_gid = volume_info.linux_gid; 2047 cifs_sb->mnt_gid = volume_info.linux_gid;
1976 cifs_sb->mnt_file_mode = volume_info.file_mode; 2048 cifs_sb->mnt_file_mode = volume_info.file_mode;
1977 cifs_sb->mnt_dir_mode = volume_info.dir_mode; 2049 cifs_sb->mnt_dir_mode = volume_info.dir_mode;
1978 cFYI(1,("file mode: 0x%x dir mode: 0x%x", 2050 cFYI(1, ("file mode: 0x%x dir mode: 0x%x",
1979 cifs_sb->mnt_file_mode,cifs_sb->mnt_dir_mode)); 2051 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode));
1980 2052
1981 if (volume_info.noperm) 2053 if (volume_info.noperm)
1982 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM; 2054 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
@@ -1999,7 +2071,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1999 if (volume_info.override_gid) 2071 if (volume_info.override_gid)
2000 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID; 2072 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
2001 if (volume_info.direct_io) { 2073 if (volume_info.direct_io) {
2002 cFYI(1,("mounting share using direct i/o")); 2074 cFYI(1, ("mounting share using direct i/o"));
2003 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; 2075 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
2004 } 2076 }
2005 2077
@@ -2010,7 +2082,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2010 cFYI(1, ("Found match on UNC path")); 2082 cFYI(1, ("Found match on UNC path"));
2011 /* we can have only one retry value for a connection 2083 /* we can have only one retry value for a connection
2012 to a share so for resources mounted more than once 2084 to a share so for resources mounted more than once
2013 to the same server share the last value passed in 2085 to the same server share the last value passed in
2014 for the retry flag is used */ 2086 for the retry flag is used */
2015 tcon->retry = volume_info.retry; 2087 tcon->retry = volume_info.retry;
2016 tcon->nocase = volume_info.nocase; 2088 tcon->nocase = volume_info.nocase;
@@ -2019,17 +2091,17 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2019 if (tcon == NULL) 2091 if (tcon == NULL)
2020 rc = -ENOMEM; 2092 rc = -ENOMEM;
2021 else { 2093 else {
2022 /* check for null share name ie connecting to 2094 /* check for null share name ie connecting to
2023 * dfs root */ 2095 * dfs root */
2024 2096
2025 /* BB check if this works for exactly length 2097 /* BB check if this works for exactly length
2026 * three strings */ 2098 * three strings */
2027 if ((strchr(volume_info.UNC + 3, '\\') == NULL) 2099 if ((strchr(volume_info.UNC + 3, '\\') == NULL)
2028 && (strchr(volume_info.UNC + 3, '/') == 2100 && (strchr(volume_info.UNC + 3, '/') ==
2029 NULL)) { 2101 NULL)) {
2030 rc = connect_to_dfs_path(xid, pSesInfo, 2102 rc = connect_to_dfs_path(xid, pSesInfo,
2031 "", cifs_sb->local_nls, 2103 "", cifs_sb->local_nls,
2032 cifs_sb->mnt_cifs_flags & 2104 cifs_sb->mnt_cifs_flags &
2033 CIFS_MOUNT_MAP_SPECIAL_CHR); 2105 CIFS_MOUNT_MAP_SPECIAL_CHR);
2034 kfree(volume_info.UNC); 2106 kfree(volume_info.UNC);
2035 FreeXid(xid); 2107 FreeXid(xid);
@@ -2038,7 +2110,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2038 /* BB Do we need to wrap sesSem around 2110 /* BB Do we need to wrap sesSem around
2039 * this TCon call and Unix SetFS as 2111 * this TCon call and Unix SetFS as
2040 * we do on SessSetup and reconnect? */ 2112 * we do on SessSetup and reconnect? */
2041 rc = CIFSTCon(xid, pSesInfo, 2113 rc = CIFSTCon(xid, pSesInfo,
2042 volume_info.UNC, 2114 volume_info.UNC,
2043 tcon, cifs_sb->local_nls); 2115 tcon, cifs_sb->local_nls);
2044 cFYI(1, ("CIFS Tcon rc = %d", rc)); 2116 cFYI(1, ("CIFS Tcon rc = %d", rc));
@@ -2075,9 +2147,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2075 always wake up processes blocked in 2147 always wake up processes blocked in
2076 tcp in recv_mesg then we could remove the 2148 tcp in recv_mesg then we could remove the
2077 send_sig call */ 2149 send_sig call */
2078 send_sig(SIGKILL,srvTcp->tsk,1); 2150 force_sig(SIGKILL, srvTcp->tsk);
2079 tsk = srvTcp->tsk; 2151 tsk = srvTcp->tsk;
2080 if(tsk) 2152 if (tsk)
2081 kthread_stop(tsk); 2153 kthread_stop(tsk);
2082 } 2154 }
2083 } 2155 }
@@ -2086,15 +2158,17 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2086 tconInfoFree(tcon); 2158 tconInfoFree(tcon);
2087 if (existingCifsSes == NULL) { 2159 if (existingCifsSes == NULL) {
2088 if (pSesInfo) { 2160 if (pSesInfo) {
2089 if ((pSesInfo->server) && 2161 if ((pSesInfo->server) &&
2090 (pSesInfo->status == CifsGood)) { 2162 (pSesInfo->status == CifsGood)) {
2091 int temp_rc; 2163 int temp_rc;
2092 temp_rc = CIFSSMBLogoff(xid, pSesInfo); 2164 temp_rc = CIFSSMBLogoff(xid, pSesInfo);
2093 /* if the socketUseCount is now zero */ 2165 /* if the socketUseCount is now zero */
2094 if ((temp_rc == -ESHUTDOWN) && 2166 if ((temp_rc == -ESHUTDOWN) &&
2095 (pSesInfo->server) && (pSesInfo->server->tsk)) { 2167 (pSesInfo->server) &&
2168 (pSesInfo->server->tsk)) {
2096 struct task_struct *tsk; 2169 struct task_struct *tsk;
2097 send_sig(SIGKILL,pSesInfo->server->tsk,1); 2170 force_sig(SIGKILL,
2171 pSesInfo->server->tsk);
2098 tsk = pSesInfo->server->tsk; 2172 tsk = pSesInfo->server->tsk;
2099 if (tsk) 2173 if (tsk)
2100 kthread_stop(tsk); 2174 kthread_stop(tsk);
@@ -2113,19 +2187,29 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2113 /* do not care if following two calls succeed - informational */ 2187 /* do not care if following two calls succeed - informational */
2114 CIFSSMBQFSDeviceInfo(xid, tcon); 2188 CIFSSMBQFSDeviceInfo(xid, tcon);
2115 CIFSSMBQFSAttributeInfo(xid, tcon); 2189 CIFSSMBQFSAttributeInfo(xid, tcon);
2116 2190
2117 /* tell server which Unix caps we support */ 2191 /* tell server which Unix caps we support */
2118 if (tcon->ses->capabilities & CAP_UNIX) 2192 if (tcon->ses->capabilities & CAP_UNIX)
2193 /* reset of caps checks mount to see if unix extensions
2194 disabled for just this mount */
2119 reset_cifs_unix_caps(xid, tcon, sb, &volume_info); 2195 reset_cifs_unix_caps(xid, tcon, sb, &volume_info);
2120 2196 else
2197 tcon->unix_ext = 0; /* server does not support them */
2198
2199 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
2200 cifs_sb->rsize = 1024 * 127;
2201#ifdef CONFIG_CIFS_DEBUG2
2202 cFYI(1, ("no very large read support, rsize now 127K"));
2203#endif
2204 }
2121 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X)) 2205 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
2122 cifs_sb->wsize = min(cifs_sb->wsize, 2206 cifs_sb->wsize = min(cifs_sb->wsize,
2123 (tcon->ses->server->maxBuf - 2207 (tcon->ses->server->maxBuf -
2124 MAX_CIFS_HDR_SIZE)); 2208 MAX_CIFS_HDR_SIZE));
2125 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X)) 2209 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
2126 cifs_sb->rsize = min(cifs_sb->rsize, 2210 cifs_sb->rsize = min(cifs_sb->rsize,
2127 (tcon->ses->server->maxBuf - 2211 (tcon->ses->server->maxBuf -
2128 MAX_CIFS_HDR_SIZE)); 2212 MAX_CIFS_HDR_SIZE));
2129 } 2213 }
2130 2214
2131 /* volume_info.password is freed above when existing session found 2215 /* volume_info.password is freed above when existing session found
@@ -2178,7 +2262,8 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2178 pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); 2262 pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2179 pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq); 2263 pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2180 2264
2181 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 2265 if (ses->server->secMode &
2266 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2182 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 2267 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2183 2268
2184 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS | 2269 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
@@ -2197,7 +2282,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2197 } 2282 }
2198 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities); 2283 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
2199 2284
2200 pSMB->req_no_secext.CaseInsensitivePasswordLength = 2285 pSMB->req_no_secext.CaseInsensitivePasswordLength =
2201 cpu_to_le16(CIFS_SESS_KEY_SIZE); 2286 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2202 2287
2203 pSMB->req_no_secext.CaseSensitivePasswordLength = 2288 pSMB->req_no_secext.CaseSensitivePasswordLength =
@@ -2215,9 +2300,9 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2215 } 2300 }
2216 if (user == NULL) 2301 if (user == NULL)
2217 bytes_returned = 0; /* skip null user */ 2302 bytes_returned = 0; /* skip null user */
2218 else 2303 else
2219 bytes_returned = 2304 bytes_returned =
2220 cifs_strtoUCS((__le16 *) bcc_ptr, user, 100, 2305 cifs_strtoUCS((__le16 *) bcc_ptr, user, 100,
2221 nls_codepage); 2306 nls_codepage);
2222 /* convert number of 16 bit words to bytes */ 2307 /* convert number of 16 bit words to bytes */
2223 bcc_ptr += 2 * bytes_returned; 2308 bcc_ptr += 2 * bytes_returned;
@@ -2247,7 +2332,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2247 bcc_ptr += 2 * bytes_returned; 2332 bcc_ptr += 2 * bytes_returned;
2248 bcc_ptr += 2; 2333 bcc_ptr += 2;
2249 } else { 2334 } else {
2250 if (user != NULL) { 2335 if (user != NULL) {
2251 strncpy(bcc_ptr, user, 200); 2336 strncpy(bcc_ptr, user, 200);
2252 bcc_ptr += strnlen(user, 200); 2337 bcc_ptr += strnlen(user, 200);
2253 } 2338 }
@@ -2282,11 +2367,12 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2282 __u16 action = le16_to_cpu(pSMBr->resp.Action); 2367 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2283 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength); 2368 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2284 if (action & GUEST_LOGIN) 2369 if (action & GUEST_LOGIN)
2285 cFYI(1, (" Guest login")); /* do we want to mark SesInfo struct ? */ 2370 cFYI(1, (" Guest login")); /* BB mark SesInfo struct? */
2286 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format (le) */ 2371 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format
2372 (little endian) */
2287 cFYI(1, ("UID = %d ", ses->Suid)); 2373 cFYI(1, ("UID = %d ", ses->Suid));
2288 /* response can have either 3 or 4 word count - Samba sends 3 */ 2374 /* response can have either 3 or 4 word count - Samba sends 3 */
2289 bcc_ptr = pByteArea(smb_buffer_response); 2375 bcc_ptr = pByteArea(smb_buffer_response);
2290 if ((pSMBr->resp.hdr.WordCount == 3) 2376 if ((pSMBr->resp.hdr.WordCount == 3)
2291 || ((pSMBr->resp.hdr.WordCount == 4) 2377 || ((pSMBr->resp.hdr.WordCount == 4)
2292 && (blob_len < pSMBr->resp.ByteCount))) { 2378 && (blob_len < pSMBr->resp.ByteCount))) {
@@ -2296,8 +2382,10 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2296 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) { 2382 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2297 if ((long) (bcc_ptr) % 2) { 2383 if ((long) (bcc_ptr) % 2) {
2298 remaining_words = 2384 remaining_words =
2299 (BCC(smb_buffer_response) - 1) /2; 2385 (BCC(smb_buffer_response) - 1) / 2;
2300 bcc_ptr++; /* Unicode strings must be word aligned */ 2386 /* Unicode strings must be word
2387 aligned */
2388 bcc_ptr++;
2301 } else { 2389 } else {
2302 remaining_words = 2390 remaining_words =
2303 BCC(smb_buffer_response) / 2; 2391 BCC(smb_buffer_response) / 2;
@@ -2308,13 +2396,15 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2308/* We look for obvious messed up bcc or strings in response so we do not go off 2396/* We look for obvious messed up bcc or strings in response so we do not go off
2309 the end since (at least) WIN2K and Windows XP have a major bug in not null 2397 the end since (at least) WIN2K and Windows XP have a major bug in not null
2310 terminating last Unicode string in response */ 2398 terminating last Unicode string in response */
2311 if(ses->serverOS) 2399 if (ses->serverOS)
2312 kfree(ses->serverOS); 2400 kfree(ses->serverOS);
2313 ses->serverOS = kzalloc(2 * (len + 1), GFP_KERNEL); 2401 ses->serverOS = kzalloc(2 * (len + 1),
2314 if(ses->serverOS == NULL) 2402 GFP_KERNEL);
2403 if (ses->serverOS == NULL)
2315 goto sesssetup_nomem; 2404 goto sesssetup_nomem;
2316 cifs_strfromUCS_le(ses->serverOS, 2405 cifs_strfromUCS_le(ses->serverOS,
2317 (__le16 *)bcc_ptr, len,nls_codepage); 2406 (__le16 *)bcc_ptr,
2407 len, nls_codepage);
2318 bcc_ptr += 2 * (len + 1); 2408 bcc_ptr += 2 * (len + 1);
2319 remaining_words -= len + 1; 2409 remaining_words -= len + 1;
2320 ses->serverOS[2 * len] = 0; 2410 ses->serverOS[2 * len] = 0;
@@ -2323,42 +2413,49 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2323 len = UniStrnlen((wchar_t *)bcc_ptr, 2413 len = UniStrnlen((wchar_t *)bcc_ptr,
2324 remaining_words-1); 2414 remaining_words-1);
2325 kfree(ses->serverNOS); 2415 kfree(ses->serverNOS);
2326 ses->serverNOS = kzalloc(2 * (len + 1),GFP_KERNEL); 2416 ses->serverNOS = kzalloc(2 * (len + 1),
2327 if(ses->serverNOS == NULL) 2417 GFP_KERNEL);
2418 if (ses->serverNOS == NULL)
2328 goto sesssetup_nomem; 2419 goto sesssetup_nomem;
2329 cifs_strfromUCS_le(ses->serverNOS, 2420 cifs_strfromUCS_le(ses->serverNOS,
2330 (__le16 *)bcc_ptr,len,nls_codepage); 2421 (__le16 *)bcc_ptr,
2422 len, nls_codepage);
2331 bcc_ptr += 2 * (len + 1); 2423 bcc_ptr += 2 * (len + 1);
2332 ses->serverNOS[2 * len] = 0; 2424 ses->serverNOS[2 * len] = 0;
2333 ses->serverNOS[1 + (2 * len)] = 0; 2425 ses->serverNOS[1 + (2 * len)] = 0;
2334 if(strncmp(ses->serverNOS, 2426 if (strncmp(ses->serverNOS,
2335 "NT LAN Manager 4",16) == 0) { 2427 "NT LAN Manager 4", 16) == 0) {
2336 cFYI(1,("NT4 server")); 2428 cFYI(1, ("NT4 server"));
2337 ses->flags |= CIFS_SES_NT4; 2429 ses->flags |= CIFS_SES_NT4;
2338 } 2430 }
2339 remaining_words -= len + 1; 2431 remaining_words -= len + 1;
2340 if (remaining_words > 0) { 2432 if (remaining_words > 0) {
2341 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); 2433 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2342 /* last string is not always null terminated (for e.g. for Windows XP & 2000) */ 2434 /* last string is not always null terminated
2343 if(ses->serverDomain) 2435 (for e.g. for Windows XP & 2000) */
2436 if (ses->serverDomain)
2344 kfree(ses->serverDomain); 2437 kfree(ses->serverDomain);
2345 ses->serverDomain = 2438 ses->serverDomain =
2346 kzalloc(2*(len+1),GFP_KERNEL); 2439 kzalloc(2*(len+1),
2347 if(ses->serverDomain == NULL) 2440 GFP_KERNEL);
2441 if (ses->serverDomain == NULL)
2348 goto sesssetup_nomem; 2442 goto sesssetup_nomem;
2349 cifs_strfromUCS_le(ses->serverDomain, 2443 cifs_strfromUCS_le(ses->serverDomain,
2350 (__le16 *)bcc_ptr,len,nls_codepage); 2444 (__le16 *)bcc_ptr,
2445 len, nls_codepage);
2351 bcc_ptr += 2 * (len + 1); 2446 bcc_ptr += 2 * (len + 1);
2352 ses->serverDomain[2*len] = 0; 2447 ses->serverDomain[2*len] = 0;
2353 ses->serverDomain[1+(2*len)] = 0; 2448 ses->serverDomain[1+(2*len)] = 0;
2354 } /* else no more room so create dummy domain string */ 2449 } else { /* else no more room so create
2355 else { 2450 dummy domain string */
2356 if(ses->serverDomain) 2451 if (ses->serverDomain)
2357 kfree(ses->serverDomain); 2452 kfree(ses->serverDomain);
2358 ses->serverDomain = 2453 ses->serverDomain =
2359 kzalloc(2, GFP_KERNEL); 2454 kzalloc(2, GFP_KERNEL);
2360 } 2455 }
2361 } else { /* no room so create dummy domain and NOS string */ 2456 } else { /* no room so create dummy domain
2457 and NOS string */
2458
2362 /* if these kcallocs fail not much we 2459 /* if these kcallocs fail not much we
2363 can do, but better to not fail the 2460 can do, but better to not fail the
2364 sesssetup itself */ 2461 sesssetup itself */
@@ -2375,19 +2472,22 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2375 pByteArea(smb_buffer_response) 2472 pByteArea(smb_buffer_response)
2376 <= BCC(smb_buffer_response)) { 2473 <= BCC(smb_buffer_response)) {
2377 kfree(ses->serverOS); 2474 kfree(ses->serverOS);
2378 ses->serverOS = kzalloc(len + 1,GFP_KERNEL); 2475 ses->serverOS = kzalloc(len + 1,
2379 if(ses->serverOS == NULL) 2476 GFP_KERNEL);
2477 if (ses->serverOS == NULL)
2380 goto sesssetup_nomem; 2478 goto sesssetup_nomem;
2381 strncpy(ses->serverOS,bcc_ptr, len); 2479 strncpy(ses->serverOS, bcc_ptr, len);
2382 2480
2383 bcc_ptr += len; 2481 bcc_ptr += len;
2384 bcc_ptr[0] = 0; /* null terminate the string */ 2482 /* null terminate the string */
2483 bcc_ptr[0] = 0;
2385 bcc_ptr++; 2484 bcc_ptr++;
2386 2485
2387 len = strnlen(bcc_ptr, 1024); 2486 len = strnlen(bcc_ptr, 1024);
2388 kfree(ses->serverNOS); 2487 kfree(ses->serverNOS);
2389 ses->serverNOS = kzalloc(len + 1,GFP_KERNEL); 2488 ses->serverNOS = kzalloc(len + 1,
2390 if(ses->serverNOS == NULL) 2489 GFP_KERNEL);
2490 if (ses->serverNOS == NULL)
2391 goto sesssetup_nomem; 2491 goto sesssetup_nomem;
2392 strncpy(ses->serverNOS, bcc_ptr, len); 2492 strncpy(ses->serverNOS, bcc_ptr, len);
2393 bcc_ptr += len; 2493 bcc_ptr += len;
@@ -2395,23 +2495,27 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2395 bcc_ptr++; 2495 bcc_ptr++;
2396 2496
2397 len = strnlen(bcc_ptr, 1024); 2497 len = strnlen(bcc_ptr, 1024);
2398 if(ses->serverDomain) 2498 if (ses->serverDomain)
2399 kfree(ses->serverDomain); 2499 kfree(ses->serverDomain);
2400 ses->serverDomain = kzalloc(len + 1,GFP_KERNEL); 2500 ses->serverDomain = kzalloc(len + 1,
2401 if(ses->serverDomain == NULL) 2501 GFP_KERNEL);
2502 if (ses->serverDomain == NULL)
2402 goto sesssetup_nomem; 2503 goto sesssetup_nomem;
2403 strncpy(ses->serverDomain, bcc_ptr, len); 2504 strncpy(ses->serverDomain, bcc_ptr,
2505 len);
2404 bcc_ptr += len; 2506 bcc_ptr += len;
2405 bcc_ptr[0] = 0; 2507 bcc_ptr[0] = 0;
2406 bcc_ptr++; 2508 bcc_ptr++;
2407 } else 2509 } else
2408 cFYI(1, 2510 cFYI(1,
2409 ("Variable field of length %d extends beyond end of smb ", 2511 ("Variable field of length %d "
2512 "extends beyond end of smb ",
2410 len)); 2513 len));
2411 } 2514 }
2412 } else { 2515 } else {
2413 cERROR(1, 2516 cERROR(1,
2414 (" Security Blob Length extends beyond end of SMB")); 2517 (" Security Blob Length extends beyond "
2518 "end of SMB"));
2415 } 2519 }
2416 } else { 2520 } else {
2417 cERROR(1, 2521 cERROR(1,
@@ -2430,7 +2534,7 @@ sesssetup_nomem: /* do not return an error on nomem for the info strings,
2430 2534
2431static int 2535static int
2432CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, 2536CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2433 struct cifsSesInfo *ses, int * pNTLMv2_flag, 2537 struct cifsSesInfo *ses, int *pNTLMv2_flag,
2434 const struct nls_table *nls_codepage) 2538 const struct nls_table *nls_codepage)
2435{ 2539{
2436 struct smb_hdr *smb_buffer; 2540 struct smb_hdr *smb_buffer;
@@ -2450,7 +2554,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2450 __u16 count; 2554 __u16 count;
2451 2555
2452 cFYI(1, ("In NTLMSSP sesssetup (negotiate)")); 2556 cFYI(1, ("In NTLMSSP sesssetup (negotiate)"));
2453 if(ses == NULL) 2557 if (ses == NULL)
2454 return -EINVAL; 2558 return -EINVAL;
2455 domain = ses->domainName; 2559 domain = ses->domainName;
2456 *pNTLMv2_flag = FALSE; 2560 *pNTLMv2_flag = FALSE;
@@ -2474,7 +2578,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2474 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); 2578 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2475 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq); 2579 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2476 2580
2477 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 2581 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2478 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 2582 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2479 2583
2480 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS | 2584 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
@@ -2502,9 +2606,9 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2502 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM | 2606 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM |
2503 NTLMSSP_NEGOTIATE_56 | 2607 NTLMSSP_NEGOTIATE_56 |
2504 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128; 2608 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128;
2505 if(sign_CIFS_PDUs) 2609 if (sign_CIFS_PDUs)
2506 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN; 2610 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN;
2507/* if(ntlmv2_support) 2611/* if (ntlmv2_support)
2508 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;*/ 2612 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;*/
2509 /* setup pointers to domain name and workstation name */ 2613 /* setup pointers to domain name and workstation name */
2510 bcc_ptr += SecurityBlobLength; 2614 bcc_ptr += SecurityBlobLength;
@@ -2574,11 +2678,11 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2574 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength); 2678 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2575 2679
2576 if (action & GUEST_LOGIN) 2680 if (action & GUEST_LOGIN)
2577 cFYI(1, (" Guest login")); 2681 cFYI(1, (" Guest login"));
2578 /* Do we want to set anything in SesInfo struct when guest login? */ 2682 /* Do we want to set anything in SesInfo struct when guest login? */
2579 2683
2580 bcc_ptr = pByteArea(smb_buffer_response); 2684 bcc_ptr = pByteArea(smb_buffer_response);
2581 /* response can have either 3 or 4 word count - Samba sends 3 */ 2685 /* response can have either 3 or 4 word count - Samba sends 3 */
2582 2686
2583 SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr; 2687 SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr;
2584 if (SecurityBlob2->MessageType != NtLmChallenge) { 2688 if (SecurityBlob2->MessageType != NtLmChallenge) {
@@ -2586,7 +2690,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2586 ("Unexpected NTLMSSP message type received %d", 2690 ("Unexpected NTLMSSP message type received %d",
2587 SecurityBlob2->MessageType)); 2691 SecurityBlob2->MessageType));
2588 } else if (ses) { 2692 } else if (ses) {
2589 ses->Suid = smb_buffer_response->Uid; /* UID left in le format */ 2693 ses->Suid = smb_buffer_response->Uid; /* UID left in le format */
2590 cFYI(1, ("UID = %d", ses->Suid)); 2694 cFYI(1, ("UID = %d", ses->Suid));
2591 if ((pSMBr->resp.hdr.WordCount == 3) 2695 if ((pSMBr->resp.hdr.WordCount == 3)
2592 || ((pSMBr->resp.hdr.WordCount == 4) 2696 || ((pSMBr->resp.hdr.WordCount == 4)
@@ -2604,18 +2708,18 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2604 memcpy(ses->server->cryptKey, 2708 memcpy(ses->server->cryptKey,
2605 SecurityBlob2->Challenge, 2709 SecurityBlob2->Challenge,
2606 CIFS_CRYPTO_KEY_SIZE); 2710 CIFS_CRYPTO_KEY_SIZE);
2607 if(SecurityBlob2->NegotiateFlags & 2711 if (SecurityBlob2->NegotiateFlags &
2608 cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2)) 2712 cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
2609 *pNTLMv2_flag = TRUE; 2713 *pNTLMv2_flag = TRUE;
2610 2714
2611 if((SecurityBlob2->NegotiateFlags & 2715 if ((SecurityBlob2->NegotiateFlags &
2612 cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) 2716 cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN))
2613 || (sign_CIFS_PDUs > 1)) 2717 || (sign_CIFS_PDUs > 1))
2614 ses->server->secMode |= 2718 ses->server->secMode |=
2615 SECMODE_SIGN_REQUIRED; 2719 SECMODE_SIGN_REQUIRED;
2616 if ((SecurityBlob2->NegotiateFlags & 2720 if ((SecurityBlob2->NegotiateFlags &
2617 cpu_to_le32(NTLMSSP_NEGOTIATE_SIGN)) && (sign_CIFS_PDUs)) 2721 cpu_to_le32(NTLMSSP_NEGOTIATE_SIGN)) && (sign_CIFS_PDUs))
2618 ses->server->secMode |= 2722 ses->server->secMode |=
2619 SECMODE_SIGN_ENABLED; 2723 SECMODE_SIGN_ENABLED;
2620 2724
2621 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) { 2725 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
@@ -2623,7 +2727,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2623 remaining_words = 2727 remaining_words =
2624 (BCC(smb_buffer_response) 2728 (BCC(smb_buffer_response)
2625 - 1) / 2; 2729 - 1) / 2;
2626 bcc_ptr++; /* Unicode strings must be word aligned */ 2730 /* Must word align unicode strings */
2731 bcc_ptr++;
2627 } else { 2732 } else {
2628 remaining_words = 2733 remaining_words =
2629 BCC 2734 BCC
@@ -2635,7 +2740,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2635/* We look for obvious messed up bcc or strings in response so we do not go off 2740/* We look for obvious messed up bcc or strings in response so we do not go off
2636 the end since (at least) WIN2K and Windows XP have a major bug in not null 2741 the end since (at least) WIN2K and Windows XP have a major bug in not null
2637 terminating last Unicode string in response */ 2742 terminating last Unicode string in response */
2638 if(ses->serverOS) 2743 if (ses->serverOS)
2639 kfree(ses->serverOS); 2744 kfree(ses->serverOS);
2640 ses->serverOS = 2745 ses->serverOS =
2641 kzalloc(2 * (len + 1), GFP_KERNEL); 2746 kzalloc(2 * (len + 1), GFP_KERNEL);
@@ -2668,8 +2773,9 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2668 (2 * len)] = 0; 2773 (2 * len)] = 0;
2669 remaining_words -= len + 1; 2774 remaining_words -= len + 1;
2670 if (remaining_words > 0) { 2775 if (remaining_words > 0) {
2671 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); 2776 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2672 /* last string is not always null terminated (for e.g. for Windows XP & 2000) */ 2777 /* last string not always null terminated
2778 (for e.g. for Windows XP & 2000) */
2673 kfree(ses->serverDomain); 2779 kfree(ses->serverDomain);
2674 ses->serverDomain = 2780 ses->serverDomain =
2675 kzalloc(2 * 2781 kzalloc(2 *
@@ -2707,7 +2813,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2707 if (((long) bcc_ptr + len) - (long) 2813 if (((long) bcc_ptr + len) - (long)
2708 pByteArea(smb_buffer_response) 2814 pByteArea(smb_buffer_response)
2709 <= BCC(smb_buffer_response)) { 2815 <= BCC(smb_buffer_response)) {
2710 if(ses->serverOS) 2816 if (ses->serverOS)
2711 kfree(ses->serverOS); 2817 kfree(ses->serverOS);
2712 ses->serverOS = 2818 ses->serverOS =
2713 kzalloc(len + 1, 2819 kzalloc(len + 1,
@@ -2734,18 +2840,20 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2734 ses->serverDomain = 2840 ses->serverDomain =
2735 kzalloc(len + 1, 2841 kzalloc(len + 1,
2736 GFP_KERNEL); 2842 GFP_KERNEL);
2737 strncpy(ses->serverDomain, bcc_ptr, len); 2843 strncpy(ses->serverDomain,
2844 bcc_ptr, len);
2738 bcc_ptr += len; 2845 bcc_ptr += len;
2739 bcc_ptr[0] = 0; 2846 bcc_ptr[0] = 0;
2740 bcc_ptr++; 2847 bcc_ptr++;
2741 } else 2848 } else
2742 cFYI(1, 2849 cFYI(1,
2743 ("Variable field of length %d extends beyond end of smb", 2850 ("field of length %d "
2851 "extends beyond end of smb",
2744 len)); 2852 len));
2745 } 2853 }
2746 } else { 2854 } else {
2747 cERROR(1, 2855 cERROR(1, ("Security Blob Length extends beyond"
2748 (" Security Blob Length extends beyond end of SMB")); 2856 " end of SMB"));
2749 } 2857 }
2750 } else { 2858 } else {
2751 cERROR(1, ("No session structure passed in.")); 2859 cERROR(1, ("No session structure passed in."));
@@ -2784,7 +2892,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2784 __u16 count; 2892 __u16 count;
2785 2893
2786 cFYI(1, ("In NTLMSSPSessSetup (Authenticate)")); 2894 cFYI(1, ("In NTLMSSPSessSetup (Authenticate)"));
2787 if(ses == NULL) 2895 if (ses == NULL)
2788 return -EINVAL; 2896 return -EINVAL;
2789 user = ses->userName; 2897 user = ses->userName;
2790 domain = ses->domainName; 2898 domain = ses->domainName;
@@ -2809,7 +2917,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2809 2917
2810 pSMB->req.hdr.Uid = ses->Suid; 2918 pSMB->req.hdr.Uid = ses->Suid;
2811 2919
2812 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 2920 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2813 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 2921 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2814 2922
2815 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS | 2923 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
@@ -2833,13 +2941,13 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2833 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8); 2941 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2834 SecurityBlob->MessageType = NtLmAuthenticate; 2942 SecurityBlob->MessageType = NtLmAuthenticate;
2835 bcc_ptr += SecurityBlobLength; 2943 bcc_ptr += SecurityBlobLength;
2836 negotiate_flags = 2944 negotiate_flags =
2837 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET | 2945 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
2838 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO | 2946 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
2839 0x80000000 | NTLMSSP_NEGOTIATE_128; 2947 0x80000000 | NTLMSSP_NEGOTIATE_128;
2840 if(sign_CIFS_PDUs) 2948 if (sign_CIFS_PDUs)
2841 negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN; 2949 negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
2842 if(ntlmv2_flag) 2950 if (ntlmv2_flag)
2843 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2; 2951 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;
2844 2952
2845/* setup pointers to domain name and workstation name */ 2953/* setup pointers to domain name and workstation name */
@@ -2903,13 +3011,17 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2903 cpu_to_le16(len); 3011 cpu_to_le16(len);
2904 } 3012 }
2905 3013
2906 /* SecurityBlob->WorkstationName.Length = cifs_strtoUCS((__le16 *) bcc_ptr, "AMACHINE",64, nls_codepage); 3014 /* SecurityBlob->WorkstationName.Length =
3015 cifs_strtoUCS((__le16 *) bcc_ptr, "AMACHINE",64, nls_codepage);
2907 SecurityBlob->WorkstationName.Length *= 2; 3016 SecurityBlob->WorkstationName.Length *= 2;
2908 SecurityBlob->WorkstationName.MaximumLength = cpu_to_le16(SecurityBlob->WorkstationName.Length); 3017 SecurityBlob->WorkstationName.MaximumLength =
2909 SecurityBlob->WorkstationName.Buffer = cpu_to_le32(SecurityBlobLength); 3018 cpu_to_le16(SecurityBlob->WorkstationName.Length);
3019 SecurityBlob->WorkstationName.Buffer =
3020 cpu_to_le32(SecurityBlobLength);
2910 bcc_ptr += SecurityBlob->WorkstationName.Length; 3021 bcc_ptr += SecurityBlob->WorkstationName.Length;
2911 SecurityBlobLength += SecurityBlob->WorkstationName.Length; 3022 SecurityBlobLength += SecurityBlob->WorkstationName.Length;
2912 SecurityBlob->WorkstationName.Length = cpu_to_le16(SecurityBlob->WorkstationName.Length); */ 3023 SecurityBlob->WorkstationName.Length =
3024 cpu_to_le16(SecurityBlob->WorkstationName.Length); */
2913 3025
2914 if ((long) bcc_ptr % 2) { 3026 if ((long) bcc_ptr % 2) {
2915 *bcc_ptr = 0; 3027 *bcc_ptr = 0;
@@ -2995,17 +3107,20 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2995 __u16 blob_len = 3107 __u16 blob_len =
2996 le16_to_cpu(pSMBr->resp.SecurityBlobLength); 3108 le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2997 if (action & GUEST_LOGIN) 3109 if (action & GUEST_LOGIN)
2998 cFYI(1, (" Guest login")); /* BB do we want to set anything in SesInfo struct ? */ 3110 cFYI(1, (" Guest login")); /* BB Should we set anything
2999/* if(SecurityBlob2->MessageType != NtLm??){ 3111 in SesInfo struct ? */
3000 cFYI("Unexpected message type on auth response is %d ")); 3112/* if (SecurityBlob2->MessageType != NtLm??) {
3001 } */ 3113 cFYI("Unexpected message type on auth response is %d"));
3114 } */
3115
3002 if (ses) { 3116 if (ses) {
3003 cFYI(1, 3117 cFYI(1,
3004 ("Does UID on challenge %d match auth response UID %d ", 3118 ("Check challenge UID %d vs auth response UID %d",
3005 ses->Suid, smb_buffer_response->Uid)); 3119 ses->Suid, smb_buffer_response->Uid));
3006 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format */ 3120 /* UID left in wire format */
3007 bcc_ptr = pByteArea(smb_buffer_response); 3121 ses->Suid = smb_buffer_response->Uid;
3008 /* response can have either 3 or 4 word count - Samba sends 3 */ 3122 bcc_ptr = pByteArea(smb_buffer_response);
3123 /* response can have either 3 or 4 word count - Samba sends 3 */
3009 if ((pSMBr->resp.hdr.WordCount == 3) 3124 if ((pSMBr->resp.hdr.WordCount == 3)
3010 || ((pSMBr->resp.hdr.WordCount == 4) 3125 || ((pSMBr->resp.hdr.WordCount == 4)
3011 && (blob_len < 3126 && (blob_len <
@@ -3035,7 +3150,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
3035/* We look for obvious messed up bcc or strings in response so we do not go off 3150/* We look for obvious messed up bcc or strings in response so we do not go off
3036 the end since (at least) WIN2K and Windows XP have a major bug in not null 3151 the end since (at least) WIN2K and Windows XP have a major bug in not null
3037 terminating last Unicode string in response */ 3152 terminating last Unicode string in response */
3038 if(ses->serverOS) 3153 if (ses->serverOS)
3039 kfree(ses->serverOS); 3154 kfree(ses->serverOS);
3040 ses->serverOS = 3155 ses->serverOS =
3041 kzalloc(2 * (len + 1), GFP_KERNEL); 3156 kzalloc(2 * (len + 1), GFP_KERNEL);
@@ -3067,9 +3182,9 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
3067 ses->serverNOS[1+(2*len)] = 0; 3182 ses->serverNOS[1+(2*len)] = 0;
3068 remaining_words -= len + 1; 3183 remaining_words -= len + 1;
3069 if (remaining_words > 0) { 3184 if (remaining_words > 0) {
3070 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); 3185 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
3071 /* last string not always null terminated (e.g. for Windows XP & 2000) */ 3186 /* last string not always null terminated (e.g. for Windows XP & 2000) */
3072 if(ses->serverDomain) 3187 if (ses->serverDomain)
3073 kfree(ses->serverDomain); 3188 kfree(ses->serverDomain);
3074 ses->serverDomain = 3189 ses->serverDomain =
3075 kzalloc(2 * 3190 kzalloc(2 *
@@ -3097,12 +3212,12 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
3097 = 0; 3212 = 0;
3098 } /* else no more room so create dummy domain string */ 3213 } /* else no more room so create dummy domain string */
3099 else { 3214 else {
3100 if(ses->serverDomain) 3215 if (ses->serverDomain)
3101 kfree(ses->serverDomain); 3216 kfree(ses->serverDomain);
3102 ses->serverDomain = kzalloc(2,GFP_KERNEL); 3217 ses->serverDomain = kzalloc(2,GFP_KERNEL);
3103 } 3218 }
3104 } else { /* no room so create dummy domain and NOS string */ 3219 } else { /* no room so create dummy domain and NOS string */
3105 if(ses->serverDomain) 3220 if (ses->serverDomain)
3106 kfree(ses->serverDomain); 3221 kfree(ses->serverDomain);
3107 ses->serverDomain = kzalloc(2, GFP_KERNEL); 3222 ses->serverDomain = kzalloc(2, GFP_KERNEL);
3108 kfree(ses->serverNOS); 3223 kfree(ses->serverNOS);
@@ -3110,10 +3225,10 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
3110 } 3225 }
3111 } else { /* ASCII */ 3226 } else { /* ASCII */
3112 len = strnlen(bcc_ptr, 1024); 3227 len = strnlen(bcc_ptr, 1024);
3113 if (((long) bcc_ptr + len) - 3228 if (((long) bcc_ptr + len) -
3114 (long) pByteArea(smb_buffer_response) 3229 (long) pByteArea(smb_buffer_response)
3115 <= BCC(smb_buffer_response)) { 3230 <= BCC(smb_buffer_response)) {
3116 if(ses->serverOS) 3231 if (ses->serverOS)
3117 kfree(ses->serverOS); 3232 kfree(ses->serverOS);
3118 ses->serverOS = kzalloc(len + 1,GFP_KERNEL); 3233 ses->serverOS = kzalloc(len + 1,GFP_KERNEL);
3119 strncpy(ses->serverOS,bcc_ptr, len); 3234 strncpy(ses->serverOS,bcc_ptr, len);
@@ -3124,28 +3239,35 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
3124 3239
3125 len = strnlen(bcc_ptr, 1024); 3240 len = strnlen(bcc_ptr, 1024);
3126 kfree(ses->serverNOS); 3241 kfree(ses->serverNOS);
3127 ses->serverNOS = kzalloc(len+1,GFP_KERNEL); 3242 ses->serverNOS = kzalloc(len+1,
3128 strncpy(ses->serverNOS, bcc_ptr, len); 3243 GFP_KERNEL);
3244 strncpy(ses->serverNOS,
3245 bcc_ptr, len);
3129 bcc_ptr += len; 3246 bcc_ptr += len;
3130 bcc_ptr[0] = 0; 3247 bcc_ptr[0] = 0;
3131 bcc_ptr++; 3248 bcc_ptr++;
3132 3249
3133 len = strnlen(bcc_ptr, 1024); 3250 len = strnlen(bcc_ptr, 1024);
3134 if(ses->serverDomain) 3251 if (ses->serverDomain)
3135 kfree(ses->serverDomain); 3252 kfree(ses->serverDomain);
3136 ses->serverDomain = kzalloc(len+1,GFP_KERNEL); 3253 ses->serverDomain =
3137 strncpy(ses->serverDomain, bcc_ptr, len); 3254 kzalloc(len+1,
3255 GFP_KERNEL);
3256 strncpy(ses->serverDomain,
3257 bcc_ptr, len);
3138 bcc_ptr += len; 3258 bcc_ptr += len;
3139 bcc_ptr[0] = 0; 3259 bcc_ptr[0] = 0;
3140 bcc_ptr++; 3260 bcc_ptr++;
3141 } else 3261 } else
3142 cFYI(1, 3262 cFYI(1,
3143 ("Variable field of length %d extends beyond end of smb ", 3263 ("field of length %d "
3264 "extends beyond end of smb ",
3144 len)); 3265 len));
3145 } 3266 }
3146 } else { 3267 } else {
3147 cERROR(1, 3268 cERROR(1,
3148 (" Security Blob Length extends beyond end of SMB")); 3269 (" Security Blob extends beyond end "
3270 "of SMB"));
3149 } 3271 }
3150 } else { 3272 } else {
3151 cERROR(1, ("No session structure passed in.")); 3273 cERROR(1, ("No session structure passed in."));
@@ -3197,7 +3319,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3197 pSMB->AndXCommand = 0xFF; 3319 pSMB->AndXCommand = 0xFF;
3198 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO); 3320 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
3199 bcc_ptr = &pSMB->Password[0]; 3321 bcc_ptr = &pSMB->Password[0];
3200 if((ses->server->secMode) & SECMODE_USER) { 3322 if ((ses->server->secMode) & SECMODE_USER) {
3201 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */ 3323 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
3202 *bcc_ptr = 0; /* password is null byte */ 3324 *bcc_ptr = 0; /* password is null byte */
3203 bcc_ptr++; /* skip password */ 3325 bcc_ptr++; /* skip password */
@@ -3211,7 +3333,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3211 by Samba (not sure whether other servers allow 3333 by Samba (not sure whether other servers allow
3212 NTLMv2 password here) */ 3334 NTLMv2 password here) */
3213#ifdef CONFIG_CIFS_WEAK_PW_HASH 3335#ifdef CONFIG_CIFS_WEAK_PW_HASH
3214 if((extended_security & CIFSSEC_MAY_LANMAN) && 3336 if ((extended_security & CIFSSEC_MAY_LANMAN) &&
3215 (ses->server->secType == LANMAN)) 3337 (ses->server->secType == LANMAN))
3216 calc_lanman_hash(ses, bcc_ptr); 3338 calc_lanman_hash(ses, bcc_ptr);
3217 else 3339 else
@@ -3221,14 +3343,14 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3221 bcc_ptr); 3343 bcc_ptr);
3222 3344
3223 bcc_ptr += CIFS_SESS_KEY_SIZE; 3345 bcc_ptr += CIFS_SESS_KEY_SIZE;
3224 if(ses->capabilities & CAP_UNICODE) { 3346 if (ses->capabilities & CAP_UNICODE) {
3225 /* must align unicode strings */ 3347 /* must align unicode strings */
3226 *bcc_ptr = 0; /* null byte password */ 3348 *bcc_ptr = 0; /* null byte password */
3227 bcc_ptr++; 3349 bcc_ptr++;
3228 } 3350 }
3229 } 3351 }
3230 3352
3231 if(ses->server->secMode & 3353 if (ses->server->secMode &
3232 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 3354 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3233 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 3355 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3234 3356
@@ -3241,8 +3363,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3241 if (ses->capabilities & CAP_UNICODE) { 3363 if (ses->capabilities & CAP_UNICODE) {
3242 smb_buffer->Flags2 |= SMBFLG2_UNICODE; 3364 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3243 length = 3365 length =
3244 cifs_strtoUCS((__le16 *) bcc_ptr, tree, 3366 cifs_strtoUCS((__le16 *) bcc_ptr, tree,
3245 6 /* max utf8 char length in bytes */ * 3367 6 /* max utf8 char length in bytes */ *
3246 (/* server len*/ + 256 /* share len */), nls_codepage); 3368 (/* server len*/ + 256 /* share len */), nls_codepage);
3247 bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */ 3369 bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */
3248 bcc_ptr += 2; /* skip trailing null */ 3370 bcc_ptr += 2; /* skip trailing null */
@@ -3266,8 +3388,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3266 tcon->tid = smb_buffer_response->Tid; 3388 tcon->tid = smb_buffer_response->Tid;
3267 bcc_ptr = pByteArea(smb_buffer_response); 3389 bcc_ptr = pByteArea(smb_buffer_response);
3268 length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2); 3390 length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
3269 /* skip service field (NB: this field is always ASCII) */ 3391 /* skip service field (NB: this field is always ASCII) */
3270 bcc_ptr += length + 1; 3392 bcc_ptr += length + 1;
3271 strncpy(tcon->treeName, tree, MAX_TREE_SIZE); 3393 strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
3272 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) { 3394 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3273 length = UniStrnlen((wchar_t *) bcc_ptr, 512); 3395 length = UniStrnlen((wchar_t *) bcc_ptr, 512);
@@ -3285,7 +3407,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3285 bcc_ptr[1] = 0; 3407 bcc_ptr[1] = 0;
3286 bcc_ptr += 2; 3408 bcc_ptr += 2;
3287 } 3409 }
3288 /* else do not bother copying these informational fields */ 3410 /* else do not bother copying these information fields*/
3289 } else { 3411 } else {
3290 length = strnlen(bcc_ptr, 1024); 3412 length = strnlen(bcc_ptr, 1024);
3291 if ((bcc_ptr + length) - 3413 if ((bcc_ptr + length) -
@@ -3297,9 +3419,9 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3297 strncpy(tcon->nativeFileSystem, bcc_ptr, 3419 strncpy(tcon->nativeFileSystem, bcc_ptr,
3298 length); 3420 length);
3299 } 3421 }
3300 /* else do not bother copying these informational fields */ 3422 /* else do not bother copying these information fields*/
3301 } 3423 }
3302 if((smb_buffer_response->WordCount == 3) || 3424 if ((smb_buffer_response->WordCount == 3) ||
3303 (smb_buffer_response->WordCount == 7)) 3425 (smb_buffer_response->WordCount == 7))
3304 /* field is in same location */ 3426 /* field is in same location */
3305 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport); 3427 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
@@ -3307,7 +3429,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3307 tcon->Flags = 0; 3429 tcon->Flags = 0;
3308 cFYI(1, ("Tcon flags: 0x%x ", tcon->Flags)); 3430 cFYI(1, ("Tcon flags: 0x%x ", tcon->Flags));
3309 } else if ((rc == 0) && tcon == NULL) { 3431 } else if ((rc == 0) && tcon == NULL) {
3310 /* all we need to save for IPC$ connection */ 3432 /* all we need to save for IPC$ connection */
3311 ses->ipc_tid = smb_buffer_response->Tid; 3433 ses->ipc_tid = smb_buffer_response->Tid;
3312 } 3434 }
3313 3435
@@ -3323,7 +3445,7 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3323 int xid; 3445 int xid;
3324 struct cifsSesInfo *ses = NULL; 3446 struct cifsSesInfo *ses = NULL;
3325 struct task_struct *cifsd_task; 3447 struct task_struct *cifsd_task;
3326 char * tmp; 3448 char *tmp;
3327 3449
3328 xid = GetXid(); 3450 xid = GetXid();
3329 3451
@@ -3344,9 +3466,9 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3344 FreeXid(xid); 3466 FreeXid(xid);
3345 return 0; 3467 return 0;
3346 } else if (rc == -ESHUTDOWN) { 3468 } else if (rc == -ESHUTDOWN) {
3347 cFYI(1,("Waking up socket by sending it signal")); 3469 cFYI(1, ("Waking up socket by sending signal"));
3348 if (cifsd_task) { 3470 if (cifsd_task) {
3349 send_sig(SIGKILL,cifsd_task,1); 3471 force_sig(SIGKILL, cifsd_task);
3350 kthread_stop(cifsd_task); 3472 kthread_stop(cifsd_task);
3351 } 3473 }
3352 rc = 0; 3474 rc = 0;
@@ -3355,7 +3477,7 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3355 } else 3477 } else
3356 cFYI(1, ("No session or bad tcon")); 3478 cFYI(1, ("No session or bad tcon"));
3357 } 3479 }
3358 3480
3359 cifs_sb->tcon = NULL; 3481 cifs_sb->tcon = NULL;
3360 tmp = cifs_sb->prepath; 3482 tmp = cifs_sb->prepath;
3361 cifs_sb->prepathlen = 0; 3483 cifs_sb->prepathlen = 0;
@@ -3367,11 +3489,11 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3367 sesInfoFree(ses); 3489 sesInfoFree(ses);
3368 3490
3369 FreeXid(xid); 3491 FreeXid(xid);
3370 return rc; /* BB check if we should always return zero here */ 3492 return rc; /* BB check if we should always return zero here */
3371} 3493}
3372 3494
3373int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, 3495int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3374 struct nls_table * nls_info) 3496 struct nls_table *nls_info)
3375{ 3497{
3376 int rc = 0; 3498 int rc = 0;
3377 char ntlm_session_key[CIFS_SESS_KEY_SIZE]; 3499 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
@@ -3379,16 +3501,16 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3379 int first_time = 0; 3501 int first_time = 0;
3380 3502
3381 /* what if server changes its buffer size after dropping the session? */ 3503 /* what if server changes its buffer size after dropping the session? */
3382 if(pSesInfo->server->maxBuf == 0) /* no need to send on reconnect */ { 3504 if (pSesInfo->server->maxBuf == 0) /* no need to send on reconnect */ {
3383 rc = CIFSSMBNegotiate(xid, pSesInfo); 3505 rc = CIFSSMBNegotiate(xid, pSesInfo);
3384 if(rc == -EAGAIN) /* retry only once on 1st time connection */ { 3506 if (rc == -EAGAIN) /* retry only once on 1st time connection */ {
3385 rc = CIFSSMBNegotiate(xid, pSesInfo); 3507 rc = CIFSSMBNegotiate(xid, pSesInfo);
3386 if(rc == -EAGAIN) 3508 if (rc == -EAGAIN)
3387 rc = -EHOSTDOWN; 3509 rc = -EHOSTDOWN;
3388 } 3510 }
3389 if(rc == 0) { 3511 if (rc == 0) {
3390 spin_lock(&GlobalMid_Lock); 3512 spin_lock(&GlobalMid_Lock);
3391 if(pSesInfo->server->tcpStatus != CifsExiting) 3513 if (pSesInfo->server->tcpStatus != CifsExiting)
3392 pSesInfo->server->tcpStatus = CifsGood; 3514 pSesInfo->server->tcpStatus = CifsGood;
3393 else 3515 else
3394 rc = -EHOSTDOWN; 3516 rc = -EHOSTDOWN;
@@ -3400,18 +3522,19 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3400 if (!rc) { 3522 if (!rc) {
3401 pSesInfo->flags = 0; 3523 pSesInfo->flags = 0;
3402 pSesInfo->capabilities = pSesInfo->server->capabilities; 3524 pSesInfo->capabilities = pSesInfo->server->capabilities;
3403 if(linuxExtEnabled == 0) 3525 if (linuxExtEnabled == 0)
3404 pSesInfo->capabilities &= (~CAP_UNIX); 3526 pSesInfo->capabilities &= (~CAP_UNIX);
3405 /* pSesInfo->sequence_number = 0;*/ 3527 /* pSesInfo->sequence_number = 0;*/
3406 cFYI(1,("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d", 3528 cFYI(1,
3529 ("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
3407 pSesInfo->server->secMode, 3530 pSesInfo->server->secMode,
3408 pSesInfo->server->capabilities, 3531 pSesInfo->server->capabilities,
3409 pSesInfo->server->timeAdj)); 3532 pSesInfo->server->timeAdj));
3410 if(experimEnabled < 2) 3533 if (experimEnabled < 2)
3411 rc = CIFS_SessSetup(xid, pSesInfo, 3534 rc = CIFS_SessSetup(xid, pSesInfo,
3412 first_time, nls_info); 3535 first_time, nls_info);
3413 else if (extended_security 3536 else if (extended_security
3414 && (pSesInfo->capabilities 3537 && (pSesInfo->capabilities
3415 & CAP_EXTENDED_SECURITY) 3538 & CAP_EXTENDED_SECURITY)
3416 && (pSesInfo->server->secType == NTLMSSP)) { 3539 && (pSesInfo->server->secType == NTLMSSP)) {
3417 rc = -EOPNOTSUPP; 3540 rc = -EOPNOTSUPP;
@@ -3424,21 +3547,22 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3424 &ntlmv2_flag, 3547 &ntlmv2_flag,
3425 nls_info); 3548 nls_info);
3426 if (!rc) { 3549 if (!rc) {
3427 if(ntlmv2_flag) { 3550 if (ntlmv2_flag) {
3428 char * v2_response; 3551 char *v2_response;
3429 cFYI(1,("more secure NTLM ver2 hash")); 3552 cFYI(1, ("more secure NTLM ver2 hash"));
3430 if(CalcNTLMv2_partial_mac_key(pSesInfo, 3553 if (CalcNTLMv2_partial_mac_key(pSesInfo,
3431 nls_info)) { 3554 nls_info)) {
3432 rc = -ENOMEM; 3555 rc = -ENOMEM;
3433 goto ss_err_exit; 3556 goto ss_err_exit;
3434 } else 3557 } else
3435 v2_response = kmalloc(16 + 64 /* blob */, GFP_KERNEL); 3558 v2_response = kmalloc(16 + 64 /* blob */, GFP_KERNEL);
3436 if(v2_response) { 3559 if (v2_response) {
3437 CalcNTLMv2_response(pSesInfo,v2_response); 3560 CalcNTLMv2_response(pSesInfo,
3438 /* if(first_time) 3561 v2_response);
3439 cifs_calculate_ntlmv2_mac_key( 3562 /* if (first_time)
3440 pSesInfo->server->mac_signing_key, 3563 cifs_calculate_ntlmv2_mac_key(
3441 response, ntlm_session_key, */ 3564 pSesInfo->server->mac_signing_key,
3565 response, ntlm_session_key,*/
3442 kfree(v2_response); 3566 kfree(v2_response);
3443 /* BB Put dummy sig in SessSetup PDU? */ 3567 /* BB Put dummy sig in SessSetup PDU? */
3444 } else { 3568 } else {
@@ -3451,9 +3575,9 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3451 pSesInfo->server->cryptKey, 3575 pSesInfo->server->cryptKey,
3452 ntlm_session_key); 3576 ntlm_session_key);
3453 3577
3454 if(first_time) 3578 if (first_time)
3455 cifs_calculate_mac_key( 3579 cifs_calculate_mac_key(
3456 pSesInfo->server->mac_signing_key, 3580 &pSesInfo->server->mac_signing_key,
3457 ntlm_session_key, 3581 ntlm_session_key,
3458 pSesInfo->password); 3582 pSesInfo->password);
3459 } 3583 }
@@ -3471,18 +3595,18 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3471 pSesInfo->server->cryptKey, 3595 pSesInfo->server->cryptKey,
3472 ntlm_session_key); 3596 ntlm_session_key);
3473 3597
3474 if(first_time) 3598 if (first_time)
3475 cifs_calculate_mac_key( 3599 cifs_calculate_mac_key(
3476 pSesInfo->server->mac_signing_key, 3600 &pSesInfo->server->mac_signing_key,
3477 ntlm_session_key, pSesInfo->password); 3601 ntlm_session_key, pSesInfo->password);
3478 3602
3479 rc = CIFSSessSetup(xid, pSesInfo, 3603 rc = CIFSSessSetup(xid, pSesInfo,
3480 ntlm_session_key, nls_info); 3604 ntlm_session_key, nls_info);
3481 } 3605 }
3482 if (rc) { 3606 if (rc) {
3483 cERROR(1,("Send error in SessSetup = %d",rc)); 3607 cERROR(1, ("Send error in SessSetup = %d", rc));
3484 } else { 3608 } else {
3485 cFYI(1,("CIFS Session Established successfully")); 3609 cFYI(1, ("CIFS Session Established successfully"));
3486 pSesInfo->status = CifsGood; 3610 pSesInfo->status = CifsGood;
3487 } 3611 }
3488 } 3612 }
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 8e86aaceb68a..4830acc86d74 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -135,10 +135,10 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
135 struct cifs_sb_info *cifs_sb; 135 struct cifs_sb_info *cifs_sb;
136 struct cifsTconInfo *pTcon; 136 struct cifsTconInfo *pTcon;
137 char *full_path = NULL; 137 char *full_path = NULL;
138 FILE_ALL_INFO * buf = NULL; 138 FILE_ALL_INFO *buf = NULL;
139 struct inode *newinode = NULL; 139 struct inode *newinode = NULL;
140 struct cifsFileInfo * pCifsFile = NULL; 140 struct cifsFileInfo *pCifsFile = NULL;
141 struct cifsInodeInfo * pCifsInode; 141 struct cifsInodeInfo *pCifsInode;
142 int disposition = FILE_OVERWRITE_IF; 142 int disposition = FILE_OVERWRITE_IF;
143 int write_only = FALSE; 143 int write_only = FALSE;
144 144
@@ -207,8 +207,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
207 } else { 207 } else {
208 /* If Open reported that we actually created a file 208 /* If Open reported that we actually created a file
209 then we now have to set the mode if possible */ 209 then we now have to set the mode if possible */
210 if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX) && 210 if ((pTcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) {
211 (oplock & CIFS_CREATE_ACTION)) {
212 mode &= ~current->fs->umask; 211 mode &= ~current->fs->umask;
213 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { 212 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
214 CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, 213 CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
@@ -235,8 +234,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
235 /* Could set r/o dos attribute if mode & 0222 == 0 */ 234 /* Could set r/o dos attribute if mode & 0222 == 0 */
236 } 235 }
237 236
238 /* BB server might mask mode so we have to query for Unix case*/ 237 /* server might mask mode so we have to query for it */
239 if (pTcon->ses->capabilities & CAP_UNIX) 238 if (pTcon->unix_ext)
240 rc = cifs_get_inode_info_unix(&newinode, full_path, 239 rc = cifs_get_inode_info_unix(&newinode, full_path,
241 inode->i_sb, xid); 240 inode->i_sb, xid);
242 else { 241 else {
@@ -264,7 +263,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
264 direntry->d_op = &cifs_dentry_ops; 263 direntry->d_op = &cifs_dentry_ops;
265 d_instantiate(direntry, newinode); 264 d_instantiate(direntry, newinode);
266 } 265 }
267 if ((nd->flags & LOOKUP_OPEN) == FALSE) { 266 if ((nd == NULL /* nfsd case - nfs srv does not set nd */) ||
267 ((nd->flags & LOOKUP_OPEN) == FALSE)) {
268 /* mknod case - do not leave file open */ 268 /* mknod case - do not leave file open */
269 CIFSSMBClose(xid, pTcon, fileHandle); 269 CIFSSMBClose(xid, pTcon, fileHandle);
270 } else if (newinode) { 270 } else if (newinode) {
@@ -323,7 +323,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
323 struct cifs_sb_info *cifs_sb; 323 struct cifs_sb_info *cifs_sb;
324 struct cifsTconInfo *pTcon; 324 struct cifsTconInfo *pTcon;
325 char *full_path = NULL; 325 char *full_path = NULL;
326 struct inode * newinode = NULL; 326 struct inode *newinode = NULL;
327 327
328 if (!old_valid_dev(device_number)) 328 if (!old_valid_dev(device_number))
329 return -EINVAL; 329 return -EINVAL;
@@ -336,7 +336,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
336 full_path = build_path_from_dentry(direntry); 336 full_path = build_path_from_dentry(direntry);
337 if (full_path == NULL) 337 if (full_path == NULL)
338 rc = -ENOMEM; 338 rc = -ENOMEM;
339 else if (pTcon->ses->capabilities & CAP_UNIX) { 339 else if (pTcon->unix_ext) {
340 mode &= ~current->fs->umask; 340 mode &= ~current->fs->umask;
341 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { 341 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
342 rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, 342 rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path,
@@ -490,7 +490,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
490 cFYI(1, 490 cFYI(1,
491 (" Full path: %s inode = 0x%p", full_path, direntry->d_inode)); 491 (" Full path: %s inode = 0x%p", full_path, direntry->d_inode));
492 492
493 if (pTcon->ses->capabilities & CAP_UNIX) 493 if (pTcon->unix_ext)
494 rc = cifs_get_inode_info_unix(&newInode, full_path, 494 rc = cifs_get_inode_info_unix(&newInode, full_path,
495 parent_dir_inode->i_sb, xid); 495 parent_dir_inode->i_sb, xid);
496 else 496 else
diff --git a/fs/cifs/export.c b/fs/cifs/export.c
index 96df1d51fdc3..893fd0aebff8 100644
--- a/fs/cifs/export.c
+++ b/fs/cifs/export.c
@@ -5,7 +5,7 @@
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * Common Internet FileSystem (CIFS) client 7 * Common Internet FileSystem (CIFS) client
8 * 8 *
9 * Operations related to support for exporting files via NFSD 9 * Operations related to support for exporting files via NFSD
10 * 10 *
11 * This library is free software; you can redistribute it and/or modify 11 * This library is free software; you can redistribute it and/or modify
@@ -22,32 +22,45 @@
22 * along with this library; if not, write to the Free Software 22 * along with this library; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */ 24 */
25 25
26 /* 26 /*
27 * See Documentation/filesystems/Exporting 27 * See Documentation/filesystems/Exporting
28 * and examples in fs/exportfs 28 * and examples in fs/exportfs
29 *
30 * Since cifs is a network file system, an "fsid" must be included for
31 * any nfs exports file entries which refer to cifs paths. In addition
32 * the cifs mount must be mounted with the "serverino" option (ie use stable
33 * server inode numbers instead of locally generated temporary ones).
34 * Although cifs inodes do not use generation numbers (have generation number
35 * of zero) - the inode number alone should be good enough for simple cases
36 * in which users want to export cifs shares with NFS. The decode and encode
37 * could be improved by using a new routine which expects 64 bit inode numbers
38 * instead of the default 32 bit routines in fs/exportfs
39 *
29 */ 40 */
30 41
31#include <linux/fs.h> 42#include <linux/fs.h>
32#include <linux/exportfs.h> 43#include <linux/exportfs.h>
33 44#include "cifsglob.h"
45#include "cifs_debug.h"
46
34#ifdef CONFIG_CIFS_EXPERIMENTAL 47#ifdef CONFIG_CIFS_EXPERIMENTAL
35
36static struct dentry *cifs_get_parent(struct dentry *dentry) 48static struct dentry *cifs_get_parent(struct dentry *dentry)
37{ 49{
38 /* BB need to add code here eventually to enable export via NFSD */ 50 /* BB need to add code here eventually to enable export via NFSD */
39 return ERR_PTR(-EACCES); 51 cFYI(1, ("get parent for %p", dentry));
52 return ERR_PTR(-EACCES);
40} 53}
41 54
42struct export_operations cifs_export_ops = { 55struct export_operations cifs_export_ops = {
43 .get_parent = cifs_get_parent, 56 .get_parent = cifs_get_parent,
44/* Following five export operations are unneeded so far and can default */ 57/* Following five export operations are unneeded so far and can default:
45/* .get_dentry = 58 .get_dentry =
46 .get_name = 59 .get_name =
47 .find_exported_dentry = 60 .find_exported_dentry =
48 .decode_fh = 61 .decode_fh =
49 .encode_fs = */ 62 .encode_fs = */
50 }; 63};
51 64
52#endif /* EXPERIMENTAL */ 65#endif /* EXPERIMENTAL */
53 66
diff --git a/fs/cifs/fcntl.c b/fs/cifs/fcntl.c
index 8e375bb4b379..995474c90885 100644
--- a/fs/cifs/fcntl.c
+++ b/fs/cifs/fcntl.c
@@ -66,7 +66,7 @@ static __u32 convert_to_cifs_notify_flags(unsigned long fcntl_notify_flags)
66 return cifs_ntfy_flags; 66 return cifs_ntfy_flags;
67} 67}
68 68
69int cifs_dir_notify(struct file * file, unsigned long arg) 69int cifs_dir_notify(struct file *file, unsigned long arg)
70{ 70{
71 int xid; 71 int xid;
72 int rc = -EINVAL; 72 int rc = -EINVAL;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 94d5b49049df..e13592afca9c 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2,8 +2,8 @@
2 * fs/cifs/file.c 2 * fs/cifs/file.c
3 * 3 *
4 * vfs operations that deal with files 4 * vfs operations that deal with files
5 * 5 *
6 * Copyright (C) International Business Machines Corp., 2002,2003 6 * Copyright (C) International Business Machines Corp., 2002,2007
7 * Author(s): Steve French (sfrench@us.ibm.com) 7 * Author(s): Steve French (sfrench@us.ibm.com)
8 * Jeremy Allison (jra@samba.org) 8 * Jeremy Allison (jra@samba.org)
9 * 9 *
@@ -45,7 +45,7 @@ static inline struct cifsFileInfo *cifs_init_private(
45{ 45{
46 memset(private_data, 0, sizeof(struct cifsFileInfo)); 46 memset(private_data, 0, sizeof(struct cifsFileInfo));
47 private_data->netfid = netfid; 47 private_data->netfid = netfid;
48 private_data->pid = current->tgid; 48 private_data->pid = current->tgid;
49 init_MUTEX(&private_data->fh_sem); 49 init_MUTEX(&private_data->fh_sem);
50 mutex_init(&private_data->lock_mutex); 50 mutex_init(&private_data->lock_mutex);
51 INIT_LIST_HEAD(&private_data->llist); 51 INIT_LIST_HEAD(&private_data->llist);
@@ -57,7 +57,7 @@ static inline struct cifsFileInfo *cifs_init_private(
57 does not tell us which handle the write is for so there can 57 does not tell us which handle the write is for so there can
58 be a close (overlapping with write) of the filehandle that 58 be a close (overlapping with write) of the filehandle that
59 cifs_writepages chose to use */ 59 cifs_writepages chose to use */
60 atomic_set(&private_data->wrtPending,0); 60 atomic_set(&private_data->wrtPending, 0);
61 61
62 return private_data; 62 return private_data;
63} 63}
@@ -105,7 +105,7 @@ static inline int cifs_open_inode_helper(struct inode *inode, struct file *file,
105 in the list so we do not have to walk the 105 in the list so we do not have to walk the
106 list to search for one in prepare_write */ 106 list to search for one in prepare_write */
107 if ((file->f_flags & O_ACCMODE) == O_WRONLY) { 107 if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
108 list_add_tail(&pCifsFile->flist, 108 list_add_tail(&pCifsFile->flist,
109 &pCifsInode->openFileList); 109 &pCifsInode->openFileList);
110 } else { 110 } else {
111 list_add(&pCifsFile->flist, 111 list_add(&pCifsFile->flist,
@@ -138,7 +138,7 @@ static inline int cifs_open_inode_helper(struct inode *inode, struct file *file,
138 } 138 }
139 139
140client_can_cache: 140client_can_cache:
141 if (pTcon->ses->capabilities & CAP_UNIX) 141 if (pTcon->unix_ext)
142 rc = cifs_get_inode_info_unix(&file->f_path.dentry->d_inode, 142 rc = cifs_get_inode_info_unix(&file->f_path.dentry->d_inode,
143 full_path, inode->i_sb, xid); 143 full_path, inode->i_sb, xid);
144 else 144 else
@@ -189,7 +189,7 @@ int cifs_open(struct inode *inode, struct file *file)
189 189
190 /* needed for writepage */ 190 /* needed for writepage */
191 pCifsFile->pfile = file; 191 pCifsFile->pfile = file;
192 192
193 file->private_data = pCifsFile; 193 file->private_data = pCifsFile;
194 break; 194 break;
195 } 195 }
@@ -212,15 +212,15 @@ int cifs_open(struct inode *inode, struct file *file)
212 return -ENOMEM; 212 return -ENOMEM;
213 } 213 }
214 214
215 cFYI(1, (" inode = 0x%p file flags are 0x%x for %s", 215 cFYI(1, ("inode = 0x%p file flags are 0x%x for %s",
216 inode, file->f_flags, full_path)); 216 inode, file->f_flags, full_path));
217 desiredAccess = cifs_convert_flags(file->f_flags); 217 desiredAccess = cifs_convert_flags(file->f_flags);
218 218
219/********************************************************************* 219/*********************************************************************
220 * open flag mapping table: 220 * open flag mapping table:
221 * 221 *
222 * POSIX Flag CIFS Disposition 222 * POSIX Flag CIFS Disposition
223 * ---------- ---------------- 223 * ---------- ----------------
224 * O_CREAT FILE_OPEN_IF 224 * O_CREAT FILE_OPEN_IF
225 * O_CREAT | O_EXCL FILE_CREATE 225 * O_CREAT | O_EXCL FILE_CREATE
226 * O_CREAT | O_TRUNC FILE_OVERWRITE_IF 226 * O_CREAT | O_TRUNC FILE_OVERWRITE_IF
@@ -228,12 +228,12 @@ int cifs_open(struct inode *inode, struct file *file)
228 * none of the above FILE_OPEN 228 * none of the above FILE_OPEN
229 * 229 *
230 * Note that there is not a direct match between disposition 230 * Note that there is not a direct match between disposition
231 * FILE_SUPERSEDE (ie create whether or not file exists although 231 * FILE_SUPERSEDE (ie create whether or not file exists although
232 * O_CREAT | O_TRUNC is similar but truncates the existing 232 * O_CREAT | O_TRUNC is similar but truncates the existing
233 * file rather than creating a new file as FILE_SUPERSEDE does 233 * file rather than creating a new file as FILE_SUPERSEDE does
234 * (which uses the attributes / metadata passed in on open call) 234 * (which uses the attributes / metadata passed in on open call)
235 *? 235 *?
236 *? O_SYNC is a reasonable match to CIFS writethrough flag 236 *? O_SYNC is a reasonable match to CIFS writethrough flag
237 *? and the read write flags match reasonably. O_LARGEFILE 237 *? and the read write flags match reasonably. O_LARGEFILE
238 *? is irrelevant because largefile support is always used 238 *? is irrelevant because largefile support is always used
239 *? by this client. Flags O_APPEND, O_DIRECT, O_DIRECTORY, 239 *? by this client. Flags O_APPEND, O_DIRECT, O_DIRECTORY,
@@ -253,8 +253,8 @@ int cifs_open(struct inode *inode, struct file *file)
253 and calling get_inode_info with returned buf (at least helps 253 and calling get_inode_info with returned buf (at least helps
254 non-Unix server case) */ 254 non-Unix server case) */
255 255
256 /* BB we can not do this if this is the second open of a file 256 /* BB we can not do this if this is the second open of a file
257 and the first handle has writebehind data, we might be 257 and the first handle has writebehind data, we might be
258 able to simply do a filemap_fdatawrite/filemap_fdatawait first */ 258 able to simply do a filemap_fdatawrite/filemap_fdatawait first */
259 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); 259 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
260 if (!buf) { 260 if (!buf) {
@@ -263,7 +263,7 @@ int cifs_open(struct inode *inode, struct file *file)
263 } 263 }
264 264
265 if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS) 265 if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS)
266 rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, 266 rc = CIFSSMBOpen(xid, pTcon, full_path, disposition,
267 desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf, 267 desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf,
268 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags 268 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
269 & CIFS_MOUNT_MAP_SPECIAL_CHR); 269 & CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -300,15 +300,15 @@ int cifs_open(struct inode *inode, struct file *file)
300 write_unlock(&GlobalSMBSeslock); 300 write_unlock(&GlobalSMBSeslock);
301 } 301 }
302 302
303 if (oplock & CIFS_CREATE_ACTION) { 303 if (oplock & CIFS_CREATE_ACTION) {
304 /* time to set mode which we can not set earlier due to 304 /* time to set mode which we can not set earlier due to
305 problems creating new read-only files */ 305 problems creating new read-only files */
306 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) { 306 if (pTcon->unix_ext) {
307 CIFSSMBUnixSetPerms(xid, pTcon, full_path, 307 CIFSSMBUnixSetPerms(xid, pTcon, full_path,
308 inode->i_mode, 308 inode->i_mode,
309 (__u64)-1, (__u64)-1, 0 /* dev */, 309 (__u64)-1, (__u64)-1, 0 /* dev */,
310 cifs_sb->local_nls, 310 cifs_sb->local_nls,
311 cifs_sb->mnt_cifs_flags & 311 cifs_sb->mnt_cifs_flags &
312 CIFS_MOUNT_MAP_SPECIAL_CHR); 312 CIFS_MOUNT_MAP_SPECIAL_CHR);
313 } else { 313 } else {
314 /* BB implement via Windows security descriptors eg 314 /* BB implement via Windows security descriptors eg
@@ -345,7 +345,7 @@ static int cifs_reopen_file(struct file *file, int can_flush)
345 struct cifsTconInfo *pTcon; 345 struct cifsTconInfo *pTcon;
346 struct cifsFileInfo *pCifsFile; 346 struct cifsFileInfo *pCifsFile;
347 struct cifsInodeInfo *pCifsInode; 347 struct cifsInodeInfo *pCifsInode;
348 struct inode * inode; 348 struct inode *inode;
349 char *full_path = NULL; 349 char *full_path = NULL;
350 int desiredAccess; 350 int desiredAccess;
351 int disposition = FILE_OPEN; 351 int disposition = FILE_OPEN;
@@ -372,13 +372,13 @@ static int cifs_reopen_file(struct file *file, int can_flush)
372 } 372 }
373 373
374 inode = file->f_path.dentry->d_inode; 374 inode = file->f_path.dentry->d_inode;
375 if(inode == NULL) { 375 if (inode == NULL) {
376 cERROR(1, ("inode not valid")); 376 cERROR(1, ("inode not valid"));
377 dump_stack(); 377 dump_stack();
378 rc = -EBADF; 378 rc = -EBADF;
379 goto reopen_error_exit; 379 goto reopen_error_exit;
380 } 380 }
381 381
382 cifs_sb = CIFS_SB(inode->i_sb); 382 cifs_sb = CIFS_SB(inode->i_sb);
383 pTcon = cifs_sb->tcon; 383 pTcon = cifs_sb->tcon;
384 384
@@ -396,7 +396,7 @@ reopen_error_exit:
396 } 396 }
397 397
398 cFYI(1, ("inode = 0x%p file flags 0x%x for %s", 398 cFYI(1, ("inode = 0x%p file flags 0x%x for %s",
399 inode, file->f_flags,full_path)); 399 inode, file->f_flags, full_path));
400 desiredAccess = cifs_convert_flags(file->f_flags); 400 desiredAccess = cifs_convert_flags(file->f_flags);
401 401
402 if (oplockEnabled) 402 if (oplockEnabled)
@@ -405,14 +405,14 @@ reopen_error_exit:
405 oplock = FALSE; 405 oplock = FALSE;
406 406
407 /* Can not refresh inode by passing in file_info buf to be returned 407 /* Can not refresh inode by passing in file_info buf to be returned
408 by SMBOpen and then calling get_inode_info with returned buf 408 by SMBOpen and then calling get_inode_info with returned buf
409 since file might have write behind data that needs to be flushed 409 since file might have write behind data that needs to be flushed
410 and server version of file size can be stale. If we knew for sure 410 and server version of file size can be stale. If we knew for sure
411 that inode was not dirty locally we could do this */ 411 that inode was not dirty locally we could do this */
412 412
413 rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess, 413 rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess,
414 CREATE_NOT_DIR, &netfid, &oplock, NULL, 414 CREATE_NOT_DIR, &netfid, &oplock, NULL,
415 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 415 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
416 CIFS_MOUNT_MAP_SPECIAL_CHR); 416 CIFS_MOUNT_MAP_SPECIAL_CHR);
417 if (rc) { 417 if (rc) {
418 up(&pCifsFile->fh_sem); 418 up(&pCifsFile->fh_sem);
@@ -430,7 +430,7 @@ reopen_error_exit:
430 go to server to get inode info */ 430 go to server to get inode info */
431 pCifsInode->clientCanCacheAll = FALSE; 431 pCifsInode->clientCanCacheAll = FALSE;
432 pCifsInode->clientCanCacheRead = FALSE; 432 pCifsInode->clientCanCacheRead = FALSE;
433 if (pTcon->ses->capabilities & CAP_UNIX) 433 if (pTcon->unix_ext)
434 rc = cifs_get_inode_info_unix(&inode, 434 rc = cifs_get_inode_info_unix(&inode,
435 full_path, inode->i_sb, xid); 435 full_path, inode->i_sb, xid);
436 else 436 else
@@ -486,23 +486,24 @@ int cifs_close(struct inode *inode, struct file *file)
486 already closed */ 486 already closed */
487 if (pTcon->tidStatus != CifsNeedReconnect) { 487 if (pTcon->tidStatus != CifsNeedReconnect) {
488 int timeout = 2; 488 int timeout = 2;
489 while((atomic_read(&pSMBFile->wrtPending) != 0) 489 while ((atomic_read(&pSMBFile->wrtPending) != 0)
490 && (timeout < 1000) ) { 490 && (timeout < 1000) ) {
491 /* Give write a better chance to get to 491 /* Give write a better chance to get to
492 server ahead of the close. We do not 492 server ahead of the close. We do not
493 want to add a wait_q here as it would 493 want to add a wait_q here as it would
494 increase the memory utilization as 494 increase the memory utilization as
495 the struct would be in each open file, 495 the struct would be in each open file,
496 but this should give enough time to 496 but this should give enough time to
497 clear the socket */ 497 clear the socket */
498#ifdef CONFIG_CIFS_DEBUG2 498#ifdef CONFIG_CIFS_DEBUG2
499 cFYI(1,("close delay, write pending")); 499 cFYI(1, ("close delay, write pending"));
500#endif /* DEBUG2 */ 500#endif /* DEBUG2 */
501 msleep(timeout); 501 msleep(timeout);
502 timeout *= 4; 502 timeout *= 4;
503 } 503 }
504 if(atomic_read(&pSMBFile->wrtPending)) 504 if (atomic_read(&pSMBFile->wrtPending))
505 cERROR(1,("close with pending writes")); 505 cERROR(1,
506 ("close with pending writes"));
506 rc = CIFSSMBClose(xid, pTcon, 507 rc = CIFSSMBClose(xid, pTcon,
507 pSMBFile->netfid); 508 pSMBFile->netfid);
508 } 509 }
@@ -534,7 +535,7 @@ int cifs_close(struct inode *inode, struct file *file)
534 CIFS_I(inode)->clientCanCacheRead = FALSE; 535 CIFS_I(inode)->clientCanCacheRead = FALSE;
535 CIFS_I(inode)->clientCanCacheAll = FALSE; 536 CIFS_I(inode)->clientCanCacheAll = FALSE;
536 } 537 }
537 if ((rc ==0) && CIFS_I(inode)->write_behind_rc) 538 if ((rc == 0) && CIFS_I(inode)->write_behind_rc)
538 rc = CIFS_I(inode)->write_behind_rc; 539 rc = CIFS_I(inode)->write_behind_rc;
539 FreeXid(xid); 540 FreeXid(xid);
540 return rc; 541 return rc;
@@ -554,7 +555,8 @@ int cifs_closedir(struct inode *inode, struct file *file)
554 555
555 if (pCFileStruct) { 556 if (pCFileStruct) {
556 struct cifsTconInfo *pTcon; 557 struct cifsTconInfo *pTcon;
557 struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 558 struct cifs_sb_info *cifs_sb =
559 CIFS_SB(file->f_path.dentry->d_sb);
558 560
559 pTcon = cifs_sb->tcon; 561 pTcon = cifs_sb->tcon;
560 562
@@ -572,7 +574,7 @@ int cifs_closedir(struct inode *inode, struct file *file)
572 if (ptmp) { 574 if (ptmp) {
573 cFYI(1, ("closedir free smb buf in srch struct")); 575 cFYI(1, ("closedir free smb buf in srch struct"));
574 pCFileStruct->srch_inf.ntwrk_buf_start = NULL; 576 pCFileStruct->srch_inf.ntwrk_buf_start = NULL;
575 if(pCFileStruct->srch_inf.smallBuf) 577 if (pCFileStruct->srch_inf.smallBuf)
576 cifs_small_buf_release(ptmp); 578 cifs_small_buf_release(ptmp);
577 else 579 else
578 cifs_buf_release(ptmp); 580 cifs_buf_release(ptmp);
@@ -594,7 +596,8 @@ int cifs_closedir(struct inode *inode, struct file *file)
594static int store_file_lock(struct cifsFileInfo *fid, __u64 len, 596static int store_file_lock(struct cifsFileInfo *fid, __u64 len,
595 __u64 offset, __u8 lockType) 597 __u64 offset, __u8 lockType)
596{ 598{
597 struct cifsLockInfo *li = kmalloc(sizeof(struct cifsLockInfo), GFP_KERNEL); 599 struct cifsLockInfo *li =
600 kmalloc(sizeof(struct cifsLockInfo), GFP_KERNEL);
598 if (li == NULL) 601 if (li == NULL)
599 return -ENOMEM; 602 return -ENOMEM;
600 li->offset = offset; 603 li->offset = offset;
@@ -625,8 +628,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
625 628
626 cFYI(1, ("Lock parm: 0x%x flockflags: " 629 cFYI(1, ("Lock parm: 0x%x flockflags: "
627 "0x%x flocktype: 0x%x start: %lld end: %lld", 630 "0x%x flocktype: 0x%x start: %lld end: %lld",
628 cmd, pfLock->fl_flags, pfLock->fl_type, pfLock->fl_start, 631 cmd, pfLock->fl_flags, pfLock->fl_type, pfLock->fl_start,
629 pfLock->fl_end)); 632 pfLock->fl_end));
630 633
631 if (pfLock->fl_flags & FL_POSIX) 634 if (pfLock->fl_flags & FL_POSIX)
632 cFYI(1, ("Posix")); 635 cFYI(1, ("Posix"));
@@ -641,7 +644,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
641 "not implemented yet")); 644 "not implemented yet"));
642 if (pfLock->fl_flags & FL_LEASE) 645 if (pfLock->fl_flags & FL_LEASE)
643 cFYI(1, ("Lease on file - not implemented yet")); 646 cFYI(1, ("Lease on file - not implemented yet"));
644 if (pfLock->fl_flags & 647 if (pfLock->fl_flags &
645 (~(FL_POSIX | FL_FLOCK | FL_SLEEP | FL_ACCESS | FL_LEASE))) 648 (~(FL_POSIX | FL_FLOCK | FL_SLEEP | FL_ACCESS | FL_LEASE)))
646 cFYI(1, ("Unknown lock flags 0x%x", pfLock->fl_flags)); 649 cFYI(1, ("Unknown lock flags 0x%x", pfLock->fl_flags));
647 650
@@ -683,9 +686,9 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
683 account for negative length which we can not accept over the 686 account for negative length which we can not accept over the
684 wire */ 687 wire */
685 if (IS_GETLK(cmd)) { 688 if (IS_GETLK(cmd)) {
686 if(posix_locking) { 689 if (posix_locking) {
687 int posix_lock_type; 690 int posix_lock_type;
688 if(lockType & LOCKING_ANDX_SHARED_LOCK) 691 if (lockType & LOCKING_ANDX_SHARED_LOCK)
689 posix_lock_type = CIFS_RDLCK; 692 posix_lock_type = CIFS_RDLCK;
690 else 693 else
691 posix_lock_type = CIFS_WRLCK; 694 posix_lock_type = CIFS_WRLCK;
@@ -700,7 +703,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
700 rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start, 703 rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start,
701 0, 1, lockType, 0 /* wait flag */ ); 704 0, 1, lockType, 0 /* wait flag */ );
702 if (rc == 0) { 705 if (rc == 0) {
703 rc = CIFSSMBLock(xid, pTcon, netfid, length, 706 rc = CIFSSMBLock(xid, pTcon, netfid, length,
704 pfLock->fl_start, 1 /* numUnlock */ , 707 pfLock->fl_start, 1 /* numUnlock */ ,
705 0 /* numLock */ , lockType, 708 0 /* numLock */ , lockType,
706 0 /* wait flag */ ); 709 0 /* wait flag */ );
@@ -729,22 +732,24 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
729 732
730 if (posix_locking) { 733 if (posix_locking) {
731 int posix_lock_type; 734 int posix_lock_type;
732 if(lockType & LOCKING_ANDX_SHARED_LOCK) 735 if (lockType & LOCKING_ANDX_SHARED_LOCK)
733 posix_lock_type = CIFS_RDLCK; 736 posix_lock_type = CIFS_RDLCK;
734 else 737 else
735 posix_lock_type = CIFS_WRLCK; 738 posix_lock_type = CIFS_WRLCK;
736 739
737 if(numUnlock == 1) 740 if (numUnlock == 1)
738 posix_lock_type = CIFS_UNLCK; 741 posix_lock_type = CIFS_UNLCK;
739 742
740 rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */, 743 rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */,
741 length, pfLock, 744 length, pfLock,
742 posix_lock_type, wait_flag); 745 posix_lock_type, wait_flag);
743 } else { 746 } else {
744 struct cifsFileInfo *fid = (struct cifsFileInfo *)file->private_data; 747 struct cifsFileInfo *fid =
748 (struct cifsFileInfo *)file->private_data;
745 749
746 if (numLock) { 750 if (numLock) {
747 rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start, 751 rc = CIFSSMBLock(xid, pTcon, netfid, length,
752 pfLock->fl_start,
748 0, numLock, lockType, wait_flag); 753 0, numLock, lockType, wait_flag);
749 754
750 if (rc == 0) { 755 if (rc == 0) {
@@ -763,7 +768,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
763 list_for_each_entry_safe(li, tmp, &fid->llist, llist) { 768 list_for_each_entry_safe(li, tmp, &fid->llist, llist) {
764 if (pfLock->fl_start <= li->offset && 769 if (pfLock->fl_start <= li->offset &&
765 length >= li->length) { 770 length >= li->length) {
766 stored_rc = CIFSSMBLock(xid, pTcon, netfid, 771 stored_rc = CIFSSMBLock(xid, pTcon,
772 netfid,
767 li->length, li->offset, 773 li->length, li->offset,
768 1, 0, li->type, FALSE); 774 1, 0, li->type, FALSE);
769 if (stored_rc) 775 if (stored_rc)
@@ -805,7 +811,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
805 if (file->private_data == NULL) 811 if (file->private_data == NULL)
806 return -EBADF; 812 return -EBADF;
807 open_file = (struct cifsFileInfo *) file->private_data; 813 open_file = (struct cifsFileInfo *) file->private_data;
808 814
809 xid = GetXid(); 815 xid = GetXid();
810 816
811 if (*poffset > file->f_path.dentry->d_inode->i_size) 817 if (*poffset > file->f_path.dentry->d_inode->i_size)
@@ -824,7 +830,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
824 and blocked, and the file has been freed on us while 830 and blocked, and the file has been freed on us while
825 we blocked so return what we managed to write */ 831 we blocked so return what we managed to write */
826 return total_written; 832 return total_written;
827 } 833 }
828 if (open_file->closePend) { 834 if (open_file->closePend) {
829 FreeXid(xid); 835 FreeXid(xid);
830 if (total_written) 836 if (total_written)
@@ -867,8 +873,8 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
867 /* since the write may have blocked check these pointers again */ 873 /* since the write may have blocked check these pointers again */
868 if ((file->f_path.dentry) && (file->f_path.dentry->d_inode)) { 874 if ((file->f_path.dentry) && (file->f_path.dentry->d_inode)) {
869 struct inode *inode = file->f_path.dentry->d_inode; 875 struct inode *inode = file->f_path.dentry->d_inode;
870/* Do not update local mtime - server will set its actual value on write 876/* Do not update local mtime - server will set its actual value on write
871 * inode->i_ctime = inode->i_mtime = 877 * inode->i_ctime = inode->i_mtime =
872 * current_fs_time(inode->i_sb);*/ 878 * current_fs_time(inode->i_sb);*/
873 if (total_written > 0) { 879 if (total_written > 0) {
874 spin_lock(&inode->i_lock); 880 spin_lock(&inode->i_lock);
@@ -877,7 +883,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
877 *poffset); 883 *poffset);
878 spin_unlock(&inode->i_lock); 884 spin_unlock(&inode->i_lock);
879 } 885 }
880 mark_inode_dirty_sync(file->f_path.dentry->d_inode); 886 mark_inode_dirty_sync(file->f_path.dentry->d_inode);
881 } 887 }
882 FreeXid(xid); 888 FreeXid(xid);
883 return total_written; 889 return total_written;
@@ -898,13 +904,13 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
898 904
899 pTcon = cifs_sb->tcon; 905 pTcon = cifs_sb->tcon;
900 906
901 cFYI(1,("write %zd bytes to offset %lld of %s", write_size, 907 cFYI(1, ("write %zd bytes to offset %lld of %s", write_size,
902 *poffset, file->f_path.dentry->d_name.name)); 908 *poffset, file->f_path.dentry->d_name.name));
903 909
904 if (file->private_data == NULL) 910 if (file->private_data == NULL)
905 return -EBADF; 911 return -EBADF;
906 open_file = (struct cifsFileInfo *)file->private_data; 912 open_file = (struct cifsFileInfo *)file->private_data;
907 913
908 xid = GetXid(); 914 xid = GetXid();
909 915
910 if (*poffset > file->f_path.dentry->d_inode->i_size) 916 if (*poffset > file->f_path.dentry->d_inode->i_size)
@@ -921,10 +927,10 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
921 FreeXid(xid); 927 FreeXid(xid);
922 /* if we have gotten here we have written some data 928 /* if we have gotten here we have written some data
923 and blocked, and the file has been freed on us 929 and blocked, and the file has been freed on us
924 while we blocked so return what we managed to 930 while we blocked so return what we managed to
925 write */ 931 write */
926 return total_written; 932 return total_written;
927 } 933 }
928 if (open_file->closePend) { 934 if (open_file->closePend) {
929 FreeXid(xid); 935 FreeXid(xid);
930 if (total_written) 936 if (total_written)
@@ -935,14 +941,14 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
935 if (open_file->invalidHandle) { 941 if (open_file->invalidHandle) {
936 /* we could deadlock if we called 942 /* we could deadlock if we called
937 filemap_fdatawait from here so tell 943 filemap_fdatawait from here so tell
938 reopen_file not to flush data to 944 reopen_file not to flush data to
939 server now */ 945 server now */
940 rc = cifs_reopen_file(file, FALSE); 946 rc = cifs_reopen_file(file, FALSE);
941 if (rc != 0) 947 if (rc != 0)
942 break; 948 break;
943 } 949 }
944 if(experimEnabled || (pTcon->ses->server && 950 if (experimEnabled || (pTcon->ses->server &&
945 ((pTcon->ses->server->secMode & 951 ((pTcon->ses->server->secMode &
946 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 952 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
947 == 0))) { 953 == 0))) {
948 struct kvec iov[2]; 954 struct kvec iov[2];
@@ -976,7 +982,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
976 } 982 }
977 } else 983 } else
978 *poffset += bytes_written; 984 *poffset += bytes_written;
979 long_op = FALSE; /* subsequent writes fast - 985 long_op = FALSE; /* subsequent writes fast -
980 15 seconds is plenty */ 986 15 seconds is plenty */
981 } 987 }
982 988
@@ -1009,8 +1015,8 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)
1009 the VFS or MM) should not happen but we had reports of on oops (due to 1015 the VFS or MM) should not happen but we had reports of on oops (due to
1010 it being zero) during stress testcases so we need to check for it */ 1016 it being zero) during stress testcases so we need to check for it */
1011 1017
1012 if(cifs_inode == NULL) { 1018 if (cifs_inode == NULL) {
1013 cERROR(1,("Null inode passed to cifs_writeable_file")); 1019 cERROR(1, ("Null inode passed to cifs_writeable_file"));
1014 dump_stack(); 1020 dump_stack();
1015 return NULL; 1021 return NULL;
1016 } 1022 }
@@ -1024,13 +1030,14 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)
1024 (open_file->pfile->f_flags & O_WRONLY))) { 1030 (open_file->pfile->f_flags & O_WRONLY))) {
1025 atomic_inc(&open_file->wrtPending); 1031 atomic_inc(&open_file->wrtPending);
1026 read_unlock(&GlobalSMBSeslock); 1032 read_unlock(&GlobalSMBSeslock);
1027 if((open_file->invalidHandle) && 1033 if ((open_file->invalidHandle) &&
1028 (!open_file->closePend) /* BB fixme -since the second clause can not be true remove it BB */) { 1034 (!open_file->closePend) /* BB fixme -since the second clause can not be true remove it BB */) {
1029 rc = cifs_reopen_file(open_file->pfile, FALSE); 1035 rc = cifs_reopen_file(open_file->pfile, FALSE);
1030 /* if it fails, try another handle - might be */ 1036 /* if it fails, try another handle - might be */
1031 /* dangerous to hold up writepages with retry */ 1037 /* dangerous to hold up writepages with retry */
1032 if(rc) { 1038 if (rc) {
1033 cFYI(1,("failed on reopen file in wp")); 1039 cFYI(1,
1040 ("failed on reopen file in wp"));
1034 read_lock(&GlobalSMBSeslock); 1041 read_lock(&GlobalSMBSeslock);
1035 /* can not use this handle, no write 1042 /* can not use this handle, no write
1036 pending on this one after all */ 1043 pending on this one after all */
@@ -1082,7 +1089,7 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
1082 1089
1083 /* check to make sure that we are not extending the file */ 1090 /* check to make sure that we are not extending the file */
1084 if (mapping->host->i_size - offset < (loff_t)to) 1091 if (mapping->host->i_size - offset < (loff_t)to)
1085 to = (unsigned)(mapping->host->i_size - offset); 1092 to = (unsigned)(mapping->host->i_size - offset);
1086 1093
1087 open_file = find_writable_file(CIFS_I(mapping->host)); 1094 open_file = find_writable_file(CIFS_I(mapping->host));
1088 if (open_file) { 1095 if (open_file) {
@@ -1116,8 +1123,8 @@ static int cifs_writepages(struct address_space *mapping,
1116 int done = 0; 1123 int done = 0;
1117 pgoff_t end; 1124 pgoff_t end;
1118 pgoff_t index; 1125 pgoff_t index;
1119 int range_whole = 0; 1126 int range_whole = 0;
1120 struct kvec * iov; 1127 struct kvec *iov;
1121 int len; 1128 int len;
1122 int n_iov = 0; 1129 int n_iov = 0;
1123 pgoff_t next; 1130 pgoff_t next;
@@ -1131,7 +1138,7 @@ static int cifs_writepages(struct address_space *mapping,
1131 int xid; 1138 int xid;
1132 1139
1133 cifs_sb = CIFS_SB(mapping->host->i_sb); 1140 cifs_sb = CIFS_SB(mapping->host->i_sb);
1134 1141
1135 /* 1142 /*
1136 * If wsize is smaller that the page cache size, default to writing 1143 * If wsize is smaller that the page cache size, default to writing
1137 * one page at a time via cifs_writepage 1144 * one page at a time via cifs_writepage
@@ -1139,14 +1146,14 @@ static int cifs_writepages(struct address_space *mapping,
1139 if (cifs_sb->wsize < PAGE_CACHE_SIZE) 1146 if (cifs_sb->wsize < PAGE_CACHE_SIZE)
1140 return generic_writepages(mapping, wbc); 1147 return generic_writepages(mapping, wbc);
1141 1148
1142 if((cifs_sb->tcon->ses) && (cifs_sb->tcon->ses->server)) 1149 if ((cifs_sb->tcon->ses) && (cifs_sb->tcon->ses->server))
1143 if(cifs_sb->tcon->ses->server->secMode & 1150 if (cifs_sb->tcon->ses->server->secMode &
1144 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 1151 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
1145 if(!experimEnabled) 1152 if (!experimEnabled)
1146 return generic_writepages(mapping, wbc); 1153 return generic_writepages(mapping, wbc);
1147 1154
1148 iov = kmalloc(32 * sizeof(struct kvec), GFP_KERNEL); 1155 iov = kmalloc(32 * sizeof(struct kvec), GFP_KERNEL);
1149 if(iov == NULL) 1156 if (iov == NULL)
1150 return generic_writepages(mapping, wbc); 1157 return generic_writepages(mapping, wbc);
1151 1158
1152 1159
@@ -1279,7 +1286,7 @@ retry:
1279 1); 1286 1);
1280 atomic_dec(&open_file->wrtPending); 1287 atomic_dec(&open_file->wrtPending);
1281 if (rc || bytes_written < bytes_to_write) { 1288 if (rc || bytes_written < bytes_to_write) {
1282 cERROR(1,("Write2 ret %d, written = %d", 1289 cERROR(1, ("Write2 ret %d, wrote %d",
1283 rc, bytes_written)); 1290 rc, bytes_written));
1284 /* BB what if continued retry is 1291 /* BB what if continued retry is
1285 requested via mount flags? */ 1292 requested via mount flags? */
@@ -1295,8 +1302,8 @@ retry:
1295 success rc but too little data written? */ 1302 success rc but too little data written? */
1296 /* BB investigate retry logic on temporary 1303 /* BB investigate retry logic on temporary
1297 server crash cases and how recovery works 1304 server crash cases and how recovery works
1298 when page marked as error */ 1305 when page marked as error */
1299 if(rc) 1306 if (rc)
1300 SetPageError(page); 1307 SetPageError(page);
1301 kunmap(page); 1308 kunmap(page);
1302 unlock_page(page); 1309 unlock_page(page);
@@ -1326,7 +1333,7 @@ retry:
1326 return rc; 1333 return rc;
1327} 1334}
1328 1335
1329static int cifs_writepage(struct page* page, struct writeback_control *wbc) 1336static int cifs_writepage(struct page *page, struct writeback_control *wbc)
1330{ 1337{
1331 int rc = -EFAULT; 1338 int rc = -EFAULT;
1332 int xid; 1339 int xid;
@@ -1334,7 +1341,7 @@ static int cifs_writepage(struct page* page, struct writeback_control *wbc)
1334 xid = GetXid(); 1341 xid = GetXid();
1335/* BB add check for wbc flags */ 1342/* BB add check for wbc flags */
1336 page_cache_get(page); 1343 page_cache_get(page);
1337 if (!PageUptodate(page)) { 1344 if (!PageUptodate(page)) {
1338 cFYI(1, ("ppw - page not up to date")); 1345 cFYI(1, ("ppw - page not up to date"));
1339 } 1346 }
1340 1347
@@ -1348,7 +1355,7 @@ static int cifs_writepage(struct page* page, struct writeback_control *wbc)
1348 * Just unlocking the page will cause the radix tree tag-bits 1355 * Just unlocking the page will cause the radix tree tag-bits
1349 * to fail to update with the state of the page correctly. 1356 * to fail to update with the state of the page correctly.
1350 */ 1357 */
1351 set_page_writeback(page); 1358 set_page_writeback(page);
1352 rc = cifs_partialpagewrite(page, 0, PAGE_CACHE_SIZE); 1359 rc = cifs_partialpagewrite(page, 0, PAGE_CACHE_SIZE);
1353 SetPageUptodate(page); /* BB add check for error and Clearuptodate? */ 1360 SetPageUptodate(page); /* BB add check for error and Clearuptodate? */
1354 unlock_page(page); 1361 unlock_page(page);
@@ -1368,7 +1375,7 @@ static int cifs_commit_write(struct file *file, struct page *page,
1368 char *page_data; 1375 char *page_data;
1369 1376
1370 xid = GetXid(); 1377 xid = GetXid();
1371 cFYI(1, ("commit write for page %p up to position %lld for %d", 1378 cFYI(1, ("commit write for page %p up to position %lld for %d",
1372 page, position, to)); 1379 page, position, to));
1373 spin_lock(&inode->i_lock); 1380 spin_lock(&inode->i_lock);
1374 if (position > inode->i_size) { 1381 if (position > inode->i_size) {
@@ -1396,7 +1403,7 @@ static int cifs_commit_write(struct file *file, struct page *page,
1396 rc = 0; 1403 rc = 0;
1397 /* else if (rc < 0) should we set writebehind rc? */ 1404 /* else if (rc < 0) should we set writebehind rc? */
1398 kunmap(page); 1405 kunmap(page);
1399 } else { 1406 } else {
1400 set_page_dirty(page); 1407 set_page_dirty(page);
1401 } 1408 }
1402 1409
@@ -1412,9 +1419,9 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
1412 1419
1413 xid = GetXid(); 1420 xid = GetXid();
1414 1421
1415 cFYI(1, ("Sync file - name: %s datasync: 0x%x", 1422 cFYI(1, ("Sync file - name: %s datasync: 0x%x",
1416 dentry->d_name.name, datasync)); 1423 dentry->d_name.name, datasync));
1417 1424
1418 rc = filemap_fdatawrite(inode->i_mapping); 1425 rc = filemap_fdatawrite(inode->i_mapping);
1419 if (rc == 0) 1426 if (rc == 0)
1420 CIFS_I(inode)->write_behind_rc = 0; 1427 CIFS_I(inode)->write_behind_rc = 0;
@@ -1438,7 +1445,7 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
1438 if (!inode) 1445 if (!inode)
1439 return; */ 1446 return; */
1440 1447
1441/* fill in rpages then 1448/* fill in rpages then
1442 result = cifs_pagein_inode(inode, index, rpages); */ /* BB finish */ 1449 result = cifs_pagein_inode(inode, index, rpages); */ /* BB finish */
1443 1450
1444/* cFYI(1, ("rpages is %d for sync page of Index %ld", rpages, index)); 1451/* cFYI(1, ("rpages is %d for sync page of Index %ld", rpages, index));
@@ -1456,7 +1463,7 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
1456 */ 1463 */
1457int cifs_flush(struct file *file, fl_owner_t id) 1464int cifs_flush(struct file *file, fl_owner_t id)
1458{ 1465{
1459 struct inode * inode = file->f_path.dentry->d_inode; 1466 struct inode *inode = file->f_path.dentry->d_inode;
1460 int rc = 0; 1467 int rc = 0;
1461 1468
1462 /* Rather than do the steps manually: 1469 /* Rather than do the steps manually:
@@ -1471,8 +1478,8 @@ int cifs_flush(struct file *file, fl_owner_t id)
1471 rc = filemap_fdatawrite(inode->i_mapping); 1478 rc = filemap_fdatawrite(inode->i_mapping);
1472 if (!rc) /* reset wb rc if we were able to write out dirty pages */ 1479 if (!rc) /* reset wb rc if we were able to write out dirty pages */
1473 CIFS_I(inode)->write_behind_rc = 0; 1480 CIFS_I(inode)->write_behind_rc = 0;
1474 1481
1475 cFYI(1, ("Flush inode %p file %p rc %d",inode,file,rc)); 1482 cFYI(1, ("Flush inode %p file %p rc %d", inode, file, rc));
1476 1483
1477 return rc; 1484 return rc;
1478} 1485}
@@ -1508,13 +1515,13 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
1508 for (total_read = 0, current_offset = read_data; 1515 for (total_read = 0, current_offset = read_data;
1509 read_size > total_read; 1516 read_size > total_read;
1510 total_read += bytes_read, current_offset += bytes_read) { 1517 total_read += bytes_read, current_offset += bytes_read) {
1511 current_read_size = min_t(const int, read_size - total_read, 1518 current_read_size = min_t(const int, read_size - total_read,
1512 cifs_sb->rsize); 1519 cifs_sb->rsize);
1513 rc = -EAGAIN; 1520 rc = -EAGAIN;
1514 smb_read_data = NULL; 1521 smb_read_data = NULL;
1515 while (rc == -EAGAIN) { 1522 while (rc == -EAGAIN) {
1516 int buf_type = CIFS_NO_BUFFER; 1523 int buf_type = CIFS_NO_BUFFER;
1517 if ((open_file->invalidHandle) && 1524 if ((open_file->invalidHandle) &&
1518 (!open_file->closePend)) { 1525 (!open_file->closePend)) {
1519 rc = cifs_reopen_file(file, TRUE); 1526 rc = cifs_reopen_file(file, TRUE);
1520 if (rc != 0) 1527 if (rc != 0)
@@ -1535,9 +1542,9 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
1535 rc = -EFAULT; 1542 rc = -EFAULT;
1536 } 1543 }
1537 1544
1538 if(buf_type == CIFS_SMALL_BUFFER) 1545 if (buf_type == CIFS_SMALL_BUFFER)
1539 cifs_small_buf_release(smb_read_data); 1546 cifs_small_buf_release(smb_read_data);
1540 else if(buf_type == CIFS_LARGE_BUFFER) 1547 else if (buf_type == CIFS_LARGE_BUFFER)
1541 cifs_buf_release(smb_read_data); 1548 cifs_buf_release(smb_read_data);
1542 smb_read_data = NULL; 1549 smb_read_data = NULL;
1543 } 1550 }
@@ -1586,21 +1593,21 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
1586 if ((file->f_flags & O_ACCMODE) == O_WRONLY) 1593 if ((file->f_flags & O_ACCMODE) == O_WRONLY)
1587 cFYI(1, ("attempting read on write only file instance")); 1594 cFYI(1, ("attempting read on write only file instance"));
1588 1595
1589 for (total_read = 0, current_offset = read_data; 1596 for (total_read = 0, current_offset = read_data;
1590 read_size > total_read; 1597 read_size > total_read;
1591 total_read += bytes_read, current_offset += bytes_read) { 1598 total_read += bytes_read, current_offset += bytes_read) {
1592 current_read_size = min_t(const int, read_size - total_read, 1599 current_read_size = min_t(const int, read_size - total_read,
1593 cifs_sb->rsize); 1600 cifs_sb->rsize);
1594 /* For windows me and 9x we do not want to request more 1601 /* For windows me and 9x we do not want to request more
1595 than it negotiated since it will refuse the read then */ 1602 than it negotiated since it will refuse the read then */
1596 if((pTcon->ses) && 1603 if ((pTcon->ses) &&
1597 !(pTcon->ses->capabilities & CAP_LARGE_FILES)) { 1604 !(pTcon->ses->capabilities & CAP_LARGE_FILES)) {
1598 current_read_size = min_t(const int, current_read_size, 1605 current_read_size = min_t(const int, current_read_size,
1599 pTcon->ses->server->maxBuf - 128); 1606 pTcon->ses->server->maxBuf - 128);
1600 } 1607 }
1601 rc = -EAGAIN; 1608 rc = -EAGAIN;
1602 while (rc == -EAGAIN) { 1609 while (rc == -EAGAIN) {
1603 if ((open_file->invalidHandle) && 1610 if ((open_file->invalidHandle) &&
1604 (!open_file->closePend)) { 1611 (!open_file->closePend)) {
1605 rc = cifs_reopen_file(file, TRUE); 1612 rc = cifs_reopen_file(file, TRUE);
1606 if (rc != 0) 1613 if (rc != 0)
@@ -1646,7 +1653,7 @@ int cifs_file_mmap(struct file *file, struct vm_area_struct *vma)
1646} 1653}
1647 1654
1648 1655
1649static void cifs_copy_cache_pages(struct address_space *mapping, 1656static void cifs_copy_cache_pages(struct address_space *mapping,
1650 struct list_head *pages, int bytes_read, char *data, 1657 struct list_head *pages, int bytes_read, char *data,
1651 struct pagevec *plru_pvec) 1658 struct pagevec *plru_pvec)
1652{ 1659{
@@ -1669,12 +1676,12 @@ static void cifs_copy_cache_pages(struct address_space *mapping,
1669 continue; 1676 continue;
1670 } 1677 }
1671 1678
1672 target = kmap_atomic(page,KM_USER0); 1679 target = kmap_atomic(page, KM_USER0);
1673 1680
1674 if (PAGE_CACHE_SIZE > bytes_read) { 1681 if (PAGE_CACHE_SIZE > bytes_read) {
1675 memcpy(target, data, bytes_read); 1682 memcpy(target, data, bytes_read);
1676 /* zero the tail end of this partial page */ 1683 /* zero the tail end of this partial page */
1677 memset(target + bytes_read, 0, 1684 memset(target + bytes_read, 0,
1678 PAGE_CACHE_SIZE - bytes_read); 1685 PAGE_CACHE_SIZE - bytes_read);
1679 bytes_read = 0; 1686 bytes_read = 0;
1680 } else { 1687 } else {
@@ -1703,7 +1710,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1703 struct cifs_sb_info *cifs_sb; 1710 struct cifs_sb_info *cifs_sb;
1704 struct cifsTconInfo *pTcon; 1711 struct cifsTconInfo *pTcon;
1705 int bytes_read = 0; 1712 int bytes_read = 0;
1706 unsigned int read_size,i; 1713 unsigned int read_size, i;
1707 char *smb_read_data = NULL; 1714 char *smb_read_data = NULL;
1708 struct smb_com_read_rsp *pSMBr; 1715 struct smb_com_read_rsp *pSMBr;
1709 struct pagevec lru_pvec; 1716 struct pagevec lru_pvec;
@@ -1720,7 +1727,9 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1720 pTcon = cifs_sb->tcon; 1727 pTcon = cifs_sb->tcon;
1721 1728
1722 pagevec_init(&lru_pvec, 0); 1729 pagevec_init(&lru_pvec, 0);
1723 1730#ifdef CONFIG_CIFS_DEBUG2
1731 cFYI(1, ("rpages: num pages %d", num_pages));
1732#endif
1724 for (i = 0; i < num_pages; ) { 1733 for (i = 0; i < num_pages; ) {
1725 unsigned contig_pages; 1734 unsigned contig_pages;
1726 struct page *tmp_page; 1735 struct page *tmp_page;
@@ -1734,14 +1743,14 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1734 1743
1735 /* count adjacent pages that we will read into */ 1744 /* count adjacent pages that we will read into */
1736 contig_pages = 0; 1745 contig_pages = 0;
1737 expected_index = 1746 expected_index =
1738 list_entry(page_list->prev, struct page, lru)->index; 1747 list_entry(page_list->prev, struct page, lru)->index;
1739 list_for_each_entry_reverse(tmp_page,page_list,lru) { 1748 list_for_each_entry_reverse(tmp_page, page_list, lru) {
1740 if (tmp_page->index == expected_index) { 1749 if (tmp_page->index == expected_index) {
1741 contig_pages++; 1750 contig_pages++;
1742 expected_index++; 1751 expected_index++;
1743 } else 1752 } else
1744 break; 1753 break;
1745 } 1754 }
1746 if (contig_pages + i > num_pages) 1755 if (contig_pages + i > num_pages)
1747 contig_pages = num_pages - i; 1756 contig_pages = num_pages - i;
@@ -1753,10 +1762,13 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1753 /* Read size needs to be in multiples of one page */ 1762 /* Read size needs to be in multiples of one page */
1754 read_size = min_t(const unsigned int, read_size, 1763 read_size = min_t(const unsigned int, read_size,
1755 cifs_sb->rsize & PAGE_CACHE_MASK); 1764 cifs_sb->rsize & PAGE_CACHE_MASK);
1756 1765#ifdef CONFIG_CIFS_DEBUG2
1766 cFYI(1, ("rpages: read size 0x%x contiguous pages %d",
1767 read_size, contig_pages));
1768#endif
1757 rc = -EAGAIN; 1769 rc = -EAGAIN;
1758 while (rc == -EAGAIN) { 1770 while (rc == -EAGAIN) {
1759 if ((open_file->invalidHandle) && 1771 if ((open_file->invalidHandle) &&
1760 (!open_file->closePend)) { 1772 (!open_file->closePend)) {
1761 rc = cifs_reopen_file(file, TRUE); 1773 rc = cifs_reopen_file(file, TRUE);
1762 if (rc != 0) 1774 if (rc != 0)
@@ -1769,11 +1781,11 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1769 &bytes_read, &smb_read_data, 1781 &bytes_read, &smb_read_data,
1770 &buf_type); 1782 &buf_type);
1771 /* BB more RC checks ? */ 1783 /* BB more RC checks ? */
1772 if (rc== -EAGAIN) { 1784 if (rc == -EAGAIN) {
1773 if (smb_read_data) { 1785 if (smb_read_data) {
1774 if(buf_type == CIFS_SMALL_BUFFER) 1786 if (buf_type == CIFS_SMALL_BUFFER)
1775 cifs_small_buf_release(smb_read_data); 1787 cifs_small_buf_release(smb_read_data);
1776 else if(buf_type == CIFS_LARGE_BUFFER) 1788 else if (buf_type == CIFS_LARGE_BUFFER)
1777 cifs_buf_release(smb_read_data); 1789 cifs_buf_release(smb_read_data);
1778 smb_read_data = NULL; 1790 smb_read_data = NULL;
1779 } 1791 }
@@ -1794,10 +1806,10 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1794 if ((int)(bytes_read & PAGE_CACHE_MASK) != bytes_read) { 1806 if ((int)(bytes_read & PAGE_CACHE_MASK) != bytes_read) {
1795 i++; /* account for partial page */ 1807 i++; /* account for partial page */
1796 1808
1797 /* server copy of file can have smaller size 1809 /* server copy of file can have smaller size
1798 than client */ 1810 than client */
1799 /* BB do we need to verify this common case ? 1811 /* BB do we need to verify this common case ?
1800 this case is ok - if we are at server EOF 1812 this case is ok - if we are at server EOF
1801 we will hit it on next read */ 1813 we will hit it on next read */
1802 1814
1803 /* break; */ 1815 /* break; */
@@ -1806,14 +1818,14 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1806 cFYI(1, ("No bytes read (%d) at offset %lld . " 1818 cFYI(1, ("No bytes read (%d) at offset %lld . "
1807 "Cleaning remaining pages from readahead list", 1819 "Cleaning remaining pages from readahead list",
1808 bytes_read, offset)); 1820 bytes_read, offset));
1809 /* BB turn off caching and do new lookup on 1821 /* BB turn off caching and do new lookup on
1810 file size at server? */ 1822 file size at server? */
1811 break; 1823 break;
1812 } 1824 }
1813 if (smb_read_data) { 1825 if (smb_read_data) {
1814 if(buf_type == CIFS_SMALL_BUFFER) 1826 if (buf_type == CIFS_SMALL_BUFFER)
1815 cifs_small_buf_release(smb_read_data); 1827 cifs_small_buf_release(smb_read_data);
1816 else if(buf_type == CIFS_LARGE_BUFFER) 1828 else if (buf_type == CIFS_LARGE_BUFFER)
1817 cifs_buf_release(smb_read_data); 1829 cifs_buf_release(smb_read_data);
1818 smb_read_data = NULL; 1830 smb_read_data = NULL;
1819 } 1831 }
@@ -1824,12 +1836,12 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1824 1836
1825/* need to free smb_read_data buf before exit */ 1837/* need to free smb_read_data buf before exit */
1826 if (smb_read_data) { 1838 if (smb_read_data) {
1827 if(buf_type == CIFS_SMALL_BUFFER) 1839 if (buf_type == CIFS_SMALL_BUFFER)
1828 cifs_small_buf_release(smb_read_data); 1840 cifs_small_buf_release(smb_read_data);
1829 else if(buf_type == CIFS_LARGE_BUFFER) 1841 else if (buf_type == CIFS_LARGE_BUFFER)
1830 cifs_buf_release(smb_read_data); 1842 cifs_buf_release(smb_read_data);
1831 smb_read_data = NULL; 1843 smb_read_data = NULL;
1832 } 1844 }
1833 1845
1834 FreeXid(xid); 1846 FreeXid(xid);
1835 return rc; 1847 return rc;
@@ -1844,26 +1856,26 @@ static int cifs_readpage_worker(struct file *file, struct page *page,
1844 page_cache_get(page); 1856 page_cache_get(page);
1845 read_data = kmap(page); 1857 read_data = kmap(page);
1846 /* for reads over a certain size could initiate async read ahead */ 1858 /* for reads over a certain size could initiate async read ahead */
1847 1859
1848 rc = cifs_read(file, read_data, PAGE_CACHE_SIZE, poffset); 1860 rc = cifs_read(file, read_data, PAGE_CACHE_SIZE, poffset);
1849 1861
1850 if (rc < 0) 1862 if (rc < 0)
1851 goto io_error; 1863 goto io_error;
1852 else 1864 else
1853 cFYI(1, ("Bytes read %d",rc)); 1865 cFYI(1, ("Bytes read %d", rc));
1854 1866
1855 file->f_path.dentry->d_inode->i_atime = 1867 file->f_path.dentry->d_inode->i_atime =
1856 current_fs_time(file->f_path.dentry->d_inode->i_sb); 1868 current_fs_time(file->f_path.dentry->d_inode->i_sb);
1857 1869
1858 if (PAGE_CACHE_SIZE > rc) 1870 if (PAGE_CACHE_SIZE > rc)
1859 memset(read_data + rc, 0, PAGE_CACHE_SIZE - rc); 1871 memset(read_data + rc, 0, PAGE_CACHE_SIZE - rc);
1860 1872
1861 flush_dcache_page(page); 1873 flush_dcache_page(page);
1862 SetPageUptodate(page); 1874 SetPageUptodate(page);
1863 rc = 0; 1875 rc = 0;
1864 1876
1865io_error: 1877io_error:
1866 kunmap(page); 1878 kunmap(page);
1867 page_cache_release(page); 1879 page_cache_release(page);
1868 return rc; 1880 return rc;
1869} 1881}
@@ -1881,7 +1893,7 @@ static int cifs_readpage(struct file *file, struct page *page)
1881 return -EBADF; 1893 return -EBADF;
1882 } 1894 }
1883 1895
1884 cFYI(1, ("readpage %p at offset %d 0x%x\n", 1896 cFYI(1, ("readpage %p at offset %d 0x%x\n",
1885 page, (int)offset, (int)offset)); 1897 page, (int)offset, (int)offset));
1886 1898
1887 rc = cifs_readpage_worker(file, page, &offset); 1899 rc = cifs_readpage_worker(file, page, &offset);
@@ -1895,7 +1907,7 @@ static int cifs_readpage(struct file *file, struct page *page)
1895/* We do not want to update the file size from server for inodes 1907/* We do not want to update the file size from server for inodes
1896 open for write - to avoid races with writepage extending 1908 open for write - to avoid races with writepage extending
1897 the file - in the future we could consider allowing 1909 the file - in the future we could consider allowing
1898 refreshing the inode only on increases in the file size 1910 refreshing the inode only on increases in the file size
1899 but this is tricky to do without racing with writebehind 1911 but this is tricky to do without racing with writebehind
1900 page caching in the current Linux kernel design */ 1912 page caching in the current Linux kernel design */
1901int is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file) 1913int is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file)
@@ -1904,8 +1916,8 @@ int is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file)
1904 1916
1905 if (cifsInode) 1917 if (cifsInode)
1906 open_file = find_writable_file(cifsInode); 1918 open_file = find_writable_file(cifsInode);
1907 1919
1908 if(open_file) { 1920 if (open_file) {
1909 struct cifs_sb_info *cifs_sb; 1921 struct cifs_sb_info *cifs_sb;
1910 1922
1911 /* there is not actually a write pending so let 1923 /* there is not actually a write pending so let
@@ -1915,12 +1927,12 @@ int is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file)
1915 1927
1916 cifs_sb = CIFS_SB(cifsInode->vfs_inode.i_sb); 1928 cifs_sb = CIFS_SB(cifsInode->vfs_inode.i_sb);
1917 if ( cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO ) { 1929 if ( cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO ) {
1918 /* since no page cache to corrupt on directio 1930 /* since no page cache to corrupt on directio
1919 we can change size safely */ 1931 we can change size safely */
1920 return 1; 1932 return 1;
1921 } 1933 }
1922 1934
1923 if(i_size_read(&cifsInode->vfs_inode) < end_of_file) 1935 if (i_size_read(&cifsInode->vfs_inode) < end_of_file)
1924 return 1; 1936 return 1;
1925 1937
1926 return 0; 1938 return 0;
@@ -1935,7 +1947,7 @@ static int cifs_prepare_write(struct file *file, struct page *page,
1935 loff_t i_size; 1947 loff_t i_size;
1936 loff_t offset; 1948 loff_t offset;
1937 1949
1938 cFYI(1, ("prepare write for page %p from %d to %d",page,from,to)); 1950 cFYI(1, ("prepare write for page %p from %d to %d", page, from, to));
1939 if (PageUptodate(page)) 1951 if (PageUptodate(page))
1940 return 0; 1952 return 0;
1941 1953
@@ -1955,14 +1967,7 @@ static int cifs_prepare_write(struct file *file, struct page *page,
1955 * We don't need to read data beyond the end of the file. 1967 * We don't need to read data beyond the end of the file.
1956 * zero it, and set the page uptodate 1968 * zero it, and set the page uptodate
1957 */ 1969 */
1958 void *kaddr = kmap_atomic(page, KM_USER0); 1970 simple_prepare_write(file, page, from, to);
1959
1960 if (from)
1961 memset(kaddr, 0, from);
1962 if (to < PAGE_CACHE_SIZE)
1963 memset(kaddr + to, 0, PAGE_CACHE_SIZE - to);
1964 flush_dcache_page(page);
1965 kunmap_atomic(kaddr, KM_USER0);
1966 SetPageUptodate(page); 1971 SetPageUptodate(page);
1967 } else if ((file->f_flags & O_ACCMODE) != O_WRONLY) { 1972 } else if ((file->f_flags & O_ACCMODE) != O_WRONLY) {
1968 /* might as well read a page, it is fast enough */ 1973 /* might as well read a page, it is fast enough */
@@ -1974,8 +1979,8 @@ static int cifs_prepare_write(struct file *file, struct page *page,
1974 this will be written out by commit_write so is fine */ 1979 this will be written out by commit_write so is fine */
1975 } 1980 }
1976 1981
1977 /* we do not need to pass errors back 1982 /* we do not need to pass errors back
1978 e.g. if we do not have read access to the file 1983 e.g. if we do not have read access to the file
1979 because cifs_commit_write will do the right thing. -- shaggy */ 1984 because cifs_commit_write will do the right thing. -- shaggy */
1980 1985
1981 return 0; 1986 return 0;
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index f0ff12b3f398..dd4167762a8e 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -57,14 +57,14 @@ int cifs_get_inode_info_unix(struct inode **pinode,
57 if (tmp_path == NULL) { 57 if (tmp_path == NULL) {
58 return -ENOMEM; 58 return -ENOMEM;
59 } 59 }
60 /* have to skip first of the double backslash of 60 /* have to skip first of the double backslash of
61 UNC name */ 61 UNC name */
62 strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE); 62 strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE);
63 strncat(tmp_path, search_path, MAX_PATHCONF); 63 strncat(tmp_path, search_path, MAX_PATHCONF);
64 rc = connect_to_dfs_path(xid, pTcon->ses, 64 rc = connect_to_dfs_path(xid, pTcon->ses,
65 /* treename + */ tmp_path, 65 /* treename + */ tmp_path,
66 cifs_sb->local_nls, 66 cifs_sb->local_nls,
67 cifs_sb->mnt_cifs_flags & 67 cifs_sb->mnt_cifs_flags &
68 CIFS_MOUNT_MAP_SPECIAL_CHR); 68 CIFS_MOUNT_MAP_SPECIAL_CHR);
69 kfree(tmp_path); 69 kfree(tmp_path);
70 70
@@ -81,7 +81,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
81 /* get new inode */ 81 /* get new inode */
82 if (*pinode == NULL) { 82 if (*pinode == NULL) {
83 *pinode = new_inode(sb); 83 *pinode = new_inode(sb);
84 if (*pinode == NULL) 84 if (*pinode == NULL)
85 return -ENOMEM; 85 return -ENOMEM;
86 /* Is an i_ino of zero legal? */ 86 /* Is an i_ino of zero legal? */
87 /* Are there sanity checks we can use to ensure that 87 /* Are there sanity checks we can use to ensure that
@@ -92,7 +92,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
92 } /* note ino incremented to unique num in new_inode */ 92 } /* note ino incremented to unique num in new_inode */
93 if (sb->s_flags & MS_NOATIME) 93 if (sb->s_flags & MS_NOATIME)
94 (*pinode)->i_flags |= S_NOATIME | S_NOCMTIME; 94 (*pinode)->i_flags |= S_NOATIME | S_NOCMTIME;
95 95
96 insert_inode_hash(*pinode); 96 insert_inode_hash(*pinode);
97 } 97 }
98 98
@@ -103,7 +103,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
103 cifsInfo->time = jiffies; 103 cifsInfo->time = jiffies;
104 cFYI(1, ("New time %ld", cifsInfo->time)); 104 cFYI(1, ("New time %ld", cifsInfo->time));
105 /* this is ok to set on every inode revalidate */ 105 /* this is ok to set on every inode revalidate */
106 atomic_set(&cifsInfo->inUse,1); 106 atomic_set(&cifsInfo->inUse, 1);
107 107
108 inode->i_atime = 108 inode->i_atime =
109 cifs_NTtimeToUnix(le64_to_cpu(findData.LastAccessTime)); 109 cifs_NTtimeToUnix(le64_to_cpu(findData.LastAccessTime));
@@ -114,8 +114,8 @@ int cifs_get_inode_info_unix(struct inode **pinode,
114 cifs_NTtimeToUnix(le64_to_cpu(findData.LastStatusChange)); 114 cifs_NTtimeToUnix(le64_to_cpu(findData.LastStatusChange));
115 inode->i_mode = le64_to_cpu(findData.Permissions); 115 inode->i_mode = le64_to_cpu(findData.Permissions);
116 /* since we set the inode type below we need to mask off 116 /* since we set the inode type below we need to mask off
117 to avoid strange results if bits set above */ 117 to avoid strange results if bits set above */
118 inode->i_mode &= ~S_IFMT; 118 inode->i_mode &= ~S_IFMT;
119 if (type == UNIX_FILE) { 119 if (type == UNIX_FILE) {
120 inode->i_mode |= S_IFREG; 120 inode->i_mode |= S_IFREG;
121 } else if (type == UNIX_SYMLINK) { 121 } else if (type == UNIX_SYMLINK) {
@@ -137,9 +137,9 @@ int cifs_get_inode_info_unix(struct inode **pinode,
137 } else { 137 } else {
138 /* safest to call it a file if we do not know */ 138 /* safest to call it a file if we do not know */
139 inode->i_mode |= S_IFREG; 139 inode->i_mode |= S_IFREG;
140 cFYI(1,("unknown type %d",type)); 140 cFYI(1, ("unknown type %d", type));
141 } 141 }
142 142
143 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) 143 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
144 inode->i_uid = cifs_sb->mnt_uid; 144 inode->i_uid = cifs_sb->mnt_uid;
145 else 145 else
@@ -149,7 +149,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
149 inode->i_gid = cifs_sb->mnt_gid; 149 inode->i_gid = cifs_sb->mnt_gid;
150 else 150 else
151 inode->i_gid = le64_to_cpu(findData.Gid); 151 inode->i_gid = le64_to_cpu(findData.Gid);
152 152
153 inode->i_nlink = le64_to_cpu(findData.Nlinks); 153 inode->i_nlink = le64_to_cpu(findData.Nlinks);
154 154
155 spin_lock(&inode->i_lock); 155 spin_lock(&inode->i_lock);
@@ -183,17 +183,17 @@ int cifs_get_inode_info_unix(struct inode **pinode,
183 inode->i_op = &cifs_file_inode_ops; 183 inode->i_op = &cifs_file_inode_ops;
184 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { 184 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
185 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 185 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
186 inode->i_fop = 186 inode->i_fop =
187 &cifs_file_direct_nobrl_ops; 187 &cifs_file_direct_nobrl_ops;
188 else 188 else
189 inode->i_fop = &cifs_file_direct_ops; 189 inode->i_fop = &cifs_file_direct_ops;
190 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 190 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
191 inode->i_fop = &cifs_file_nobrl_ops; 191 inode->i_fop = &cifs_file_nobrl_ops;
192 else /* not direct, send byte range locks */ 192 else /* not direct, send byte range locks */
193 inode->i_fop = &cifs_file_ops; 193 inode->i_fop = &cifs_file_ops;
194 194
195 /* check if server can support readpages */ 195 /* check if server can support readpages */
196 if (pTcon->ses->server->maxBuf < 196 if (pTcon->ses->server->maxBuf <
197 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE) 197 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)
198 inode->i_data.a_ops = &cifs_addr_ops_smallbuf; 198 inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
199 else 199 else
@@ -215,7 +215,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
215 return rc; 215 return rc;
216} 216}
217 217
218static int decode_sfu_inode(struct inode * inode, __u64 size, 218static int decode_sfu_inode(struct inode *inode, __u64 size,
219 const unsigned char *path, 219 const unsigned char *path,
220 struct cifs_sb_info *cifs_sb, int xid) 220 struct cifs_sb_info *cifs_sb, int xid)
221{ 221{
@@ -225,7 +225,7 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
225 struct cifsTconInfo *pTcon = cifs_sb->tcon; 225 struct cifsTconInfo *pTcon = cifs_sb->tcon;
226 char buf[24]; 226 char buf[24];
227 unsigned int bytes_read; 227 unsigned int bytes_read;
228 char * pbuf; 228 char *pbuf;
229 229
230 pbuf = buf; 230 pbuf = buf;
231 231
@@ -235,22 +235,22 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
235 } else if (size < 8) { 235 } else if (size < 8) {
236 return -EINVAL; /* EOPNOTSUPP? */ 236 return -EINVAL; /* EOPNOTSUPP? */
237 } 237 }
238 238
239 rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ, 239 rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ,
240 CREATE_NOT_DIR, &netfid, &oplock, NULL, 240 CREATE_NOT_DIR, &netfid, &oplock, NULL,
241 cifs_sb->local_nls, 241 cifs_sb->local_nls,
242 cifs_sb->mnt_cifs_flags & 242 cifs_sb->mnt_cifs_flags &
243 CIFS_MOUNT_MAP_SPECIAL_CHR); 243 CIFS_MOUNT_MAP_SPECIAL_CHR);
244 if (rc==0) { 244 if (rc == 0) {
245 int buf_type = CIFS_NO_BUFFER; 245 int buf_type = CIFS_NO_BUFFER;
246 /* Read header */ 246 /* Read header */
247 rc = CIFSSMBRead(xid, pTcon, 247 rc = CIFSSMBRead(xid, pTcon,
248 netfid, 248 netfid,
249 24 /* length */, 0 /* offset */, 249 24 /* length */, 0 /* offset */,
250 &bytes_read, &pbuf, &buf_type); 250 &bytes_read, &pbuf, &buf_type);
251 if ((rc == 0) && (bytes_read >= 8)) { 251 if ((rc == 0) && (bytes_read >= 8)) {
252 if (memcmp("IntxBLK", pbuf, 8) == 0) { 252 if (memcmp("IntxBLK", pbuf, 8) == 0) {
253 cFYI(1,("Block device")); 253 cFYI(1, ("Block device"));
254 inode->i_mode |= S_IFBLK; 254 inode->i_mode |= S_IFBLK;
255 if (bytes_read == 24) { 255 if (bytes_read == 24) {
256 /* we have enough to decode dev num */ 256 /* we have enough to decode dev num */
@@ -261,7 +261,7 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
261 inode->i_rdev = MKDEV(mjr, mnr); 261 inode->i_rdev = MKDEV(mjr, mnr);
262 } 262 }
263 } else if (memcmp("IntxCHR", pbuf, 8) == 0) { 263 } else if (memcmp("IntxCHR", pbuf, 8) == 0) {
264 cFYI(1,("Char device")); 264 cFYI(1, ("Char device"));
265 inode->i_mode |= S_IFCHR; 265 inode->i_mode |= S_IFCHR;
266 if (bytes_read == 24) { 266 if (bytes_read == 24) {
267 /* we have enough to decode dev num */ 267 /* we have enough to decode dev num */
@@ -270,27 +270,26 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
270 mjr = le64_to_cpu(*(__le64 *)(pbuf+8)); 270 mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
271 mnr = le64_to_cpu(*(__le64 *)(pbuf+16)); 271 mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
272 inode->i_rdev = MKDEV(mjr, mnr); 272 inode->i_rdev = MKDEV(mjr, mnr);
273 } 273 }
274 } else if (memcmp("IntxLNK", pbuf, 7) == 0) { 274 } else if (memcmp("IntxLNK", pbuf, 7) == 0) {
275 cFYI(1,("Symlink")); 275 cFYI(1, ("Symlink"));
276 inode->i_mode |= S_IFLNK; 276 inode->i_mode |= S_IFLNK;
277 } else { 277 } else {
278 inode->i_mode |= S_IFREG; /* file? */ 278 inode->i_mode |= S_IFREG; /* file? */
279 rc = -EOPNOTSUPP; 279 rc = -EOPNOTSUPP;
280 } 280 }
281 } else { 281 } else {
282 inode->i_mode |= S_IFREG; /* then it is a file */ 282 inode->i_mode |= S_IFREG; /* then it is a file */
283 rc = -EOPNOTSUPP; /* or some unknown SFU type */ 283 rc = -EOPNOTSUPP; /* or some unknown SFU type */
284 } 284 }
285 CIFSSMBClose(xid, pTcon, netfid); 285 CIFSSMBClose(xid, pTcon, netfid);
286 } 286 }
287 return rc; 287 return rc;
288
289} 288}
290 289
291#define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID) /* SETFILEBITS valid bits */ 290#define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID) /* SETFILEBITS valid bits */
292 291
293static int get_sfu_uid_mode(struct inode * inode, 292static int get_sfu_uid_mode(struct inode *inode,
294 const unsigned char *path, 293 const unsigned char *path,
295 struct cifs_sb_info *cifs_sb, int xid) 294 struct cifs_sb_info *cifs_sb, int xid)
296{ 295{
@@ -301,15 +300,15 @@ static int get_sfu_uid_mode(struct inode * inode,
301 300
302 rc = CIFSSMBQueryEA(xid, cifs_sb->tcon, path, "SETFILEBITS", 301 rc = CIFSSMBQueryEA(xid, cifs_sb->tcon, path, "SETFILEBITS",
303 ea_value, 4 /* size of buf */, cifs_sb->local_nls, 302 ea_value, 4 /* size of buf */, cifs_sb->local_nls,
304 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 303 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
305 if (rc < 0) 304 if (rc < 0)
306 return (int)rc; 305 return (int)rc;
307 else if (rc > 3) { 306 else if (rc > 3) {
308 mode = le32_to_cpu(*((__le32 *)ea_value)); 307 mode = le32_to_cpu(*((__le32 *)ea_value));
309 inode->i_mode &= ~SFBITS_MASK; 308 inode->i_mode &= ~SFBITS_MASK;
310 cFYI(1,("special bits 0%o org mode 0%o", mode, inode->i_mode)); 309 cFYI(1, ("special bits 0%o org mode 0%o", mode, inode->i_mode));
311 inode->i_mode = (mode & SFBITS_MASK) | inode->i_mode; 310 inode->i_mode = (mode & SFBITS_MASK) | inode->i_mode;
312 cFYI(1,("special mode bits 0%o", mode)); 311 cFYI(1, ("special mode bits 0%o", mode));
313 return 0; 312 return 0;
314 } else { 313 } else {
315 return 0; 314 return 0;
@@ -317,8 +316,6 @@ static int get_sfu_uid_mode(struct inode * inode,
317#else 316#else
318 return -EOPNOTSUPP; 317 return -EOPNOTSUPP;
319#endif 318#endif
320
321
322} 319}
323 320
324int cifs_get_inode_info(struct inode **pinode, 321int cifs_get_inode_info(struct inode **pinode,
@@ -334,11 +331,11 @@ int cifs_get_inode_info(struct inode **pinode,
334 int adjustTZ = FALSE; 331 int adjustTZ = FALSE;
335 332
336 pTcon = cifs_sb->tcon; 333 pTcon = cifs_sb->tcon;
337 cFYI(1,("Getting info on %s", search_path)); 334 cFYI(1, ("Getting info on %s", search_path));
338 335
339 if ((pfindData == NULL) && (*pinode != NULL)) { 336 if ((pfindData == NULL) && (*pinode != NULL)) {
340 if (CIFS_I(*pinode)->clientCanCacheRead) { 337 if (CIFS_I(*pinode)->clientCanCacheRead) {
341 cFYI(1,("No need to revalidate cached inode sizes")); 338 cFYI(1, ("No need to revalidate cached inode sizes"));
342 return rc; 339 return rc;
343 } 340 }
344 } 341 }
@@ -359,12 +356,11 @@ int cifs_get_inode_info(struct inode **pinode,
359 failed at least once - set flag in tcon or mount */ 356 failed at least once - set flag in tcon or mount */
360 if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) { 357 if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) {
361 rc = SMBQueryInformation(xid, pTcon, search_path, 358 rc = SMBQueryInformation(xid, pTcon, search_path,
362 pfindData, cifs_sb->local_nls, 359 pfindData, cifs_sb->local_nls,
363 cifs_sb->mnt_cifs_flags & 360 cifs_sb->mnt_cifs_flags &
364 CIFS_MOUNT_MAP_SPECIAL_CHR); 361 CIFS_MOUNT_MAP_SPECIAL_CHR);
365 adjustTZ = TRUE; 362 adjustTZ = TRUE;
366 } 363 }
367
368 } 364 }
369 /* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */ 365 /* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */
370 if (rc) { 366 if (rc) {
@@ -384,8 +380,8 @@ int cifs_get_inode_info(struct inode **pinode,
384 strncat(tmp_path, search_path, MAX_PATHCONF); 380 strncat(tmp_path, search_path, MAX_PATHCONF);
385 rc = connect_to_dfs_path(xid, pTcon->ses, 381 rc = connect_to_dfs_path(xid, pTcon->ses,
386 /* treename + */ tmp_path, 382 /* treename + */ tmp_path,
387 cifs_sb->local_nls, 383 cifs_sb->local_nls,
388 cifs_sb->mnt_cifs_flags & 384 cifs_sb->mnt_cifs_flags &
389 CIFS_MOUNT_MAP_SPECIAL_CHR); 385 CIFS_MOUNT_MAP_SPECIAL_CHR);
390 kfree(tmp_path); 386 kfree(tmp_path);
391 /* BB fix up inode etc. */ 387 /* BB fix up inode etc. */
@@ -419,17 +415,17 @@ int cifs_get_inode_info(struct inode **pinode,
419 there Windows server or network appliances for which 415 there Windows server or network appliances for which
420 IndexNumber field is not guaranteed unique? */ 416 IndexNumber field is not guaranteed unique? */
421 417
422 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM){ 418 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
423 int rc1 = 0; 419 int rc1 = 0;
424 __u64 inode_num; 420 __u64 inode_num;
425 421
426 rc1 = CIFSGetSrvInodeNumber(xid, pTcon, 422 rc1 = CIFSGetSrvInodeNumber(xid, pTcon,
427 search_path, &inode_num, 423 search_path, &inode_num,
428 cifs_sb->local_nls, 424 cifs_sb->local_nls,
429 cifs_sb->mnt_cifs_flags & 425 cifs_sb->mnt_cifs_flags &
430 CIFS_MOUNT_MAP_SPECIAL_CHR); 426 CIFS_MOUNT_MAP_SPECIAL_CHR);
431 if (rc1) { 427 if (rc1) {
432 cFYI(1,("GetSrvInodeNum rc %d", rc1)); 428 cFYI(1, ("GetSrvInodeNum rc %d", rc1));
433 /* BB EOPNOSUPP disable SERVER_INUM? */ 429 /* BB EOPNOSUPP disable SERVER_INUM? */
434 } else /* do we need cast or hash to ino? */ 430 } else /* do we need cast or hash to ino? */
435 (*pinode)->i_ino = inode_num; 431 (*pinode)->i_ino = inode_num;
@@ -463,7 +459,7 @@ int cifs_get_inode_info(struct inode **pinode,
463 cFYI(0, ("Attributes came in as 0x%x", attr)); 459 cFYI(0, ("Attributes came in as 0x%x", attr));
464 if (adjustTZ && (pTcon->ses) && (pTcon->ses->server)) { 460 if (adjustTZ && (pTcon->ses) && (pTcon->ses->server)) {
465 inode->i_ctime.tv_sec += pTcon->ses->server->timeAdj; 461 inode->i_ctime.tv_sec += pTcon->ses->server->timeAdj;
466 inode->i_mtime.tv_sec += pTcon->ses->server->timeAdj; 462 inode->i_mtime.tv_sec += pTcon->ses->server->timeAdj;
467 } 463 }
468 464
469 /* set default mode. will override for dirs below */ 465 /* set default mode. will override for dirs below */
@@ -471,8 +467,9 @@ int cifs_get_inode_info(struct inode **pinode,
471 /* new inode, can safely set these fields */ 467 /* new inode, can safely set these fields */
472 inode->i_mode = cifs_sb->mnt_file_mode; 468 inode->i_mode = cifs_sb->mnt_file_mode;
473 else /* since we set the inode type below we need to mask off 469 else /* since we set the inode type below we need to mask off
474 to avoid strange results if type changes and both get orred in */ 470 to avoid strange results if type changes and both
475 inode->i_mode &= ~S_IFMT; 471 get orred in */
472 inode->i_mode &= ~S_IFMT;
476/* if (attr & ATTR_REPARSE) */ 473/* if (attr & ATTR_REPARSE) */
477 /* We no longer handle these as symlinks because we could not 474 /* We no longer handle these as symlinks because we could not
478 follow them due to the absolute path with drive letter */ 475 follow them due to the absolute path with drive letter */
@@ -490,13 +487,13 @@ int cifs_get_inode_info(struct inode **pinode,
490/* BB Finish for SFU style symlinks and devices */ 487/* BB Finish for SFU style symlinks and devices */
491 } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && 488 } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
492 (cifsInfo->cifsAttrs & ATTR_SYSTEM)) { 489 (cifsInfo->cifsAttrs & ATTR_SYSTEM)) {
493 if (decode_sfu_inode(inode, 490 if (decode_sfu_inode(inode,
494 le64_to_cpu(pfindData->EndOfFile), 491 le64_to_cpu(pfindData->EndOfFile),
495 search_path, 492 search_path,
496 cifs_sb, xid)) { 493 cifs_sb, xid)) {
497 cFYI(1,("Unrecognized sfu inode type")); 494 cFYI(1, ("Unrecognized sfu inode type"));
498 } 495 }
499 cFYI(1,("sfu mode 0%o",inode->i_mode)); 496 cFYI(1, ("sfu mode 0%o", inode->i_mode));
500 } else { 497 } else {
501 inode->i_mode |= S_IFREG; 498 inode->i_mode |= S_IFREG;
502 /* treat the dos attribute of read-only as read-only 499 /* treat the dos attribute of read-only as read-only
@@ -512,12 +509,12 @@ int cifs_get_inode_info(struct inode **pinode,
512 /* BB add code here - 509 /* BB add code here -
513 validate if device or weird share or device type? */ 510 validate if device or weird share or device type? */
514 } 511 }
515 512
516 spin_lock(&inode->i_lock); 513 spin_lock(&inode->i_lock);
517 if (is_size_safe_to_change(cifsInfo, le64_to_cpu(pfindData->EndOfFile))) { 514 if (is_size_safe_to_change(cifsInfo, le64_to_cpu(pfindData->EndOfFile))) {
518 /* can not safely shrink the file size here if the 515 /* can not safely shrink the file size here if the
519 client is writing to it due to potential races */ 516 client is writing to it due to potential races */
520 i_size_write(inode,le64_to_cpu(pfindData->EndOfFile)); 517 i_size_write(inode, le64_to_cpu(pfindData->EndOfFile));
521 518
522 /* 512 bytes (2**9) is the fake blocksize that must be 519 /* 512 bytes (2**9) is the fake blocksize that must be
523 used for this calculation */ 520 used for this calculation */
@@ -528,7 +525,7 @@ int cifs_get_inode_info(struct inode **pinode,
528 525
529 inode->i_nlink = le32_to_cpu(pfindData->NumberOfLinks); 526 inode->i_nlink = le32_to_cpu(pfindData->NumberOfLinks);
530 527
531 /* BB fill in uid and gid here? with help from winbind? 528 /* BB fill in uid and gid here? with help from winbind?
532 or retrieve from NTFS stream extended attribute */ 529 or retrieve from NTFS stream extended attribute */
533 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { 530 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
534 /* fill in uid, gid, mode from server ACL */ 531 /* fill in uid, gid, mode from server ACL */
@@ -540,7 +537,7 @@ int cifs_get_inode_info(struct inode **pinode,
540 inode->i_gid = cifs_sb->mnt_gid; 537 inode->i_gid = cifs_sb->mnt_gid;
541 /* set so we do not keep refreshing these fields with 538 /* set so we do not keep refreshing these fields with
542 bad data after user has changed them in memory */ 539 bad data after user has changed them in memory */
543 atomic_set(&cifsInfo->inUse,1); 540 atomic_set(&cifsInfo->inUse, 1);
544 } 541 }
545 542
546 if (S_ISREG(inode->i_mode)) { 543 if (S_ISREG(inode->i_mode)) {
@@ -557,7 +554,7 @@ int cifs_get_inode_info(struct inode **pinode,
557 else /* not direct, send byte range locks */ 554 else /* not direct, send byte range locks */
558 inode->i_fop = &cifs_file_ops; 555 inode->i_fop = &cifs_file_ops;
559 556
560 if (pTcon->ses->server->maxBuf < 557 if (pTcon->ses->server->maxBuf <
561 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE) 558 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)
562 inode->i_data.a_ops = &cifs_addr_ops_smallbuf; 559 inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
563 else 560 else
@@ -586,10 +583,11 @@ void cifs_read_inode(struct inode *inode)
586 583
587 cifs_sb = CIFS_SB(inode->i_sb); 584 cifs_sb = CIFS_SB(inode->i_sb);
588 xid = GetXid(); 585 xid = GetXid();
589 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) 586
590 cifs_get_inode_info_unix(&inode, "", inode->i_sb,xid); 587 if (cifs_sb->tcon->unix_ext)
588 cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid);
591 else 589 else
592 cifs_get_inode_info(&inode, "", NULL, inode->i_sb,xid); 590 cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid);
593 /* can not call macro FreeXid here since in a void func */ 591 /* can not call macro FreeXid here since in a void func */
594 _FreeXid(xid); 592 _FreeXid(xid);
595} 593}
@@ -623,9 +621,21 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
623 FreeXid(xid); 621 FreeXid(xid);
624 return -ENOMEM; 622 return -ENOMEM;
625 } 623 }
626 rc = CIFSSMBDelFile(xid, pTcon, full_path, cifs_sb->local_nls, 624
625 if ((pTcon->ses->capabilities & CAP_UNIX) &&
626 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
627 le64_to_cpu(pTcon->fsUnixInfo.Capability))) {
628 rc = CIFSPOSIXDelFile(xid, pTcon, full_path,
629 SMB_POSIX_UNLINK_FILE_TARGET, cifs_sb->local_nls,
627 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 630 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
631 cFYI(1, ("posix del rc %d", rc));
632 if ((rc == 0) || (rc == -ENOENT))
633 goto psx_del_no_retry;
634 }
628 635
636 rc = CIFSSMBDelFile(xid, pTcon, full_path, cifs_sb->local_nls,
637 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
638psx_del_no_retry:
629 if (!rc) { 639 if (!rc) {
630 if (direntry->d_inode) 640 if (direntry->d_inode)
631 drop_nlink(direntry->d_inode); 641 drop_nlink(direntry->d_inode);
@@ -638,12 +648,12 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
638 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, DELETE, 648 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, DELETE,
639 CREATE_NOT_DIR | CREATE_DELETE_ON_CLOSE, 649 CREATE_NOT_DIR | CREATE_DELETE_ON_CLOSE,
640 &netfid, &oplock, NULL, cifs_sb->local_nls, 650 &netfid, &oplock, NULL, cifs_sb->local_nls,
641 cifs_sb->mnt_cifs_flags & 651 cifs_sb->mnt_cifs_flags &
642 CIFS_MOUNT_MAP_SPECIAL_CHR); 652 CIFS_MOUNT_MAP_SPECIAL_CHR);
643 if (rc==0) { 653 if (rc == 0) {
644 CIFSSMBRenameOpenFile(xid, pTcon, netfid, NULL, 654 CIFSSMBRenameOpenFile(xid, pTcon, netfid, NULL,
645 cifs_sb->local_nls, 655 cifs_sb->local_nls,
646 cifs_sb->mnt_cifs_flags & 656 cifs_sb->mnt_cifs_flags &
647 CIFS_MOUNT_MAP_SPECIAL_CHR); 657 CIFS_MOUNT_MAP_SPECIAL_CHR);
648 CIFSSMBClose(xid, pTcon, netfid); 658 CIFSSMBClose(xid, pTcon, netfid);
649 if (direntry->d_inode) 659 if (direntry->d_inode)
@@ -659,7 +669,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
659 rc = CIFSSMBSetTimes(xid, pTcon, full_path, 669 rc = CIFSSMBSetTimes(xid, pTcon, full_path,
660 pinfo_buf, 670 pinfo_buf,
661 cifs_sb->local_nls, 671 cifs_sb->local_nls,
662 cifs_sb->mnt_cifs_flags & 672 cifs_sb->mnt_cifs_flags &
663 CIFS_MOUNT_MAP_SPECIAL_CHR); 673 CIFS_MOUNT_MAP_SPECIAL_CHR);
664 else 674 else
665 rc = -EOPNOTSUPP; 675 rc = -EOPNOTSUPP;
@@ -670,7 +680,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
670 /* rc = CIFSSMBSetAttrLegacy(xid, pTcon, 680 /* rc = CIFSSMBSetAttrLegacy(xid, pTcon,
671 full_path, 681 full_path,
672 (__u16)ATTR_NORMAL, 682 (__u16)ATTR_NORMAL,
673 cifs_sb->local_nls); 683 cifs_sb->local_nls);
674 For some strange reason it seems that NT4 eats the 684 For some strange reason it seems that NT4 eats the
675 old setattr call without actually setting the 685 old setattr call without actually setting the
676 attributes so on to the third attempted workaround 686 attributes so on to the third attempted workaround
@@ -683,9 +693,9 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
683 FILE_WRITE_ATTRIBUTES, 0, 693 FILE_WRITE_ATTRIBUTES, 0,
684 &netfid, &oplock, NULL, 694 &netfid, &oplock, NULL,
685 cifs_sb->local_nls, 695 cifs_sb->local_nls,
686 cifs_sb->mnt_cifs_flags & 696 cifs_sb->mnt_cifs_flags &
687 CIFS_MOUNT_MAP_SPECIAL_CHR); 697 CIFS_MOUNT_MAP_SPECIAL_CHR);
688 if (rc==0) { 698 if (rc == 0) {
689 rc = CIFSSMBSetFileTimes(xid, pTcon, 699 rc = CIFSSMBSetFileTimes(xid, pTcon,
690 pinfo_buf, 700 pinfo_buf,
691 netfid); 701 netfid);
@@ -694,10 +704,10 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
694 } 704 }
695 kfree(pinfo_buf); 705 kfree(pinfo_buf);
696 } 706 }
697 if (rc==0) { 707 if (rc == 0) {
698 rc = CIFSSMBDelFile(xid, pTcon, full_path, 708 rc = CIFSSMBDelFile(xid, pTcon, full_path,
699 cifs_sb->local_nls, 709 cifs_sb->local_nls,
700 cifs_sb->mnt_cifs_flags & 710 cifs_sb->mnt_cifs_flags &
701 CIFS_MOUNT_MAP_SPECIAL_CHR); 711 CIFS_MOUNT_MAP_SPECIAL_CHR);
702 if (!rc) { 712 if (!rc) {
703 if (direntry->d_inode) 713 if (direntry->d_inode)
@@ -711,10 +721,10 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
711 CREATE_NOT_DIR | 721 CREATE_NOT_DIR |
712 CREATE_DELETE_ON_CLOSE, 722 CREATE_DELETE_ON_CLOSE,
713 &netfid, &oplock, NULL, 723 &netfid, &oplock, NULL,
714 cifs_sb->local_nls, 724 cifs_sb->local_nls,
715 cifs_sb->mnt_cifs_flags & 725 cifs_sb->mnt_cifs_flags &
716 CIFS_MOUNT_MAP_SPECIAL_CHR); 726 CIFS_MOUNT_MAP_SPECIAL_CHR);
717 if (rc==0) { 727 if (rc == 0) {
718 CIFSSMBRenameOpenFile(xid, pTcon, 728 CIFSSMBRenameOpenFile(xid, pTcon,
719 netfid, NULL, 729 netfid, NULL,
720 cifs_sb->local_nls, 730 cifs_sb->local_nls,
@@ -773,8 +783,8 @@ static void posix_fill_in_inode(struct inode *tmp_inode,
773 783
774 tmp_inode->i_mode = le64_to_cpu(pData->Permissions); 784 tmp_inode->i_mode = le64_to_cpu(pData->Permissions);
775 /* since we set the inode type below we need to mask off type 785 /* since we set the inode type below we need to mask off type
776 to avoid strange results if bits above were corrupt */ 786 to avoid strange results if bits above were corrupt */
777 tmp_inode->i_mode &= ~S_IFMT; 787 tmp_inode->i_mode &= ~S_IFMT;
778 if (type == UNIX_FILE) { 788 if (type == UNIX_FILE) {
779 *pobject_type = DT_REG; 789 *pobject_type = DT_REG;
780 tmp_inode->i_mode |= S_IFREG; 790 tmp_inode->i_mode |= S_IFREG;
@@ -804,11 +814,11 @@ static void posix_fill_in_inode(struct inode *tmp_inode,
804 /* safest to just call it a file */ 814 /* safest to just call it a file */
805 *pobject_type = DT_REG; 815 *pobject_type = DT_REG;
806 tmp_inode->i_mode |= S_IFREG; 816 tmp_inode->i_mode |= S_IFREG;
807 cFYI(1,("unknown inode type %d",type)); 817 cFYI(1, ("unknown inode type %d", type));
808 } 818 }
809 819
810#ifdef CONFIG_CIFS_DEBUG2 820#ifdef CONFIG_CIFS_DEBUG2
811 cFYI(1,("object type: %d", type)); 821 cFYI(1, ("object type: %d", type));
812#endif 822#endif
813 tmp_inode->i_uid = le64_to_cpu(pData->Uid); 823 tmp_inode->i_uid = le64_to_cpu(pData->Uid);
814 tmp_inode->i_gid = le64_to_cpu(pData->Gid); 824 tmp_inode->i_gid = le64_to_cpu(pData->Gid);
@@ -816,7 +826,7 @@ static void posix_fill_in_inode(struct inode *tmp_inode,
816 826
817 spin_lock(&tmp_inode->i_lock); 827 spin_lock(&tmp_inode->i_lock);
818 if (is_size_safe_to_change(cifsInfo, end_of_file)) { 828 if (is_size_safe_to_change(cifsInfo, end_of_file)) {
819 /* can not safely change the file size here if the 829 /* can not safely change the file size here if the
820 client is writing to it due to potential races */ 830 client is writing to it due to potential races */
821 i_size_write(tmp_inode, end_of_file); 831 i_size_write(tmp_inode, end_of_file);
822 832
@@ -830,27 +840,28 @@ static void posix_fill_in_inode(struct inode *tmp_inode,
830 cFYI(1, ("File inode")); 840 cFYI(1, ("File inode"));
831 tmp_inode->i_op = &cifs_file_inode_ops; 841 tmp_inode->i_op = &cifs_file_inode_ops;
832 842
833 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { 843 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
834 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 844 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
835 tmp_inode->i_fop = &cifs_file_direct_nobrl_ops; 845 tmp_inode->i_fop = &cifs_file_direct_nobrl_ops;
836 else 846 else
837 tmp_inode->i_fop = &cifs_file_direct_ops; 847 tmp_inode->i_fop = &cifs_file_direct_ops;
838 848
839 } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 849 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
840 tmp_inode->i_fop = &cifs_file_nobrl_ops; 850 tmp_inode->i_fop = &cifs_file_nobrl_ops;
841 else 851 else
842 tmp_inode->i_fop = &cifs_file_ops; 852 tmp_inode->i_fop = &cifs_file_ops;
843 853
844 if((cifs_sb->tcon) && (cifs_sb->tcon->ses) && 854 if ((cifs_sb->tcon) && (cifs_sb->tcon->ses) &&
845 (cifs_sb->tcon->ses->server->maxBuf < 855 (cifs_sb->tcon->ses->server->maxBuf <
846 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)) 856 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE))
847 tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf; 857 tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
848 else 858 else
849 tmp_inode->i_data.a_ops = &cifs_addr_ops; 859 tmp_inode->i_data.a_ops = &cifs_addr_ops;
850 860
851 if(isNewInode) 861 if (isNewInode)
852 return; /* No sense invalidating pages for new inode since we 862 return; /* No sense invalidating pages for new inode
853 have not started caching readahead file data yet */ 863 since we we have not started caching
864 readahead file data yet */
854 865
855 if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) && 866 if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) &&
856 (local_size == tmp_inode->i_size)) { 867 (local_size == tmp_inode->i_size)) {
@@ -869,10 +880,10 @@ static void posix_fill_in_inode(struct inode *tmp_inode,
869 tmp_inode->i_op = &cifs_symlink_inode_ops; 880 tmp_inode->i_op = &cifs_symlink_inode_ops;
870/* tmp_inode->i_fop = *//* do not need to set to anything */ 881/* tmp_inode->i_fop = *//* do not need to set to anything */
871 } else { 882 } else {
872 cFYI(1, ("Special inode")); 883 cFYI(1, ("Special inode"));
873 init_special_inode(tmp_inode, tmp_inode->i_mode, 884 init_special_inode(tmp_inode, tmp_inode->i_mode,
874 tmp_inode->i_rdev); 885 tmp_inode->i_rdev);
875 } 886 }
876} 887}
877 888
878int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) 889int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
@@ -896,22 +907,22 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
896 FreeXid(xid); 907 FreeXid(xid);
897 return -ENOMEM; 908 return -ENOMEM;
898 } 909 }
899 910
900 if((pTcon->ses->capabilities & CAP_UNIX) && 911 if ((pTcon->ses->capabilities & CAP_UNIX) &&
901 (CIFS_UNIX_POSIX_PATH_OPS_CAP & 912 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
902 le64_to_cpu(pTcon->fsUnixInfo.Capability))) { 913 le64_to_cpu(pTcon->fsUnixInfo.Capability))) {
903 u32 oplock = 0; 914 u32 oplock = 0;
904 FILE_UNIX_BASIC_INFO * pInfo = 915 FILE_UNIX_BASIC_INFO * pInfo =
905 kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL); 916 kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
906 if(pInfo == NULL) { 917 if (pInfo == NULL) {
907 rc = -ENOMEM; 918 rc = -ENOMEM;
908 goto mkdir_out; 919 goto mkdir_out;
909 } 920 }
910 921
911 rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT, 922 rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT,
912 mode, NULL /* netfid */, pInfo, &oplock, 923 mode, NULL /* netfid */, pInfo, &oplock,
913 full_path, cifs_sb->local_nls, 924 full_path, cifs_sb->local_nls,
914 cifs_sb->mnt_cifs_flags & 925 cifs_sb->mnt_cifs_flags &
915 CIFS_MOUNT_MAP_SPECIAL_CHR); 926 CIFS_MOUNT_MAP_SPECIAL_CHR);
916 if (rc) { 927 if (rc) {
917 cFYI(1, ("posix mkdir returned 0x%x", rc)); 928 cFYI(1, ("posix mkdir returned 0x%x", rc));
@@ -919,8 +930,9 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
919 } else { 930 } else {
920 int obj_type; 931 int obj_type;
921 if (pInfo->Type == -1) /* no return info - go query */ 932 if (pInfo->Type == -1) /* no return info - go query */
922 goto mkdir_get_info; 933 goto mkdir_get_info;
923/*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need to set uid/gid */ 934/*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need
935 to set uid/gid */
924 inc_nlink(inode); 936 inc_nlink(inode);
925 if (pTcon->nocase) 937 if (pTcon->nocase)
926 direntry->d_op = &cifs_ci_dentry_ops; 938 direntry->d_op = &cifs_ci_dentry_ops;
@@ -937,7 +949,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
937 newinode->i_ino = 949 newinode->i_ino =
938 (unsigned long)pInfo->UniqueId; 950 (unsigned long)pInfo->UniqueId;
939 } /* note ino incremented to unique num in new_inode */ 951 } /* note ino incremented to unique num in new_inode */
940 if(inode->i_sb->s_flags & MS_NOATIME) 952 if (inode->i_sb->s_flags & MS_NOATIME)
941 newinode->i_flags |= S_NOATIME | S_NOCMTIME; 953 newinode->i_flags |= S_NOATIME | S_NOCMTIME;
942 newinode->i_nlink = 2; 954 newinode->i_nlink = 2;
943 955
@@ -949,18 +961,18 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
949 posix_fill_in_inode(direntry->d_inode, 961 posix_fill_in_inode(direntry->d_inode,
950 pInfo, &obj_type, 1 /* NewInode */); 962 pInfo, &obj_type, 1 /* NewInode */);
951#ifdef CONFIG_CIFS_DEBUG2 963#ifdef CONFIG_CIFS_DEBUG2
952 cFYI(1,("instantiated dentry %p %s to inode %p", 964 cFYI(1, ("instantiated dentry %p %s to inode %p",
953 direntry, direntry->d_name.name, newinode)); 965 direntry, direntry->d_name.name, newinode));
954 966
955 if(newinode->i_nlink != 2) 967 if (newinode->i_nlink != 2)
956 cFYI(1,("unexpected number of links %d", 968 cFYI(1, ("unexpected number of links %d",
957 newinode->i_nlink)); 969 newinode->i_nlink));
958#endif 970#endif
959 } 971 }
960 kfree(pInfo); 972 kfree(pInfo);
961 goto mkdir_out; 973 goto mkdir_out;
962 } 974 }
963 975
964 /* BB add setting the equivalent of mode via CreateX w/ACLs */ 976 /* BB add setting the equivalent of mode via CreateX w/ACLs */
965 rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls, 977 rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls,
966 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 978 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -968,14 +980,14 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
968 cFYI(1, ("cifs_mkdir returned 0x%x", rc)); 980 cFYI(1, ("cifs_mkdir returned 0x%x", rc));
969 d_drop(direntry); 981 d_drop(direntry);
970 } else { 982 } else {
971mkdir_get_info: 983mkdir_get_info:
972 inc_nlink(inode); 984 inc_nlink(inode);
973 if (pTcon->ses->capabilities & CAP_UNIX) 985 if (pTcon->unix_ext)
974 rc = cifs_get_inode_info_unix(&newinode, full_path, 986 rc = cifs_get_inode_info_unix(&newinode, full_path,
975 inode->i_sb,xid); 987 inode->i_sb, xid);
976 else 988 else
977 rc = cifs_get_inode_info(&newinode, full_path, NULL, 989 rc = cifs_get_inode_info(&newinode, full_path, NULL,
978 inode->i_sb,xid); 990 inode->i_sb, xid);
979 991
980 if (pTcon->nocase) 992 if (pTcon->nocase)
981 direntry->d_op = &cifs_ci_dentry_ops; 993 direntry->d_op = &cifs_ci_dentry_ops;
@@ -983,10 +995,10 @@ mkdir_get_info:
983 direntry->d_op = &cifs_dentry_ops; 995 direntry->d_op = &cifs_dentry_ops;
984 d_instantiate(direntry, newinode); 996 d_instantiate(direntry, newinode);
985 /* setting nlink not necessary except in cases where we 997 /* setting nlink not necessary except in cases where we
986 * failed to get it from the server or was set bogus */ 998 * failed to get it from the server or was set bogus */
987 if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2)) 999 if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2))
988 direntry->d_inode->i_nlink = 2; 1000 direntry->d_inode->i_nlink = 2;
989 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) { 1001 if (pTcon->unix_ext) {
990 mode &= ~current->fs->umask; 1002 mode &= ~current->fs->umask;
991 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { 1003 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
992 CIFSSMBUnixSetPerms(xid, pTcon, full_path, 1004 CIFSSMBUnixSetPerms(xid, pTcon, full_path,
@@ -1002,27 +1014,27 @@ mkdir_get_info:
1002 mode, (__u64)-1, 1014 mode, (__u64)-1,
1003 (__u64)-1, 0 /* dev_t */, 1015 (__u64)-1, 0 /* dev_t */,
1004 cifs_sb->local_nls, 1016 cifs_sb->local_nls,
1005 cifs_sb->mnt_cifs_flags & 1017 cifs_sb->mnt_cifs_flags &
1006 CIFS_MOUNT_MAP_SPECIAL_CHR); 1018 CIFS_MOUNT_MAP_SPECIAL_CHR);
1007 } 1019 }
1008 } else { 1020 } else {
1009 /* BB to be implemented via Windows secrty descriptors 1021 /* BB to be implemented via Windows secrty descriptors
1010 eg CIFSSMBWinSetPerms(xid, pTcon, full_path, mode, 1022 eg CIFSSMBWinSetPerms(xid, pTcon, full_path, mode,
1011 -1, -1, local_nls); */ 1023 -1, -1, local_nls); */
1012 if(direntry->d_inode) { 1024 if (direntry->d_inode) {
1013 direntry->d_inode->i_mode = mode; 1025 direntry->d_inode->i_mode = mode;
1014 direntry->d_inode->i_mode |= S_IFDIR; 1026 direntry->d_inode->i_mode |= S_IFDIR;
1015 if(cifs_sb->mnt_cifs_flags & 1027 if (cifs_sb->mnt_cifs_flags &
1016 CIFS_MOUNT_SET_UID) { 1028 CIFS_MOUNT_SET_UID) {
1017 direntry->d_inode->i_uid = 1029 direntry->d_inode->i_uid =
1018 current->fsuid; 1030 current->fsuid;
1019 direntry->d_inode->i_gid = 1031 direntry->d_inode->i_gid =
1020 current->fsgid; 1032 current->fsgid;
1021 } 1033 }
1022 } 1034 }
1023 } 1035 }
1024 } 1036 }
1025mkdir_out: 1037mkdir_out:
1026 kfree(full_path); 1038 kfree(full_path);
1027 FreeXid(xid); 1039 FreeXid(xid);
1028 return rc; 1040 return rc;
@@ -1056,7 +1068,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
1056 if (!rc) { 1068 if (!rc) {
1057 drop_nlink(inode); 1069 drop_nlink(inode);
1058 spin_lock(&direntry->d_inode->i_lock); 1070 spin_lock(&direntry->d_inode->i_lock);
1059 i_size_write(direntry->d_inode,0); 1071 i_size_write(direntry->d_inode, 0);
1060 clear_nlink(direntry->d_inode); 1072 clear_nlink(direntry->d_inode);
1061 spin_unlock(&direntry->d_inode->i_lock); 1073 spin_unlock(&direntry->d_inode->i_lock);
1062 } 1074 }
@@ -1119,9 +1131,9 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
1119 kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL); 1131 kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
1120 if (info_buf_source != NULL) { 1132 if (info_buf_source != NULL) {
1121 info_buf_target = info_buf_source + 1; 1133 info_buf_target = info_buf_source + 1;
1122 if (pTcon->ses->capabilities & CAP_UNIX) 1134 if (pTcon->unix_ext)
1123 rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName, 1135 rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName,
1124 info_buf_source, 1136 info_buf_source,
1125 cifs_sb_source->local_nls, 1137 cifs_sb_source->local_nls,
1126 cifs_sb_source->mnt_cifs_flags & 1138 cifs_sb_source->mnt_cifs_flags &
1127 CIFS_MOUNT_MAP_SPECIAL_CHR); 1139 CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -1171,12 +1183,12 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
1171 might not right be right access to request */ 1183 might not right be right access to request */
1172 rc = CIFSSMBOpen(xid, pTcon, fromName, FILE_OPEN, GENERIC_READ, 1184 rc = CIFSSMBOpen(xid, pTcon, fromName, FILE_OPEN, GENERIC_READ,
1173 CREATE_NOT_DIR, &netfid, &oplock, NULL, 1185 CREATE_NOT_DIR, &netfid, &oplock, NULL,
1174 cifs_sb_source->local_nls, 1186 cifs_sb_source->local_nls,
1175 cifs_sb_source->mnt_cifs_flags & 1187 cifs_sb_source->mnt_cifs_flags &
1176 CIFS_MOUNT_MAP_SPECIAL_CHR); 1188 CIFS_MOUNT_MAP_SPECIAL_CHR);
1177 if (rc==0) { 1189 if (rc == 0) {
1178 rc = CIFSSMBRenameOpenFile(xid, pTcon, netfid, toName, 1190 rc = CIFSSMBRenameOpenFile(xid, pTcon, netfid, toName,
1179 cifs_sb_source->local_nls, 1191 cifs_sb_source->local_nls,
1180 cifs_sb_source->mnt_cifs_flags & 1192 cifs_sb_source->mnt_cifs_flags &
1181 CIFS_MOUNT_MAP_SPECIAL_CHR); 1193 CIFS_MOUNT_MAP_SPECIAL_CHR);
1182 CIFSSMBClose(xid, pTcon, netfid); 1194 CIFSSMBClose(xid, pTcon, netfid);
@@ -1247,9 +1259,9 @@ int cifs_revalidate(struct dentry *direntry)
1247 local_mtime = direntry->d_inode->i_mtime; 1259 local_mtime = direntry->d_inode->i_mtime;
1248 local_size = direntry->d_inode->i_size; 1260 local_size = direntry->d_inode->i_size;
1249 1261
1250 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) { 1262 if (cifs_sb->tcon->unix_ext) {
1251 rc = cifs_get_inode_info_unix(&direntry->d_inode, full_path, 1263 rc = cifs_get_inode_info_unix(&direntry->d_inode, full_path,
1252 direntry->d_sb,xid); 1264 direntry->d_sb, xid);
1253 if (rc) { 1265 if (rc) {
1254 cFYI(1, ("error on getting revalidate info %d", rc)); 1266 cFYI(1, ("error on getting revalidate info %d", rc));
1255/* if (rc != -ENOENT) 1267/* if (rc != -ENOENT)
@@ -1258,7 +1270,7 @@ int cifs_revalidate(struct dentry *direntry)
1258 } 1270 }
1259 } else { 1271 } else {
1260 rc = cifs_get_inode_info(&direntry->d_inode, full_path, NULL, 1272 rc = cifs_get_inode_info(&direntry->d_inode, full_path, NULL,
1261 direntry->d_sb,xid); 1273 direntry->d_sb, xid);
1262 if (rc) { 1274 if (rc) {
1263 cFYI(1, ("error on getting revalidate info %d", rc)); 1275 cFYI(1, ("error on getting revalidate info %d", rc));
1264/* if (rc != -ENOENT) 1276/* if (rc != -ENOENT)
@@ -1271,7 +1283,7 @@ int cifs_revalidate(struct dentry *direntry)
1271 /* if not oplocked, we invalidate inode pages if mtime or file size 1283 /* if not oplocked, we invalidate inode pages if mtime or file size
1272 had changed on server */ 1284 had changed on server */
1273 1285
1274 if (timespec_equal(&local_mtime,&direntry->d_inode->i_mtime) && 1286 if (timespec_equal(&local_mtime, &direntry->d_inode->i_mtime) &&
1275 (local_size == direntry->d_inode->i_size)) { 1287 (local_size == direntry->d_inode->i_size)) {
1276 cFYI(1, ("cifs_revalidate - inode unchanged")); 1288 cFYI(1, ("cifs_revalidate - inode unchanged"));
1277 } else { 1289 } else {
@@ -1298,7 +1310,7 @@ int cifs_revalidate(struct dentry *direntry)
1298 if (invalidate_inode) { 1310 if (invalidate_inode) {
1299 /* shrink_dcache not necessary now that cifs dentry ops 1311 /* shrink_dcache not necessary now that cifs dentry ops
1300 are exported for negative dentries */ 1312 are exported for negative dentries */
1301/* if(S_ISDIR(direntry->d_inode->i_mode)) 1313/* if (S_ISDIR(direntry->d_inode->i_mode))
1302 shrink_dcache_parent(direntry); */ 1314 shrink_dcache_parent(direntry); */
1303 if (S_ISREG(direntry->d_inode->i_mode)) { 1315 if (S_ISREG(direntry->d_inode->i_mode)) {
1304 if (direntry->d_inode->i_mapping) 1316 if (direntry->d_inode->i_mapping)
@@ -1313,7 +1325,7 @@ int cifs_revalidate(struct dentry *direntry)
1313 } 1325 }
1314 } 1326 }
1315/* mutex_unlock(&direntry->d_inode->i_mutex); */ 1327/* mutex_unlock(&direntry->d_inode->i_mutex); */
1316 1328
1317 kfree(full_path); 1329 kfree(full_path);
1318 FreeXid(xid); 1330 FreeXid(xid);
1319 return rc; 1331 return rc;
@@ -1335,23 +1347,19 @@ static int cifs_truncate_page(struct address_space *mapping, loff_t from)
1335 pgoff_t index = from >> PAGE_CACHE_SHIFT; 1347 pgoff_t index = from >> PAGE_CACHE_SHIFT;
1336 unsigned offset = from & (PAGE_CACHE_SIZE - 1); 1348 unsigned offset = from & (PAGE_CACHE_SIZE - 1);
1337 struct page *page; 1349 struct page *page;
1338 char *kaddr;
1339 int rc = 0; 1350 int rc = 0;
1340 1351
1341 page = grab_cache_page(mapping, index); 1352 page = grab_cache_page(mapping, index);
1342 if (!page) 1353 if (!page)
1343 return -ENOMEM; 1354 return -ENOMEM;
1344 1355
1345 kaddr = kmap_atomic(page, KM_USER0); 1356 zero_user_page(page, offset, PAGE_CACHE_SIZE - offset, KM_USER0);
1346 memset(kaddr + offset, 0, PAGE_CACHE_SIZE - offset);
1347 flush_dcache_page(page);
1348 kunmap_atomic(kaddr, KM_USER0);
1349 unlock_page(page); 1357 unlock_page(page);
1350 page_cache_release(page); 1358 page_cache_release(page);
1351 return rc; 1359 return rc;
1352} 1360}
1353 1361
1354static int cifs_vmtruncate(struct inode * inode, loff_t offset) 1362static int cifs_vmtruncate(struct inode *inode, loff_t offset)
1355{ 1363{
1356 struct address_space *mapping = inode->i_mapping; 1364 struct address_space *mapping = inode->i_mapping;
1357 unsigned long limit; 1365 unsigned long limit;
@@ -1424,13 +1432,13 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1424 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) { 1432 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
1425 /* check if we have permission to change attrs */ 1433 /* check if we have permission to change attrs */
1426 rc = inode_change_ok(direntry->d_inode, attrs); 1434 rc = inode_change_ok(direntry->d_inode, attrs);
1427 if(rc < 0) { 1435 if (rc < 0) {
1428 FreeXid(xid); 1436 FreeXid(xid);
1429 return rc; 1437 return rc;
1430 } else 1438 } else
1431 rc = 0; 1439 rc = 0;
1432 } 1440 }
1433 1441
1434 full_path = build_path_from_dentry(direntry); 1442 full_path = build_path_from_dentry(direntry);
1435 if (full_path == NULL) { 1443 if (full_path == NULL) {
1436 FreeXid(xid); 1444 FreeXid(xid);
@@ -1459,16 +1467,16 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1459 rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, 1467 rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size,
1460 nfid, npid, FALSE); 1468 nfid, npid, FALSE);
1461 atomic_dec(&open_file->wrtPending); 1469 atomic_dec(&open_file->wrtPending);
1462 cFYI(1,("SetFSize for attrs rc = %d", rc)); 1470 cFYI(1, ("SetFSize for attrs rc = %d", rc));
1463 if((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { 1471 if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1464 int bytes_written; 1472 int bytes_written;
1465 rc = CIFSSMBWrite(xid, pTcon, 1473 rc = CIFSSMBWrite(xid, pTcon,
1466 nfid, 0, attrs->ia_size, 1474 nfid, 0, attrs->ia_size,
1467 &bytes_written, NULL, NULL, 1475 &bytes_written, NULL, NULL,
1468 1 /* 45 seconds */); 1476 1 /* 45 seconds */);
1469 cFYI(1,("Wrt seteof rc %d", rc)); 1477 cFYI(1, ("Wrt seteof rc %d", rc));
1470 } 1478 }
1471 } else 1479 } else
1472 rc = -EINVAL; 1480 rc = -EINVAL;
1473 1481
1474 if (rc != 0) { 1482 if (rc != 0) {
@@ -1478,11 +1486,11 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1478 it by handle */ 1486 it by handle */
1479 rc = CIFSSMBSetEOF(xid, pTcon, full_path, 1487 rc = CIFSSMBSetEOF(xid, pTcon, full_path,
1480 attrs->ia_size, FALSE, 1488 attrs->ia_size, FALSE,
1481 cifs_sb->local_nls, 1489 cifs_sb->local_nls,
1482 cifs_sb->mnt_cifs_flags & 1490 cifs_sb->mnt_cifs_flags &
1483 CIFS_MOUNT_MAP_SPECIAL_CHR); 1491 CIFS_MOUNT_MAP_SPECIAL_CHR);
1484 cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc)); 1492 cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc));
1485 if((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { 1493 if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1486 __u16 netfid; 1494 __u16 netfid;
1487 int oplock = FALSE; 1495 int oplock = FALSE;
1488 1496
@@ -1493,14 +1501,14 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1493 NULL, cifs_sb->local_nls, 1501 NULL, cifs_sb->local_nls,
1494 cifs_sb->mnt_cifs_flags & 1502 cifs_sb->mnt_cifs_flags &
1495 CIFS_MOUNT_MAP_SPECIAL_CHR); 1503 CIFS_MOUNT_MAP_SPECIAL_CHR);
1496 if (rc==0) { 1504 if (rc == 0) {
1497 int bytes_written; 1505 int bytes_written;
1498 rc = CIFSSMBWrite(xid, pTcon, 1506 rc = CIFSSMBWrite(xid, pTcon,
1499 netfid, 0, 1507 netfid, 0,
1500 attrs->ia_size, 1508 attrs->ia_size,
1501 &bytes_written, NULL, 1509 &bytes_written, NULL,
1502 NULL, 1 /* 45 sec */); 1510 NULL, 1 /* 45 sec */);
1503 cFYI(1,("wrt seteof rc %d",rc)); 1511 cFYI(1, ("wrt seteof rc %d", rc));
1504 CIFSSMBClose(xid, pTcon, netfid); 1512 CIFSSMBClose(xid, pTcon, netfid);
1505 } 1513 }
1506 1514
@@ -1517,7 +1525,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1517 rc = cifs_vmtruncate(direntry->d_inode, attrs->ia_size); 1525 rc = cifs_vmtruncate(direntry->d_inode, attrs->ia_size);
1518 cifs_truncate_page(direntry->d_inode->i_mapping, 1526 cifs_truncate_page(direntry->d_inode->i_mapping,
1519 direntry->d_inode->i_size); 1527 direntry->d_inode->i_size);
1520 } else 1528 } else
1521 goto cifs_setattr_exit; 1529 goto cifs_setattr_exit;
1522 } 1530 }
1523 if (attrs->ia_valid & ATTR_UID) { 1531 if (attrs->ia_valid & ATTR_UID) {
@@ -1535,11 +1543,11 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1535 mode = attrs->ia_mode; 1543 mode = attrs->ia_mode;
1536 } 1544 }
1537 1545
1538 if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX) 1546 if ((pTcon->unix_ext)
1539 && (attrs->ia_valid & (ATTR_MODE | ATTR_GID | ATTR_UID))) 1547 && (attrs->ia_valid & (ATTR_MODE | ATTR_GID | ATTR_UID)))
1540 rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, uid, gid, 1548 rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, uid, gid,
1541 0 /* dev_t */, cifs_sb->local_nls, 1549 0 /* dev_t */, cifs_sb->local_nls,
1542 cifs_sb->mnt_cifs_flags & 1550 cifs_sb->mnt_cifs_flags &
1543 CIFS_MOUNT_MAP_SPECIAL_CHR); 1551 CIFS_MOUNT_MAP_SPECIAL_CHR);
1544 else if (attrs->ia_valid & ATTR_MODE) { 1552 else if (attrs->ia_valid & ATTR_MODE) {
1545 rc = 0; 1553 rc = 0;
@@ -1559,7 +1567,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1559 time_buf.Attributes = cpu_to_le32(cifsInode->cifsAttrs & 1567 time_buf.Attributes = cpu_to_le32(cifsInode->cifsAttrs &
1560 (~ATTR_READONLY)); 1568 (~ATTR_READONLY));
1561 /* Windows ignores set to zero */ 1569 /* Windows ignores set to zero */
1562 if(time_buf.Attributes == 0) 1570 if (time_buf.Attributes == 0)
1563 time_buf.Attributes |= cpu_to_le32(ATTR_NORMAL); 1571 time_buf.Attributes |= cpu_to_le32(ATTR_NORMAL);
1564 } 1572 }
1565 /* BB to be implemented - 1573 /* BB to be implemented -
@@ -1585,7 +1593,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1585 stamps are changed explicitly (i.e. by utime() 1593 stamps are changed explicitly (i.e. by utime()
1586 since we would then have a mix of client and 1594 since we would then have a mix of client and
1587 server times */ 1595 server times */
1588 1596
1589 if (set_time && (attrs->ia_valid & ATTR_CTIME)) { 1597 if (set_time && (attrs->ia_valid & ATTR_CTIME)) {
1590 set_time = TRUE; 1598 set_time = TRUE;
1591 /* Although Samba throws this field away 1599 /* Although Samba throws this field away
@@ -1624,7 +1632,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1624 NULL, cifs_sb->local_nls, 1632 NULL, cifs_sb->local_nls,
1625 cifs_sb->mnt_cifs_flags & 1633 cifs_sb->mnt_cifs_flags &
1626 CIFS_MOUNT_MAP_SPECIAL_CHR); 1634 CIFS_MOUNT_MAP_SPECIAL_CHR);
1627 if (rc==0) { 1635 if (rc == 0) {
1628 rc = CIFSSMBSetFileTimes(xid, pTcon, &time_buf, 1636 rc = CIFSSMBSetFileTimes(xid, pTcon, &time_buf,
1629 netfid); 1637 netfid);
1630 CIFSSMBClose(xid, pTcon, netfid); 1638 CIFSSMBClose(xid, pTcon, netfid);
@@ -1634,7 +1642,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1634 granularity */ 1642 granularity */
1635 1643
1636 /* rc = CIFSSMBSetTimesLegacy(xid, pTcon, full_path, 1644 /* rc = CIFSSMBSetTimesLegacy(xid, pTcon, full_path,
1637 &time_buf, cifs_sb->local_nls); */ 1645 &time_buf, cifs_sb->local_nls); */
1638 } 1646 }
1639 } 1647 }
1640 /* Even if error on time set, no sense failing the call if 1648 /* Even if error on time set, no sense failing the call if
@@ -1642,7 +1650,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1642 and this check ensures that we are not being called from 1650 and this check ensures that we are not being called from
1643 sys_utimes in which case we ought to fail the call back to 1651 sys_utimes in which case we ought to fail the call back to
1644 the user when the server rejects the call */ 1652 the user when the server rejects the call */
1645 if((rc) && (attrs->ia_valid & 1653 if ((rc) && (attrs->ia_valid &
1646 (ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE))) 1654 (ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE)))
1647 rc = 0; 1655 rc = 0;
1648 } 1656 }
diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c
index a414f1775ae0..d24fe6880a04 100644
--- a/fs/cifs/ioctl.c
+++ b/fs/cifs/ioctl.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * vfs operations that deal with io control 4 * vfs operations that deal with io control
5 * 5 *
6 * Copyright (C) International Business Machines Corp., 2005 6 * Copyright (C) International Business Machines Corp., 2005,2007
7 * Author(s): Steve French (sfrench@us.ibm.com) 7 * Author(s): Steve French (sfrench@us.ibm.com)
8 * 8 *
9 * This library is free software; you can redistribute it and/or modify 9 * This library is free software; you can redistribute it and/or modify
@@ -30,7 +30,7 @@
30 30
31#define CIFS_IOC_CHECKUMOUNT _IO(0xCF, 2) 31#define CIFS_IOC_CHECKUMOUNT _IO(0xCF, 2)
32 32
33int cifs_ioctl (struct inode * inode, struct file * filep, 33int cifs_ioctl (struct inode *inode, struct file *filep,
34 unsigned int command, unsigned long arg) 34 unsigned int command, unsigned long arg)
35{ 35{
36 int rc = -ENOTTY; /* strange error - but the precedent */ 36 int rc = -ENOTTY; /* strange error - but the precedent */
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 6baea85d726e..6a85ef7b8797 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -50,32 +50,33 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
50 50
51 fromName = build_path_from_dentry(old_file); 51 fromName = build_path_from_dentry(old_file);
52 toName = build_path_from_dentry(direntry); 52 toName = build_path_from_dentry(direntry);
53 if((fromName == NULL) || (toName == NULL)) { 53 if ((fromName == NULL) || (toName == NULL)) {
54 rc = -ENOMEM; 54 rc = -ENOMEM;
55 goto cifs_hl_exit; 55 goto cifs_hl_exit;
56 } 56 }
57 57
58 if (cifs_sb_target->tcon->ses->capabilities & CAP_UNIX) 58/* if (cifs_sb_target->tcon->ses->capabilities & CAP_UNIX)*/
59 if (pTcon->unix_ext)
59 rc = CIFSUnixCreateHardLink(xid, pTcon, fromName, toName, 60 rc = CIFSUnixCreateHardLink(xid, pTcon, fromName, toName,
60 cifs_sb_target->local_nls, 61 cifs_sb_target->local_nls,
61 cifs_sb_target->mnt_cifs_flags & 62 cifs_sb_target->mnt_cifs_flags &
62 CIFS_MOUNT_MAP_SPECIAL_CHR); 63 CIFS_MOUNT_MAP_SPECIAL_CHR);
63 else { 64 else {
64 rc = CIFSCreateHardLink(xid, pTcon, fromName, toName, 65 rc = CIFSCreateHardLink(xid, pTcon, fromName, toName,
65 cifs_sb_target->local_nls, 66 cifs_sb_target->local_nls,
66 cifs_sb_target->mnt_cifs_flags & 67 cifs_sb_target->mnt_cifs_flags &
67 CIFS_MOUNT_MAP_SPECIAL_CHR); 68 CIFS_MOUNT_MAP_SPECIAL_CHR);
68 if((rc == -EIO) || (rc == -EINVAL)) 69 if ((rc == -EIO) || (rc == -EINVAL))
69 rc = -EOPNOTSUPP; 70 rc = -EOPNOTSUPP;
70 } 71 }
71 72
72 d_drop(direntry); /* force new lookup from server of target */ 73 d_drop(direntry); /* force new lookup from server of target */
73 74
74 /* if source file is cached (oplocked) revalidate will not go to server 75 /* if source file is cached (oplocked) revalidate will not go to server
75 until the file is closed or oplock broken so update nlinks locally */ 76 until the file is closed or oplock broken so update nlinks locally */
76 if(old_file->d_inode) { 77 if (old_file->d_inode) {
77 cifsInode = CIFS_I(old_file->d_inode); 78 cifsInode = CIFS_I(old_file->d_inode);
78 if(rc == 0) { 79 if (rc == 0) {
79 old_file->d_inode->i_nlink++; 80 old_file->d_inode->i_nlink++;
80/* BB should we make this contingent on superblock flag NOATIME? */ 81/* BB should we make this contingent on superblock flag NOATIME? */
81/* old_file->d_inode->i_ctime = CURRENT_TIME;*/ 82/* old_file->d_inode->i_ctime = CURRENT_TIME;*/
@@ -84,14 +85,14 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
84 to set the parent dir cifs inode time to zero 85 to set the parent dir cifs inode time to zero
85 to force revalidate (faster) for it too? */ 86 to force revalidate (faster) for it too? */
86 } 87 }
87 /* if not oplocked will force revalidate to get info 88 /* if not oplocked will force revalidate to get info
88 on source file from srv */ 89 on source file from srv */
89 cifsInode->time = 0; 90 cifsInode->time = 0;
90 91
91 /* Will update parent dir timestamps from srv within a second. 92 /* Will update parent dir timestamps from srv within a second.
92 Would it really be worth it to set the parent dir (cifs 93 Would it really be worth it to set the parent dir (cifs
93 inode) time field to zero to force revalidate on parent 94 inode) time field to zero to force revalidate on parent
94 directory faster ie 95 directory faster ie
95 CIFS_I(inode)->time = 0; */ 96 CIFS_I(inode)->time = 0; */
96 } 97 }
97 98
@@ -109,7 +110,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
109 int rc = -EACCES; 110 int rc = -EACCES;
110 int xid; 111 int xid;
111 char *full_path = NULL; 112 char *full_path = NULL;
112 char * target_path = ERR_PTR(-ENOMEM); 113 char *target_path = ERR_PTR(-ENOMEM);
113 struct cifs_sb_info *cifs_sb; 114 struct cifs_sb_info *cifs_sb;
114 struct cifsTconInfo *pTcon; 115 struct cifsTconInfo *pTcon;
115 116
@@ -129,13 +130,19 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
129 goto out; 130 goto out;
130 } 131 }
131 132
132/* BB add read reparse point symlink code and Unix extensions symlink code here BB */ 133 /* We could change this to:
134 if (pTcon->unix_ext)
135 but there does not seem any point in refusing to
136 get symlink info if we can, even if unix extensions
137 turned off for this mount */
138
133 if (pTcon->ses->capabilities & CAP_UNIX) 139 if (pTcon->ses->capabilities & CAP_UNIX)
134 rc = CIFSSMBUnixQuerySymLink(xid, pTcon, full_path, 140 rc = CIFSSMBUnixQuerySymLink(xid, pTcon, full_path,
135 target_path, 141 target_path,
136 PATH_MAX-1, 142 PATH_MAX-1,
137 cifs_sb->local_nls); 143 cifs_sb->local_nls);
138 else { 144 else {
145 /* BB add read reparse point symlink code here */
139 /* rc = CIFSSMBQueryReparseLinkInfo */ 146 /* rc = CIFSSMBQueryReparseLinkInfo */
140 /* BB Add code to Query ReparsePoint info */ 147 /* BB Add code to Query ReparsePoint info */
141 /* BB Add MAC style xsymlink check here if enabled */ 148 /* BB Add MAC style xsymlink check here if enabled */
@@ -176,7 +183,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
176 183
177 full_path = build_path_from_dentry(direntry); 184 full_path = build_path_from_dentry(direntry);
178 185
179 if(full_path == NULL) { 186 if (full_path == NULL) {
180 FreeXid(xid); 187 FreeXid(xid);
181 return -ENOMEM; 188 return -ENOMEM;
182 } 189 }
@@ -185,19 +192,20 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
185 cFYI(1, ("symname is %s", symname)); 192 cFYI(1, ("symname is %s", symname));
186 193
187 /* BB what if DFS and this volume is on different share? BB */ 194 /* BB what if DFS and this volume is on different share? BB */
188 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) 195 if (pTcon->unix_ext)
189 rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname, 196 rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname,
190 cifs_sb->local_nls); 197 cifs_sb->local_nls);
191 /* else 198 /* else
192 rc = CIFSCreateReparseSymLink(xid, pTcon, fromName, toName,cifs_sb_target->local_nls); */ 199 rc = CIFSCreateReparseSymLink(xid, pTcon, fromName, toName,
200 cifs_sb_target->local_nls); */
193 201
194 if (rc == 0) { 202 if (rc == 0) {
195 if (pTcon->ses->capabilities & CAP_UNIX) 203 if (pTcon->unix_ext)
196 rc = cifs_get_inode_info_unix(&newinode, full_path, 204 rc = cifs_get_inode_info_unix(&newinode, full_path,
197 inode->i_sb,xid); 205 inode->i_sb, xid);
198 else 206 else
199 rc = cifs_get_inode_info(&newinode, full_path, NULL, 207 rc = cifs_get_inode_info(&newinode, full_path, NULL,
200 inode->i_sb,xid); 208 inode->i_sb, xid);
201 209
202 if (rc != 0) { 210 if (rc != 0) {
203 cFYI(1, ("Create symlink ok, getinodeinfo fail rc = %d", 211 cFYI(1, ("Create symlink ok, getinodeinfo fail rc = %d",
@@ -226,9 +234,9 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
226 struct cifs_sb_info *cifs_sb; 234 struct cifs_sb_info *cifs_sb;
227 struct cifsTconInfo *pTcon; 235 struct cifsTconInfo *pTcon;
228 char *full_path = NULL; 236 char *full_path = NULL;
229 char *tmp_path = NULL; 237 char *tmp_path = NULL;
230 char * tmpbuffer; 238 char *tmpbuffer;
231 unsigned char * referrals = NULL; 239 unsigned char *referrals = NULL;
232 int num_referrals = 0; 240 int num_referrals = 0;
233 int len; 241 int len;
234 __u16 fid; 242 __u16 fid;
@@ -237,13 +245,13 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
237 cifs_sb = CIFS_SB(inode->i_sb); 245 cifs_sb = CIFS_SB(inode->i_sb);
238 pTcon = cifs_sb->tcon; 246 pTcon = cifs_sb->tcon;
239 247
240/* BB would it be safe against deadlock to grab this sem 248/* BB would it be safe against deadlock to grab this sem
241 even though rename itself grabs the sem and calls lookup? */ 249 even though rename itself grabs the sem and calls lookup? */
242/* mutex_lock(&inode->i_sb->s_vfs_rename_mutex);*/ 250/* mutex_lock(&inode->i_sb->s_vfs_rename_mutex);*/
243 full_path = build_path_from_dentry(direntry); 251 full_path = build_path_from_dentry(direntry);
244/* mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);*/ 252/* mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);*/
245 253
246 if(full_path == NULL) { 254 if (full_path == NULL) {
247 FreeXid(xid); 255 FreeXid(xid);
248 return -ENOMEM; 256 return -ENOMEM;
249 } 257 }
@@ -251,70 +259,80 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
251 cFYI(1, 259 cFYI(1,
252 ("Full path: %s inode = 0x%p pBuffer = 0x%p buflen = %d", 260 ("Full path: %s inode = 0x%p pBuffer = 0x%p buflen = %d",
253 full_path, inode, pBuffer, buflen)); 261 full_path, inode, pBuffer, buflen));
254 if(buflen > PATH_MAX) 262 if (buflen > PATH_MAX)
255 len = PATH_MAX; 263 len = PATH_MAX;
256 else 264 else
257 len = buflen; 265 len = buflen;
258 tmpbuffer = kmalloc(len,GFP_KERNEL); 266 tmpbuffer = kmalloc(len, GFP_KERNEL);
259 if(tmpbuffer == NULL) { 267 if (tmpbuffer == NULL) {
260 kfree(full_path); 268 kfree(full_path);
261 FreeXid(xid); 269 FreeXid(xid);
262 return -ENOMEM; 270 return -ENOMEM;
263 } 271 }
264 272
265/* BB add read reparse point symlink code and Unix extensions symlink code here BB */ 273/* BB add read reparse point symlink code and
274 Unix extensions symlink code here BB */
275/* We could disable this based on pTcon->unix_ext flag instead ... but why? */
266 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) 276 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)
267 rc = CIFSSMBUnixQuerySymLink(xid, pTcon, full_path, 277 rc = CIFSSMBUnixQuerySymLink(xid, pTcon, full_path,
268 tmpbuffer, 278 tmpbuffer,
269 len - 1, 279 len - 1,
270 cifs_sb->local_nls); 280 cifs_sb->local_nls);
271 else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { 281 else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
272 cERROR(1,("SFU style symlinks not implemented yet")); 282 cERROR(1, ("SFU style symlinks not implemented yet"));
273 /* add open and read as in fs/cifs/inode.c */ 283 /* add open and read as in fs/cifs/inode.c */
274
275 } else { 284 } else {
276 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, GENERIC_READ, 285 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, GENERIC_READ,
277 OPEN_REPARSE_POINT,&fid, &oplock, NULL, 286 OPEN_REPARSE_POINT, &fid, &oplock, NULL,
278 cifs_sb->local_nls, 287 cifs_sb->local_nls,
279 cifs_sb->mnt_cifs_flags & 288 cifs_sb->mnt_cifs_flags &
280 CIFS_MOUNT_MAP_SPECIAL_CHR); 289 CIFS_MOUNT_MAP_SPECIAL_CHR);
281 if(!rc) { 290 if (!rc) {
282 rc = CIFSSMBQueryReparseLinkInfo(xid, pTcon, full_path, 291 rc = CIFSSMBQueryReparseLinkInfo(xid, pTcon, full_path,
283 tmpbuffer, 292 tmpbuffer,
284 len - 1, 293 len - 1,
285 fid, 294 fid,
286 cifs_sb->local_nls); 295 cifs_sb->local_nls);
287 if(CIFSSMBClose(xid, pTcon, fid)) { 296 if (CIFSSMBClose(xid, pTcon, fid)) {
288 cFYI(1,("Error closing junction point (open for ioctl)")); 297 cFYI(1, ("Error closing junction point "
298 "(open for ioctl)"));
289 } 299 }
290 if(rc == -EIO) { 300 if (rc == -EIO) {
291 /* Query if DFS Junction */ 301 /* Query if DFS Junction */
292 tmp_path = 302 tmp_path =
293 kmalloc(MAX_TREE_SIZE + MAX_PATHCONF + 1, 303 kmalloc(MAX_TREE_SIZE + MAX_PATHCONF + 1,
294 GFP_KERNEL); 304 GFP_KERNEL);
295 if (tmp_path) { 305 if (tmp_path) {
296 strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE); 306 strncpy(tmp_path, pTcon->treeName,
297 strncat(tmp_path, full_path, MAX_PATHCONF); 307 MAX_TREE_SIZE);
298 rc = get_dfs_path(xid, pTcon->ses, tmp_path, 308 strncat(tmp_path, full_path,
309 MAX_PATHCONF);
310 rc = get_dfs_path(xid, pTcon->ses,
311 tmp_path,
299 cifs_sb->local_nls, 312 cifs_sb->local_nls,
300 &num_referrals, &referrals, 313 &num_referrals, &referrals,
301 cifs_sb->mnt_cifs_flags & 314 cifs_sb->mnt_cifs_flags &
302 CIFS_MOUNT_MAP_SPECIAL_CHR); 315 CIFS_MOUNT_MAP_SPECIAL_CHR);
303 cFYI(1,("Get DFS for %s rc = %d ",tmp_path, rc)); 316 cFYI(1, ("Get DFS for %s rc = %d ",
304 if((num_referrals == 0) && (rc == 0)) 317 tmp_path, rc));
318 if ((num_referrals == 0) && (rc == 0))
305 rc = -EACCES; 319 rc = -EACCES;
306 else { 320 else {
307 cFYI(1,("num referral: %d",num_referrals)); 321 cFYI(1, ("num referral: %d",
308 if(referrals) { 322 num_referrals));
309 cFYI(1,("referral string: %s",referrals)); 323 if (referrals) {
310 strncpy(tmpbuffer, referrals, len-1); 324 cFYI(1,("referral string: %s", referrals));
325 strncpy(tmpbuffer,
326 referrals,
327 len-1);
311 } 328 }
312 } 329 }
313 kfree(referrals); 330 kfree(referrals);
314 kfree(tmp_path); 331 kfree(tmp_path);
315} 332}
316 /* BB add code like else decode referrals then memcpy to 333 /* BB add code like else decode referrals
317 tmpbuffer and free referrals string array BB */ 334 then memcpy to tmpbuffer and free referrals
335 string array BB */
318 } 336 }
319 } 337 }
320 } 338 }
diff --git a/fs/cifs/md4.c b/fs/cifs/md4.c
index 46d62c9dda0f..a2415c1a14db 100644
--- a/fs/cifs/md4.c
+++ b/fs/cifs/md4.c
@@ -1,20 +1,20 @@
1/* 1/*
2 Unix SMB/Netbios implementation. 2 Unix SMB/Netbios implementation.
3 Version 1.9. 3 Version 1.9.
4 a implementation of MD4 designed for use in the SMB authentication protocol 4 a implementation of MD4 designed for use in the SMB authentication protocol
5 Copyright (C) Andrew Tridgell 1997-1998. 5 Copyright (C) Andrew Tridgell 1997-1998.
6 Modified by Steve French (sfrench@us.ibm.com) 2002-2003 6 Modified by Steve French (sfrench@us.ibm.com) 2002-2003
7 7
8 This program is free software; you can redistribute it and/or modify 8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by 9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or 10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version. 11 (at your option) any later version.
12 12
13 This program is distributed in the hope that it will be useful, 13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details. 16 GNU General Public License for more details.
17 17
18 You should have received a copy of the GNU General Public License 18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software 19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -170,7 +170,7 @@ mdfour(unsigned char *out, unsigned char *in, int n)
170 170
171 while (n > 64) { 171 while (n > 64) {
172 copy64(M, in); 172 copy64(M, in);
173 mdfour64(M,&A,&B, &C, &D); 173 mdfour64(M, &A, &B, &C, &D);
174 in += 64; 174 in += 64;
175 n -= 64; 175 n -= 64;
176 } 176 }
diff --git a/fs/cifs/md5.c b/fs/cifs/md5.c
index ccebf9b7eb86..e5c3e1212697 100644
--- a/fs/cifs/md5.c
+++ b/fs/cifs/md5.c
@@ -15,9 +15,9 @@
15 * will fill a supplied 16-byte array with the digest. 15 * will fill a supplied 16-byte array with the digest.
16 */ 16 */
17 17
18/* This code slightly modified to fit into Samba by 18/* This code slightly modified to fit into Samba by
19 abartlet@samba.org Jun 2001 19 abartlet@samba.org Jun 2001
20 and to fit the cifs vfs by 20 and to fit the cifs vfs by
21 Steve French sfrench@us.ibm.com */ 21 Steve French sfrench@us.ibm.com */
22 22
23#include <linux/string.h> 23#include <linux/string.h>
@@ -106,7 +106,7 @@ MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
106} 106}
107 107
108/* 108/*
109 * Final wrapup - pad to 64-byte boundary with the bit pattern 109 * Final wrapup - pad to 64-byte boundary with the bit pattern
110 * 1 0* (64-bit count of bits processed, MSB-first) 110 * 1 0* (64-bit count of bits processed, MSB-first)
111 */ 111 */
112void 112void
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 19cc294c7c70..0bcec0844bee 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/misc.c 2 * fs/cifs/misc.c
3 * 3 *
4 * Copyright (C) International Business Machines Corp., 2002,2005 4 * Copyright (C) International Business Machines Corp., 2002,2007
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This library is free software; you can redistribute it and/or modify 7 * This library is free software; you can redistribute it and/or modify
@@ -16,7 +16,7 @@
16 * 16 *
17 * You should have received a copy of the GNU Lesser General Public License 17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software 18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 21
22#include <linux/slab.h> 22#include <linux/slab.h>
@@ -32,12 +32,12 @@
32 32
33extern mempool_t *cifs_sm_req_poolp; 33extern mempool_t *cifs_sm_req_poolp;
34extern mempool_t *cifs_req_poolp; 34extern mempool_t *cifs_req_poolp;
35extern struct task_struct * oplockThread; 35extern struct task_struct *oplockThread;
36 36
37/* The xid serves as a useful identifier for each incoming vfs request, 37/* The xid serves as a useful identifier for each incoming vfs request,
38 in a similar way to the mid which is useful to track each sent smb, 38 in a similar way to the mid which is useful to track each sent smb,
39 and CurrentXid can also provide a running counter (although it 39 and CurrentXid can also provide a running counter (although it
40 will eventually wrap past zero) of the total vfs operations handled 40 will eventually wrap past zero) of the total vfs operations handled
41 since the cifs fs was mounted */ 41 since the cifs fs was mounted */
42 42
43unsigned int 43unsigned int
@@ -47,10 +47,12 @@ _GetXid(void)
47 47
48 spin_lock(&GlobalMid_Lock); 48 spin_lock(&GlobalMid_Lock);
49 GlobalTotalActiveXid++; 49 GlobalTotalActiveXid++;
50
51 /* keep high water mark for number of simultaneous ops in filesystem */
50 if (GlobalTotalActiveXid > GlobalMaxActiveXid) 52 if (GlobalTotalActiveXid > GlobalMaxActiveXid)
51 GlobalMaxActiveXid = GlobalTotalActiveXid; /* keep high water mark for number of simultaneous vfs ops in our filesystem */ 53 GlobalMaxActiveXid = GlobalTotalActiveXid;
52 if(GlobalTotalActiveXid > 65000) 54 if (GlobalTotalActiveXid > 65000)
53 cFYI(1,("warning: more than 65000 requests active")); 55 cFYI(1, ("warning: more than 65000 requests active"));
54 xid = GlobalCurrentXid++; 56 xid = GlobalCurrentXid++;
55 spin_unlock(&GlobalMid_Lock); 57 spin_unlock(&GlobalMid_Lock);
56 return xid; 58 return xid;
@@ -60,7 +62,7 @@ void
60_FreeXid(unsigned int xid) 62_FreeXid(unsigned int xid)
61{ 63{
62 spin_lock(&GlobalMid_Lock); 64 spin_lock(&GlobalMid_Lock);
63 /* if(GlobalTotalActiveXid == 0) 65 /* if (GlobalTotalActiveXid == 0)
64 BUG(); */ 66 BUG(); */
65 GlobalTotalActiveXid--; 67 GlobalTotalActiveXid--;
66 spin_unlock(&GlobalMid_Lock); 68 spin_unlock(&GlobalMid_Lock);
@@ -144,12 +146,12 @@ cifs_buf_get(void)
144{ 146{
145 struct smb_hdr *ret_buf = NULL; 147 struct smb_hdr *ret_buf = NULL;
146 148
147/* We could use negotiated size instead of max_msgsize - 149/* We could use negotiated size instead of max_msgsize -
148 but it may be more efficient to always alloc same size 150 but it may be more efficient to always alloc same size
149 albeit slightly larger than necessary and maxbuffersize 151 albeit slightly larger than necessary and maxbuffersize
150 defaults to this and can not be bigger */ 152 defaults to this and can not be bigger */
151 ret_buf = 153 ret_buf = (struct smb_hdr *) mempool_alloc(cifs_req_poolp,
152 (struct smb_hdr *) mempool_alloc(cifs_req_poolp, GFP_KERNEL | GFP_NOFS); 154 GFP_KERNEL | GFP_NOFS);
153 155
154 /* clear the first few header bytes */ 156 /* clear the first few header bytes */
155 /* for most paths, more is cleared in header_assemble */ 157 /* for most paths, more is cleared in header_assemble */
@@ -172,7 +174,7 @@ cifs_buf_release(void *buf_to_free)
172 /* cFYI(1, ("Null buffer passed to cifs_buf_release"));*/ 174 /* cFYI(1, ("Null buffer passed to cifs_buf_release"));*/
173 return; 175 return;
174 } 176 }
175 mempool_free(buf_to_free,cifs_req_poolp); 177 mempool_free(buf_to_free, cifs_req_poolp);
176 178
177 atomic_dec(&bufAllocCount); 179 atomic_dec(&bufAllocCount);
178 return; 180 return;
@@ -183,12 +185,12 @@ cifs_small_buf_get(void)
183{ 185{
184 struct smb_hdr *ret_buf = NULL; 186 struct smb_hdr *ret_buf = NULL;
185 187
186/* We could use negotiated size instead of max_msgsize - 188/* We could use negotiated size instead of max_msgsize -
187 but it may be more efficient to always alloc same size 189 but it may be more efficient to always alloc same size
188 albeit slightly larger than necessary and maxbuffersize 190 albeit slightly larger than necessary and maxbuffersize
189 defaults to this and can not be bigger */ 191 defaults to this and can not be bigger */
190 ret_buf = 192 ret_buf = (struct smb_hdr *) mempool_alloc(cifs_sm_req_poolp,
191 (struct smb_hdr *) mempool_alloc(cifs_sm_req_poolp, GFP_KERNEL | GFP_NOFS); 193 GFP_KERNEL | GFP_NOFS);
192 if (ret_buf) { 194 if (ret_buf) {
193 /* No need to clear memory here, cleared in header assemble */ 195 /* No need to clear memory here, cleared in header assemble */
194 /* memset(ret_buf, 0, sizeof(struct smb_hdr) + 27);*/ 196 /* memset(ret_buf, 0, sizeof(struct smb_hdr) + 27);*/
@@ -209,30 +211,30 @@ cifs_small_buf_release(void *buf_to_free)
209 cFYI(1, ("Null buffer passed to cifs_small_buf_release")); 211 cFYI(1, ("Null buffer passed to cifs_small_buf_release"));
210 return; 212 return;
211 } 213 }
212 mempool_free(buf_to_free,cifs_sm_req_poolp); 214 mempool_free(buf_to_free, cifs_sm_req_poolp);
213 215
214 atomic_dec(&smBufAllocCount); 216 atomic_dec(&smBufAllocCount);
215 return; 217 return;
216} 218}
217 219
218/* 220/*
219 Find a free multiplex id (SMB mid). Otherwise there could be 221 Find a free multiplex id (SMB mid). Otherwise there could be
220 mid collisions which might cause problems, demultiplexing the 222 mid collisions which might cause problems, demultiplexing the
221 wrong response to this request. Multiplex ids could collide if 223 wrong response to this request. Multiplex ids could collide if
222 one of a series requests takes much longer than the others, or 224 one of a series requests takes much longer than the others, or
223 if a very large number of long lived requests (byte range 225 if a very large number of long lived requests (byte range
224 locks or FindNotify requests) are pending. No more than 226 locks or FindNotify requests) are pending. No more than
225 64K-1 requests can be outstanding at one time. If no 227 64K-1 requests can be outstanding at one time. If no
226 mids are available, return zero. A future optimization 228 mids are available, return zero. A future optimization
227 could make the combination of mids and uid the key we use 229 could make the combination of mids and uid the key we use
228 to demultiplex on (rather than mid alone). 230 to demultiplex on (rather than mid alone).
229 In addition to the above check, the cifs demultiplex 231 In addition to the above check, the cifs demultiplex
230 code already used the command code as a secondary 232 code already used the command code as a secondary
231 check of the frame and if signing is negotiated the 233 check of the frame and if signing is negotiated the
232 response would be discarded if the mid were the same 234 response would be discarded if the mid were the same
233 but the signature was wrong. Since the mid is not put in the 235 but the signature was wrong. Since the mid is not put in the
234 pending queue until later (when it is about to be dispatched) 236 pending queue until later (when it is about to be dispatched)
235 we do have to limit the number of outstanding requests 237 we do have to limit the number of outstanding requests
236 to somewhat less than 64K-1 although it is hard to imagine 238 to somewhat less than 64K-1 although it is hard to imagine
237 so many threads being in the vfs at one time. 239 so many threads being in the vfs at one time.
238*/ 240*/
@@ -240,27 +242,27 @@ __u16 GetNextMid(struct TCP_Server_Info *server)
240{ 242{
241 __u16 mid = 0; 243 __u16 mid = 0;
242 __u16 last_mid; 244 __u16 last_mid;
243 int collision; 245 int collision;
244 246
245 if(server == NULL) 247 if (server == NULL)
246 return mid; 248 return mid;
247 249
248 spin_lock(&GlobalMid_Lock); 250 spin_lock(&GlobalMid_Lock);
249 last_mid = server->CurrentMid; /* we do not want to loop forever */ 251 last_mid = server->CurrentMid; /* we do not want to loop forever */
250 server->CurrentMid++; 252 server->CurrentMid++;
251 /* This nested loop looks more expensive than it is. 253 /* This nested loop looks more expensive than it is.
252 In practice the list of pending requests is short, 254 In practice the list of pending requests is short,
253 fewer than 50, and the mids are likely to be unique 255 fewer than 50, and the mids are likely to be unique
254 on the first pass through the loop unless some request 256 on the first pass through the loop unless some request
255 takes longer than the 64 thousand requests before it 257 takes longer than the 64 thousand requests before it
256 (and it would also have to have been a request that 258 (and it would also have to have been a request that
257 did not time out) */ 259 did not time out) */
258 while(server->CurrentMid != last_mid) { 260 while (server->CurrentMid != last_mid) {
259 struct list_head *tmp; 261 struct list_head *tmp;
260 struct mid_q_entry *mid_entry; 262 struct mid_q_entry *mid_entry;
261 263
262 collision = 0; 264 collision = 0;
263 if(server->CurrentMid == 0) 265 if (server->CurrentMid == 0)
264 server->CurrentMid++; 266 server->CurrentMid++;
265 267
266 list_for_each(tmp, &server->pending_mid_q) { 268 list_for_each(tmp, &server->pending_mid_q) {
@@ -273,7 +275,7 @@ __u16 GetNextMid(struct TCP_Server_Info *server)
273 break; 275 break;
274 } 276 }
275 } 277 }
276 if(collision == 0) { 278 if (collision == 0) {
277 mid = server->CurrentMid; 279 mid = server->CurrentMid;
278 break; 280 break;
279 } 281 }
@@ -290,11 +292,11 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
290 const struct cifsTconInfo *treeCon, int word_count 292 const struct cifsTconInfo *treeCon, int word_count
291 /* length of fixed section (word count) in two byte units */) 293 /* length of fixed section (word count) in two byte units */)
292{ 294{
293 struct list_head* temp_item; 295 struct list_head *temp_item;
294 struct cifsSesInfo * ses; 296 struct cifsSesInfo *ses;
295 char *temp = (char *) buffer; 297 char *temp = (char *) buffer;
296 298
297 memset(temp,0,256); /* bigger than MAX_CIFS_HDR_SIZE */ 299 memset(temp, 0, 256); /* bigger than MAX_CIFS_HDR_SIZE */
298 300
299 buffer->smb_buf_length = 301 buffer->smb_buf_length =
300 (2 * word_count) + sizeof (struct smb_hdr) - 302 (2 * word_count) + sizeof (struct smb_hdr) -
@@ -325,7 +327,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
325 /* Uid is not converted */ 327 /* Uid is not converted */
326 buffer->Uid = treeCon->ses->Suid; 328 buffer->Uid = treeCon->ses->Suid;
327 buffer->Mid = GetNextMid(treeCon->ses->server); 329 buffer->Mid = GetNextMid(treeCon->ses->server);
328 if(multiuser_mount != 0) { 330 if (multiuser_mount != 0) {
329 /* For the multiuser case, there are few obvious technically */ 331 /* For the multiuser case, there are few obvious technically */
330 /* possible mechanisms to match the local linux user (uid) */ 332 /* possible mechanisms to match the local linux user (uid) */
331 /* to a valid remote smb user (smb_uid): */ 333 /* to a valid remote smb user (smb_uid): */
@@ -348,21 +350,22 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
348 /* flag were disabled. */ 350 /* flag were disabled. */
349 351
350 /* BB Add support for establishing new tCon and SMB Session */ 352 /* BB Add support for establishing new tCon and SMB Session */
351 /* with userid/password pairs found on the smb session */ 353 /* with userid/password pairs found on the smb session */
352 /* for other target tcp/ip addresses BB */ 354 /* for other target tcp/ip addresses BB */
353 if(current->fsuid != treeCon->ses->linux_uid) { 355 if (current->fsuid != treeCon->ses->linux_uid) {
354 cFYI(1,("Multiuser mode and UID did not match tcon uid")); 356 cFYI(1, ("Multiuser mode and UID "
357 "did not match tcon uid"));
355 read_lock(&GlobalSMBSeslock); 358 read_lock(&GlobalSMBSeslock);
356 list_for_each(temp_item, &GlobalSMBSessionList) { 359 list_for_each(temp_item, &GlobalSMBSessionList) {
357 ses = list_entry(temp_item, struct cifsSesInfo, cifsSessionList); 360 ses = list_entry(temp_item, struct cifsSesInfo, cifsSessionList);
358 if(ses->linux_uid == current->fsuid) { 361 if (ses->linux_uid == current->fsuid) {
359 if(ses->server == treeCon->ses->server) { 362 if (ses->server == treeCon->ses->server) {
360 cFYI(1,("found matching uid substitute right smb_uid")); 363 cFYI(1, ("found matching uid substitute right smb_uid"));
361 buffer->Uid = ses->Suid; 364 buffer->Uid = ses->Suid;
362 break; 365 break;
363 } else { 366 } else {
364 /* BB eventually call cifs_setup_session here */ 367 /* BB eventually call cifs_setup_session here */
365 cFYI(1,("local UID found but smb sess with this server does not exist")); 368 cFYI(1, ("local UID found but no smb sess with this server exists"));
366 } 369 }
367 } 370 }
368 } 371 }
@@ -374,8 +377,8 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
374 buffer->Flags2 |= SMBFLG2_DFS; 377 buffer->Flags2 |= SMBFLG2_DFS;
375 if (treeCon->nocase) 378 if (treeCon->nocase)
376 buffer->Flags |= SMBFLG_CASELESS; 379 buffer->Flags |= SMBFLG_CASELESS;
377 if((treeCon->ses) && (treeCon->ses->server)) 380 if ((treeCon->ses) && (treeCon->ses->server))
378 if(treeCon->ses->server->secMode & 381 if (treeCon->ses->server->secMode &
379 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 382 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
380 buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 383 buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
381 } 384 }
@@ -388,18 +391,18 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
388static int 391static int
389checkSMBhdr(struct smb_hdr *smb, __u16 mid) 392checkSMBhdr(struct smb_hdr *smb, __u16 mid)
390{ 393{
391 /* Make sure that this really is an SMB, that it is a response, 394 /* Make sure that this really is an SMB, that it is a response,
392 and that the message ids match */ 395 and that the message ids match */
393 if ((*(__le32 *) smb->Protocol == cpu_to_le32(0x424d53ff)) && 396 if ((*(__le32 *) smb->Protocol == cpu_to_le32(0x424d53ff)) &&
394 (mid == smb->Mid)) { 397 (mid == smb->Mid)) {
395 if(smb->Flags & SMBFLG_RESPONSE) 398 if (smb->Flags & SMBFLG_RESPONSE)
396 return 0; 399 return 0;
397 else { 400 else {
398 /* only one valid case where server sends us request */ 401 /* only one valid case where server sends us request */
399 if(smb->Command == SMB_COM_LOCKING_ANDX) 402 if (smb->Command == SMB_COM_LOCKING_ANDX)
400 return 0; 403 return 0;
401 else 404 else
402 cERROR(1, ("Rcvd Request not response")); 405 cERROR(1, ("Received Request not response"));
403 } 406 }
404 } else { /* bad signature or mid */ 407 } else { /* bad signature or mid */
405 if (*(__le32 *) smb->Protocol != cpu_to_le32(0x424d53ff)) 408 if (*(__le32 *) smb->Protocol != cpu_to_le32(0x424d53ff))
@@ -426,9 +429,9 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)
426 smb->WordCount = 0; 429 smb->WordCount = 0;
427 /* some error cases do not return wct and bcc */ 430 /* some error cases do not return wct and bcc */
428 return 0; 431 return 0;
429 } else if ((length == sizeof(struct smb_hdr) + 1) && 432 } else if ((length == sizeof(struct smb_hdr) + 1) &&
430 (smb->WordCount == 0)) { 433 (smb->WordCount == 0)) {
431 char * tmp = (char *)smb; 434 char *tmp = (char *)smb;
432 /* Need to work around a bug in two servers here */ 435 /* Need to work around a bug in two servers here */
433 /* First, check if the part of bcc they sent was zero */ 436 /* First, check if the part of bcc they sent was zero */
434 if (tmp[sizeof(struct smb_hdr)] == 0) { 437 if (tmp[sizeof(struct smb_hdr)] == 0) {
@@ -442,7 +445,7 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)
442 tmp[sizeof(struct smb_hdr)+1] = 0; 445 tmp[sizeof(struct smb_hdr)+1] = 0;
443 return 0; 446 return 0;
444 } 447 }
445 cERROR(1,("rcvd invalid byte count (bcc)")); 448 cERROR(1, ("rcvd invalid byte count (bcc)"));
446 } else { 449 } else {
447 cERROR(1, ("Length less than smb header size")); 450 cERROR(1, ("Length less than smb header size"));
448 } 451 }
@@ -458,32 +461,33 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)
458 return 1; 461 return 1;
459 clc_len = smbCalcSize_LE(smb); 462 clc_len = smbCalcSize_LE(smb);
460 463
461 if(4 + len != length) { 464 if (4 + len != length) {
462 cERROR(1, ("Length read does not match RFC1001 length %d",len)); 465 cERROR(1, ("Length read does not match RFC1001 length %d",
466 len));
463 return 1; 467 return 1;
464 } 468 }
465 469
466 if (4 + len != clc_len) { 470 if (4 + len != clc_len) {
467 /* check if bcc wrapped around for large read responses */ 471 /* check if bcc wrapped around for large read responses */
468 if((len > 64 * 1024) && (len > clc_len)) { 472 if ((len > 64 * 1024) && (len > clc_len)) {
469 /* check if lengths match mod 64K */ 473 /* check if lengths match mod 64K */
470 if(((4 + len) & 0xFFFF) == (clc_len & 0xFFFF)) 474 if (((4 + len) & 0xFFFF) == (clc_len & 0xFFFF))
471 return 0; /* bcc wrapped */ 475 return 0; /* bcc wrapped */
472 } 476 }
473 cFYI(1, ("Calculated size %d vs length %d mismatch for mid %d", 477 cFYI(1, ("Calculated size %d vs length %d mismatch for mid %d",
474 clc_len, 4 + len, smb->Mid)); 478 clc_len, 4 + len, smb->Mid));
475 /* Windows XP can return a few bytes too much, presumably 479 /* Windows XP can return a few bytes too much, presumably
476 an illegal pad, at the end of byte range lock responses 480 an illegal pad, at the end of byte range lock responses
477 so we allow for that three byte pad, as long as actual 481 so we allow for that three byte pad, as long as actual
478 received length is as long or longer than calculated length */ 482 received length is as long or longer than calculated length */
479 /* We have now had to extend this more, since there is a 483 /* We have now had to extend this more, since there is a
480 case in which it needs to be bigger still to handle a 484 case in which it needs to be bigger still to handle a
481 malformed response to transact2 findfirst from WinXP when 485 malformed response to transact2 findfirst from WinXP when
482 access denied is returned and thus bcc and wct are zero 486 access denied is returned and thus bcc and wct are zero
483 but server says length is 0x21 bytes too long as if the server 487 but server says length is 0x21 bytes too long as if the server
484 forget to reset the smb rfc1001 length when it reset the 488 forget to reset the smb rfc1001 length when it reset the
485 wct and bcc to minimum size and drop the t2 parms and data */ 489 wct and bcc to minimum size and drop the t2 parms and data */
486 if((4+len > clc_len) && (len <= clc_len + 512)) 490 if ((4+len > clc_len) && (len <= clc_len + 512))
487 return 0; 491 return 0;
488 else { 492 else {
489 cERROR(1, ("RFC1001 size %d bigger than SMB for Mid=%d", 493 cERROR(1, ("RFC1001 size %d bigger than SMB for Mid=%d",
@@ -495,61 +499,64 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)
495} 499}
496int 500int
497is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) 501is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
498{ 502{
499 struct smb_com_lock_req * pSMB = (struct smb_com_lock_req *)buf; 503 struct smb_com_lock_req *pSMB = (struct smb_com_lock_req *)buf;
500 struct list_head *tmp; 504 struct list_head *tmp;
501 struct list_head *tmp1; 505 struct list_head *tmp1;
502 struct cifsTconInfo *tcon; 506 struct cifsTconInfo *tcon;
503 struct cifsFileInfo *netfile; 507 struct cifsFileInfo *netfile;
504 508
505 cFYI(1,("Checking for oplock break or dnotify response")); 509 cFYI(1, ("Checking for oplock break or dnotify response"));
506 if((pSMB->hdr.Command == SMB_COM_NT_TRANSACT) && 510 if ((pSMB->hdr.Command == SMB_COM_NT_TRANSACT) &&
507 (pSMB->hdr.Flags & SMBFLG_RESPONSE)) { 511 (pSMB->hdr.Flags & SMBFLG_RESPONSE)) {
508 struct smb_com_transaction_change_notify_rsp * pSMBr = 512 struct smb_com_transaction_change_notify_rsp *pSMBr =
509 (struct smb_com_transaction_change_notify_rsp *)buf; 513 (struct smb_com_transaction_change_notify_rsp *)buf;
510 struct file_notify_information * pnotify; 514 struct file_notify_information *pnotify;
511 __u32 data_offset = 0; 515 __u32 data_offset = 0;
512 if(pSMBr->ByteCount > sizeof(struct file_notify_information)) { 516 if (pSMBr->ByteCount > sizeof(struct file_notify_information)) {
513 data_offset = le32_to_cpu(pSMBr->DataOffset); 517 data_offset = le32_to_cpu(pSMBr->DataOffset);
514 518
515 pnotify = (struct file_notify_information *) 519 pnotify = (struct file_notify_information *)
516 ((char *)&pSMBr->hdr.Protocol + data_offset); 520 ((char *)&pSMBr->hdr.Protocol + data_offset);
517 cFYI(1,("dnotify on %s Action: 0x%x",pnotify->FileName, 521 cFYI(1, ("dnotify on %s Action: 0x%x",
522 pnotify->FileName,
518 pnotify->Action)); /* BB removeme BB */ 523 pnotify->Action)); /* BB removeme BB */
519 /* cifs_dump_mem("Rcvd notify Data: ",buf, 524 /* cifs_dump_mem("Rcvd notify Data: ",buf,
520 sizeof(struct smb_hdr)+60); */ 525 sizeof(struct smb_hdr)+60); */
521 return TRUE; 526 return TRUE;
522 } 527 }
523 if(pSMBr->hdr.Status.CifsError) { 528 if (pSMBr->hdr.Status.CifsError) {
524 cFYI(1,("notify err 0x%d",pSMBr->hdr.Status.CifsError)); 529 cFYI(1, ("notify err 0x%d",
530 pSMBr->hdr.Status.CifsError));
525 return TRUE; 531 return TRUE;
526 } 532 }
527 return FALSE; 533 return FALSE;
528 } 534 }
529 if(pSMB->hdr.Command != SMB_COM_LOCKING_ANDX) 535 if (pSMB->hdr.Command != SMB_COM_LOCKING_ANDX)
530 return FALSE; 536 return FALSE;
531 if(pSMB->hdr.Flags & SMBFLG_RESPONSE) { 537 if (pSMB->hdr.Flags & SMBFLG_RESPONSE) {
532 /* no sense logging error on invalid handle on oplock 538 /* no sense logging error on invalid handle on oplock
533 break - harmless race between close request and oplock 539 break - harmless race between close request and oplock
534 break response is expected from time to time writing out 540 break response is expected from time to time writing out
535 large dirty files cached on the client */ 541 large dirty files cached on the client */
536 if ((NT_STATUS_INVALID_HANDLE) == 542 if ((NT_STATUS_INVALID_HANDLE) ==
537 le32_to_cpu(pSMB->hdr.Status.CifsError)) { 543 le32_to_cpu(pSMB->hdr.Status.CifsError)) {
538 cFYI(1,("invalid handle on oplock break")); 544 cFYI(1, ("invalid handle on oplock break"));
539 return TRUE; 545 return TRUE;
540 } else if (ERRbadfid == 546 } else if (ERRbadfid ==
541 le16_to_cpu(pSMB->hdr.Status.DosError.Error)) { 547 le16_to_cpu(pSMB->hdr.Status.DosError.Error)) {
542 return TRUE; 548 return TRUE;
543 } else { 549 } else {
544 return FALSE; /* on valid oplock brk we get "request" */ 550 return FALSE; /* on valid oplock brk we get "request" */
545 } 551 }
546 } 552 }
547 if(pSMB->hdr.WordCount != 8) 553 if (pSMB->hdr.WordCount != 8)
548 return FALSE; 554 return FALSE;
549 555
550 cFYI(1,(" oplock type 0x%d level 0x%d",pSMB->LockType,pSMB->OplockLevel)); 556 cFYI(1, ("oplock type 0x%d level 0x%d",
551 if(!(pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE)) 557 pSMB->LockType, pSMB->OplockLevel));
552 return FALSE; 558 if (!(pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE))
559 return FALSE;
553 560
554 /* look up tcon based on tid & uid */ 561 /* look up tcon based on tid & uid */
555 read_lock(&GlobalSMBSeslock); 562 read_lock(&GlobalSMBSeslock);
@@ -557,36 +564,38 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
557 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); 564 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
558 if ((tcon->tid == buf->Tid) && (srv == tcon->ses->server)) { 565 if ((tcon->tid == buf->Tid) && (srv == tcon->ses->server)) {
559 cifs_stats_inc(&tcon->num_oplock_brks); 566 cifs_stats_inc(&tcon->num_oplock_brks);
560 list_for_each(tmp1,&tcon->openFileList){ 567 list_for_each(tmp1, &tcon->openFileList) {
561 netfile = list_entry(tmp1,struct cifsFileInfo, 568 netfile = list_entry(tmp1, struct cifsFileInfo,
562 tlist); 569 tlist);
563 if(pSMB->Fid == netfile->netfid) { 570 if (pSMB->Fid == netfile->netfid) {
564 struct cifsInodeInfo *pCifsInode; 571 struct cifsInodeInfo *pCifsInode;
565 read_unlock(&GlobalSMBSeslock); 572 read_unlock(&GlobalSMBSeslock);
566 cFYI(1,("file id match, oplock break")); 573 cFYI(1,
567 pCifsInode = 574 ("file id match, oplock break"));
575 pCifsInode =
568 CIFS_I(netfile->pInode); 576 CIFS_I(netfile->pInode);
569 pCifsInode->clientCanCacheAll = FALSE; 577 pCifsInode->clientCanCacheAll = FALSE;
570 if(pSMB->OplockLevel == 0) 578 if (pSMB->OplockLevel == 0)
571 pCifsInode->clientCanCacheRead 579 pCifsInode->clientCanCacheRead
572 = FALSE; 580 = FALSE;
573 pCifsInode->oplockPending = TRUE; 581 pCifsInode->oplockPending = TRUE;
574 AllocOplockQEntry(netfile->pInode, 582 AllocOplockQEntry(netfile->pInode,
575 netfile->netfid, 583 netfile->netfid,
576 tcon); 584 tcon);
577 cFYI(1,("about to wake up oplock thd")); 585 cFYI(1,
578 if(oplockThread) 586 ("about to wake up oplock thread"));
587 if (oplockThread)
579 wake_up_process(oplockThread); 588 wake_up_process(oplockThread);
580 return TRUE; 589 return TRUE;
581 } 590 }
582 } 591 }
583 read_unlock(&GlobalSMBSeslock); 592 read_unlock(&GlobalSMBSeslock);
584 cFYI(1,("No matching file for oplock break")); 593 cFYI(1, ("No matching file for oplock break"));
585 return TRUE; 594 return TRUE;
586 } 595 }
587 } 596 }
588 read_unlock(&GlobalSMBSeslock); 597 read_unlock(&GlobalSMBSeslock);
589 cFYI(1,("Can not process oplock break for non-existent connection")); 598 cFYI(1, ("Can not process oplock break for non-existent connection"));
590 return TRUE; 599 return TRUE;
591} 600}
592 601
@@ -643,13 +652,13 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length)
643 only legal in POSIX-like OS (if they are present in the string). Path 652 only legal in POSIX-like OS (if they are present in the string). Path
644 names are little endian 16 bit Unicode on the wire */ 653 names are little endian 16 bit Unicode on the wire */
645int 654int
646cifs_convertUCSpath(char *target, const __le16 * source, int maxlen, 655cifs_convertUCSpath(char *target, const __le16 *source, int maxlen,
647 const struct nls_table * cp) 656 const struct nls_table *cp)
648{ 657{
649 int i,j,len; 658 int i, j, len;
650 __u16 src_char; 659 __u16 src_char;
651 660
652 for(i = 0, j = 0; i < maxlen; i++) { 661 for (i = 0, j = 0; i < maxlen; i++) {
653 src_char = le16_to_cpu(source[i]); 662 src_char = le16_to_cpu(source[i]);
654 switch (src_char) { 663 switch (src_char) {
655 case 0: 664 case 0:
@@ -678,10 +687,10 @@ cifs_convertUCSpath(char *target, const __le16 * source, int maxlen,
678 case UNI_LESSTHAN: 687 case UNI_LESSTHAN:
679 target[j] = '<'; 688 target[j] = '<';
680 break; 689 break;
681 default: 690 default:
682 len = cp->uni2char(src_char, &target[j], 691 len = cp->uni2char(src_char, &target[j],
683 NLS_MAX_CHARSET_SIZE); 692 NLS_MAX_CHARSET_SIZE);
684 if(len > 0) { 693 if (len > 0) {
685 j += len; 694 j += len;
686 continue; 695 continue;
687 } else { 696 } else {
@@ -690,7 +699,7 @@ cifs_convertUCSpath(char *target, const __le16 * source, int maxlen,
690 } 699 }
691 j++; 700 j++;
692 /* make sure we do not overrun callers allocated temp buffer */ 701 /* make sure we do not overrun callers allocated temp buffer */
693 if(j >= (2 * NAME_MAX)) 702 if (j >= (2 * NAME_MAX))
694 break; 703 break;
695 } 704 }
696cUCS_out: 705cUCS_out:
@@ -703,18 +712,18 @@ cUCS_out:
703 only legal in POSIX-like OS (if they are present in the string). Path 712 only legal in POSIX-like OS (if they are present in the string). Path
704 names are little endian 16 bit Unicode on the wire */ 713 names are little endian 16 bit Unicode on the wire */
705int 714int
706cifsConvertToUCS(__le16 * target, const char *source, int maxlen, 715cifsConvertToUCS(__le16 *target, const char *source, int maxlen,
707 const struct nls_table * cp, int mapChars) 716 const struct nls_table *cp, int mapChars)
708{ 717{
709 int i,j,charlen; 718 int i, j, charlen;
710 int len_remaining = maxlen; 719 int len_remaining = maxlen;
711 char src_char; 720 char src_char;
712 __u16 temp; 721 __u16 temp;
713 722
714 if(!mapChars) 723 if (!mapChars)
715 return cifs_strtoUCS(target, source, PATH_MAX, cp); 724 return cifs_strtoUCS(target, source, PATH_MAX, cp);
716 725
717 for(i = 0, j = 0; i < maxlen; j++) { 726 for (i = 0, j = 0; i < maxlen; j++) {
718 src_char = source[i]; 727 src_char = source[i];
719 switch (src_char) { 728 switch (src_char) {
720 case 0: 729 case 0:
@@ -737,7 +746,7 @@ cifsConvertToUCS(__le16 * target, const char *source, int maxlen,
737 break; 746 break;
738 case '|': 747 case '|':
739 target[j] = cpu_to_le16(UNI_PIPE); 748 target[j] = cpu_to_le16(UNI_PIPE);
740 break; 749 break;
741 /* BB We can not handle remapping slash until 750 /* BB We can not handle remapping slash until
742 all the calls to build_path_from_dentry 751 all the calls to build_path_from_dentry
743 are modified, as they use slash as separator BB */ 752 are modified, as they use slash as separator BB */
@@ -749,7 +758,7 @@ cifsConvertToUCS(__le16 * target, const char *source, int maxlen,
749 len_remaining, &temp); 758 len_remaining, &temp);
750 /* if no match, use question mark, which 759 /* if no match, use question mark, which
751 at least in some cases servers as wild card */ 760 at least in some cases servers as wild card */
752 if(charlen < 1) { 761 if (charlen < 1) {
753 target[j] = cpu_to_le16(0x003f); 762 target[j] = cpu_to_le16(0x003f);
754 charlen = 1; 763 charlen = 1;
755 } else 764 } else
@@ -758,7 +767,7 @@ cifsConvertToUCS(__le16 * target, const char *source, int maxlen,
758 /* character may take more than one byte in the 767 /* character may take more than one byte in the
759 the source string, but will take exactly two 768 the source string, but will take exactly two
760 bytes in the target string */ 769 bytes in the target string */
761 i+= charlen; 770 i += charlen;
762 continue; 771 continue;
763 } 772 }
764 i++; /* move to next char in source string */ 773 i++; /* move to next char in source string */
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
index 53e304d59544..2bfed3f45d0f 100644
--- a/fs/cifs/netmisc.c
+++ b/fs/cifs/netmisc.c
@@ -3,23 +3,22 @@
3 * 3 *
4 * Copyright (c) International Business Machines Corp., 2002 4 * Copyright (c) International Business Machines Corp., 2002
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * Error mapping routines from Samba libsmb/errormap.c 7 * Error mapping routines from Samba libsmb/errormap.c
8 * Copyright (C) Andrew Tridgell 2001 8 * Copyright (C) Andrew Tridgell 2001
9 * 9 *
10 *
11 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or 12 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version. 13 * (at your option) any later version.
15 * 14 *
16 * This program is distributed in the hope that it will be useful, 15 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
19 * the GNU General Public License for more details. 18 * the GNU General Public License for more details.
20 * 19 *
21 * You should have received a copy of the GNU General Public License 20 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software 21 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */ 23 */
25 24
@@ -30,9 +29,7 @@
30#include <linux/fs.h> 29#include <linux/fs.h>
31#include <asm/div64.h> 30#include <asm/div64.h>
32#include <asm/byteorder.h> 31#include <asm/byteorder.h>
33#ifdef CONFIG_CIFS_EXPERIMENTAL
34#include <linux/inet.h> 32#include <linux/inet.h>
35#endif
36#include "cifsfs.h" 33#include "cifsfs.h"
37#include "cifspdu.h" 34#include "cifspdu.h"
38#include "cifsglob.h" 35#include "cifsglob.h"
@@ -67,22 +64,22 @@ static const struct smb_to_posix_error mapping_table_ERRDOS[] = {
67 {ERRbadshare, -ETXTBSY}, 64 {ERRbadshare, -ETXTBSY},
68 {ERRlock, -EACCES}, 65 {ERRlock, -EACCES},
69 {ERRunsup, -EINVAL}, 66 {ERRunsup, -EINVAL},
70 {ERRnosuchshare,-ENXIO}, 67 {ERRnosuchshare, -ENXIO},
71 {ERRfilexists, -EEXIST}, 68 {ERRfilexists, -EEXIST},
72 {ERRinvparm, -EINVAL}, 69 {ERRinvparm, -EINVAL},
73 {ERRdiskfull, -ENOSPC}, 70 {ERRdiskfull, -ENOSPC},
74 {ERRinvname, -ENOENT}, 71 {ERRinvname, -ENOENT},
75 {ERRinvlevel,-EOPNOTSUPP}, 72 {ERRinvlevel, -EOPNOTSUPP},
76 {ERRdirnotempty, -ENOTEMPTY}, 73 {ERRdirnotempty, -ENOTEMPTY},
77 {ERRnotlocked, -ENOLCK}, 74 {ERRnotlocked, -ENOLCK},
78 {ERRcancelviolation, -ENOLCK}, 75 {ERRcancelviolation, -ENOLCK},
79 {ERRalreadyexists, -EEXIST}, 76 {ERRalreadyexists, -EEXIST},
80 {ERRmoredata, -EOVERFLOW}, 77 {ERRmoredata, -EOVERFLOW},
81 {ERReasnotsupported,-EOPNOTSUPP}, 78 {ERReasnotsupported, -EOPNOTSUPP},
82 {ErrQuota, -EDQUOT}, 79 {ErrQuota, -EDQUOT},
83 {ErrNotALink, -ENOLINK}, 80 {ErrNotALink, -ENOLINK},
84 {ERRnetlogonNotStarted,-ENOPROTOOPT}, 81 {ERRnetlogonNotStarted, -ENOPROTOOPT},
85 {ErrTooManyLinks,-EMLINK}, 82 {ErrTooManyLinks, -EMLINK},
86 {0, 0} 83 {0, 0}
87}; 84};
88 85
@@ -133,85 +130,24 @@ static const struct smb_to_posix_error mapping_table_ERRHRD[] = {
133/* returns 0 if invalid address */ 130/* returns 0 if invalid address */
134 131
135int 132int
136cifs_inet_pton(int address_family, char *cp,void *dst) 133cifs_inet_pton(int address_family, char *cp, void *dst)
137{ 134{
138#ifdef CONFIG_CIFS_EXPERIMENTAL
139 int ret = 0; 135 int ret = 0;
140 136
141 /* calculate length by finding first slash or NULL */ 137 /* calculate length by finding first slash or NULL */
142 /* BB Should we convert '/' slash to '\' here since it seems already done 138 /* BB Should we convert '/' slash to '\' here since it seems already
143 before this */ 139 * done before this */
144 if( address_family == AF_INET ){ 140 if ( address_family == AF_INET ) {
145 ret = in4_pton(cp, -1 /* len */, dst , '\\', NULL); 141 ret = in4_pton(cp, -1 /* len */, dst , '\\', NULL);
146 } else if( address_family == AF_INET6 ){ 142 } else if ( address_family == AF_INET6 ) {
147 ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL); 143 ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL);
148 } 144 }
149#ifdef CONFIG_CIFS_DEBUG2 145#ifdef CONFIG_CIFS_DEBUG2
150 cFYI(1,("address conversion returned %d for %s", ret, cp)); 146 cFYI(1, ("address conversion returned %d for %s", ret, cp));
151#endif 147#endif
152 if (ret > 0) 148 if (ret > 0)
153 ret = 1; 149 ret = 1;
154 return ret; 150 return ret;
155#else
156 int value;
157 int digit;
158 int i;
159 char temp;
160 char bytes[4];
161 char *end = bytes;
162 static const int addr_class_max[4] =
163 { 0xffffffff, 0xffffff, 0xffff, 0xff };
164
165 if(address_family != AF_INET)
166 return -EAFNOSUPPORT;
167
168 for (i = 0; i < 4; i++) {
169 bytes[i] = 0;
170 }
171
172 temp = *cp;
173
174 while (TRUE) {
175 if (!isdigit(temp))
176 return 0;
177
178 value = 0;
179 digit = 0;
180 for (;;) {
181 if (isascii(temp) && isdigit(temp)) {
182 value = (value * 10) + temp - '0';
183 temp = *++cp;
184 digit = 1;
185 } else
186 break;
187 }
188
189 if (temp == '.') {
190 if ((end > bytes + 2) || (value > 255))
191 return 0;
192 *end++ = value;
193 temp = *++cp;
194 } else if (temp == ':') {
195 cFYI(1,("IPv6 addresses not supported for CIFS mounts yet"));
196 return -1;
197 } else
198 break;
199 }
200
201 /* check for last characters */
202 if (temp != '\0' && (!isascii(temp) || !isspace(temp)))
203 if (temp != '\\') {
204 if (temp != '/')
205 return 0;
206 else
207 (*cp = '\\'); /* switch the slash the expected way */
208 }
209 if (value > addr_class_max[end - bytes])
210 return 0;
211
212 *((__be32 *)dst) = *((__be32 *) bytes) | htonl(value);
213 return 1; /* success */
214#endif /* EXPERIMENTAL */
215} 151}
216 152
217/***************************************************************************** 153/*****************************************************************************
@@ -246,7 +182,7 @@ static const struct {
246 ERRHRD, ERRgeneral, NT_STATUS_UNRECOGNIZED_MEDIA}, { 182 ERRHRD, ERRgeneral, NT_STATUS_UNRECOGNIZED_MEDIA}, {
247 ERRDOS, 27, NT_STATUS_NONEXISTENT_SECTOR}, 183 ERRDOS, 27, NT_STATUS_NONEXISTENT_SECTOR},
248/* { This NT error code was 'sqashed' 184/* { This NT error code was 'sqashed'
249 from NT_STATUS_MORE_PROCESSING_REQUIRED to NT_STATUS_OK 185 from NT_STATUS_MORE_PROCESSING_REQUIRED to NT_STATUS_OK
250 during the session setup } */ 186 during the session setup } */
251 { 187 {
252 ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY}, { 188 ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY}, {
@@ -261,7 +197,7 @@ static const struct {
261 ERRDOS, 193, NT_STATUS_INVALID_FILE_FOR_SECTION}, { 197 ERRDOS, 193, NT_STATUS_INVALID_FILE_FOR_SECTION}, {
262 ERRDOS, ERRnoaccess, NT_STATUS_ALREADY_COMMITTED}, 198 ERRDOS, ERRnoaccess, NT_STATUS_ALREADY_COMMITTED},
263/* { This NT error code was 'sqashed' 199/* { This NT error code was 'sqashed'
264 from NT_STATUS_ACCESS_DENIED to NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE 200 from NT_STATUS_ACCESS_DENIED to NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE
265 during the session setup } */ 201 during the session setup } */
266 { 202 {
267 ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED}, { 203 ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED}, {
@@ -331,7 +267,7 @@ static const struct {
331 ERRHRD, ERRgeneral, NT_STATUS_INVALID_ACCOUNT_NAME}, { 267 ERRHRD, ERRgeneral, NT_STATUS_INVALID_ACCOUNT_NAME}, {
332 ERRHRD, ERRgeneral, NT_STATUS_USER_EXISTS}, 268 ERRHRD, ERRgeneral, NT_STATUS_USER_EXISTS},
333/* { This NT error code was 'sqashed' 269/* { This NT error code was 'sqashed'
334 from NT_STATUS_NO_SUCH_USER to NT_STATUS_LOGON_FAILURE 270 from NT_STATUS_NO_SUCH_USER to NT_STATUS_LOGON_FAILURE
335 during the session setup } */ 271 during the session setup } */
336 { 272 {
337 ERRDOS, ERRnoaccess, NT_STATUS_NO_SUCH_USER}, { 273 ERRDOS, ERRnoaccess, NT_STATUS_NO_SUCH_USER}, {
@@ -341,7 +277,7 @@ static const struct {
341 ERRHRD, ERRgeneral, NT_STATUS_MEMBER_NOT_IN_GROUP}, { 277 ERRHRD, ERRgeneral, NT_STATUS_MEMBER_NOT_IN_GROUP}, {
342 ERRHRD, ERRgeneral, NT_STATUS_LAST_ADMIN}, 278 ERRHRD, ERRgeneral, NT_STATUS_LAST_ADMIN},
343/* { This NT error code was 'sqashed' 279/* { This NT error code was 'sqashed'
344 from NT_STATUS_WRONG_PASSWORD to NT_STATUS_LOGON_FAILURE 280 from NT_STATUS_WRONG_PASSWORD to NT_STATUS_LOGON_FAILURE
345 during the session setup } */ 281 during the session setup } */
346 { 282 {
347 ERRSRV, ERRbadpw, NT_STATUS_WRONG_PASSWORD}, { 283 ERRSRV, ERRbadpw, NT_STATUS_WRONG_PASSWORD}, {
@@ -393,8 +329,8 @@ static const struct {
393 ERRHRD, ERRgeneral, NT_STATUS_FILE_INVALID}, { 329 ERRHRD, ERRgeneral, NT_STATUS_FILE_INVALID}, {
394 ERRHRD, ERRgeneral, NT_STATUS_ALLOTTED_SPACE_EXCEEDED}, 330 ERRHRD, ERRgeneral, NT_STATUS_ALLOTTED_SPACE_EXCEEDED},
395/* { This NT error code was 'sqashed' 331/* { This NT error code was 'sqashed'
396 from NT_STATUS_INSUFFICIENT_RESOURCES to NT_STATUS_INSUFF_SERVER_RESOURCES 332 from NT_STATUS_INSUFFICIENT_RESOURCES to
397 during the session setup } */ 333 NT_STATUS_INSUFF_SERVER_RESOURCES during the session setup } */
398 { 334 {
399 ERRDOS, ERRnomem, NT_STATUS_INSUFFICIENT_RESOURCES}, { 335 ERRDOS, ERRnomem, NT_STATUS_INSUFFICIENT_RESOURCES}, {
400 ERRDOS, ERRbadpath, NT_STATUS_DFS_EXIT_PATH_FOUND}, { 336 ERRDOS, ERRbadpath, NT_STATUS_DFS_EXIT_PATH_FOUND}, {
@@ -638,8 +574,8 @@ static const struct {
638 ERRDOS, 19, NT_STATUS_TOO_LATE}, { 574 ERRDOS, 19, NT_STATUS_TOO_LATE}, {
639 ERRDOS, ERRnoaccess, NT_STATUS_NO_TRUST_LSA_SECRET}, 575 ERRDOS, ERRnoaccess, NT_STATUS_NO_TRUST_LSA_SECRET},
640/* { This NT error code was 'sqashed' 576/* { This NT error code was 'sqashed'
641 from NT_STATUS_NO_TRUST_SAM_ACCOUNT to NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE 577 from NT_STATUS_NO_TRUST_SAM_ACCOUNT to
642 during the session setup } */ 578 NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE during the session setup } */
643 { 579 {
644 ERRDOS, ERRnoaccess, NT_STATUS_NO_TRUST_SAM_ACCOUNT}, { 580 ERRDOS, ERRnoaccess, NT_STATUS_NO_TRUST_SAM_ACCOUNT}, {
645 ERRDOS, ERRnoaccess, NT_STATUS_TRUSTED_DOMAIN_FAILURE}, { 581 ERRDOS, ERRnoaccess, NT_STATUS_TRUSTED_DOMAIN_FAILURE}, {
@@ -658,7 +594,7 @@ static const struct {
658 ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT}, { 594 ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT}, {
659 ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT}, 595 ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT},
660/* { This NT error code was 'sqashed' 596/* { This NT error code was 'sqashed'
661 from NT_STATUS_DOMAIN_TRUST_INCONSISTENT to NT_STATUS_LOGON_FAILURE 597 from NT_STATUS_DOMAIN_TRUST_INCONSISTENT to NT_STATUS_LOGON_FAILURE
662 during the session setup } */ 598 during the session setup } */
663 { 599 {
664 ERRDOS, ERRnoaccess, NT_STATUS_DOMAIN_TRUST_INCONSISTENT}, { 600 ERRDOS, ERRnoaccess, NT_STATUS_DOMAIN_TRUST_INCONSISTENT}, {
@@ -789,7 +725,7 @@ cifs_print_status(__u32 status_code)
789 if (((nt_errs[idx].nt_errcode) & 0xFFFFFF) == 725 if (((nt_errs[idx].nt_errcode) & 0xFFFFFF) ==
790 (status_code & 0xFFFFFF)) { 726 (status_code & 0xFFFFFF)) {
791 printk(KERN_NOTICE "Status code returned 0x%08x %s\n", 727 printk(KERN_NOTICE "Status code returned 0x%08x %s\n",
792 status_code,nt_errs[idx].nt_errstr); 728 status_code, nt_errs[idx].nt_errstr);
793 } 729 }
794 idx++; 730 idx++;
795 } 731 }
@@ -821,7 +757,7 @@ int
821map_smb_to_linux_error(struct smb_hdr *smb) 757map_smb_to_linux_error(struct smb_hdr *smb)
822{ 758{
823 unsigned int i; 759 unsigned int i;
824 int rc = -EIO; /* if transport error smb error may not be set */ 760 int rc = -EIO; /* if transport error smb error may not be set */
825 __u8 smberrclass; 761 __u8 smberrclass;
826 __u16 smberrcode; 762 __u16 smberrcode;
827 763
@@ -832,9 +768,10 @@ map_smb_to_linux_error(struct smb_hdr *smb)
832 return 0; 768 return 0;
833 769
834 if (smb->Flags2 & SMBFLG2_ERR_STATUS) { 770 if (smb->Flags2 & SMBFLG2_ERR_STATUS) {
835 /* translate the newer STATUS codes to old style errors and then to POSIX errors */ 771 /* translate the newer STATUS codes to old style SMB errors
772 * and then to POSIX errors */
836 __u32 err = le32_to_cpu(smb->Status.CifsError); 773 __u32 err = le32_to_cpu(smb->Status.CifsError);
837 if(cifsFYI & CIFS_RC) 774 if (cifsFYI & CIFS_RC)
838 cifs_print_status(err); 775 cifs_print_status(err);
839 ntstatus_to_dos(err, &smberrclass, &smberrcode); 776 ntstatus_to_dos(err, &smberrclass, &smberrcode);
840 } else { 777 } else {
@@ -845,38 +782,42 @@ map_smb_to_linux_error(struct smb_hdr *smb)
845 /* old style errors */ 782 /* old style errors */
846 783
847 /* DOS class smb error codes - map DOS */ 784 /* DOS class smb error codes - map DOS */
848 if (smberrclass == ERRDOS) { /* one byte field no need to byte reverse */ 785 if (smberrclass == ERRDOS) { /* 1 byte field no need to byte reverse */
849 for (i = 0; 786 for (i = 0;
850 i < 787 i <
851 sizeof (mapping_table_ERRDOS) / 788 sizeof (mapping_table_ERRDOS) /
852 sizeof (struct smb_to_posix_error); i++) { 789 sizeof (struct smb_to_posix_error); i++) {
853 if (mapping_table_ERRDOS[i].smb_err == 0) 790 if (mapping_table_ERRDOS[i].smb_err == 0)
854 break; 791 break;
855 else if (mapping_table_ERRDOS[i].smb_err == smberrcode) { 792 else if (mapping_table_ERRDOS[i].smb_err ==
793 smberrcode) {
856 rc = mapping_table_ERRDOS[i].posix_code; 794 rc = mapping_table_ERRDOS[i].posix_code;
857 break; 795 break;
858 } 796 }
859 /* else try the next error mapping one to see if it will match */ 797 /* else try next error mapping one to see if match */
860 } 798 }
861 } else if (smberrclass == ERRSRV) { /* server class of error codes */ 799 } else if (smberrclass == ERRSRV) { /* server class of error codes */
862 for (i = 0; 800 for (i = 0;
863 i < 801 i <
864 sizeof (mapping_table_ERRSRV) / 802 sizeof (mapping_table_ERRSRV) /
865 sizeof (struct smb_to_posix_error); i++) { 803 sizeof (struct smb_to_posix_error); i++) {
866 if (mapping_table_ERRSRV[i].smb_err == 0) 804 if (mapping_table_ERRSRV[i].smb_err == 0)
867 break; 805 break;
868 else if (mapping_table_ERRSRV[i].smb_err == smberrcode) { 806 else if (mapping_table_ERRSRV[i].smb_err ==
807 smberrcode) {
869 rc = mapping_table_ERRSRV[i].posix_code; 808 rc = mapping_table_ERRSRV[i].posix_code;
870 break; 809 break;
871 } 810 }
872 /* else try the next error mapping one to see if it will match */ 811 /* else try next error mapping to see if match */
873 } 812 }
874 } 813 }
875 /* else ERRHRD class errors or junk - return EIO */ 814 /* else ERRHRD class errors or junk - return EIO */
876 815
877 cFYI(1, (" !!Mapping smb error code %d to POSIX err %d !!", smberrcode,rc)); 816 cFYI(1, (" !!Mapping smb error code %d to POSIX err %d !!",
817 smberrcode, rc));
878 818
879 /* generic corrective action e.g. reconnect SMB session on ERRbaduid could be added */ 819 /* generic corrective action e.g. reconnect SMB session on
820 * ERRbaduid could be added */
880 821
881 return rc; 822 return rc;
882} 823}
@@ -910,7 +851,7 @@ smbCalcSize_LE(struct smb_hdr *ptr)
910struct timespec 851struct timespec
911cifs_NTtimeToUnix(u64 ntutc) 852cifs_NTtimeToUnix(u64 ntutc)
912{ 853{
913 struct timespec ts; 854 struct timespec ts;
914 /* BB what about the timezone? BB */ 855 /* BB what about the timezone? BB */
915 856
916 /* Subtract the NTFS time offset, then convert to 1s intervals. */ 857 /* Subtract the NTFS time offset, then convert to 1s intervals. */
@@ -918,7 +859,7 @@ cifs_NTtimeToUnix(u64 ntutc)
918 859
919 t = ntutc - NTFS_TIME_OFFSET; 860 t = ntutc - NTFS_TIME_OFFSET;
920 ts.tv_nsec = do_div(t, 10000000) * 100; 861 ts.tv_nsec = do_div(t, 10000000) * 100;
921 ts.tv_sec = t; 862 ts.tv_sec = t;
922 return ts; 863 return ts;
923} 864}
924 865
@@ -946,20 +887,20 @@ struct timespec cnvrtDosUnixTm(__u16 date, __u16 time)
946 SMB_TIME * st = (SMB_TIME *)&time; 887 SMB_TIME * st = (SMB_TIME *)&time;
947 SMB_DATE * sd = (SMB_DATE *)&date; 888 SMB_DATE * sd = (SMB_DATE *)&date;
948 889
949 cFYI(1,("date %d time %d",date, time)); 890 cFYI(1, ("date %d time %d", date, time));
950 891
951 sec = 2 * st->TwoSeconds; 892 sec = 2 * st->TwoSeconds;
952 min = st->Minutes; 893 min = st->Minutes;
953 if((sec > 59) || (min > 59)) 894 if ((sec > 59) || (min > 59))
954 cERROR(1,("illegal time min %d sec %d", min, sec)); 895 cERROR(1, ("illegal time min %d sec %d", min, sec));
955 sec += (min * 60); 896 sec += (min * 60);
956 sec += 60 * 60 * st->Hours; 897 sec += 60 * 60 * st->Hours;
957 if(st->Hours > 24) 898 if (st->Hours > 24)
958 cERROR(1,("illegal hours %d",st->Hours)); 899 cERROR(1, ("illegal hours %d", st->Hours));
959 days = sd->Day; 900 days = sd->Day;
960 month = sd->Month; 901 month = sd->Month;
961 if((days > 31) || (month > 12)) 902 if ((days > 31) || (month > 12))
962 cERROR(1,("illegal date, month %d day: %d", month, days)); 903 cERROR(1, ("illegal date, month %d day: %d", month, days));
963 month -= 1; 904 month -= 1;
964 days += total_days_of_prev_months[month]; 905 days += total_days_of_prev_months[month];
965 days += 3652; /* account for difference in days between 1980 and 1970 */ 906 days += 3652; /* account for difference in days between 1980 and 1970 */
@@ -970,15 +911,15 @@ struct timespec cnvrtDosUnixTm(__u16 date, __u16 time)
970 for years/100 except for years/400, but since the maximum number for DOS 911 for years/100 except for years/400, but since the maximum number for DOS
971 year is 2**7, the last year is 1980+127, which means we need only 912 year is 2**7, the last year is 1980+127, which means we need only
972 consider 2 special case years, ie the years 2000 and 2100, and only 913 consider 2 special case years, ie the years 2000 and 2100, and only
973 adjust for the lack of leap year for the year 2100, as 2000 was a 914 adjust for the lack of leap year for the year 2100, as 2000 was a
974 leap year (divisable by 400) */ 915 leap year (divisable by 400) */
975 if(year >= 120) /* the year 2100 */ 916 if (year >= 120) /* the year 2100 */
976 days = days - 1; /* do not count leap year for the year 2100 */ 917 days = days - 1; /* do not count leap year for the year 2100 */
977 918
978 /* adjust for leap year where we are still before leap day */ 919 /* adjust for leap year where we are still before leap day */
979 if(year != 120) 920 if (year != 120)
980 days -= ((year & 0x03) == 0) && (month < 2 ? 1 : 0); 921 days -= ((year & 0x03) == 0) && (month < 2 ? 1 : 0);
981 sec += 24 * 60 * 60 * days; 922 sec += 24 * 60 * 60 * days;
982 923
983 ts.tv_sec = sec; 924 ts.tv_sec = sec;
984 925
@@ -986,4 +927,4 @@ struct timespec cnvrtDosUnixTm(__u16 date, __u16 time)
986 927
987 ts.tv_nsec = 0; 928 ts.tv_nsec = 0;
988 return ts; 929 return ts;
989} 930}
diff --git a/fs/cifs/nterr.c b/fs/cifs/nterr.c
index 4da50cd34469..819fd994b121 100644
--- a/fs/cifs/nterr.c
+++ b/fs/cifs/nterr.c
@@ -1,19 +1,19 @@
1/* 1/*
2 * Unix SMB/Netbios implementation. 2 * Unix SMB/Netbios implementation.
3 * Version 1.9. 3 * Version 1.9.
4 * RPC Pipe client / server routines 4 * RPC Pipe client / server routines
5 * Copyright (C) Luke Kenneth Casson Leighton 1997-2001. 5 * Copyright (C) Luke Kenneth Casson Leighton 1997-2001.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or 9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version. 10 * (at your option) any later version.
11 * 11 *
12 * This program is distributed in the hope that it will be useful, 12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details. 15 * GNU General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software 18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
diff --git a/fs/cifs/nterr.h b/fs/cifs/nterr.h
index d2fb06c97dfa..588abbb9d08c 100644
--- a/fs/cifs/nterr.h
+++ b/fs/cifs/nterr.h
@@ -1,4 +1,4 @@
1/* 1/*
2 Unix SMB/Netbios implementation. 2 Unix SMB/Netbios implementation.
3 Version 1.9. 3 Version 1.9.
4 NT error code constants 4 NT error code constants
@@ -6,17 +6,17 @@
6 Copyright (C) John H Terpstra 1996-2000 6 Copyright (C) John H Terpstra 1996-2000
7 Copyright (C) Luke Kenneth Casson Leighton 1996-2000 7 Copyright (C) Luke Kenneth Casson Leighton 1996-2000
8 Copyright (C) Paul Ashton 1998-2000 8 Copyright (C) Paul Ashton 1998-2000
9 9
10 This program is free software; you can redistribute it and/or modify 10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by 11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or 12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version. 13 (at your option) any later version.
14 14
15 This program is distributed in the hope that it will be useful, 15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details. 18 GNU General Public License for more details.
19 19
20 You should have received a copy of the GNU General Public License 20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software 21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
diff --git a/fs/cifs/ntlmssp.h b/fs/cifs/ntlmssp.h
index d39b712a11c5..7170a9b70f1e 100644
--- a/fs/cifs/ntlmssp.h
+++ b/fs/cifs/ntlmssp.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/ntlmssp.h 2 * fs/cifs/ntlmssp.h
3 * 3 *
4 * Copyright (c) International Business Machines Corp., 2002,2006 4 * Copyright (c) International Business Machines Corp., 2002,2007
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This library is free software; you can redistribute it and/or modify 7 * This library is free software; you can redistribute it and/or modify
@@ -16,7 +16,7 @@
16 * 16 *
17 * You should have received a copy of the GNU Lesser General Public License 17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software 18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 21
22#define NTLMSSP_SIGNATURE "NTLMSSP" 22#define NTLMSSP_SIGNATURE "NTLMSSP"
@@ -27,18 +27,18 @@
27#define UnknownMessage cpu_to_le32(8) 27#define UnknownMessage cpu_to_le32(8)
28 28
29/* Negotiate Flags */ 29/* Negotiate Flags */
30#define NTLMSSP_NEGOTIATE_UNICODE 0x01 // Text strings are in unicode 30#define NTLMSSP_NEGOTIATE_UNICODE 0x01 /* Text strings are in unicode */
31#define NTLMSSP_NEGOTIATE_OEM 0x02 // Text strings are in OEM 31#define NTLMSSP_NEGOTIATE_OEM 0x02 /* Text strings are in OEM */
32#define NTLMSSP_REQUEST_TARGET 0x04 // Server return its auth realm 32#define NTLMSSP_REQUEST_TARGET 0x04 /* Server return its auth realm */
33#define NTLMSSP_NEGOTIATE_SIGN 0x0010 // Request signature capability 33#define NTLMSSP_NEGOTIATE_SIGN 0x0010 /* Request signature capability */
34#define NTLMSSP_NEGOTIATE_SEAL 0x0020 // Request confidentiality 34#define NTLMSSP_NEGOTIATE_SEAL 0x0020 /* Request confidentiality */
35#define NTLMSSP_NEGOTIATE_DGRAM 0x0040 35#define NTLMSSP_NEGOTIATE_DGRAM 0x0040
36#define NTLMSSP_NEGOTIATE_LM_KEY 0x0080 // Use LM session key for sign/seal 36#define NTLMSSP_NEGOTIATE_LM_KEY 0x0080 /* Sign/seal use LM session key */
37#define NTLMSSP_NEGOTIATE_NTLM 0x0200 // NTLM authentication 37#define NTLMSSP_NEGOTIATE_NTLM 0x0200 /* NTLM authentication */
38#define NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED 0x1000 38#define NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED 0x1000
39#define NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED 0x2000 39#define NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED 0x2000
40#define NTLMSSP_NEGOTIATE_LOCAL_CALL 0x4000 // client/server on same machine 40#define NTLMSSP_NEGOTIATE_LOCAL_CALL 0x4000 /* client/server on same machine */
41#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x8000 // Sign for all security levels 41#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x8000 /* Sign for all security levels */
42#define NTLMSSP_TARGET_TYPE_DOMAIN 0x10000 42#define NTLMSSP_TARGET_TYPE_DOMAIN 0x10000
43#define NTLMSSP_TARGET_TYPE_SERVER 0x20000 43#define NTLMSSP_TARGET_TYPE_SERVER 0x20000
44#define NTLMSSP_TARGET_TYPE_SHARE 0x40000 44#define NTLMSSP_TARGET_TYPE_SHARE 0x40000
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index c08bda9fcac6..916df9431336 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -2,7 +2,7 @@
2 * fs/cifs/readdir.c 2 * fs/cifs/readdir.c
3 * 3 *
4 * Directory search handling 4 * Directory search handling
5 * 5 *
6 * Copyright (C) International Business Machines Corp., 2004, 2007 6 * Copyright (C) International Business Machines Corp., 2004, 2007
7 * Author(s): Steve French (sfrench@us.ibm.com) 7 * Author(s): Steve French (sfrench@us.ibm.com)
8 * 8 *
@@ -34,24 +34,23 @@
34#ifdef CONFIG_CIFS_DEBUG2 34#ifdef CONFIG_CIFS_DEBUG2
35static void dump_cifs_file_struct(struct file *file, char *label) 35static void dump_cifs_file_struct(struct file *file, char *label)
36{ 36{
37 struct cifsFileInfo * cf; 37 struct cifsFileInfo *cf;
38 38
39 if (file) { 39 if (file) {
40 cf = file->private_data; 40 cf = file->private_data;
41 if (cf == NULL) { 41 if (cf == NULL) {
42 cFYI(1,("empty cifs private file data")); 42 cFYI(1, ("empty cifs private file data"));
43 return; 43 return;
44 } 44 }
45 if (cf->invalidHandle) { 45 if (cf->invalidHandle) {
46 cFYI(1,("invalid handle")); 46 cFYI(1, ("invalid handle"));
47 } 47 }
48 if (cf->srch_inf.endOfSearch) { 48 if (cf->srch_inf.endOfSearch) {
49 cFYI(1,("end of search")); 49 cFYI(1, ("end of search"));
50 } 50 }
51 if (cf->srch_inf.emptyDir) { 51 if (cf->srch_inf.emptyDir) {
52 cFYI(1,("empty dir")); 52 cFYI(1, ("empty dir"));
53 } 53 }
54
55 } 54 }
56} 55}
57#endif /* DEBUG2 */ 56#endif /* DEBUG2 */
@@ -73,7 +72,8 @@ static int construct_dentry(struct qstr *qstring, struct file *file,
73 qstring->hash = full_name_hash(qstring->name, qstring->len); 72 qstring->hash = full_name_hash(qstring->name, qstring->len);
74 tmp_dentry = d_lookup(file->f_path.dentry, qstring); 73 tmp_dentry = d_lookup(file->f_path.dentry, qstring);
75 if (tmp_dentry) { 74 if (tmp_dentry) {
76 cFYI(0, ("existing dentry with inode 0x%p", tmp_dentry->d_inode)); 75 cFYI(0, ("existing dentry with inode 0x%p",
76 tmp_dentry->d_inode));
77 *ptmp_inode = tmp_dentry->d_inode; 77 *ptmp_inode = tmp_dentry->d_inode;
78/* BB overwrite old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len??*/ 78/* BB overwrite old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len??*/
79 if (*ptmp_inode == NULL) { 79 if (*ptmp_inode == NULL) {
@@ -87,7 +87,7 @@ static int construct_dentry(struct qstr *qstring, struct file *file,
87 } else { 87 } else {
88 tmp_dentry = d_alloc(file->f_path.dentry, qstring); 88 tmp_dentry = d_alloc(file->f_path.dentry, qstring);
89 if (tmp_dentry == NULL) { 89 if (tmp_dentry == NULL) {
90 cERROR(1,("Failed allocating dentry")); 90 cERROR(1, ("Failed allocating dentry"));
91 *ptmp_inode = NULL; 91 *ptmp_inode = NULL;
92 return rc; 92 return rc;
93 } 93 }
@@ -100,7 +100,7 @@ static int construct_dentry(struct qstr *qstring, struct file *file,
100 if (*ptmp_inode == NULL) 100 if (*ptmp_inode == NULL)
101 return rc; 101 return rc;
102 if (file->f_path.dentry->d_sb->s_flags & MS_NOATIME) 102 if (file->f_path.dentry->d_sb->s_flags & MS_NOATIME)
103 (*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME; 103 (*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME;
104 rc = 2; 104 rc = 2;
105 } 105 }
106 106
@@ -109,7 +109,7 @@ static int construct_dentry(struct qstr *qstring, struct file *file,
109 return rc; 109 return rc;
110} 110}
111 111
112static void AdjustForTZ(struct cifsTconInfo * tcon, struct inode * inode) 112static void AdjustForTZ(struct cifsTconInfo *tcon, struct inode *inode)
113{ 113{
114 if ((tcon) && (tcon->ses) && (tcon->ses->server)) { 114 if ((tcon) && (tcon->ses) && (tcon->ses->server)) {
115 inode->i_ctime.tv_sec += tcon->ses->server->timeAdj; 115 inode->i_ctime.tv_sec += tcon->ses->server->timeAdj;
@@ -121,7 +121,7 @@ static void AdjustForTZ(struct cifsTconInfo * tcon, struct inode * inode)
121 121
122 122
123static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, 123static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
124 char * buf, int *pobject_type, int isNewInode) 124 char *buf, int *pobject_type, int isNewInode)
125{ 125{
126 loff_t local_size; 126 loff_t local_size;
127 struct timespec local_mtime; 127 struct timespec local_mtime;
@@ -150,7 +150,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
150 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); 150 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
151 } else { /* legacy, OS2 and DOS style */ 151 } else { /* legacy, OS2 and DOS style */
152/* struct timespec ts;*/ 152/* struct timespec ts;*/
153 FIND_FILE_STANDARD_INFO * pfindData = 153 FIND_FILE_STANDARD_INFO * pfindData =
154 (FIND_FILE_STANDARD_INFO *)buf; 154 (FIND_FILE_STANDARD_INFO *)buf;
155 155
156 tmp_inode->i_mtime = cnvrtDosUnixTm( 156 tmp_inode->i_mtime = cnvrtDosUnixTm(
@@ -175,7 +175,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
175 175
176 /* treat dos attribute of read-only as read-only mode bit e.g. 555? */ 176 /* treat dos attribute of read-only as read-only mode bit e.g. 555? */
177 /* 2767 perms - indicate mandatory locking */ 177 /* 2767 perms - indicate mandatory locking */
178 /* BB fill in uid and gid here? with help from winbind? 178 /* BB fill in uid and gid here? with help from winbind?
179 or retrieve from NTFS stream extended attribute */ 179 or retrieve from NTFS stream extended attribute */
180 if (atomic_read(&cifsInfo->inUse) == 0) { 180 if (atomic_read(&cifsInfo->inUse) == 0) {
181 tmp_inode->i_uid = cifs_sb->mnt_uid; 181 tmp_inode->i_uid = cifs_sb->mnt_uid;
@@ -196,7 +196,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
196 tmp_inode->i_mode = cifs_sb->mnt_dir_mode; 196 tmp_inode->i_mode = cifs_sb->mnt_dir_mode;
197 } 197 }
198 tmp_inode->i_mode |= S_IFDIR; 198 tmp_inode->i_mode |= S_IFDIR;
199 } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && 199 } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
200 (attr & ATTR_SYSTEM)) { 200 (attr & ATTR_SYSTEM)) {
201 if (end_of_file == 0) { 201 if (end_of_file == 0) {
202 *pobject_type = DT_FIFO; 202 *pobject_type = DT_FIFO;
@@ -206,13 +206,13 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
206 inode as needing revalidate and get the real type 206 inode as needing revalidate and get the real type
207 (blk vs chr vs. symlink) later ie in lookup */ 207 (blk vs chr vs. symlink) later ie in lookup */
208 *pobject_type = DT_REG; 208 *pobject_type = DT_REG;
209 tmp_inode->i_mode |= S_IFREG; 209 tmp_inode->i_mode |= S_IFREG;
210 cifsInfo->time = 0; 210 cifsInfo->time = 0;
211 } 211 }
212/* we no longer mark these because we could not follow them */ 212/* we no longer mark these because we could not follow them */
213/* } else if (attr & ATTR_REPARSE) { 213/* } else if (attr & ATTR_REPARSE) {
214 *pobject_type = DT_LNK; 214 *pobject_type = DT_LNK;
215 tmp_inode->i_mode |= S_IFLNK; */ 215 tmp_inode->i_mode |= S_IFLNK; */
216 } else { 216 } else {
217 *pobject_type = DT_REG; 217 *pobject_type = DT_REG;
218 tmp_inode->i_mode |= S_IFREG; 218 tmp_inode->i_mode |= S_IFREG;
@@ -220,7 +220,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
220 tmp_inode->i_mode &= ~(S_IWUGO); 220 tmp_inode->i_mode &= ~(S_IWUGO);
221 else if ((tmp_inode->i_mode & S_IWUGO) == 0) 221 else if ((tmp_inode->i_mode & S_IWUGO) == 0)
222 /* the ATTR_READONLY flag may have been changed on */ 222 /* the ATTR_READONLY flag may have been changed on */
223 /* server -- set any w bits allowed by mnt_file_mode */ 223 /* server -- set any w bits allowed by mnt_file_mode */
224 tmp_inode->i_mode |= (S_IWUGO & cifs_sb->mnt_file_mode); 224 tmp_inode->i_mode |= (S_IWUGO & cifs_sb->mnt_file_mode);
225 } /* could add code here - to validate if device or weird share type? */ 225 } /* could add code here - to validate if device or weird share type? */
226 226
@@ -231,7 +231,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
231 231
232 spin_lock(&tmp_inode->i_lock); 232 spin_lock(&tmp_inode->i_lock);
233 if (is_size_safe_to_change(cifsInfo, end_of_file)) { 233 if (is_size_safe_to_change(cifsInfo, end_of_file)) {
234 /* can not safely change the file size here if the 234 /* can not safely change the file size here if the
235 client is writing to it due to potential races */ 235 client is writing to it due to potential races */
236 i_size_write(tmp_inode, end_of_file); 236 i_size_write(tmp_inode, end_of_file);
237 237
@@ -254,7 +254,6 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
254 tmp_inode->i_fop = &cifs_file_direct_nobrl_ops; 254 tmp_inode->i_fop = &cifs_file_direct_nobrl_ops;
255 else 255 else
256 tmp_inode->i_fop = &cifs_file_direct_ops; 256 tmp_inode->i_fop = &cifs_file_direct_ops;
257
258 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 257 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
259 tmp_inode->i_fop = &cifs_file_nobrl_ops; 258 tmp_inode->i_fop = &cifs_file_nobrl_ops;
260 else 259 else
@@ -322,8 +321,8 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
322 321
323 tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions); 322 tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions);
324 /* since we set the inode type below we need to mask off type 323 /* since we set the inode type below we need to mask off type
325 to avoid strange results if bits above were corrupt */ 324 to avoid strange results if bits above were corrupt */
326 tmp_inode->i_mode &= ~S_IFMT; 325 tmp_inode->i_mode &= ~S_IFMT;
327 if (type == UNIX_FILE) { 326 if (type == UNIX_FILE) {
328 *pobject_type = DT_REG; 327 *pobject_type = DT_REG;
329 tmp_inode->i_mode |= S_IFREG; 328 tmp_inode->i_mode |= S_IFREG;
@@ -353,7 +352,7 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
353 /* safest to just call it a file */ 352 /* safest to just call it a file */
354 *pobject_type = DT_REG; 353 *pobject_type = DT_REG;
355 tmp_inode->i_mode |= S_IFREG; 354 tmp_inode->i_mode |= S_IFREG;
356 cFYI(1,("unknown inode type %d",type)); 355 cFYI(1, ("unknown inode type %d", type));
357 } 356 }
358 357
359 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) 358 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
@@ -368,7 +367,7 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
368 367
369 spin_lock(&tmp_inode->i_lock); 368 spin_lock(&tmp_inode->i_lock);
370 if (is_size_safe_to_change(cifsInfo, end_of_file)) { 369 if (is_size_safe_to_change(cifsInfo, end_of_file)) {
371 /* can not safely change the file size here if the 370 /* can not safely change the file size here if the
372 client is writing to it due to potential races */ 371 client is writing to it due to potential races */
373 i_size_write(tmp_inode, end_of_file); 372 i_size_write(tmp_inode, end_of_file);
374 373
@@ -393,15 +392,16 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
393 tmp_inode->i_fop = &cifs_file_ops; 392 tmp_inode->i_fop = &cifs_file_ops;
394 393
395 if ((cifs_sb->tcon) && (cifs_sb->tcon->ses) && 394 if ((cifs_sb->tcon) && (cifs_sb->tcon->ses) &&
396 (cifs_sb->tcon->ses->server->maxBuf < 395 (cifs_sb->tcon->ses->server->maxBuf <
397 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)) 396 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE))
398 tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf; 397 tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
399 else 398 else
400 tmp_inode->i_data.a_ops = &cifs_addr_ops; 399 tmp_inode->i_data.a_ops = &cifs_addr_ops;
401 400
402 if (isNewInode) 401 if (isNewInode)
403 return; /* No sense invalidating pages for new inode since we 402 return; /* No sense invalidating pages for new inode
404 have not started caching readahead file data yet */ 403 since we have not started caching readahead
404 file data for it yet */
405 405
406 if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) && 406 if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) &&
407 (local_size == tmp_inode->i_size)) { 407 (local_size == tmp_inode->i_size)) {
@@ -420,7 +420,7 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
420 tmp_inode->i_op = &cifs_symlink_inode_ops; 420 tmp_inode->i_op = &cifs_symlink_inode_ops;
421/* tmp_inode->i_fop = *//* do not need to set to anything */ 421/* tmp_inode->i_fop = *//* do not need to set to anything */
422 } else { 422 } else {
423 cFYI(1, ("Special inode")); 423 cFYI(1, ("Special inode"));
424 init_special_inode(tmp_inode, tmp_inode->i_mode, 424 init_special_inode(tmp_inode, tmp_inode->i_mode,
425 tmp_inode->i_rdev); 425 tmp_inode->i_rdev);
426 } 426 }
@@ -429,14 +429,14 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
429static int initiate_cifs_search(const int xid, struct file *file) 429static int initiate_cifs_search(const int xid, struct file *file)
430{ 430{
431 int rc = 0; 431 int rc = 0;
432 char * full_path; 432 char *full_path;
433 struct cifsFileInfo * cifsFile; 433 struct cifsFileInfo *cifsFile;
434 struct cifs_sb_info *cifs_sb; 434 struct cifs_sb_info *cifs_sb;
435 struct cifsTconInfo *pTcon; 435 struct cifsTconInfo *pTcon;
436 436
437 if (file->private_data == NULL) { 437 if (file->private_data == NULL) {
438 file->private_data = 438 file->private_data =
439 kzalloc(sizeof(struct cifsFileInfo),GFP_KERNEL); 439 kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
440 } 440 }
441 441
442 if (file->private_data == NULL) 442 if (file->private_data == NULL)
@@ -463,9 +463,11 @@ static int initiate_cifs_search(const int xid, struct file *file)
463 463
464ffirst_retry: 464ffirst_retry:
465 /* test for Unix extensions */ 465 /* test for Unix extensions */
466 if (pTcon->ses->capabilities & CAP_UNIX) { 466 /* but now check for them on the share/mount not on the SMB session */
467/* if (pTcon->ses->capabilities & CAP_UNIX) { */
468 if (pTcon->unix_ext) {
467 cifsFile->srch_inf.info_level = SMB_FIND_FILE_UNIX; 469 cifsFile->srch_inf.info_level = SMB_FIND_FILE_UNIX;
468 } else if ((pTcon->ses->capabilities & 470 } else if ((pTcon->ses->capabilities &
469 (CAP_NT_SMBS | CAP_NT_FIND)) == 0) { 471 (CAP_NT_SMBS | CAP_NT_FIND)) == 0) {
470 cifsFile->srch_inf.info_level = SMB_FIND_FILE_INFO_STANDARD; 472 cifsFile->srch_inf.info_level = SMB_FIND_FILE_INFO_STANDARD;
471 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { 473 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
@@ -474,13 +476,13 @@ ffirst_retry:
474 cifsFile->srch_inf.info_level = SMB_FIND_FILE_DIRECTORY_INFO; 476 cifsFile->srch_inf.info_level = SMB_FIND_FILE_DIRECTORY_INFO;
475 } 477 }
476 478
477 rc = CIFSFindFirst(xid, pTcon,full_path,cifs_sb->local_nls, 479 rc = CIFSFindFirst(xid, pTcon, full_path, cifs_sb->local_nls,
478 &cifsFile->netfid, &cifsFile->srch_inf, 480 &cifsFile->netfid, &cifsFile->srch_inf,
479 cifs_sb->mnt_cifs_flags & 481 cifs_sb->mnt_cifs_flags &
480 CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb)); 482 CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb));
481 if (rc == 0) 483 if (rc == 0)
482 cifsFile->invalidHandle = FALSE; 484 cifsFile->invalidHandle = FALSE;
483 if ((rc == -EOPNOTSUPP) && 485 if ((rc == -EOPNOTSUPP) &&
484 (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) { 486 (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) {
485 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM; 487 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM;
486 goto ffirst_retry; 488 goto ffirst_retry;
@@ -495,17 +497,17 @@ static int cifs_unicode_bytelen(char *str)
495 int len; 497 int len;
496 __le16 * ustr = (__le16 *)str; 498 __le16 * ustr = (__le16 *)str;
497 499
498 for(len=0;len <= PATH_MAX;len++) { 500 for (len = 0; len <= PATH_MAX; len++) {
499 if (ustr[len] == 0) 501 if (ustr[len] == 0)
500 return len << 1; 502 return len << 1;
501 } 503 }
502 cFYI(1,("Unicode string longer than PATH_MAX found")); 504 cFYI(1, ("Unicode string longer than PATH_MAX found"));
503 return len << 1; 505 return len << 1;
504} 506}
505 507
506static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level) 508static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level)
507{ 509{
508 char * new_entry; 510 char *new_entry;
509 FILE_DIRECTORY_INFO * pDirInfo = (FILE_DIRECTORY_INFO *)old_entry; 511 FILE_DIRECTORY_INFO * pDirInfo = (FILE_DIRECTORY_INFO *)old_entry;
510 512
511 if (level == SMB_FIND_FILE_INFO_STANDARD) { 513 if (level == SMB_FIND_FILE_INFO_STANDARD) {
@@ -516,21 +518,21 @@ static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level)
516 pfData->FileNameLength; 518 pfData->FileNameLength;
517 } else 519 } else
518 new_entry = old_entry + le32_to_cpu(pDirInfo->NextEntryOffset); 520 new_entry = old_entry + le32_to_cpu(pDirInfo->NextEntryOffset);
519 cFYI(1,("new entry %p old entry %p",new_entry,old_entry)); 521 cFYI(1, ("new entry %p old entry %p", new_entry, old_entry));
520 /* validate that new_entry is not past end of SMB */ 522 /* validate that new_entry is not past end of SMB */
521 if (new_entry >= end_of_smb) { 523 if (new_entry >= end_of_smb) {
522 cERROR(1, 524 cERROR(1,
523 ("search entry %p began after end of SMB %p old entry %p", 525 ("search entry %p began after end of SMB %p old entry %p",
524 new_entry, end_of_smb, old_entry)); 526 new_entry, end_of_smb, old_entry));
525 return NULL; 527 return NULL;
526 } else if (((level == SMB_FIND_FILE_INFO_STANDARD) && 528 } else if (((level == SMB_FIND_FILE_INFO_STANDARD) &&
527 (new_entry + sizeof(FIND_FILE_STANDARD_INFO) > end_of_smb)) || 529 (new_entry + sizeof(FIND_FILE_STANDARD_INFO) > end_of_smb))
528 ((level != SMB_FIND_FILE_INFO_STANDARD) && 530 || ((level != SMB_FIND_FILE_INFO_STANDARD) &&
529 (new_entry + sizeof(FILE_DIRECTORY_INFO) > end_of_smb))) { 531 (new_entry + sizeof(FILE_DIRECTORY_INFO) > end_of_smb))) {
530 cERROR(1,("search entry %p extends after end of SMB %p", 532 cERROR(1, ("search entry %p extends after end of SMB %p",
531 new_entry, end_of_smb)); 533 new_entry, end_of_smb));
532 return NULL; 534 return NULL;
533 } else 535 } else
534 return new_entry; 536 return new_entry;
535 537
536} 538}
@@ -541,8 +543,8 @@ static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level)
541static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile) 543static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile)
542{ 544{
543 int rc = 0; 545 int rc = 0;
544 char * filename = NULL; 546 char *filename = NULL;
545 int len = 0; 547 int len = 0;
546 548
547 if (cfile->srch_inf.info_level == SMB_FIND_FILE_UNIX) { 549 if (cfile->srch_inf.info_level == SMB_FIND_FILE_UNIX) {
548 FILE_UNIX_INFO * pFindData = (FILE_UNIX_INFO *)current_entry; 550 FILE_UNIX_INFO * pFindData = (FILE_UNIX_INFO *)current_entry;
@@ -554,25 +556,25 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile)
554 len = strnlen(filename, 5); 556 len = strnlen(filename, 5);
555 } 557 }
556 } else if (cfile->srch_inf.info_level == SMB_FIND_FILE_DIRECTORY_INFO) { 558 } else if (cfile->srch_inf.info_level == SMB_FIND_FILE_DIRECTORY_INFO) {
557 FILE_DIRECTORY_INFO * pFindData = 559 FILE_DIRECTORY_INFO * pFindData =
558 (FILE_DIRECTORY_INFO *)current_entry; 560 (FILE_DIRECTORY_INFO *)current_entry;
559 filename = &pFindData->FileName[0]; 561 filename = &pFindData->FileName[0];
560 len = le32_to_cpu(pFindData->FileNameLength); 562 len = le32_to_cpu(pFindData->FileNameLength);
561 } else if (cfile->srch_inf.info_level == 563 } else if (cfile->srch_inf.info_level ==
562 SMB_FIND_FILE_FULL_DIRECTORY_INFO) { 564 SMB_FIND_FILE_FULL_DIRECTORY_INFO) {
563 FILE_FULL_DIRECTORY_INFO * pFindData = 565 FILE_FULL_DIRECTORY_INFO * pFindData =
564 (FILE_FULL_DIRECTORY_INFO *)current_entry; 566 (FILE_FULL_DIRECTORY_INFO *)current_entry;
565 filename = &pFindData->FileName[0]; 567 filename = &pFindData->FileName[0];
566 len = le32_to_cpu(pFindData->FileNameLength); 568 len = le32_to_cpu(pFindData->FileNameLength);
567 } else if (cfile->srch_inf.info_level == 569 } else if (cfile->srch_inf.info_level ==
568 SMB_FIND_FILE_ID_FULL_DIR_INFO) { 570 SMB_FIND_FILE_ID_FULL_DIR_INFO) {
569 SEARCH_ID_FULL_DIR_INFO * pFindData = 571 SEARCH_ID_FULL_DIR_INFO * pFindData =
570 (SEARCH_ID_FULL_DIR_INFO *)current_entry; 572 (SEARCH_ID_FULL_DIR_INFO *)current_entry;
571 filename = &pFindData->FileName[0]; 573 filename = &pFindData->FileName[0];
572 len = le32_to_cpu(pFindData->FileNameLength); 574 len = le32_to_cpu(pFindData->FileNameLength);
573 } else if (cfile->srch_inf.info_level == 575 } else if (cfile->srch_inf.info_level ==
574 SMB_FIND_FILE_BOTH_DIRECTORY_INFO) { 576 SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
575 FILE_BOTH_DIRECTORY_INFO * pFindData = 577 FILE_BOTH_DIRECTORY_INFO * pFindData =
576 (FILE_BOTH_DIRECTORY_INFO *)current_entry; 578 (FILE_BOTH_DIRECTORY_INFO *)current_entry;
577 filename = &pFindData->FileName[0]; 579 filename = &pFindData->FileName[0];
578 len = le32_to_cpu(pFindData->FileNameLength); 580 len = le32_to_cpu(pFindData->FileNameLength);
@@ -582,7 +584,8 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile)
582 filename = &pFindData->FileName[0]; 584 filename = &pFindData->FileName[0];
583 len = pFindData->FileNameLength; 585 len = pFindData->FileNameLength;
584 } else { 586 } else {
585 cFYI(1,("Unknown findfirst level %d",cfile->srch_inf.info_level)); 587 cFYI(1, ("Unknown findfirst level %d",
588 cfile->srch_inf.info_level));
586 } 589 }
587 590
588 if (filename) { 591 if (filename) {
@@ -595,15 +598,15 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile)
595 } else if (len == 4) { 598 } else if (len == 4) {
596 /* check for .. */ 599 /* check for .. */
597 if ((ufilename[0] == UNICODE_DOT) 600 if ((ufilename[0] == UNICODE_DOT)
598 &&(ufilename[1] == UNICODE_DOT)) 601 && (ufilename[1] == UNICODE_DOT))
599 rc = 2; 602 rc = 2;
600 } 603 }
601 } else /* ASCII */ { 604 } else /* ASCII */ {
602 if (len == 1) { 605 if (len == 1) {
603 if (filename[0] == '.') 606 if (filename[0] == '.')
604 rc = 1; 607 rc = 1;
605 } else if (len == 2) { 608 } else if (len == 2) {
606 if((filename[0] == '.') && (filename[1] == '.')) 609 if ((filename[0] == '.') && (filename[1] == '.'))
607 rc = 2; 610 rc = 2;
608 } 611 }
609 } 612 }
@@ -614,7 +617,7 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile)
614 617
615/* Check if directory that we are searching has changed so we can decide 618/* Check if directory that we are searching has changed so we can decide
616 whether we can use the cached search results from the previous search */ 619 whether we can use the cached search results from the previous search */
617static int is_dir_changed(struct file * file) 620static int is_dir_changed(struct file *file)
618{ 621{
619 struct inode *inode = file->f_path.dentry->d_inode; 622 struct inode *inode = file->f_path.dentry->d_inode;
620 struct cifsInodeInfo *cifsInfo = CIFS_I(inode); 623 struct cifsInodeInfo *cifsInfo = CIFS_I(inode);
@@ -633,22 +636,22 @@ static int is_dir_changed(struct file * file)
633/* We start counting in the buffer with entry 2 and increment for every 636/* We start counting in the buffer with entry 2 and increment for every
634 entry (do not increment for . or .. entry) */ 637 entry (do not increment for . or .. entry) */
635static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, 638static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
636 struct file *file, char **ppCurrentEntry, int *num_to_ret) 639 struct file *file, char **ppCurrentEntry, int *num_to_ret)
637{ 640{
638 int rc = 0; 641 int rc = 0;
639 int pos_in_buf = 0; 642 int pos_in_buf = 0;
640 loff_t first_entry_in_buffer; 643 loff_t first_entry_in_buffer;
641 loff_t index_to_find = file->f_pos; 644 loff_t index_to_find = file->f_pos;
642 struct cifsFileInfo * cifsFile = file->private_data; 645 struct cifsFileInfo *cifsFile = file->private_data;
643 /* check if index in the buffer */ 646 /* check if index in the buffer */
644 647
645 if ((cifsFile == NULL) || (ppCurrentEntry == NULL) || 648 if ((cifsFile == NULL) || (ppCurrentEntry == NULL) ||
646 (num_to_ret == NULL)) 649 (num_to_ret == NULL))
647 return -ENOENT; 650 return -ENOENT;
648 651
649 *ppCurrentEntry = NULL; 652 *ppCurrentEntry = NULL;
650 first_entry_in_buffer = 653 first_entry_in_buffer =
651 cifsFile->srch_inf.index_of_last_entry - 654 cifsFile->srch_inf.index_of_last_entry -
652 cifsFile->srch_inf.entries_in_buffer; 655 cifsFile->srch_inf.entries_in_buffer;
653 656
654 /* if first entry in buf is zero then is first buffer 657 /* if first entry in buf is zero then is first buffer
@@ -660,17 +663,17 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
660#ifdef CONFIG_CIFS_DEBUG2 663#ifdef CONFIG_CIFS_DEBUG2
661 dump_cifs_file_struct(file, "In fce "); 664 dump_cifs_file_struct(file, "In fce ");
662#endif 665#endif
663 if (((index_to_find < cifsFile->srch_inf.index_of_last_entry) && 666 if (((index_to_find < cifsFile->srch_inf.index_of_last_entry) &&
664 is_dir_changed(file)) || 667 is_dir_changed(file)) ||
665 (index_to_find < first_entry_in_buffer)) { 668 (index_to_find < first_entry_in_buffer)) {
666 /* close and restart search */ 669 /* close and restart search */
667 cFYI(1,("search backing up - close and restart search")); 670 cFYI(1, ("search backing up - close and restart search"));
668 cifsFile->invalidHandle = TRUE; 671 cifsFile->invalidHandle = TRUE;
669 CIFSFindClose(xid, pTcon, cifsFile->netfid); 672 CIFSFindClose(xid, pTcon, cifsFile->netfid);
670 kfree(cifsFile->search_resume_name); 673 kfree(cifsFile->search_resume_name);
671 cifsFile->search_resume_name = NULL; 674 cifsFile->search_resume_name = NULL;
672 if (cifsFile->srch_inf.ntwrk_buf_start) { 675 if (cifsFile->srch_inf.ntwrk_buf_start) {
673 cFYI(1,("freeing SMB ff cache buf on search rewind")); 676 cFYI(1, ("freeing SMB ff cache buf on search rewind"));
674 if (cifsFile->srch_inf.smallBuf) 677 if (cifsFile->srch_inf.smallBuf)
675 cifs_small_buf_release(cifsFile->srch_inf. 678 cifs_small_buf_release(cifsFile->srch_inf.
676 ntwrk_buf_start); 679 ntwrk_buf_start);
@@ -678,17 +681,18 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
678 cifs_buf_release(cifsFile->srch_inf. 681 cifs_buf_release(cifsFile->srch_inf.
679 ntwrk_buf_start); 682 ntwrk_buf_start);
680 } 683 }
681 rc = initiate_cifs_search(xid,file); 684 rc = initiate_cifs_search(xid, file);
682 if (rc) { 685 if (rc) {
683 cFYI(1,("error %d reinitiating a search on rewind",rc)); 686 cFYI(1, ("error %d reinitiating a search on rewind",
687 rc));
684 return rc; 688 return rc;
685 } 689 }
686 } 690 }
687 691
688 while((index_to_find >= cifsFile->srch_inf.index_of_last_entry) && 692 while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) &&
689 (rc == 0) && (cifsFile->srch_inf.endOfSearch == FALSE)){ 693 (rc == 0) && (cifsFile->srch_inf.endOfSearch == FALSE)) {
690 cFYI(1,("calling findnext2")); 694 cFYI(1, ("calling findnext2"));
691 rc = CIFSFindNext(xid,pTcon,cifsFile->netfid, 695 rc = CIFSFindNext(xid, pTcon, cifsFile->netfid,
692 &cifsFile->srch_inf); 696 &cifsFile->srch_inf);
693 if (rc) 697 if (rc)
694 return -ENOENT; 698 return -ENOENT;
@@ -697,8 +701,8 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
697 /* we found the buffer that contains the entry */ 701 /* we found the buffer that contains the entry */
698 /* scan and find it */ 702 /* scan and find it */
699 int i; 703 int i;
700 char * current_entry; 704 char *current_entry;
701 char * end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + 705 char *end_of_smb = cifsFile->srch_inf.ntwrk_buf_start +
702 smbCalcSize((struct smb_hdr *) 706 smbCalcSize((struct smb_hdr *)
703 cifsFile->srch_inf.ntwrk_buf_start); 707 cifsFile->srch_inf.ntwrk_buf_start);
704 708
@@ -706,28 +710,28 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
706 first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry 710 first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry
707 - cifsFile->srch_inf.entries_in_buffer; 711 - cifsFile->srch_inf.entries_in_buffer;
708 pos_in_buf = index_to_find - first_entry_in_buffer; 712 pos_in_buf = index_to_find - first_entry_in_buffer;
709 cFYI(1,("found entry - pos_in_buf %d",pos_in_buf)); 713 cFYI(1, ("found entry - pos_in_buf %d", pos_in_buf));
710 714
711 for(i=0;(i<(pos_in_buf)) && (current_entry != NULL);i++) { 715 for (i=0; (i < (pos_in_buf)) && (current_entry != NULL); i++) {
712 /* go entry by entry figuring out which is first */ 716 /* go entry by entry figuring out which is first */
713 current_entry = nxt_dir_entry(current_entry,end_of_smb, 717 current_entry = nxt_dir_entry(current_entry, end_of_smb,
714 cifsFile->srch_inf.info_level); 718 cifsFile->srch_inf.info_level);
715 } 719 }
716 if((current_entry == NULL) && (i < pos_in_buf)) { 720 if ((current_entry == NULL) && (i < pos_in_buf)) {
717 /* BB fixme - check if we should flag this error */ 721 /* BB fixme - check if we should flag this error */
718 cERROR(1,("reached end of buf searching for pos in buf" 722 cERROR(1, ("reached end of buf searching for pos in buf"
719 " %d index to find %lld rc %d", 723 " %d index to find %lld rc %d",
720 pos_in_buf,index_to_find,rc)); 724 pos_in_buf, index_to_find, rc));
721 } 725 }
722 rc = 0; 726 rc = 0;
723 *ppCurrentEntry = current_entry; 727 *ppCurrentEntry = current_entry;
724 } else { 728 } else {
725 cFYI(1,("index not in buffer - could not findnext into it")); 729 cFYI(1, ("index not in buffer - could not findnext into it"));
726 return 0; 730 return 0;
727 } 731 }
728 732
729 if(pos_in_buf >= cifsFile->srch_inf.entries_in_buffer) { 733 if (pos_in_buf >= cifsFile->srch_inf.entries_in_buffer) {
730 cFYI(1,("can not return entries pos_in_buf beyond last entry")); 734 cFYI(1, ("can not return entries pos_in_buf beyond last"));
731 *num_to_ret = 0; 735 *num_to_ret = 0;
732 } else 736 } else
733 *num_to_ret = cifsFile->srch_inf.entries_in_buffer - pos_in_buf; 737 *num_to_ret = cifsFile->srch_inf.entries_in_buffer - pos_in_buf;
@@ -738,81 +742,81 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
738/* inode num, inode type and filename returned */ 742/* inode num, inode type and filename returned */
739static int cifs_get_name_from_search_buf(struct qstr *pqst, 743static int cifs_get_name_from_search_buf(struct qstr *pqst,
740 char *current_entry, __u16 level, unsigned int unicode, 744 char *current_entry, __u16 level, unsigned int unicode,
741 struct cifs_sb_info * cifs_sb, int max_len, ino_t *pinum) 745 struct cifs_sb_info *cifs_sb, int max_len, ino_t *pinum)
742{ 746{
743 int rc = 0; 747 int rc = 0;
744 unsigned int len = 0; 748 unsigned int len = 0;
745 char * filename; 749 char *filename;
746 struct nls_table * nlt = cifs_sb->local_nls; 750 struct nls_table *nlt = cifs_sb->local_nls;
747 751
748 *pinum = 0; 752 *pinum = 0;
749 753
750 if(level == SMB_FIND_FILE_UNIX) { 754 if (level == SMB_FIND_FILE_UNIX) {
751 FILE_UNIX_INFO * pFindData = (FILE_UNIX_INFO *)current_entry; 755 FILE_UNIX_INFO *pFindData = (FILE_UNIX_INFO *)current_entry;
752 756
753 filename = &pFindData->FileName[0]; 757 filename = &pFindData->FileName[0];
754 if(unicode) { 758 if (unicode) {
755 len = cifs_unicode_bytelen(filename); 759 len = cifs_unicode_bytelen(filename);
756 } else { 760 } else {
757 /* BB should we make this strnlen of PATH_MAX? */ 761 /* BB should we make this strnlen of PATH_MAX? */
758 len = strnlen(filename, PATH_MAX); 762 len = strnlen(filename, PATH_MAX);
759 } 763 }
760 764
761 /* BB fixme - hash low and high 32 bits if not 64 bit arch BB fixme */ 765 /* BB fixme - hash low and high 32 bits if not 64 bit arch BB */
762 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) 766 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
763 *pinum = pFindData->UniqueId; 767 *pinum = pFindData->UniqueId;
764 } else if(level == SMB_FIND_FILE_DIRECTORY_INFO) { 768 } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) {
765 FILE_DIRECTORY_INFO * pFindData = 769 FILE_DIRECTORY_INFO *pFindData =
766 (FILE_DIRECTORY_INFO *)current_entry; 770 (FILE_DIRECTORY_INFO *)current_entry;
767 filename = &pFindData->FileName[0]; 771 filename = &pFindData->FileName[0];
768 len = le32_to_cpu(pFindData->FileNameLength); 772 len = le32_to_cpu(pFindData->FileNameLength);
769 } else if(level == SMB_FIND_FILE_FULL_DIRECTORY_INFO) { 773 } else if (level == SMB_FIND_FILE_FULL_DIRECTORY_INFO) {
770 FILE_FULL_DIRECTORY_INFO * pFindData = 774 FILE_FULL_DIRECTORY_INFO *pFindData =
771 (FILE_FULL_DIRECTORY_INFO *)current_entry; 775 (FILE_FULL_DIRECTORY_INFO *)current_entry;
772 filename = &pFindData->FileName[0]; 776 filename = &pFindData->FileName[0];
773 len = le32_to_cpu(pFindData->FileNameLength); 777 len = le32_to_cpu(pFindData->FileNameLength);
774 } else if(level == SMB_FIND_FILE_ID_FULL_DIR_INFO) { 778 } else if (level == SMB_FIND_FILE_ID_FULL_DIR_INFO) {
775 SEARCH_ID_FULL_DIR_INFO * pFindData = 779 SEARCH_ID_FULL_DIR_INFO *pFindData =
776 (SEARCH_ID_FULL_DIR_INFO *)current_entry; 780 (SEARCH_ID_FULL_DIR_INFO *)current_entry;
777 filename = &pFindData->FileName[0]; 781 filename = &pFindData->FileName[0];
778 len = le32_to_cpu(pFindData->FileNameLength); 782 len = le32_to_cpu(pFindData->FileNameLength);
779 *pinum = pFindData->UniqueId; 783 *pinum = pFindData->UniqueId;
780 } else if(level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) { 784 } else if (level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
781 FILE_BOTH_DIRECTORY_INFO * pFindData = 785 FILE_BOTH_DIRECTORY_INFO *pFindData =
782 (FILE_BOTH_DIRECTORY_INFO *)current_entry; 786 (FILE_BOTH_DIRECTORY_INFO *)current_entry;
783 filename = &pFindData->FileName[0]; 787 filename = &pFindData->FileName[0];
784 len = le32_to_cpu(pFindData->FileNameLength); 788 len = le32_to_cpu(pFindData->FileNameLength);
785 } else if(level == SMB_FIND_FILE_INFO_STANDARD) { 789 } else if (level == SMB_FIND_FILE_INFO_STANDARD) {
786 FIND_FILE_STANDARD_INFO * pFindData = 790 FIND_FILE_STANDARD_INFO * pFindData =
787 (FIND_FILE_STANDARD_INFO *)current_entry; 791 (FIND_FILE_STANDARD_INFO *)current_entry;
788 filename = &pFindData->FileName[0]; 792 filename = &pFindData->FileName[0];
789 /* one byte length, no name conversion */ 793 /* one byte length, no name conversion */
790 len = (unsigned int)pFindData->FileNameLength; 794 len = (unsigned int)pFindData->FileNameLength;
791 } else { 795 } else {
792 cFYI(1,("Unknown findfirst level %d",level)); 796 cFYI(1, ("Unknown findfirst level %d", level));
793 return -EINVAL; 797 return -EINVAL;
794 } 798 }
795 799
796 if(len > max_len) { 800 if (len > max_len) {
797 cERROR(1,("bad search response length %d past smb end", len)); 801 cERROR(1, ("bad search response length %d past smb end", len));
798 return -EINVAL; 802 return -EINVAL;
799 } 803 }
800 804
801 if(unicode) { 805 if (unicode) {
802 /* BB fixme - test with long names */ 806 /* BB fixme - test with long names */
803 /* Note converted filename can be longer than in unicode */ 807 /* Note converted filename can be longer than in unicode */
804 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR) 808 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR)
805 pqst->len = cifs_convertUCSpath((char *)pqst->name, 809 pqst->len = cifs_convertUCSpath((char *)pqst->name,
806 (__le16 *)filename, len/2, nlt); 810 (__le16 *)filename, len/2, nlt);
807 else 811 else
808 pqst->len = cifs_strfromUCS_le((char *)pqst->name, 812 pqst->len = cifs_strfromUCS_le((char *)pqst->name,
809 (__le16 *)filename,len/2,nlt); 813 (__le16 *)filename, len/2, nlt);
810 } else { 814 } else {
811 pqst->name = filename; 815 pqst->name = filename;
812 pqst->len = len; 816 pqst->len = len;
813 } 817 }
814 pqst->hash = full_name_hash(pqst->name,pqst->len); 818 pqst->hash = full_name_hash(pqst->name, pqst->len);
815/* cFYI(1,("filldir on %s",pqst->name)); */ 819/* cFYI(1, ("filldir on %s",pqst->name)); */
816 return rc; 820 return rc;
817} 821}
818 822
@@ -821,49 +825,50 @@ static int cifs_filldir(char *pfindEntry, struct file *file,
821{ 825{
822 int rc = 0; 826 int rc = 0;
823 struct qstr qstring; 827 struct qstr qstring;
824 struct cifsFileInfo * pCifsF; 828 struct cifsFileInfo *pCifsF;
825 unsigned obj_type; 829 unsigned obj_type;
826 ino_t inum; 830 ino_t inum;
827 struct cifs_sb_info * cifs_sb; 831 struct cifs_sb_info *cifs_sb;
828 struct inode *tmp_inode; 832 struct inode *tmp_inode;
829 struct dentry *tmp_dentry; 833 struct dentry *tmp_dentry;
830 834
831 /* get filename and len into qstring */ 835 /* get filename and len into qstring */
832 /* get dentry */ 836 /* get dentry */
833 /* decide whether to create and populate ionde */ 837 /* decide whether to create and populate ionde */
834 if((direntry == NULL) || (file == NULL)) 838 if ((direntry == NULL) || (file == NULL))
835 return -EINVAL; 839 return -EINVAL;
836 840
837 pCifsF = file->private_data; 841 pCifsF = file->private_data;
838 842
839 if((scratch_buf == NULL) || (pfindEntry == NULL) || (pCifsF == NULL)) 843 if ((scratch_buf == NULL) || (pfindEntry == NULL) || (pCifsF == NULL))
840 return -ENOENT; 844 return -ENOENT;
841 845
842 rc = cifs_entry_is_dot(pfindEntry,pCifsF); 846 rc = cifs_entry_is_dot(pfindEntry, pCifsF);
843 /* skip . and .. since we added them first */ 847 /* skip . and .. since we added them first */
844 if(rc != 0) 848 if (rc != 0)
845 return 0; 849 return 0;
846 850
847 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 851 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
848 852
849 qstring.name = scratch_buf; 853 qstring.name = scratch_buf;
850 rc = cifs_get_name_from_search_buf(&qstring,pfindEntry, 854 rc = cifs_get_name_from_search_buf(&qstring, pfindEntry,
851 pCifsF->srch_inf.info_level, 855 pCifsF->srch_inf.info_level,
852 pCifsF->srch_inf.unicode,cifs_sb, 856 pCifsF->srch_inf.unicode, cifs_sb,
853 max_len, 857 max_len,
854 &inum /* returned */); 858 &inum /* returned */);
855 859
856 if(rc) 860 if (rc)
857 return rc; 861 return rc;
858 862
859 rc = construct_dentry(&qstring,file,&tmp_inode, &tmp_dentry); 863 rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry);
860 if((tmp_inode == NULL) || (tmp_dentry == NULL)) 864 if ((tmp_inode == NULL) || (tmp_dentry == NULL))
861 return -ENOMEM; 865 return -ENOMEM;
862 866
863 if(rc) { 867 if (rc) {
864 /* inode created, we need to hash it with right inode number */ 868 /* inode created, we need to hash it with right inode number */
865 if(inum != 0) { 869 if (inum != 0) {
866 /* BB fixme - hash the 2 32 quantities bits together if necessary BB */ 870 /* BB fixme - hash the 2 32 quantities bits together if
871 * necessary BB */
867 tmp_inode->i_ino = inum; 872 tmp_inode->i_ino = inum;
868 } 873 }
869 insert_inode_hash(tmp_inode); 874 insert_inode_hash(tmp_inode);
@@ -872,27 +877,27 @@ static int cifs_filldir(char *pfindEntry, struct file *file,
872 /* we pass in rc below, indicating whether it is a new inode, 877 /* we pass in rc below, indicating whether it is a new inode,
873 so we can figure out whether to invalidate the inode cached 878 so we can figure out whether to invalidate the inode cached
874 data if the file has changed */ 879 data if the file has changed */
875 if(pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX) 880 if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX)
876 unix_fill_in_inode(tmp_inode, 881 unix_fill_in_inode(tmp_inode,
877 (FILE_UNIX_INFO *)pfindEntry, 882 (FILE_UNIX_INFO *)pfindEntry,
878 &obj_type, rc); 883 &obj_type, rc);
879 else if(pCifsF->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD) 884 else if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD)
880 fill_in_inode(tmp_inode, 0 /* old level 1 buffer type */, 885 fill_in_inode(tmp_inode, 0 /* old level 1 buffer type */,
881 pfindEntry, &obj_type, rc); 886 pfindEntry, &obj_type, rc);
882 else 887 else
883 fill_in_inode(tmp_inode, 1 /* NT */, pfindEntry, &obj_type, rc); 888 fill_in_inode(tmp_inode, 1 /* NT */, pfindEntry, &obj_type, rc);
884 889
885 if(rc) /* new inode - needs to be tied to dentry */ { 890 if (rc) /* new inode - needs to be tied to dentry */ {
886 d_instantiate(tmp_dentry, tmp_inode); 891 d_instantiate(tmp_dentry, tmp_inode);
887 if(rc == 2) 892 if (rc == 2)
888 d_rehash(tmp_dentry); 893 d_rehash(tmp_dentry);
889 } 894 }
890 895
891 896
892 rc = filldir(direntry,qstring.name,qstring.len,file->f_pos, 897 rc = filldir(direntry, qstring.name, qstring.len, file->f_pos,
893 tmp_inode->i_ino,obj_type); 898 tmp_inode->i_ino, obj_type);
894 if(rc) { 899 if (rc) {
895 cFYI(1,("filldir rc = %d",rc)); 900 cFYI(1, ("filldir rc = %d", rc));
896 /* we can not return filldir errors to the caller 901 /* we can not return filldir errors to the caller
897 since they are "normal" when the stat blocksize 902 since they are "normal" when the stat blocksize
898 is too small - we return remapped error instead */ 903 is too small - we return remapped error instead */
@@ -909,57 +914,57 @@ static int cifs_save_resume_key(const char *current_entry,
909 int rc = 0; 914 int rc = 0;
910 unsigned int len = 0; 915 unsigned int len = 0;
911 __u16 level; 916 __u16 level;
912 char * filename; 917 char *filename;
913 918
914 if((cifsFile == NULL) || (current_entry == NULL)) 919 if ((cifsFile == NULL) || (current_entry == NULL))
915 return -EINVAL; 920 return -EINVAL;
916 921
917 level = cifsFile->srch_inf.info_level; 922 level = cifsFile->srch_inf.info_level;
918 923
919 if(level == SMB_FIND_FILE_UNIX) { 924 if (level == SMB_FIND_FILE_UNIX) {
920 FILE_UNIX_INFO * pFindData = (FILE_UNIX_INFO *)current_entry; 925 FILE_UNIX_INFO * pFindData = (FILE_UNIX_INFO *)current_entry;
921 926
922 filename = &pFindData->FileName[0]; 927 filename = &pFindData->FileName[0];
923 if(cifsFile->srch_inf.unicode) { 928 if (cifsFile->srch_inf.unicode) {
924 len = cifs_unicode_bytelen(filename); 929 len = cifs_unicode_bytelen(filename);
925 } else { 930 } else {
926 /* BB should we make this strnlen of PATH_MAX? */ 931 /* BB should we make this strnlen of PATH_MAX? */
927 len = strnlen(filename, PATH_MAX); 932 len = strnlen(filename, PATH_MAX);
928 } 933 }
929 cifsFile->srch_inf.resume_key = pFindData->ResumeKey; 934 cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
930 } else if(level == SMB_FIND_FILE_DIRECTORY_INFO) { 935 } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) {
931 FILE_DIRECTORY_INFO * pFindData = 936 FILE_DIRECTORY_INFO *pFindData =
932 (FILE_DIRECTORY_INFO *)current_entry; 937 (FILE_DIRECTORY_INFO *)current_entry;
933 filename = &pFindData->FileName[0]; 938 filename = &pFindData->FileName[0];
934 len = le32_to_cpu(pFindData->FileNameLength); 939 len = le32_to_cpu(pFindData->FileNameLength);
935 cifsFile->srch_inf.resume_key = pFindData->FileIndex; 940 cifsFile->srch_inf.resume_key = pFindData->FileIndex;
936 } else if(level == SMB_FIND_FILE_FULL_DIRECTORY_INFO) { 941 } else if (level == SMB_FIND_FILE_FULL_DIRECTORY_INFO) {
937 FILE_FULL_DIRECTORY_INFO * pFindData = 942 FILE_FULL_DIRECTORY_INFO *pFindData =
938 (FILE_FULL_DIRECTORY_INFO *)current_entry; 943 (FILE_FULL_DIRECTORY_INFO *)current_entry;
939 filename = &pFindData->FileName[0]; 944 filename = &pFindData->FileName[0];
940 len = le32_to_cpu(pFindData->FileNameLength); 945 len = le32_to_cpu(pFindData->FileNameLength);
941 cifsFile->srch_inf.resume_key = pFindData->FileIndex; 946 cifsFile->srch_inf.resume_key = pFindData->FileIndex;
942 } else if(level == SMB_FIND_FILE_ID_FULL_DIR_INFO) { 947 } else if (level == SMB_FIND_FILE_ID_FULL_DIR_INFO) {
943 SEARCH_ID_FULL_DIR_INFO * pFindData = 948 SEARCH_ID_FULL_DIR_INFO *pFindData =
944 (SEARCH_ID_FULL_DIR_INFO *)current_entry; 949 (SEARCH_ID_FULL_DIR_INFO *)current_entry;
945 filename = &pFindData->FileName[0]; 950 filename = &pFindData->FileName[0];
946 len = le32_to_cpu(pFindData->FileNameLength); 951 len = le32_to_cpu(pFindData->FileNameLength);
947 cifsFile->srch_inf.resume_key = pFindData->FileIndex; 952 cifsFile->srch_inf.resume_key = pFindData->FileIndex;
948 } else if(level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) { 953 } else if (level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
949 FILE_BOTH_DIRECTORY_INFO * pFindData = 954 FILE_BOTH_DIRECTORY_INFO *pFindData =
950 (FILE_BOTH_DIRECTORY_INFO *)current_entry; 955 (FILE_BOTH_DIRECTORY_INFO *)current_entry;
951 filename = &pFindData->FileName[0]; 956 filename = &pFindData->FileName[0];
952 len = le32_to_cpu(pFindData->FileNameLength); 957 len = le32_to_cpu(pFindData->FileNameLength);
953 cifsFile->srch_inf.resume_key = pFindData->FileIndex; 958 cifsFile->srch_inf.resume_key = pFindData->FileIndex;
954 } else if(level == SMB_FIND_FILE_INFO_STANDARD) { 959 } else if (level == SMB_FIND_FILE_INFO_STANDARD) {
955 FIND_FILE_STANDARD_INFO * pFindData = 960 FIND_FILE_STANDARD_INFO *pFindData =
956 (FIND_FILE_STANDARD_INFO *)current_entry; 961 (FIND_FILE_STANDARD_INFO *)current_entry;
957 filename = &pFindData->FileName[0]; 962 filename = &pFindData->FileName[0];
958 /* one byte length, no name conversion */ 963 /* one byte length, no name conversion */
959 len = (unsigned int)pFindData->FileNameLength; 964 len = (unsigned int)pFindData->FileNameLength;
960 cifsFile->srch_inf.resume_key = pFindData->ResumeKey; 965 cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
961 } else { 966 } else {
962 cFYI(1,("Unknown findfirst level %d",level)); 967 cFYI(1, ("Unknown findfirst level %d", level));
963 return -EINVAL; 968 return -EINVAL;
964 } 969 }
965 cifsFile->srch_inf.resume_name_len = len; 970 cifsFile->srch_inf.resume_name_len = len;
@@ -970,21 +975,21 @@ static int cifs_save_resume_key(const char *current_entry,
970int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) 975int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
971{ 976{
972 int rc = 0; 977 int rc = 0;
973 int xid,i; 978 int xid, i;
974 struct cifs_sb_info *cifs_sb; 979 struct cifs_sb_info *cifs_sb;
975 struct cifsTconInfo *pTcon; 980 struct cifsTconInfo *pTcon;
976 struct cifsFileInfo *cifsFile = NULL; 981 struct cifsFileInfo *cifsFile = NULL;
977 char * current_entry; 982 char *current_entry;
978 int num_to_fill = 0; 983 int num_to_fill = 0;
979 char * tmp_buf = NULL; 984 char *tmp_buf = NULL;
980 char * end_of_smb; 985 char *end_of_smb;
981 int max_len; 986 int max_len;
982 987
983 xid = GetXid(); 988 xid = GetXid();
984 989
985 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 990 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
986 pTcon = cifs_sb->tcon; 991 pTcon = cifs_sb->tcon;
987 if(pTcon == NULL) 992 if (pTcon == NULL)
988 return -EINVAL; 993 return -EINVAL;
989 994
990 switch ((int) file->f_pos) { 995 switch ((int) file->f_pos) {
@@ -1005,27 +1010,27 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
1005 } 1010 }
1006 file->f_pos++; 1011 file->f_pos++;
1007 default: 1012 default:
1008 /* 1) If search is active, 1013 /* 1) If search is active,
1009 is in current search buffer? 1014 is in current search buffer?
1010 if it before then restart search 1015 if it before then restart search
1011 if after then keep searching till find it */ 1016 if after then keep searching till find it */
1012 1017
1013 if(file->private_data == NULL) { 1018 if (file->private_data == NULL) {
1014 rc = initiate_cifs_search(xid,file); 1019 rc = initiate_cifs_search(xid, file);
1015 cFYI(1,("initiate cifs search rc %d",rc)); 1020 cFYI(1, ("initiate cifs search rc %d", rc));
1016 if(rc) { 1021 if (rc) {
1017 FreeXid(xid); 1022 FreeXid(xid);
1018 return rc; 1023 return rc;
1019 } 1024 }
1020 } 1025 }
1021 if(file->private_data == NULL) { 1026 if (file->private_data == NULL) {
1022 rc = -EINVAL; 1027 rc = -EINVAL;
1023 FreeXid(xid); 1028 FreeXid(xid);
1024 return rc; 1029 return rc;
1025 } 1030 }
1026 cifsFile = file->private_data; 1031 cifsFile = file->private_data;
1027 if (cifsFile->srch_inf.endOfSearch) { 1032 if (cifsFile->srch_inf.endOfSearch) {
1028 if(cifsFile->srch_inf.emptyDir) { 1033 if (cifsFile->srch_inf.emptyDir) {
1029 cFYI(1, ("End of search, empty dir")); 1034 cFYI(1, ("End of search, empty dir"));
1030 rc = 0; 1035 rc = 0;
1031 break; 1036 break;
@@ -1033,23 +1038,23 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
1033 } /* else { 1038 } /* else {
1034 cifsFile->invalidHandle = TRUE; 1039 cifsFile->invalidHandle = TRUE;
1035 CIFSFindClose(xid, pTcon, cifsFile->netfid); 1040 CIFSFindClose(xid, pTcon, cifsFile->netfid);
1036 } 1041 }
1037 kfree(cifsFile->search_resume_name); 1042 kfree(cifsFile->search_resume_name);
1038 cifsFile->search_resume_name = NULL; */ 1043 cifsFile->search_resume_name = NULL; */
1039 1044
1040 rc = find_cifs_entry(xid,pTcon, file, 1045 rc = find_cifs_entry(xid, pTcon, file,
1041 &current_entry,&num_to_fill); 1046 &current_entry, &num_to_fill);
1042 if(rc) { 1047 if (rc) {
1043 cFYI(1,("fce error %d",rc)); 1048 cFYI(1, ("fce error %d", rc));
1044 goto rddir2_exit; 1049 goto rddir2_exit;
1045 } else if (current_entry != NULL) { 1050 } else if (current_entry != NULL) {
1046 cFYI(1,("entry %lld found",file->f_pos)); 1051 cFYI(1, ("entry %lld found", file->f_pos));
1047 } else { 1052 } else {
1048 cFYI(1,("could not find entry")); 1053 cFYI(1, ("could not find entry"));
1049 goto rddir2_exit; 1054 goto rddir2_exit;
1050 } 1055 }
1051 cFYI(1,("loop through %d times filling dir for net buf %p", 1056 cFYI(1, ("loop through %d times filling dir for net buf %p",
1052 num_to_fill,cifsFile->srch_inf.ntwrk_buf_start)); 1057 num_to_fill, cifsFile->srch_inf.ntwrk_buf_start));
1053 max_len = smbCalcSize((struct smb_hdr *) 1058 max_len = smbCalcSize((struct smb_hdr *)
1054 cifsFile->srch_inf.ntwrk_buf_start); 1059 cifsFile->srch_inf.ntwrk_buf_start);
1055 end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + max_len; 1060 end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + max_len;
@@ -1059,8 +1064,8 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
1059 such multibyte target UTF-8 characters. cifs_unicode.c, 1064 such multibyte target UTF-8 characters. cifs_unicode.c,
1060 which actually does the conversion, has the same limit */ 1065 which actually does the conversion, has the same limit */
1061 tmp_buf = kmalloc((2 * NAME_MAX) + 4, GFP_KERNEL); 1066 tmp_buf = kmalloc((2 * NAME_MAX) + 4, GFP_KERNEL);
1062 for(i=0;(i<num_to_fill) && (rc == 0);i++) { 1067 for (i = 0; (i < num_to_fill) && (rc == 0); i++) {
1063 if(current_entry == NULL) { 1068 if (current_entry == NULL) {
1064 /* evaluate whether this case is an error */ 1069 /* evaluate whether this case is an error */
1065 cERROR(1,("past end of SMB num to fill %d i %d", 1070 cERROR(1,("past end of SMB num to fill %d i %d",
1066 num_to_fill, i)); 1071 num_to_fill, i));
@@ -1070,20 +1075,20 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
1070 we want to check for that here? */ 1075 we want to check for that here? */
1071 rc = cifs_filldir(current_entry, file, 1076 rc = cifs_filldir(current_entry, file,
1072 filldir, direntry, tmp_buf, max_len); 1077 filldir, direntry, tmp_buf, max_len);
1073 if(rc == -EOVERFLOW) { 1078 if (rc == -EOVERFLOW) {
1074 rc = 0; 1079 rc = 0;
1075 break; 1080 break;
1076 } 1081 }
1077 1082
1078 file->f_pos++; 1083 file->f_pos++;
1079 if(file->f_pos == 1084 if (file->f_pos ==
1080 cifsFile->srch_inf.index_of_last_entry) { 1085 cifsFile->srch_inf.index_of_last_entry) {
1081 cFYI(1,("last entry in buf at pos %lld %s", 1086 cFYI(1, ("last entry in buf at pos %lld %s",
1082 file->f_pos,tmp_buf)); 1087 file->f_pos, tmp_buf));
1083 cifs_save_resume_key(current_entry,cifsFile); 1088 cifs_save_resume_key(current_entry, cifsFile);
1084 break; 1089 break;
1085 } else 1090 } else
1086 current_entry = 1091 current_entry =
1087 nxt_dir_entry(current_entry, end_of_smb, 1092 nxt_dir_entry(current_entry, end_of_smb,
1088 cifsFile->srch_inf.info_level); 1093 cifsFile->srch_inf.info_level);
1089 } 1094 }
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index 758464630893..2ea027dda215 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * SMB/CIFS session setup handling routines 4 * SMB/CIFS session setup handling routines
5 * 5 *
6 * Copyright (c) International Business Machines Corp., 2006 6 * Copyright (c) International Business Machines Corp., 2006, 2007
7 * Author(s): Steve French (sfrench@us.ibm.com) 7 * Author(s): Steve French (sfrench@us.ibm.com)
8 * 8 *
9 * This library is free software; you can redistribute it and/or modify 9 * This library is free software; you can redistribute it and/or modify
@@ -31,7 +31,7 @@
31#include <linux/utsname.h> 31#include <linux/utsname.h>
32 32
33extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, 33extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
34 unsigned char *p24); 34 unsigned char *p24);
35 35
36static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB) 36static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
37{ 37{
@@ -45,13 +45,14 @@ static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
45 45
46 /* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */ 46 /* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */
47 47
48 /* BB verify whether signing required on neg or just on auth frame 48 /* BB verify whether signing required on neg or just on auth frame
49 (and NTLM case) */ 49 (and NTLM case) */
50 50
51 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS | 51 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
52 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X; 52 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
53 53
54 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 54 if (ses->server->secMode &
55 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
55 pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 56 pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
56 57
57 if (ses->capabilities & CAP_UNICODE) { 58 if (ses->capabilities & CAP_UNICODE) {
@@ -74,10 +75,10 @@ static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
74 return capabilities; 75 return capabilities;
75} 76}
76 77
77static void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses, 78static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
78 const struct nls_table * nls_cp) 79 const struct nls_table *nls_cp)
79{ 80{
80 char * bcc_ptr = *pbcc_area; 81 char *bcc_ptr = *pbcc_area;
81 int bytes_ret = 0; 82 int bytes_ret = 0;
82 83
83 /* BB FIXME add check that strings total less 84 /* BB FIXME add check that strings total less
@@ -89,7 +90,7 @@ static void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
89 bcc_ptr++; 90 bcc_ptr++;
90 } */ 91 } */
91 /* copy user */ 92 /* copy user */
92 if(ses->userName == NULL) { 93 if (ses->userName == NULL) {
93 /* null user mount */ 94 /* null user mount */
94 *bcc_ptr = 0; 95 *bcc_ptr = 0;
95 *(bcc_ptr+1) = 0; 96 *(bcc_ptr+1) = 0;
@@ -100,14 +101,14 @@ static void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
100 bcc_ptr += 2 * bytes_ret; 101 bcc_ptr += 2 * bytes_ret;
101 bcc_ptr += 2; /* account for null termination */ 102 bcc_ptr += 2; /* account for null termination */
102 /* copy domain */ 103 /* copy domain */
103 if(ses->domainName == NULL) { 104 if (ses->domainName == NULL) {
104 /* Sending null domain better than using a bogus domain name (as 105 /* Sending null domain better than using a bogus domain name (as
105 we did briefly in 2.6.18) since server will use its default */ 106 we did briefly in 2.6.18) since server will use its default */
106 *bcc_ptr = 0; 107 *bcc_ptr = 0;
107 *(bcc_ptr+1) = 0; 108 *(bcc_ptr+1) = 0;
108 bytes_ret = 0; 109 bytes_ret = 0;
109 } else 110 } else
110 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName, 111 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName,
111 256, nls_cp); 112 256, nls_cp);
112 bcc_ptr += 2 * bytes_ret; 113 bcc_ptr += 2 * bytes_ret;
113 bcc_ptr += 2; /* account for null terminator */ 114 bcc_ptr += 2; /* account for null terminator */
@@ -122,37 +123,37 @@ static void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
122 bcc_ptr += 2; /* trailing null */ 123 bcc_ptr += 2; /* trailing null */
123 124
124 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS, 125 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
125 32, nls_cp); 126 32, nls_cp);
126 bcc_ptr += 2 * bytes_ret; 127 bcc_ptr += 2 * bytes_ret;
127 bcc_ptr += 2; /* trailing null */ 128 bcc_ptr += 2; /* trailing null */
128 129
129 *pbcc_area = bcc_ptr; 130 *pbcc_area = bcc_ptr;
130} 131}
131 132
132static void ascii_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses, 133static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
133 const struct nls_table * nls_cp) 134 const struct nls_table *nls_cp)
134{ 135{
135 char * bcc_ptr = *pbcc_area; 136 char *bcc_ptr = *pbcc_area;
136 137
137 /* copy user */ 138 /* copy user */
138 /* BB what about null user mounts - check that we do this BB */ 139 /* BB what about null user mounts - check that we do this BB */
139 /* copy user */ 140 /* copy user */
140 if(ses->userName == NULL) { 141 if (ses->userName == NULL) {
141 /* BB what about null user mounts - check that we do this BB */ 142 /* BB what about null user mounts - check that we do this BB */
142 } else { /* 300 should be long enough for any conceivable user name */ 143 } else { /* 300 should be long enough for any conceivable user name */
143 strncpy(bcc_ptr, ses->userName, 300); 144 strncpy(bcc_ptr, ses->userName, 300);
144 } 145 }
145 /* BB improve check for overflow */ 146 /* BB improve check for overflow */
146 bcc_ptr += strnlen(ses->userName, 300); 147 bcc_ptr += strnlen(ses->userName, 300);
147 *bcc_ptr = 0; 148 *bcc_ptr = 0;
148 bcc_ptr++; /* account for null termination */ 149 bcc_ptr++; /* account for null termination */
149 150
150 /* copy domain */ 151 /* copy domain */
151 152
152 if(ses->domainName != NULL) { 153 if (ses->domainName != NULL) {
153 strncpy(bcc_ptr, ses->domainName, 256); 154 strncpy(bcc_ptr, ses->domainName, 256);
154 bcc_ptr += strnlen(ses->domainName, 256); 155 bcc_ptr += strnlen(ses->domainName, 256);
155 } /* else we will send a null domain name 156 } /* else we will send a null domain name
156 so the server will default to its own domain */ 157 so the server will default to its own domain */
157 *bcc_ptr = 0; 158 *bcc_ptr = 0;
158 bcc_ptr++; 159 bcc_ptr++;
@@ -167,19 +168,20 @@ static void ascii_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
167 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS); 168 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
168 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1; 169 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
169 170
170 *pbcc_area = bcc_ptr; 171 *pbcc_area = bcc_ptr;
171} 172}
172 173
173static int decode_unicode_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo *ses, 174static int decode_unicode_ssetup(char **pbcc_area, int bleft,
174 const struct nls_table * nls_cp) 175 struct cifsSesInfo *ses,
176 const struct nls_table *nls_cp)
175{ 177{
176 int rc = 0; 178 int rc = 0;
177 int words_left, len; 179 int words_left, len;
178 char * data = *pbcc_area; 180 char *data = *pbcc_area;
179 181
180 182
181 183
182 cFYI(1,("bleft %d",bleft)); 184 cFYI(1, ("bleft %d", bleft));
183 185
184 186
185 /* SMB header is unaligned, so cifs servers word align start of 187 /* SMB header is unaligned, so cifs servers word align start of
@@ -189,7 +191,7 @@ static int decode_unicode_ssetup(char ** pbcc_area, int bleft, struct cifsSesInf
189 their final Unicode string - in which case we 191 their final Unicode string - in which case we
190 now will not attempt to decode the byte of junk 192 now will not attempt to decode the byte of junk
191 which follows it */ 193 which follows it */
192 194
193 words_left = bleft / 2; 195 words_left = bleft / 2;
194 196
195 /* save off server operating system */ 197 /* save off server operating system */
@@ -198,14 +200,14 @@ static int decode_unicode_ssetup(char ** pbcc_area, int bleft, struct cifsSesInf
198/* We look for obvious messed up bcc or strings in response so we do not go off 200/* We look for obvious messed up bcc or strings in response so we do not go off
199 the end since (at least) WIN2K and Windows XP have a major bug in not null 201 the end since (at least) WIN2K and Windows XP have a major bug in not null
200 terminating last Unicode string in response */ 202 terminating last Unicode string in response */
201 if(len >= words_left) 203 if (len >= words_left)
202 return rc; 204 return rc;
203 205
204 if(ses->serverOS) 206 if (ses->serverOS)
205 kfree(ses->serverOS); 207 kfree(ses->serverOS);
206 /* UTF-8 string will not grow more than four times as big as UCS-16 */ 208 /* UTF-8 string will not grow more than four times as big as UCS-16 */
207 ses->serverOS = kzalloc(4 * len, GFP_KERNEL); 209 ses->serverOS = kzalloc(4 * len, GFP_KERNEL);
208 if(ses->serverOS != NULL) { 210 if (ses->serverOS != NULL) {
209 cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, 211 cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len,
210 nls_cp); 212 nls_cp);
211 } 213 }
@@ -215,67 +217,68 @@ static int decode_unicode_ssetup(char ** pbcc_area, int bleft, struct cifsSesInf
215 /* save off server network operating system */ 217 /* save off server network operating system */
216 len = UniStrnlen((wchar_t *) data, words_left); 218 len = UniStrnlen((wchar_t *) data, words_left);
217 219
218 if(len >= words_left) 220 if (len >= words_left)
219 return rc; 221 return rc;
220 222
221 if(ses->serverNOS) 223 if (ses->serverNOS)
222 kfree(ses->serverNOS); 224 kfree(ses->serverNOS);
223 ses->serverNOS = kzalloc(4 * len, GFP_KERNEL); /* BB this is wrong length FIXME BB */ 225 ses->serverNOS = kzalloc(4 * len, GFP_KERNEL); /* BB this is wrong length FIXME BB */
224 if(ses->serverNOS != NULL) { 226 if (ses->serverNOS != NULL) {
225 cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len, 227 cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len,
226 nls_cp); 228 nls_cp);
227 if(strncmp(ses->serverNOS, "NT LAN Manager 4",16) == 0) { 229 if (strncmp(ses->serverNOS, "NT LAN Manager 4", 16) == 0) {
228 cFYI(1,("NT4 server")); 230 cFYI(1, ("NT4 server"));
229 ses->flags |= CIFS_SES_NT4; 231 ses->flags |= CIFS_SES_NT4;
230 } 232 }
231 } 233 }
232 data += 2 * (len + 1); 234 data += 2 * (len + 1);
233 words_left -= len + 1; 235 words_left -= len + 1;
234 236
235 /* save off server domain */ 237 /* save off server domain */
236 len = UniStrnlen((wchar_t *) data, words_left); 238 len = UniStrnlen((wchar_t *) data, words_left);
237 239
238 if(len > words_left) 240 if (len > words_left)
239 return rc; 241 return rc;
240 242
241 if(ses->serverDomain) 243 if (ses->serverDomain)
242 kfree(ses->serverDomain); 244 kfree(ses->serverDomain);
243 ses->serverDomain = kzalloc(2 * (len + 1), GFP_KERNEL); /* BB FIXME wrong length */ 245 ses->serverDomain = kzalloc(2 * (len + 1), GFP_KERNEL); /* BB FIXME wrong length */
244 if(ses->serverDomain != NULL) { 246 if (ses->serverDomain != NULL) {
245 cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len, 247 cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len,
246 nls_cp); 248 nls_cp);
247 ses->serverDomain[2*len] = 0; 249 ses->serverDomain[2*len] = 0;
248 ses->serverDomain[(2*len) + 1] = 0; 250 ses->serverDomain[(2*len) + 1] = 0;
249 } 251 }
250 data += 2 * (len + 1); 252 data += 2 * (len + 1);
251 words_left -= len + 1; 253 words_left -= len + 1;
252 254
253 cFYI(1,("words left: %d",words_left)); 255 cFYI(1, ("words left: %d", words_left));
254 256
255 return rc; 257 return rc;
256} 258}
257 259
258static int decode_ascii_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo *ses, 260static int decode_ascii_ssetup(char **pbcc_area, int bleft,
259 const struct nls_table * nls_cp) 261 struct cifsSesInfo *ses,
262 const struct nls_table *nls_cp)
260{ 263{
261 int rc = 0; 264 int rc = 0;
262 int len; 265 int len;
263 char * bcc_ptr = *pbcc_area; 266 char *bcc_ptr = *pbcc_area;
267
268 cFYI(1, ("decode sessetup ascii. bleft %d", bleft));
264 269
265 cFYI(1,("decode sessetup ascii. bleft %d", bleft));
266
267 len = strnlen(bcc_ptr, bleft); 270 len = strnlen(bcc_ptr, bleft);
268 if(len >= bleft) 271 if (len >= bleft)
269 return rc; 272 return rc;
270 273
271 if(ses->serverOS) 274 if (ses->serverOS)
272 kfree(ses->serverOS); 275 kfree(ses->serverOS);
273 276
274 ses->serverOS = kzalloc(len + 1, GFP_KERNEL); 277 ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
275 if(ses->serverOS) 278 if (ses->serverOS)
276 strncpy(ses->serverOS, bcc_ptr, len); 279 strncpy(ses->serverOS, bcc_ptr, len);
277 if(strncmp(ses->serverOS, "OS/2",4) == 0) { 280 if (strncmp(ses->serverOS, "OS/2", 4) == 0) {
278 cFYI(1,("OS/2 server")); 281 cFYI(1, ("OS/2 server"));
279 ses->flags |= CIFS_SES_OS2; 282 ses->flags |= CIFS_SES_OS2;
280 } 283 }
281 284
@@ -283,34 +286,34 @@ static int decode_ascii_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo
283 bleft -= len + 1; 286 bleft -= len + 1;
284 287
285 len = strnlen(bcc_ptr, bleft); 288 len = strnlen(bcc_ptr, bleft);
286 if(len >= bleft) 289 if (len >= bleft)
287 return rc; 290 return rc;
288 291
289 if(ses->serverNOS) 292 if (ses->serverNOS)
290 kfree(ses->serverNOS); 293 kfree(ses->serverNOS);
291 294
292 ses->serverNOS = kzalloc(len + 1, GFP_KERNEL); 295 ses->serverNOS = kzalloc(len + 1, GFP_KERNEL);
293 if(ses->serverNOS) 296 if (ses->serverNOS)
294 strncpy(ses->serverNOS, bcc_ptr, len); 297 strncpy(ses->serverNOS, bcc_ptr, len);
295 298
296 bcc_ptr += len + 1; 299 bcc_ptr += len + 1;
297 bleft -= len + 1; 300 bleft -= len + 1;
298 301
299 len = strnlen(bcc_ptr, bleft); 302 len = strnlen(bcc_ptr, bleft);
300 if(len > bleft) 303 if (len > bleft)
301 return rc; 304 return rc;
302 305
303 /* No domain field in LANMAN case. Domain is 306 /* No domain field in LANMAN case. Domain is
304 returned by old servers in the SMB negprot response */ 307 returned by old servers in the SMB negprot response */
305 /* BB For newer servers which do not support Unicode, 308 /* BB For newer servers which do not support Unicode,
306 but thus do return domain here we could add parsing 309 but thus do return domain here we could add parsing
307 for it later, but it is not very important */ 310 for it later, but it is not very important */
308 cFYI(1,("ascii: bytes left %d",bleft)); 311 cFYI(1, ("ascii: bytes left %d", bleft));
309 312
310 return rc; 313 return rc;
311} 314}
312 315
313int 316int
314CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, 317CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
315 const struct nls_table *nls_cp) 318 const struct nls_table *nls_cp)
316{ 319{
@@ -328,13 +331,13 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
328 __u16 action; 331 __u16 action;
329 int bytes_remaining; 332 int bytes_remaining;
330 333
331 if(ses == NULL) 334 if (ses == NULL)
332 return -EINVAL; 335 return -EINVAL;
333 336
334 type = ses->server->secType; 337 type = ses->server->secType;
335 338
336 cFYI(1,("sess setup type %d",type)); 339 cFYI(1, ("sess setup type %d", type));
337 if(type == LANMAN) { 340 if (type == LANMAN) {
338#ifndef CONFIG_CIFS_WEAK_PW_HASH 341#ifndef CONFIG_CIFS_WEAK_PW_HASH
339 /* LANMAN and plaintext are less secure and off by default. 342 /* LANMAN and plaintext are less secure and off by default.
340 So we make this explicitly be turned on in kconfig (in the 343 So we make this explicitly be turned on in kconfig (in the
@@ -344,15 +347,15 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
344 return -EOPNOTSUPP; 347 return -EOPNOTSUPP;
345#endif 348#endif
346 wct = 10; /* lanman 2 style sessionsetup */ 349 wct = 10; /* lanman 2 style sessionsetup */
347 } else if((type == NTLM) || (type == NTLMv2)) { 350 } else if ((type == NTLM) || (type == NTLMv2)) {
348 /* For NTLMv2 failures eventually may need to retry NTLM */ 351 /* For NTLMv2 failures eventually may need to retry NTLM */
349 wct = 13; /* old style NTLM sessionsetup */ 352 wct = 13; /* old style NTLM sessionsetup */
350 } else /* same size for negotiate or auth, NTLMSSP or extended security */ 353 } else /* same size: negotiate or auth, NTLMSSP or extended security */
351 wct = 12; 354 wct = 12;
352 355
353 rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses, 356 rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
354 (void **)&smb_buf); 357 (void **)&smb_buf);
355 if(rc) 358 if (rc)
356 return rc; 359 return rc;
357 360
358 pSMB = (SESSION_SETUP_ANDX *)smb_buf; 361 pSMB = (SESSION_SETUP_ANDX *)smb_buf;
@@ -364,8 +367,8 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
364 second part which will include the strings 367 second part which will include the strings
365 and rest of bcc area, in order to avoid having 368 and rest of bcc area, in order to avoid having
366 to do a large buffer 17K allocation */ 369 to do a large buffer 17K allocation */
367 iov[0].iov_base = (char *)pSMB; 370 iov[0].iov_base = (char *)pSMB;
368 iov[0].iov_len = smb_buf->smb_buf_length + 4; 371 iov[0].iov_len = smb_buf->smb_buf_length + 4;
369 372
370 /* 2000 big enough to fit max user, domain, NOS name etc. */ 373 /* 2000 big enough to fit max user, domain, NOS name etc. */
371 str_area = kmalloc(2000, GFP_KERNEL); 374 str_area = kmalloc(2000, GFP_KERNEL);
@@ -373,18 +376,18 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
373 376
374 ses->flags &= ~CIFS_SES_LANMAN; 377 ses->flags &= ~CIFS_SES_LANMAN;
375 378
376 if(type == LANMAN) { 379 if (type == LANMAN) {
377#ifdef CONFIG_CIFS_WEAK_PW_HASH 380#ifdef CONFIG_CIFS_WEAK_PW_HASH
378 char lnm_session_key[CIFS_SESS_KEY_SIZE]; 381 char lnm_session_key[CIFS_SESS_KEY_SIZE];
379 382
380 /* no capabilities flags in old lanman negotiation */ 383 /* no capabilities flags in old lanman negotiation */
381 384
382 pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE); 385 pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
383 /* BB calculate hash with password */ 386 /* BB calculate hash with password */
384 /* and copy into bcc */ 387 /* and copy into bcc */
385 388
386 calc_lanman_hash(ses, lnm_session_key); 389 calc_lanman_hash(ses, lnm_session_key);
387 ses->flags |= CIFS_SES_LANMAN; 390 ses->flags |= CIFS_SES_LANMAN;
388/* #ifdef CONFIG_CIFS_DEBUG2 391/* #ifdef CONFIG_CIFS_DEBUG2
389 cifs_dump_mem("cryptkey: ",ses->server->cryptKey, 392 cifs_dump_mem("cryptkey: ",ses->server->cryptKey,
390 CIFS_SESS_KEY_SIZE); 393 CIFS_SESS_KEY_SIZE);
@@ -397,10 +400,10 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
397 changed to do higher than lanman dialect and 400 changed to do higher than lanman dialect and
398 we reconnected would we ever calc signing_key? */ 401 we reconnected would we ever calc signing_key? */
399 402
400 cFYI(1,("Negotiating LANMAN setting up strings")); 403 cFYI(1, ("Negotiating LANMAN setting up strings"));
401 /* Unicode not allowed for LANMAN dialects */ 404 /* Unicode not allowed for LANMAN dialects */
402 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp); 405 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
403#endif 406#endif
404 } else if (type == NTLM) { 407 } else if (type == NTLM) {
405 char ntlm_session_key[CIFS_SESS_KEY_SIZE]; 408 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
406 409
@@ -409,38 +412,38 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
409 cpu_to_le16(CIFS_SESS_KEY_SIZE); 412 cpu_to_le16(CIFS_SESS_KEY_SIZE);
410 pSMB->req_no_secext.CaseSensitivePasswordLength = 413 pSMB->req_no_secext.CaseSensitivePasswordLength =
411 cpu_to_le16(CIFS_SESS_KEY_SIZE); 414 cpu_to_le16(CIFS_SESS_KEY_SIZE);
412 415
413 /* calculate session key */ 416 /* calculate session key */
414 SMBNTencrypt(ses->password, ses->server->cryptKey, 417 SMBNTencrypt(ses->password, ses->server->cryptKey,
415 ntlm_session_key); 418 ntlm_session_key);
416 419
417 if(first_time) /* should this be moved into common code 420 if (first_time) /* should this be moved into common code
418 with similar ntlmv2 path? */ 421 with similar ntlmv2 path? */
419 cifs_calculate_mac_key(ses->server->mac_signing_key, 422 cifs_calculate_mac_key(&ses->server->mac_signing_key,
420 ntlm_session_key, ses->password); 423 ntlm_session_key, ses->password);
421 /* copy session key */ 424 /* copy session key */
422 425
423 memcpy(bcc_ptr, (char *)ntlm_session_key,CIFS_SESS_KEY_SIZE); 426 memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE);
424 bcc_ptr += CIFS_SESS_KEY_SIZE; 427 bcc_ptr += CIFS_SESS_KEY_SIZE;
425 memcpy(bcc_ptr, (char *)ntlm_session_key,CIFS_SESS_KEY_SIZE); 428 memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE);
426 bcc_ptr += CIFS_SESS_KEY_SIZE; 429 bcc_ptr += CIFS_SESS_KEY_SIZE;
427 if(ses->capabilities & CAP_UNICODE) { 430 if (ses->capabilities & CAP_UNICODE) {
428 /* unicode strings must be word aligned */ 431 /* unicode strings must be word aligned */
429 if (iov[0].iov_len % 2) { 432 if (iov[0].iov_len % 2) {
430 *bcc_ptr = 0; 433 *bcc_ptr = 0;
431 bcc_ptr++; 434 bcc_ptr++;
432 } 435 }
433 unicode_ssetup_strings(&bcc_ptr, ses, nls_cp); 436 unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
434 } else 437 } else
435 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp); 438 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
436 } else if (type == NTLMv2) { 439 } else if (type == NTLMv2) {
437 char * v2_sess_key = 440 char *v2_sess_key =
438 kmalloc(sizeof(struct ntlmv2_resp), GFP_KERNEL); 441 kmalloc(sizeof(struct ntlmv2_resp), GFP_KERNEL);
439 442
440 /* BB FIXME change all users of v2_sess_key to 443 /* BB FIXME change all users of v2_sess_key to
441 struct ntlmv2_resp */ 444 struct ntlmv2_resp */
442 445
443 if(v2_sess_key == NULL) { 446 if (v2_sess_key == NULL) {
444 cifs_small_buf_release(smb_buf); 447 cifs_small_buf_release(smb_buf);
445 return -ENOMEM; 448 return -ENOMEM;
446 } 449 }
@@ -456,8 +459,8 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
456 459
457 /* calculate session key */ 460 /* calculate session key */
458 setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp); 461 setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp);
459 if(first_time) /* should this be moved into common code 462 if (first_time) /* should this be moved into common code
460 with similar ntlmv2 path? */ 463 with similar ntlmv2 path? */
461 /* cifs_calculate_ntlmv2_mac_key(ses->server->mac_signing_key, 464 /* cifs_calculate_ntlmv2_mac_key(ses->server->mac_signing_key,
462 response BB FIXME, v2_sess_key); */ 465 response BB FIXME, v2_sess_key); */
463 466
@@ -465,11 +468,12 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
465 468
466 /* memcpy(bcc_ptr, (char *)ntlm_session_key,LM2_SESS_KEY_SIZE); 469 /* memcpy(bcc_ptr, (char *)ntlm_session_key,LM2_SESS_KEY_SIZE);
467 bcc_ptr += LM2_SESS_KEY_SIZE; */ 470 bcc_ptr += LM2_SESS_KEY_SIZE; */
468 memcpy(bcc_ptr, (char *)v2_sess_key, sizeof(struct ntlmv2_resp)); 471 memcpy(bcc_ptr, (char *)v2_sess_key,
472 sizeof(struct ntlmv2_resp));
469 bcc_ptr += sizeof(struct ntlmv2_resp); 473 bcc_ptr += sizeof(struct ntlmv2_resp);
470 kfree(v2_sess_key); 474 kfree(v2_sess_key);
471 if(ses->capabilities & CAP_UNICODE) { 475 if (ses->capabilities & CAP_UNICODE) {
472 if(iov[0].iov_len % 2) { 476 if (iov[0].iov_len % 2) {
473 *bcc_ptr = 0; 477 *bcc_ptr = 0;
474 } bcc_ptr++; 478 } bcc_ptr++;
475 unicode_ssetup_strings(&bcc_ptr, ses, nls_cp); 479 unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
@@ -488,20 +492,20 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
488 BCC_LE(smb_buf) = cpu_to_le16(count); 492 BCC_LE(smb_buf) = cpu_to_le16(count);
489 493
490 iov[1].iov_base = str_area; 494 iov[1].iov_base = str_area;
491 iov[1].iov_len = count; 495 iov[1].iov_len = count;
492 rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type, 0); 496 rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type, 0);
493 /* SMB request buf freed in SendReceive2 */ 497 /* SMB request buf freed in SendReceive2 */
494 498
495 cFYI(1,("ssetup rc from sendrecv2 is %d",rc)); 499 cFYI(1, ("ssetup rc from sendrecv2 is %d", rc));
496 if(rc) 500 if (rc)
497 goto ssetup_exit; 501 goto ssetup_exit;
498 502
499 pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base; 503 pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base;
500 smb_buf = (struct smb_hdr *)iov[0].iov_base; 504 smb_buf = (struct smb_hdr *)iov[0].iov_base;
501 505
502 if((smb_buf->WordCount != 3) && (smb_buf->WordCount != 4)) { 506 if ((smb_buf->WordCount != 3) && (smb_buf->WordCount != 4)) {
503 rc = -EIO; 507 rc = -EIO;
504 cERROR(1,("bad word count %d", smb_buf->WordCount)); 508 cERROR(1, ("bad word count %d", smb_buf->WordCount));
505 goto ssetup_exit; 509 goto ssetup_exit;
506 } 510 }
507 action = le16_to_cpu(pSMB->resp.Action); 511 action = le16_to_cpu(pSMB->resp.Action);
@@ -514,31 +518,32 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
514 bytes_remaining = BCC(smb_buf); 518 bytes_remaining = BCC(smb_buf);
515 bcc_ptr = pByteArea(smb_buf); 519 bcc_ptr = pByteArea(smb_buf);
516 520
517 if(smb_buf->WordCount == 4) { 521 if (smb_buf->WordCount == 4) {
518 __u16 blob_len; 522 __u16 blob_len;
519 blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength); 523 blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
520 bcc_ptr += blob_len; 524 bcc_ptr += blob_len;
521 if(blob_len > bytes_remaining) { 525 if (blob_len > bytes_remaining) {
522 cERROR(1,("bad security blob length %d", blob_len)); 526 cERROR(1, ("bad security blob length %d", blob_len));
523 rc = -EINVAL; 527 rc = -EINVAL;
524 goto ssetup_exit; 528 goto ssetup_exit;
525 } 529 }
526 bytes_remaining -= blob_len; 530 bytes_remaining -= blob_len;
527 } 531 }
528 532
529 /* BB check if Unicode and decode strings */ 533 /* BB check if Unicode and decode strings */
530 if(smb_buf->Flags2 & SMBFLG2_UNICODE) 534 if (smb_buf->Flags2 & SMBFLG2_UNICODE)
531 rc = decode_unicode_ssetup(&bcc_ptr, bytes_remaining, 535 rc = decode_unicode_ssetup(&bcc_ptr, bytes_remaining,
532 ses, nls_cp); 536 ses, nls_cp);
533 else 537 else
534 rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,nls_cp); 538 rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining,
535 539 ses, nls_cp);
540
536ssetup_exit: 541ssetup_exit:
537 kfree(str_area); 542 kfree(str_area);
538 if(resp_buf_type == CIFS_SMALL_BUFFER) { 543 if (resp_buf_type == CIFS_SMALL_BUFFER) {
539 cFYI(1,("ssetup freeing small buf %p", iov[0].iov_base)); 544 cFYI(1, ("ssetup freeing small buf %p", iov[0].iov_base));
540 cifs_small_buf_release(iov[0].iov_base); 545 cifs_small_buf_release(iov[0].iov_base);
541 } else if(resp_buf_type == CIFS_LARGE_BUFFER) 546 } else if (resp_buf_type == CIFS_LARGE_BUFFER)
542 cifs_buf_release(iov[0].iov_base); 547 cifs_buf_release(iov[0].iov_base);
543 548
544 return rc; 549 return rc;
diff --git a/fs/cifs/smbdes.c b/fs/cifs/smbdes.c
index 1b1daf63f062..cfa6d21fb4e8 100644
--- a/fs/cifs/smbdes.c
+++ b/fs/cifs/smbdes.c
@@ -1,32 +1,32 @@
1/* 1/*
2 Unix SMB/Netbios implementation. 2 Unix SMB/Netbios implementation.
3 Version 1.9. 3 Version 1.9.
4 4
5 a partial implementation of DES designed for use in the 5 a partial implementation of DES designed for use in the
6 SMB authentication protocol 6 SMB authentication protocol
7 7
8 Copyright (C) Andrew Tridgell 1998 8 Copyright (C) Andrew Tridgell 1998
9 Modified by Steve French (sfrench@us.ibm.com) 2002,2004 9 Modified by Steve French (sfrench@us.ibm.com) 2002,2004
10 10
11 This program is free software; you can redistribute it and/or modify 11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by 12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or 13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version. 14 (at your option) any later version.
15 15
16 This program is distributed in the hope that it will be useful, 16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details. 19 GNU General Public License for more details.
20 20
21 You should have received a copy of the GNU General Public License 21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software 22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24*/ 24*/
25 25
26/* NOTES: 26/* NOTES:
27 27
28 This code makes no attempt to be fast! In fact, it is a very 28 This code makes no attempt to be fast! In fact, it is a very
29 slow implementation 29 slow implementation
30 30
31 This code is NOT a complete DES implementation. It implements only 31 This code is NOT a complete DES implementation. It implements only
32 the minimum necessary for SMB authentication, as used by all SMB 32 the minimum necessary for SMB authentication, as used by all SMB
@@ -153,7 +153,7 @@ static uchar sbox[8][4][16] = {
153}; 153};
154 154
155static void 155static void
156permute(char *out, char *in, uchar * p, int n) 156permute(char *out, char *in, uchar *p, int n)
157{ 157{
158 int i; 158 int i;
159 for (i = 0; i < n; i++) 159 for (i = 0; i < n; i++)
@@ -202,18 +202,18 @@ dohash(char *out, char *in, char *key, int forw)
202 char *rl; 202 char *rl;
203 203
204 /* Have to reduce stack usage */ 204 /* Have to reduce stack usage */
205 pk1 = kmalloc(56+56+64+64,GFP_KERNEL); 205 pk1 = kmalloc(56+56+64+64, GFP_KERNEL);
206 if(pk1 == NULL) 206 if (pk1 == NULL)
207 return; 207 return;
208 208
209 ki = kmalloc(16*48, GFP_KERNEL); 209 ki = kmalloc(16*48, GFP_KERNEL);
210 if(ki == NULL) { 210 if (ki == NULL) {
211 kfree(pk1); 211 kfree(pk1);
212 return; 212 return;
213 } 213 }
214 214
215 cd = pk1 + 56; 215 cd = pk1 + 56;
216 pd1= cd + 56; 216 pd1 = cd + 56;
217 rl = pd1 + 64; 217 rl = pd1 + 64;
218 218
219 permute(pk1, key, perm1, 56); 219 permute(pk1, key, perm1, 56);
@@ -247,7 +247,7 @@ dohash(char *out, char *in, char *key, int forw)
247 char *r2; /* r2[32] */ 247 char *r2; /* r2[32] */
248 248
249 er = kmalloc(48+48+32+32+32, GFP_KERNEL); 249 er = kmalloc(48+48+32+32+32, GFP_KERNEL);
250 if(er == NULL) { 250 if (er == NULL) {
251 kfree(pk1); 251 kfree(pk1);
252 kfree(ki); 252 kfree(ki);
253 return; 253 return;
@@ -327,8 +327,8 @@ smbhash(unsigned char *out, unsigned char *in, unsigned char *key, int forw)
327 char *keyb; /* keyb[64] */ 327 char *keyb; /* keyb[64] */
328 unsigned char key2[8]; 328 unsigned char key2[8];
329 329
330 outb = kmalloc(64 * 3,GFP_KERNEL); 330 outb = kmalloc(64 * 3, GFP_KERNEL);
331 if(outb == NULL) 331 if (outb == NULL)
332 return; 332 return;
333 333
334 inb = outb + 64; 334 inb = outb + 64;
diff --git a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c
index 4b25ba92180d..90542a39be17 100644
--- a/fs/cifs/smbencrypt.c
+++ b/fs/cifs/smbencrypt.c
@@ -1,4 +1,4 @@
1/* 1/*
2 Unix SMB/Netbios implementation. 2 Unix SMB/Netbios implementation.
3 Version 1.9. 3 Version 1.9.
4 SMB parameters and setup 4 SMB parameters and setup
@@ -7,17 +7,17 @@
7 Modified by Jeremy Allison 1995. 7 Modified by Jeremy Allison 1995.
8 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003 8 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003
9 Modified by Steve French (sfrench@us.ibm.com) 2002-2003 9 Modified by Steve French (sfrench@us.ibm.com) 2002-2003
10 10
11 This program is free software; you can redistribute it and/or modify 11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by 12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or 13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version. 14 (at your option) any later version.
15 15
16 This program is distributed in the hope that it will be useful, 16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details. 19 GNU General Public License for more details.
20 20
21 You should have received a copy of the GNU General Public License 21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software 22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -57,7 +57,7 @@ void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24);
57 57
58/* 58/*
59 This implements the X/Open SMB password encryption 59 This implements the X/Open SMB password encryption
60 It takes a password, a 8 byte "crypt key" and puts 24 bytes of 60 It takes a password, a 8 byte "crypt key" and puts 24 bytes of
61 encrypted password into p24 */ 61 encrypted password into p24 */
62/* Note that password must be uppercased and null terminated */ 62/* Note that password must be uppercased and null terminated */
63void 63void
@@ -73,9 +73,9 @@ SMBencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24)
73 E_P16(p14, p21); 73 E_P16(p14, p21);
74 74
75 SMBOWFencrypt(p21, c8, p24); 75 SMBOWFencrypt(p21, c8, p24);
76 76
77 memset(p14,0,15); 77 memset(p14, 0, 15);
78 memset(p21,0,21); 78 memset(p21, 0, 21);
79} 79}
80 80
81/* Routines for Windows NT MD4 Hash functions. */ 81/* Routines for Windows NT MD4 Hash functions. */
@@ -90,14 +90,14 @@ _my_wcslen(__u16 * str)
90 90
91/* 91/*
92 * Convert a string into an NT UNICODE string. 92 * Convert a string into an NT UNICODE string.
93 * Note that regardless of processor type 93 * Note that regardless of processor type
94 * this must be in intel (little-endian) 94 * this must be in intel (little-endian)
95 * format. 95 * format.
96 */ 96 */
97 97
98static int 98static int
99_my_mbstowcs(__u16 * dst, const unsigned char *src, int len) 99_my_mbstowcs(__u16 * dst, const unsigned char *src, int len)
100{ /* not a very good conversion routine - change/fix */ 100{ /* BB not a very good conversion routine - change/fix */
101 int i; 101 int i;
102 __u16 val; 102 __u16 val;
103 103
@@ -112,7 +112,7 @@ _my_mbstowcs(__u16 * dst, const unsigned char *src, int len)
112 return i; 112 return i;
113} 113}
114 114
115/* 115/*
116 * Creates the MD4 Hash of the users password in NT UNICODE. 116 * Creates the MD4 Hash of the users password in NT UNICODE.
117 */ 117 */
118 118
@@ -123,7 +123,7 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16)
123 __u16 wpwd[129]; 123 __u16 wpwd[129];
124 124
125 /* Password cannot be longer than 128 characters */ 125 /* Password cannot be longer than 128 characters */
126 if(passwd) { 126 if (passwd) {
127 len = strlen((char *) passwd); 127 len = strlen((char *) passwd);
128 if (len > 128) { 128 if (len > 128) {
129 len = 128; 129 len = 128;
@@ -138,7 +138,7 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16)
138 len = _my_wcslen(wpwd) * sizeof (__u16); 138 len = _my_wcslen(wpwd) * sizeof (__u16);
139 139
140 mdfour(p16, (unsigned char *) wpwd, len); 140 mdfour(p16, (unsigned char *) wpwd, len);
141 memset(wpwd,0,129 * 2); 141 memset(wpwd, 0, 129 * 2);
142} 142}
143 143
144#if 0 /* currently unused */ 144#if 0 /* currently unused */
@@ -178,17 +178,17 @@ ntv2_owf_gen(const unsigned char owf[16], const char *user_n,
178 const char *domain_n, unsigned char kr_buf[16], 178 const char *domain_n, unsigned char kr_buf[16],
179 const struct nls_table *nls_codepage) 179 const struct nls_table *nls_codepage)
180{ 180{
181 wchar_t * user_u; 181 wchar_t *user_u;
182 wchar_t * dom_u; 182 wchar_t *dom_u;
183 int user_l, domain_l; 183 int user_l, domain_l;
184 struct HMACMD5Context ctx; 184 struct HMACMD5Context ctx;
185 185
186 /* might as well do one alloc to hold both (user_u and dom_u) */ 186 /* might as well do one alloc to hold both (user_u and dom_u) */
187 user_u = kmalloc(2048 * sizeof(wchar_t),GFP_KERNEL); 187 user_u = kmalloc(2048 * sizeof(wchar_t), GFP_KERNEL);
188 if(user_u == NULL) 188 if (user_u == NULL)
189 return; 189 return;
190 dom_u = user_u + 1024; 190 dom_u = user_u + 1024;
191 191
192 /* push_ucs2(NULL, user_u, user_n, (user_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); 192 /* push_ucs2(NULL, user_u, user_n, (user_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER);
193 push_ucs2(NULL, dom_u, domain_n, (domain_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); */ 193 push_ucs2(NULL, dom_u, domain_n, (domain_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); */
194 194
@@ -206,7 +206,7 @@ ntv2_owf_gen(const unsigned char owf[16], const char *user_n,
206 206
207 kfree(user_u); 207 kfree(user_u);
208} 208}
209#endif 209#endif
210 210
211/* Does the des encryption from the NT or LM MD4 hash. */ 211/* Does the des encryption from the NT or LM MD4 hash. */
212static void 212static void
@@ -256,15 +256,15 @@ SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24)
256#if 0 256#if 0
257static void 257static void
258SMBOWFencrypt_ntv2(const unsigned char kr[16], 258SMBOWFencrypt_ntv2(const unsigned char kr[16],
259 const struct data_blob * srv_chal, 259 const struct data_blob *srv_chal,
260 const struct data_blob * cli_chal, unsigned char resp_buf[16]) 260 const struct data_blob *cli_chal, unsigned char resp_buf[16])
261{ 261{
262 struct HMACMD5Context ctx; 262 struct HMACMD5Context ctx;
263 263
264 hmac_md5_init_limK_to_64(kr, 16, &ctx); 264 hmac_md5_init_limK_to_64(kr, 16, &ctx);
265 hmac_md5_update(srv_chal->data, srv_chal->length, &ctx); 265 hmac_md5_update(srv_chal->data, srv_chal->length, &ctx);
266 hmac_md5_update(cli_chal->data, cli_chal->length, &ctx); 266 hmac_md5_update(cli_chal->data, cli_chal->length, &ctx);
267 hmac_md5_final(resp_buf, &ctx); 267 hmac_md5_final(resp_buf, &ctx);
268} 268}
269 269
270static void 270static void
diff --git a/fs/cifs/smberr.h b/fs/cifs/smberr.h
index 212c3c296409..2ef0be288820 100644
--- a/fs/cifs/smberr.h
+++ b/fs/cifs/smberr.h
@@ -4,8 +4,8 @@
4 * Copyright (c) International Business Machines Corp., 2002,2004 4 * Copyright (c) International Business Machines Corp., 2002,2004
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * See Error Codes section of the SNIA CIFS Specification 7 * See Error Codes section of the SNIA CIFS Specification
8 * for more information 8 * for more information
9 * 9 *
10 * This library is free software; you can redistribute it and/or modify 10 * This library is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License as published 11 * it under the terms of the GNU Lesser General Public License as published
@@ -19,7 +19,7 @@
19 * 19 *
20 * You should have received a copy of the GNU Lesser General Public License 20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this library; if not, write to the Free Software 21 * along with this library; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */ 23 */
24 24
25#define SUCCESS 0x00 /* The request was successful. */ 25#define SUCCESS 0x00 /* The request was successful. */
@@ -110,7 +110,7 @@
110 110
111/* Below errors are used internally (do not come over the wire) for passthrough 111/* Below errors are used internally (do not come over the wire) for passthrough
112 from STATUS codes to POSIX only */ 112 from STATUS codes to POSIX only */
113#define ErrTooManyLinks 0xFFFE 113#define ErrTooManyLinks 0xFFFE
114 114
115/* Following error codes may be generated with the ERRSRV error class.*/ 115/* Following error codes may be generated with the ERRSRV error class.*/
116 116
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 5f468459a1e2..746bc9405db1 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * fs/cifs/transport.c 2 * fs/cifs/transport.c
3 * 3 *
4 * Copyright (C) International Business Machines Corp., 2002,2005 4 * Copyright (C) International Business Machines Corp., 2002,2007
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * Jeremy Allison (jra@samba.org) 2006. 6 * Jeremy Allison (jra@samba.org) 2006.
7 * 7 *
8 * This library is free software; you can redistribute it and/or modify 8 * This library is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published 9 * it under the terms of the GNU Lesser General Public License as published
10 * by the Free Software Foundation; either version 2.1 of the License, or 10 * by the Free Software Foundation; either version 2.1 of the License, or
@@ -17,7 +17,7 @@
17 * 17 *
18 * You should have received a copy of the GNU Lesser General Public License 18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this library; if not, write to the Free Software 19 * along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */ 21 */
22 22
23#include <linux/fs.h> 23#include <linux/fs.h>
@@ -32,7 +32,7 @@
32#include "cifsglob.h" 32#include "cifsglob.h"
33#include "cifsproto.h" 33#include "cifsproto.h"
34#include "cifs_debug.h" 34#include "cifs_debug.h"
35 35
36extern mempool_t *cifs_mid_poolp; 36extern mempool_t *cifs_mid_poolp;
37extern struct kmem_cache *cifs_oplock_cachep; 37extern struct kmem_cache *cifs_oplock_cachep;
38 38
@@ -49,7 +49,7 @@ AllocMidQEntry(const struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
49 cERROR(1, ("Null TCP session in AllocMidQEntry")); 49 cERROR(1, ("Null TCP session in AllocMidQEntry"));
50 return NULL; 50 return NULL;
51 } 51 }
52 52
53 temp = (struct mid_q_entry *) mempool_alloc(cifs_mid_poolp, 53 temp = (struct mid_q_entry *) mempool_alloc(cifs_mid_poolp,
54 GFP_KERNEL | GFP_NOFS); 54 GFP_KERNEL | GFP_NOFS);
55 if (temp == NULL) 55 if (temp == NULL)
@@ -86,7 +86,7 @@ DeleteMidQEntry(struct mid_q_entry *midEntry)
86 list_del(&midEntry->qhead); 86 list_del(&midEntry->qhead);
87 atomic_dec(&midCount); 87 atomic_dec(&midCount);
88 spin_unlock(&GlobalMid_Lock); 88 spin_unlock(&GlobalMid_Lock);
89 if(midEntry->largeBuf) 89 if (midEntry->largeBuf)
90 cifs_buf_release(midEntry->resp_buf); 90 cifs_buf_release(midEntry->resp_buf);
91 else 91 else
92 cifs_small_buf_release(midEntry->resp_buf); 92 cifs_small_buf_release(midEntry->resp_buf);
@@ -94,8 +94,8 @@ DeleteMidQEntry(struct mid_q_entry *midEntry)
94 now = jiffies; 94 now = jiffies;
95 /* commands taking longer than one second are indications that 95 /* commands taking longer than one second are indications that
96 something is wrong, unless it is quite a slow link or server */ 96 something is wrong, unless it is quite a slow link or server */
97 if((now - midEntry->when_alloc) > HZ) { 97 if ((now - midEntry->when_alloc) > HZ) {
98 if((cifsFYI & CIFS_TIMER) && 98 if ((cifsFYI & CIFS_TIMER) &&
99 (midEntry->command != SMB_COM_LOCKING_ANDX)) { 99 (midEntry->command != SMB_COM_LOCKING_ANDX)) {
100 printk(KERN_DEBUG " CIFS slow rsp: cmd %d mid %d", 100 printk(KERN_DEBUG " CIFS slow rsp: cmd %d mid %d",
101 midEntry->command, midEntry->mid); 101 midEntry->command, midEntry->mid);
@@ -110,10 +110,10 @@ DeleteMidQEntry(struct mid_q_entry *midEntry)
110} 110}
111 111
112struct oplock_q_entry * 112struct oplock_q_entry *
113AllocOplockQEntry(struct inode * pinode, __u16 fid, struct cifsTconInfo * tcon) 113AllocOplockQEntry(struct inode *pinode, __u16 fid, struct cifsTconInfo *tcon)
114{ 114{
115 struct oplock_q_entry *temp; 115 struct oplock_q_entry *temp;
116 if ((pinode== NULL) || (tcon == NULL)) { 116 if ((pinode == NULL) || (tcon == NULL)) {
117 cERROR(1, ("Null parms passed to AllocOplockQEntry")); 117 cERROR(1, ("Null parms passed to AllocOplockQEntry"));
118 return NULL; 118 return NULL;
119 } 119 }
@@ -133,9 +133,9 @@ AllocOplockQEntry(struct inode * pinode, __u16 fid, struct cifsTconInfo * tcon)
133 133
134} 134}
135 135
136void DeleteOplockQEntry(struct oplock_q_entry * oplockEntry) 136void DeleteOplockQEntry(struct oplock_q_entry *oplockEntry)
137{ 137{
138 spin_lock(&GlobalMid_Lock); 138 spin_lock(&GlobalMid_Lock);
139 /* should we check if list empty first? */ 139 /* should we check if list empty first? */
140 list_del(&oplockEntry->qhead); 140 list_del(&oplockEntry->qhead);
141 spin_unlock(&GlobalMid_Lock); 141 spin_unlock(&GlobalMid_Lock);
@@ -152,7 +152,7 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
152 struct kvec iov; 152 struct kvec iov;
153 unsigned len = smb_buf_length + 4; 153 unsigned len = smb_buf_length + 4;
154 154
155 if(ssocket == NULL) 155 if (ssocket == NULL)
156 return -ENOTSOCK; /* BB eventually add reconnect code here */ 156 return -ENOTSOCK; /* BB eventually add reconnect code here */
157 iov.iov_base = smb_buffer; 157 iov.iov_base = smb_buffer;
158 iov.iov_len = len; 158 iov.iov_len = len;
@@ -164,8 +164,8 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
164 smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; /* BB add more flags?*/ 164 smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; /* BB add more flags?*/
165 165
166 /* smb header is converted in header_assemble. bcc and rest of SMB word 166 /* smb header is converted in header_assemble. bcc and rest of SMB word
167 area, and byte area if necessary, is converted to littleendian in 167 area, and byte area if necessary, is converted to littleendian in
168 cifssmb.c and RFC1001 len is converted to bigendian in smb_send 168 cifssmb.c and RFC1001 len is converted to bigendian in smb_send
169 Flags2 is converted in SendReceive */ 169 Flags2 is converted in SendReceive */
170 170
171 smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length); 171 smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length);
@@ -177,9 +177,9 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
177 if ((rc == -ENOSPC) || (rc == -EAGAIN)) { 177 if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
178 i++; 178 i++;
179 /* smaller timeout here than send2 since smaller size */ 179 /* smaller timeout here than send2 since smaller size */
180 /* Although it may not be required, this also is smaller 180 /* Although it may not be required, this also is smaller
181 oplock break time */ 181 oplock break time */
182 if(i > 12) { 182 if (i > 12) {
183 cERROR(1, 183 cERROR(1,
184 ("sends on sock %p stuck for 7 seconds", 184 ("sends on sock %p stuck for 7 seconds",
185 ssocket)); 185 ssocket));
@@ -189,7 +189,7 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
189 msleep(1 << i); 189 msleep(1 << i);
190 continue; 190 continue;
191 } 191 }
192 if (rc < 0) 192 if (rc < 0)
193 break; 193 break;
194 else 194 else
195 i = 0; /* reset i after each successful send */ 195 i = 0; /* reset i after each successful send */
@@ -199,7 +199,7 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
199 } 199 }
200 200
201 if (rc < 0) { 201 if (rc < 0) {
202 cERROR(1,("Error %d sending data on socket to server", rc)); 202 cERROR(1, ("Error %d sending data on socket to server", rc));
203 } else { 203 } else {
204 rc = 0; 204 rc = 0;
205 } 205 }
@@ -223,8 +223,8 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
223 unsigned int total_len; 223 unsigned int total_len;
224 int first_vec = 0; 224 int first_vec = 0;
225 unsigned int smb_buf_length = smb_buffer->smb_buf_length; 225 unsigned int smb_buf_length = smb_buffer->smb_buf_length;
226 226
227 if(ssocket == NULL) 227 if (ssocket == NULL)
228 return -ENOTSOCK; /* BB eventually add reconnect code here */ 228 return -ENOTSOCK; /* BB eventually add reconnect code here */
229 229
230 smb_msg.msg_name = sin; 230 smb_msg.msg_name = sin;
@@ -234,8 +234,8 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
234 smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; /* BB add more flags?*/ 234 smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; /* BB add more flags?*/
235 235
236 /* smb header is converted in header_assemble. bcc and rest of SMB word 236 /* smb header is converted in header_assemble. bcc and rest of SMB word
237 area, and byte area if necessary, is converted to littleendian in 237 area, and byte area if necessary, is converted to littleendian in
238 cifssmb.c and RFC1001 len is converted to bigendian in smb_send 238 cifssmb.c and RFC1001 len is converted to bigendian in smb_send
239 Flags2 is converted in SendReceive */ 239 Flags2 is converted in SendReceive */
240 240
241 241
@@ -252,7 +252,7 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
252 n_vec - first_vec, total_len); 252 n_vec - first_vec, total_len);
253 if ((rc == -ENOSPC) || (rc == -EAGAIN)) { 253 if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
254 i++; 254 i++;
255 if(i >= 14) { 255 if (i >= 14) {
256 cERROR(1, 256 cERROR(1,
257 ("sends on sock %p stuck for 15 seconds", 257 ("sends on sock %p stuck for 15 seconds",
258 ssocket)); 258 ssocket));
@@ -262,17 +262,17 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
262 msleep(1 << i); 262 msleep(1 << i);
263 continue; 263 continue;
264 } 264 }
265 if (rc < 0) 265 if (rc < 0)
266 break; 266 break;
267 267
268 if (rc >= total_len) { 268 if (rc >= total_len) {
269 WARN_ON(rc > total_len); 269 WARN_ON(rc > total_len);
270 break; 270 break;
271 } 271 }
272 if(rc == 0) { 272 if (rc == 0) {
273 /* should never happen, letting socket clear before 273 /* should never happen, letting socket clear before
274 retrying is our only obvious option here */ 274 retrying is our only obvious option here */
275 cERROR(1,("tcp sent no data")); 275 cERROR(1, ("tcp sent no data"));
276 msleep(500); 276 msleep(500);
277 continue; 277 continue;
278 } 278 }
@@ -295,7 +295,7 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
295 } 295 }
296 296
297 if (rc < 0) { 297 if (rc < 0) {
298 cERROR(1,("Error %d sending data on socket to server", rc)); 298 cERROR(1, ("Error %d sending data on socket to server", rc));
299 } else 299 } else
300 rc = 0; 300 rc = 0;
301 301
@@ -308,13 +308,13 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
308 308
309static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op) 309static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op)
310{ 310{
311 if(long_op == -1) { 311 if (long_op == -1) {
312 /* oplock breaks must not be held up */ 312 /* oplock breaks must not be held up */
313 atomic_inc(&ses->server->inFlight); 313 atomic_inc(&ses->server->inFlight);
314 } else { 314 } else {
315 spin_lock(&GlobalMid_Lock); 315 spin_lock(&GlobalMid_Lock);
316 while(1) { 316 while (1) {
317 if(atomic_read(&ses->server->inFlight) >= 317 if (atomic_read(&ses->server->inFlight) >=
318 cifs_max_pending){ 318 cifs_max_pending){
319 spin_unlock(&GlobalMid_Lock); 319 spin_unlock(&GlobalMid_Lock);
320#ifdef CONFIG_CIFS_STATS2 320#ifdef CONFIG_CIFS_STATS2
@@ -328,14 +328,14 @@ static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op)
328#endif 328#endif
329 spin_lock(&GlobalMid_Lock); 329 spin_lock(&GlobalMid_Lock);
330 } else { 330 } else {
331 if(ses->server->tcpStatus == CifsExiting) { 331 if (ses->server->tcpStatus == CifsExiting) {
332 spin_unlock(&GlobalMid_Lock); 332 spin_unlock(&GlobalMid_Lock);
333 return -ENOENT; 333 return -ENOENT;
334 } 334 }
335 335
336 /* can not count locking commands against total since 336 /* can not count locking commands against total
337 they are allowed to block on server */ 337 as they are allowed to block on server */
338 338
339 /* update # of requests on the wire to server */ 339 /* update # of requests on the wire to server */
340 if (long_op < 3) 340 if (long_op < 3)
341 atomic_inc(&ses->server->inFlight); 341 atomic_inc(&ses->server->inFlight);
@@ -353,11 +353,11 @@ static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf,
353 if (ses->server->tcpStatus == CifsExiting) { 353 if (ses->server->tcpStatus == CifsExiting) {
354 return -ENOENT; 354 return -ENOENT;
355 } else if (ses->server->tcpStatus == CifsNeedReconnect) { 355 } else if (ses->server->tcpStatus == CifsNeedReconnect) {
356 cFYI(1,("tcp session dead - return to caller to retry")); 356 cFYI(1, ("tcp session dead - return to caller to retry"));
357 return -EAGAIN; 357 return -EAGAIN;
358 } else if (ses->status != CifsGood) { 358 } else if (ses->status != CifsGood) {
359 /* check if SMB session is bad because we are setting it up */ 359 /* check if SMB session is bad because we are setting it up */
360 if((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) && 360 if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) &&
361 (in_buf->Command != SMB_COM_NEGOTIATE)) { 361 (in_buf->Command != SMB_COM_NEGOTIATE)) {
362 return -EAGAIN; 362 return -EAGAIN;
363 } /* else ok - we are setting up session */ 363 } /* else ok - we are setting up session */
@@ -369,7 +369,7 @@ static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf,
369 return 0; 369 return 0;
370} 370}
371 371
372static int wait_for_response(struct cifsSesInfo *ses, 372static int wait_for_response(struct cifsSesInfo *ses,
373 struct mid_q_entry *midQ, 373 struct mid_q_entry *midQ,
374 unsigned long timeout, 374 unsigned long timeout,
375 unsigned long time_to_wait) 375 unsigned long time_to_wait)
@@ -379,8 +379,8 @@ static int wait_for_response(struct cifsSesInfo *ses,
379 for (;;) { 379 for (;;) {
380 curr_timeout = timeout + jiffies; 380 curr_timeout = timeout + jiffies;
381 wait_event(ses->server->response_q, 381 wait_event(ses->server->response_q,
382 (!(midQ->midState == MID_REQUEST_SUBMITTED)) || 382 (!(midQ->midState == MID_REQUEST_SUBMITTED)) ||
383 time_after(jiffies, curr_timeout) || 383 time_after(jiffies, curr_timeout) ||
384 ((ses->server->tcpStatus != CifsGood) && 384 ((ses->server->tcpStatus != CifsGood) &&
385 (ses->server->tcpStatus != CifsNew))); 385 (ses->server->tcpStatus != CifsNew)));
386 386
@@ -398,16 +398,16 @@ static int wait_for_response(struct cifsSesInfo *ses,
398 spin_unlock(&GlobalMid_Lock); 398 spin_unlock(&GlobalMid_Lock);
399 399
400 /* Calculate time_to_wait past last receive time. 400 /* Calculate time_to_wait past last receive time.
401 Although we prefer not to time out if the 401 Although we prefer not to time out if the
402 server is still responding - we will time 402 server is still responding - we will time
403 out if the server takes more than 15 (or 45 403 out if the server takes more than 15 (or 45
404 or 180) seconds to respond to this request 404 or 180) seconds to respond to this request
405 and has not responded to any request from 405 and has not responded to any request from
406 other threads on the client within 10 seconds */ 406 other threads on the client within 10 seconds */
407 lrt += time_to_wait; 407 lrt += time_to_wait;
408 if (time_after(jiffies, lrt)) { 408 if (time_after(jiffies, lrt)) {
409 /* No replies for time_to_wait. */ 409 /* No replies for time_to_wait. */
410 cERROR(1,("server not responding")); 410 cERROR(1, ("server not responding"));
411 return -1; 411 return -1;
412 } 412 }
413 } else { 413 } else {
@@ -417,8 +417,8 @@ static int wait_for_response(struct cifsSesInfo *ses,
417} 417}
418 418
419int 419int
420SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, 420SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
421 struct kvec *iov, int n_vec, int * pRespBufType /* ret */, 421 struct kvec *iov, int n_vec, int *pRespBufType /* ret */,
422 const int long_op) 422 const int long_op)
423{ 423{
424 int rc = 0; 424 int rc = 0;
@@ -426,21 +426,21 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
426 unsigned long timeout; 426 unsigned long timeout;
427 struct mid_q_entry *midQ; 427 struct mid_q_entry *midQ;
428 struct smb_hdr *in_buf = iov[0].iov_base; 428 struct smb_hdr *in_buf = iov[0].iov_base;
429 429
430 *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */ 430 *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */
431 431
432 if ((ses == NULL) || (ses->server == NULL)) { 432 if ((ses == NULL) || (ses->server == NULL)) {
433 cifs_small_buf_release(in_buf); 433 cifs_small_buf_release(in_buf);
434 cERROR(1,("Null session")); 434 cERROR(1, ("Null session"));
435 return -EIO; 435 return -EIO;
436 } 436 }
437 437
438 if(ses->server->tcpStatus == CifsExiting) { 438 if (ses->server->tcpStatus == CifsExiting) {
439 cifs_small_buf_release(in_buf); 439 cifs_small_buf_release(in_buf);
440 return -ENOENT; 440 return -ENOENT;
441 } 441 }
442 442
443 /* Ensure that we do not send more than 50 overlapping requests 443 /* Ensure that we do not send more than 50 overlapping requests
444 to the same server. We may make this configurable later or 444 to the same server. We may make this configurable later or
445 use ses->maxReq */ 445 use ses->maxReq */
446 446
@@ -450,23 +450,23 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
450 return rc; 450 return rc;
451 } 451 }
452 452
453 /* make sure that we sign in the same order that we send on this socket 453 /* make sure that we sign in the same order that we send on this socket
454 and avoid races inside tcp sendmsg code that could cause corruption 454 and avoid races inside tcp sendmsg code that could cause corruption
455 of smb data */ 455 of smb data */
456 456
457 down(&ses->server->tcpSem); 457 down(&ses->server->tcpSem);
458 458
459 rc = allocate_mid(ses, in_buf, &midQ); 459 rc = allocate_mid(ses, in_buf, &midQ);
460 if (rc) { 460 if (rc) {
461 up(&ses->server->tcpSem); 461 up(&ses->server->tcpSem);
462 cifs_small_buf_release(in_buf); 462 cifs_small_buf_release(in_buf);
463 /* Update # of requests on wire to server */ 463 /* Update # of requests on wire to server */
464 atomic_dec(&ses->server->inFlight); 464 atomic_dec(&ses->server->inFlight);
465 wake_up(&ses->server->request_q); 465 wake_up(&ses->server->request_q);
466 return rc; 466 return rc;
467 } 467 }
468 468
469 rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number); 469 rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number);
470 470
471 midQ->midState = MID_REQUEST_SUBMITTED; 471 midQ->midState = MID_REQUEST_SUBMITTED;
472#ifdef CONFIG_CIFS_STATS2 472#ifdef CONFIG_CIFS_STATS2
@@ -482,7 +482,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
482 up(&ses->server->tcpSem); 482 up(&ses->server->tcpSem);
483 cifs_small_buf_release(in_buf); 483 cifs_small_buf_release(in_buf);
484 484
485 if(rc < 0) 485 if (rc < 0)
486 goto out; 486 goto out;
487 487
488 if (long_op == -1) 488 if (long_op == -1)
@@ -490,18 +490,18 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
490 else if (long_op == 2) /* writes past end of file can take loong time */ 490 else if (long_op == 2) /* writes past end of file can take loong time */
491 timeout = 180 * HZ; 491 timeout = 180 * HZ;
492 else if (long_op == 1) 492 else if (long_op == 1)
493 timeout = 45 * HZ; /* should be greater than 493 timeout = 45 * HZ; /* should be greater than
494 servers oplock break timeout (about 43 seconds) */ 494 servers oplock break timeout (about 43 seconds) */
495 else 495 else
496 timeout = 15 * HZ; 496 timeout = 15 * HZ;
497 497
498 /* wait for 15 seconds or until woken up due to response arriving or 498 /* wait for 15 seconds or until woken up due to response arriving or
499 due to last connection to this server being unmounted */ 499 due to last connection to this server being unmounted */
500 if (signal_pending(current)) { 500 if (signal_pending(current)) {
501 /* if signal pending do not hold up user for full smb timeout 501 /* if signal pending do not hold up user for full smb timeout
502 but we still give response a chance to complete */ 502 but we still give response a chance to complete */
503 timeout = 2 * HZ; 503 timeout = 2 * HZ;
504 } 504 }
505 505
506 /* No user interrupts in wait - wreaks havoc with performance */ 506 /* No user interrupts in wait - wreaks havoc with performance */
507 wait_for_response(ses, midQ, timeout, 10 * HZ); 507 wait_for_response(ses, midQ, timeout, 10 * HZ);
@@ -511,10 +511,10 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
511 spin_unlock(&GlobalMid_Lock); 511 spin_unlock(&GlobalMid_Lock);
512 receive_len = midQ->resp_buf->smb_buf_length; 512 receive_len = midQ->resp_buf->smb_buf_length;
513 } else { 513 } else {
514 cERROR(1,("No response to cmd %d mid %d", 514 cERROR(1, ("No response to cmd %d mid %d",
515 midQ->command, midQ->mid)); 515 midQ->command, midQ->mid));
516 if(midQ->midState == MID_REQUEST_SUBMITTED) { 516 if (midQ->midState == MID_REQUEST_SUBMITTED) {
517 if(ses->server->tcpStatus == CifsExiting) 517 if (ses->server->tcpStatus == CifsExiting)
518 rc = -EHOSTDOWN; 518 rc = -EHOSTDOWN;
519 else { 519 else {
520 ses->server->tcpStatus = CifsNeedReconnect; 520 ses->server->tcpStatus = CifsNeedReconnect;
@@ -523,9 +523,9 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
523 } 523 }
524 524
525 if (rc != -EHOSTDOWN) { 525 if (rc != -EHOSTDOWN) {
526 if(midQ->midState == MID_RETRY_NEEDED) { 526 if (midQ->midState == MID_RETRY_NEEDED) {
527 rc = -EAGAIN; 527 rc = -EAGAIN;
528 cFYI(1,("marking request for retry")); 528 cFYI(1, ("marking request for retry"));
529 } else { 529 } else {
530 rc = -EIO; 530 rc = -EIO;
531 } 531 }
@@ -533,21 +533,21 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
533 spin_unlock(&GlobalMid_Lock); 533 spin_unlock(&GlobalMid_Lock);
534 DeleteMidQEntry(midQ); 534 DeleteMidQEntry(midQ);
535 /* Update # of requests on wire to server */ 535 /* Update # of requests on wire to server */
536 atomic_dec(&ses->server->inFlight); 536 atomic_dec(&ses->server->inFlight);
537 wake_up(&ses->server->request_q); 537 wake_up(&ses->server->request_q);
538 return rc; 538 return rc;
539 } 539 }
540 540
541 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { 541 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
542 cERROR(1, ("Frame too large received. Length: %d Xid: %d", 542 cERROR(1, ("Frame too large received. Length: %d Xid: %d",
543 receive_len, xid)); 543 receive_len, xid));
544 rc = -EIO; 544 rc = -EIO;
545 } else { /* rcvd frame is ok */ 545 } else { /* rcvd frame is ok */
546 if (midQ->resp_buf && 546 if (midQ->resp_buf &&
547 (midQ->midState == MID_RESPONSE_RECEIVED)) { 547 (midQ->midState == MID_RESPONSE_RECEIVED)) {
548 548
549 iov[0].iov_base = (char *)midQ->resp_buf; 549 iov[0].iov_base = (char *)midQ->resp_buf;
550 if(midQ->largeBuf) 550 if (midQ->largeBuf)
551 *pRespBufType = CIFS_LARGE_BUFFER; 551 *pRespBufType = CIFS_LARGE_BUFFER;
552 else 552 else
553 *pRespBufType = CIFS_SMALL_BUFFER; 553 *pRespBufType = CIFS_SMALL_BUFFER;
@@ -555,14 +555,14 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
555 555
556 dump_smb(midQ->resp_buf, 80); 556 dump_smb(midQ->resp_buf, 80);
557 /* convert the length into a more usable form */ 557 /* convert the length into a more usable form */
558 if((receive_len > 24) && 558 if ((receive_len > 24) &&
559 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 559 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
560 SECMODE_SIGN_ENABLED))) { 560 SECMODE_SIGN_ENABLED))) {
561 rc = cifs_verify_signature(midQ->resp_buf, 561 rc = cifs_verify_signature(midQ->resp_buf,
562 ses->server->mac_signing_key, 562 &ses->server->mac_signing_key,
563 midQ->sequence_number+1); 563 midQ->sequence_number+1);
564 if(rc) { 564 if (rc) {
565 cERROR(1,("Unexpected SMB signature")); 565 cERROR(1, ("Unexpected SMB signature"));
566 /* BB FIXME add code to kill session */ 566 /* BB FIXME add code to kill session */
567 } 567 }
568 } 568 }
@@ -576,19 +576,19 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
576 sizeof (struct smb_hdr) - 576 sizeof (struct smb_hdr) -
577 4 /* do not count RFC1001 header */ + 577 4 /* do not count RFC1001 header */ +
578 (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ ) 578 (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ )
579 BCC(midQ->resp_buf) = 579 BCC(midQ->resp_buf) =
580 le16_to_cpu(BCC_LE(midQ->resp_buf)); 580 le16_to_cpu(BCC_LE(midQ->resp_buf));
581 midQ->resp_buf = NULL; /* mark it so will not be freed 581 midQ->resp_buf = NULL; /* mark it so will not be freed
582 by DeleteMidQEntry */ 582 by DeleteMidQEntry */
583 } else { 583 } else {
584 rc = -EIO; 584 rc = -EIO;
585 cFYI(1,("Bad MID state?")); 585 cFYI(1, ("Bad MID state?"));
586 } 586 }
587 } 587 }
588 588
589out: 589out:
590 DeleteMidQEntry(midQ); 590 DeleteMidQEntry(midQ);
591 atomic_dec(&ses->server->inFlight); 591 atomic_dec(&ses->server->inFlight);
592 wake_up(&ses->server->request_q); 592 wake_up(&ses->server->request_q);
593 593
594 return rc; 594 return rc;
@@ -605,18 +605,18 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
605 struct mid_q_entry *midQ; 605 struct mid_q_entry *midQ;
606 606
607 if (ses == NULL) { 607 if (ses == NULL) {
608 cERROR(1,("Null smb session")); 608 cERROR(1, ("Null smb session"));
609 return -EIO; 609 return -EIO;
610 } 610 }
611 if(ses->server == NULL) { 611 if (ses->server == NULL) {
612 cERROR(1,("Null tcp session")); 612 cERROR(1, ("Null tcp session"));
613 return -EIO; 613 return -EIO;
614 } 614 }
615 615
616 if(ses->server->tcpStatus == CifsExiting) 616 if (ses->server->tcpStatus == CifsExiting)
617 return -ENOENT; 617 return -ENOENT;
618 618
619 /* Ensure that we do not send more than 50 overlapping requests 619 /* Ensure that we do not send more than 50 overlapping requests
620 to the same server. We may make this configurable later or 620 to the same server. We may make this configurable later or
621 use ses->maxReq */ 621 use ses->maxReq */
622 622
@@ -624,17 +624,17 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
624 if (rc) 624 if (rc)
625 return rc; 625 return rc;
626 626
627 /* make sure that we sign in the same order that we send on this socket 627 /* make sure that we sign in the same order that we send on this socket
628 and avoid races inside tcp sendmsg code that could cause corruption 628 and avoid races inside tcp sendmsg code that could cause corruption
629 of smb data */ 629 of smb data */
630 630
631 down(&ses->server->tcpSem); 631 down(&ses->server->tcpSem);
632 632
633 rc = allocate_mid(ses, in_buf, &midQ); 633 rc = allocate_mid(ses, in_buf, &midQ);
634 if (rc) { 634 if (rc) {
635 up(&ses->server->tcpSem); 635 up(&ses->server->tcpSem);
636 /* Update # of requests on wire to server */ 636 /* Update # of requests on wire to server */
637 atomic_dec(&ses->server->inFlight); 637 atomic_dec(&ses->server->inFlight);
638 wake_up(&ses->server->request_q); 638 wake_up(&ses->server->request_q);
639 return rc; 639 return rc;
640 } 640 }
@@ -645,7 +645,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
645 DeleteMidQEntry(midQ); 645 DeleteMidQEntry(midQ);
646 up(&ses->server->tcpSem); 646 up(&ses->server->tcpSem);
647 /* Update # of requests on wire to server */ 647 /* Update # of requests on wire to server */
648 atomic_dec(&ses->server->inFlight); 648 atomic_dec(&ses->server->inFlight);
649 wake_up(&ses->server->request_q); 649 wake_up(&ses->server->request_q);
650 return -EIO; 650 return -EIO;
651 } 651 }
@@ -664,7 +664,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
664#endif 664#endif
665 up(&ses->server->tcpSem); 665 up(&ses->server->tcpSem);
666 666
667 if(rc < 0) 667 if (rc < 0)
668 goto out; 668 goto out;
669 669
670 if (long_op == -1) 670 if (long_op == -1)
@@ -672,17 +672,17 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
672 else if (long_op == 2) /* writes past end of file can take loong time */ 672 else if (long_op == 2) /* writes past end of file can take loong time */
673 timeout = 180 * HZ; 673 timeout = 180 * HZ;
674 else if (long_op == 1) 674 else if (long_op == 1)
675 timeout = 45 * HZ; /* should be greater than 675 timeout = 45 * HZ; /* should be greater than
676 servers oplock break timeout (about 43 seconds) */ 676 servers oplock break timeout (about 43 seconds) */
677 else 677 else
678 timeout = 15 * HZ; 678 timeout = 15 * HZ;
679 /* wait for 15 seconds or until woken up due to response arriving or 679 /* wait for 15 seconds or until woken up due to response arriving or
680 due to last connection to this server being unmounted */ 680 due to last connection to this server being unmounted */
681 if (signal_pending(current)) { 681 if (signal_pending(current)) {
682 /* if signal pending do not hold up user for full smb timeout 682 /* if signal pending do not hold up user for full smb timeout
683 but we still give response a chance to complete */ 683 but we still give response a chance to complete */
684 timeout = 2 * HZ; 684 timeout = 2 * HZ;
685 } 685 }
686 686
687 /* No user interrupts in wait - wreaks havoc with performance */ 687 /* No user interrupts in wait - wreaks havoc with performance */
688 wait_for_response(ses, midQ, timeout, 10 * HZ); 688 wait_for_response(ses, midQ, timeout, 10 * HZ);
@@ -692,10 +692,10 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
692 spin_unlock(&GlobalMid_Lock); 692 spin_unlock(&GlobalMid_Lock);
693 receive_len = midQ->resp_buf->smb_buf_length; 693 receive_len = midQ->resp_buf->smb_buf_length;
694 } else { 694 } else {
695 cERROR(1,("No response for cmd %d mid %d", 695 cERROR(1, ("No response for cmd %d mid %d",
696 midQ->command, midQ->mid)); 696 midQ->command, midQ->mid));
697 if(midQ->midState == MID_REQUEST_SUBMITTED) { 697 if (midQ->midState == MID_REQUEST_SUBMITTED) {
698 if(ses->server->tcpStatus == CifsExiting) 698 if (ses->server->tcpStatus == CifsExiting)
699 rc = -EHOSTDOWN; 699 rc = -EHOSTDOWN;
700 else { 700 else {
701 ses->server->tcpStatus = CifsNeedReconnect; 701 ses->server->tcpStatus = CifsNeedReconnect;
@@ -704,9 +704,9 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
704 } 704 }
705 705
706 if (rc != -EHOSTDOWN) { 706 if (rc != -EHOSTDOWN) {
707 if(midQ->midState == MID_RETRY_NEEDED) { 707 if (midQ->midState == MID_RETRY_NEEDED) {
708 rc = -EAGAIN; 708 rc = -EAGAIN;
709 cFYI(1,("marking request for retry")); 709 cFYI(1, ("marking request for retry"));
710 } else { 710 } else {
711 rc = -EIO; 711 rc = -EIO;
712 } 712 }
@@ -714,11 +714,11 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
714 spin_unlock(&GlobalMid_Lock); 714 spin_unlock(&GlobalMid_Lock);
715 DeleteMidQEntry(midQ); 715 DeleteMidQEntry(midQ);
716 /* Update # of requests on wire to server */ 716 /* Update # of requests on wire to server */
717 atomic_dec(&ses->server->inFlight); 717 atomic_dec(&ses->server->inFlight);
718 wake_up(&ses->server->request_q); 718 wake_up(&ses->server->request_q);
719 return rc; 719 return rc;
720 } 720 }
721 721
722 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { 722 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
723 cERROR(1, ("Frame too large received. Length: %d Xid: %d", 723 cERROR(1, ("Frame too large received. Length: %d Xid: %d",
724 receive_len, xid)); 724 receive_len, xid));
@@ -734,14 +734,14 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
734 734
735 dump_smb(out_buf, 92); 735 dump_smb(out_buf, 92);
736 /* convert the length into a more usable form */ 736 /* convert the length into a more usable form */
737 if((receive_len > 24) && 737 if ((receive_len > 24) &&
738 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 738 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
739 SECMODE_SIGN_ENABLED))) { 739 SECMODE_SIGN_ENABLED))) {
740 rc = cifs_verify_signature(out_buf, 740 rc = cifs_verify_signature(out_buf,
741 ses->server->mac_signing_key, 741 &ses->server->mac_signing_key,
742 midQ->sequence_number+1); 742 midQ->sequence_number+1);
743 if(rc) { 743 if (rc) {
744 cERROR(1,("Unexpected SMB signature")); 744 cERROR(1, ("Unexpected SMB signature"));
745 /* BB FIXME add code to kill session */ 745 /* BB FIXME add code to kill session */
746 } 746 }
747 } 747 }
@@ -759,13 +759,13 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
759 BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf)); 759 BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
760 } else { 760 } else {
761 rc = -EIO; 761 rc = -EIO;
762 cERROR(1,("Bad MID state?")); 762 cERROR(1, ("Bad MID state?"));
763 } 763 }
764 } 764 }
765 765
766out: 766out:
767 DeleteMidQEntry(midQ); 767 DeleteMidQEntry(midQ);
768 atomic_dec(&ses->server->inFlight); 768 atomic_dec(&ses->server->inFlight);
769 wake_up(&ses->server->request_q); 769 wake_up(&ses->server->request_q);
770 770
771 return rc; 771 return rc;
@@ -783,7 +783,7 @@ send_nt_cancel(struct cifsTconInfo *tcon, struct smb_hdr *in_buf,
783 783
784 header_assemble(in_buf, SMB_COM_NT_CANCEL, tcon, 0); 784 header_assemble(in_buf, SMB_COM_NT_CANCEL, tcon, 0);
785 in_buf->Mid = mid; 785 in_buf->Mid = mid;
786 down(&ses->server->tcpSem); 786 down(&ses->server->tcpSem);
787 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number); 787 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
788 if (rc) { 788 if (rc) {
789 up(&ses->server->tcpSem); 789 up(&ses->server->tcpSem);
@@ -832,20 +832,20 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
832 struct cifsSesInfo *ses; 832 struct cifsSesInfo *ses;
833 833
834 if (tcon == NULL || tcon->ses == NULL) { 834 if (tcon == NULL || tcon->ses == NULL) {
835 cERROR(1,("Null smb session")); 835 cERROR(1, ("Null smb session"));
836 return -EIO; 836 return -EIO;
837 } 837 }
838 ses = tcon->ses; 838 ses = tcon->ses;
839 839
840 if(ses->server == NULL) { 840 if (ses->server == NULL) {
841 cERROR(1,("Null tcp session")); 841 cERROR(1, ("Null tcp session"));
842 return -EIO; 842 return -EIO;
843 } 843 }
844 844
845 if(ses->server->tcpStatus == CifsExiting) 845 if (ses->server->tcpStatus == CifsExiting)
846 return -ENOENT; 846 return -ENOENT;
847 847
848 /* Ensure that we do not send more than 50 overlapping requests 848 /* Ensure that we do not send more than 50 overlapping requests
849 to the same server. We may make this configurable later or 849 to the same server. We may make this configurable later or
850 use ses->maxReq */ 850 use ses->maxReq */
851 851
@@ -853,11 +853,11 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
853 if (rc) 853 if (rc)
854 return rc; 854 return rc;
855 855
856 /* make sure that we sign in the same order that we send on this socket 856 /* make sure that we sign in the same order that we send on this socket
857 and avoid races inside tcp sendmsg code that could cause corruption 857 and avoid races inside tcp sendmsg code that could cause corruption
858 of smb data */ 858 of smb data */
859 859
860 down(&ses->server->tcpSem); 860 down(&ses->server->tcpSem);
861 861
862 rc = allocate_mid(ses, in_buf, &midQ); 862 rc = allocate_mid(ses, in_buf, &midQ);
863 if (rc) { 863 if (rc) {
@@ -887,14 +887,14 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
887#endif 887#endif
888 up(&ses->server->tcpSem); 888 up(&ses->server->tcpSem);
889 889
890 if(rc < 0) { 890 if (rc < 0) {
891 DeleteMidQEntry(midQ); 891 DeleteMidQEntry(midQ);
892 return rc; 892 return rc;
893 } 893 }
894 894
895 /* Wait for a reply - allow signals to interrupt. */ 895 /* Wait for a reply - allow signals to interrupt. */
896 rc = wait_event_interruptible(ses->server->response_q, 896 rc = wait_event_interruptible(ses->server->response_q,
897 (!(midQ->midState == MID_REQUEST_SUBMITTED)) || 897 (!(midQ->midState == MID_REQUEST_SUBMITTED)) ||
898 ((ses->server->tcpStatus != CifsGood) && 898 ((ses->server->tcpStatus != CifsGood) &&
899 (ses->server->tcpStatus != CifsNew))); 899 (ses->server->tcpStatus != CifsNew)));
900 900
@@ -928,7 +928,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
928 } 928 }
929 929
930 /* Wait 5 seconds for the response. */ 930 /* Wait 5 seconds for the response. */
931 if (wait_for_response(ses, midQ, 5 * HZ, 5 * HZ)==0) { 931 if (wait_for_response(ses, midQ, 5 * HZ, 5 * HZ) == 0) {
932 /* We got the response - restart system call. */ 932 /* We got the response - restart system call. */
933 rstart = 1; 933 rstart = 1;
934 } 934 }
@@ -939,10 +939,10 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
939 spin_unlock(&GlobalMid_Lock); 939 spin_unlock(&GlobalMid_Lock);
940 receive_len = midQ->resp_buf->smb_buf_length; 940 receive_len = midQ->resp_buf->smb_buf_length;
941 } else { 941 } else {
942 cERROR(1,("No response for cmd %d mid %d", 942 cERROR(1, ("No response for cmd %d mid %d",
943 midQ->command, midQ->mid)); 943 midQ->command, midQ->mid));
944 if(midQ->midState == MID_REQUEST_SUBMITTED) { 944 if (midQ->midState == MID_REQUEST_SUBMITTED) {
945 if(ses->server->tcpStatus == CifsExiting) 945 if (ses->server->tcpStatus == CifsExiting)
946 rc = -EHOSTDOWN; 946 rc = -EHOSTDOWN;
947 else { 947 else {
948 ses->server->tcpStatus = CifsNeedReconnect; 948 ses->server->tcpStatus = CifsNeedReconnect;
@@ -951,9 +951,9 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
951 } 951 }
952 952
953 if (rc != -EHOSTDOWN) { 953 if (rc != -EHOSTDOWN) {
954 if(midQ->midState == MID_RETRY_NEEDED) { 954 if (midQ->midState == MID_RETRY_NEEDED) {
955 rc = -EAGAIN; 955 rc = -EAGAIN;
956 cFYI(1,("marking request for retry")); 956 cFYI(1, ("marking request for retry"));
957 } else { 957 } else {
958 rc = -EIO; 958 rc = -EIO;
959 } 959 }
@@ -962,7 +962,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
962 DeleteMidQEntry(midQ); 962 DeleteMidQEntry(midQ);
963 return rc; 963 return rc;
964 } 964 }
965 965
966 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { 966 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
967 cERROR(1, ("Frame too large received. Length: %d Xid: %d", 967 cERROR(1, ("Frame too large received. Length: %d Xid: %d",
968 receive_len, xid)); 968 receive_len, xid));
@@ -978,14 +978,14 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
978 978
979 dump_smb(out_buf, 92); 979 dump_smb(out_buf, 92);
980 /* convert the length into a more usable form */ 980 /* convert the length into a more usable form */
981 if((receive_len > 24) && 981 if ((receive_len > 24) &&
982 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 982 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
983 SECMODE_SIGN_ENABLED))) { 983 SECMODE_SIGN_ENABLED))) {
984 rc = cifs_verify_signature(out_buf, 984 rc = cifs_verify_signature(out_buf,
985 ses->server->mac_signing_key, 985 &ses->server->mac_signing_key,
986 midQ->sequence_number+1); 986 midQ->sequence_number+1);
987 if(rc) { 987 if (rc) {
988 cERROR(1,("Unexpected SMB signature")); 988 cERROR(1, ("Unexpected SMB signature"));
989 /* BB FIXME add code to kill session */ 989 /* BB FIXME add code to kill session */
990 } 990 }
991 } 991 }
@@ -1003,7 +1003,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
1003 BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf)); 1003 BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
1004 } else { 1004 } else {
1005 rc = -EIO; 1005 rc = -EIO;
1006 cERROR(1,("Bad MID state?")); 1006 cERROR(1, ("Bad MID state?"));
1007 } 1007 }
1008 } 1008 }
1009 DeleteMidQEntry(midQ); 1009 DeleteMidQEntry(midQ);
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c
index 18fcec190f8b..f61e433d281c 100644
--- a/fs/cifs/xattr.c
+++ b/fs/cifs/xattr.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/xattr.c 2 * fs/cifs/xattr.c
3 * 3 *
4 * Copyright (c) International Business Machines Corp., 2003 4 * Copyright (c) International Business Machines Corp., 2003, 2007
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This library is free software; you can redistribute it and/or modify 7 * This library is free software; you can redistribute it and/or modify
@@ -37,50 +37,52 @@
37#define XATTR_TRUSTED_PREFIX_LEN 8 37#define XATTR_TRUSTED_PREFIX_LEN 8
38#define XATTR_SECURITY_PREFIX_LEN 9 38#define XATTR_SECURITY_PREFIX_LEN 9
39/* BB need to add server (Samba e.g) support for security and trusted prefix */ 39/* BB need to add server (Samba e.g) support for security and trusted prefix */
40
41 40
42 41
43int cifs_removexattr(struct dentry * direntry, const char * ea_name) 42
43int cifs_removexattr(struct dentry *direntry, const char *ea_name)
44{ 44{
45 int rc = -EOPNOTSUPP; 45 int rc = -EOPNOTSUPP;
46#ifdef CONFIG_CIFS_XATTR 46#ifdef CONFIG_CIFS_XATTR
47 int xid; 47 int xid;
48 struct cifs_sb_info *cifs_sb; 48 struct cifs_sb_info *cifs_sb;
49 struct cifsTconInfo *pTcon; 49 struct cifsTconInfo *pTcon;
50 struct super_block * sb; 50 struct super_block *sb;
51 char * full_path; 51 char *full_path;
52 52
53 if(direntry == NULL) 53 if (direntry == NULL)
54 return -EIO; 54 return -EIO;
55 if(direntry->d_inode == NULL) 55 if (direntry->d_inode == NULL)
56 return -EIO; 56 return -EIO;
57 sb = direntry->d_inode->i_sb; 57 sb = direntry->d_inode->i_sb;
58 if(sb == NULL) 58 if (sb == NULL)
59 return -EIO; 59 return -EIO;
60 xid = GetXid(); 60 xid = GetXid();
61 61
62 cifs_sb = CIFS_SB(sb); 62 cifs_sb = CIFS_SB(sb);
63 pTcon = cifs_sb->tcon; 63 pTcon = cifs_sb->tcon;
64 64
65 full_path = build_path_from_dentry(direntry); 65 full_path = build_path_from_dentry(direntry);
66 if(full_path == NULL) { 66 if (full_path == NULL) {
67 FreeXid(xid); 67 FreeXid(xid);
68 return -ENOMEM; 68 return -ENOMEM;
69 } 69 }
70 if(ea_name == NULL) { 70 if (ea_name == NULL) {
71 cFYI(1,("Null xattr names not supported")); 71 cFYI(1, ("Null xattr names not supported"));
72 } else if(strncmp(ea_name,CIFS_XATTR_USER_PREFIX,5) 72 } else if (strncmp(ea_name, CIFS_XATTR_USER_PREFIX, 5)
73 && (strncmp(ea_name,CIFS_XATTR_OS2_PREFIX,4))) { 73 && (strncmp(ea_name, CIFS_XATTR_OS2_PREFIX, 4))) {
74 cFYI(1,("illegal xattr namespace %s (only user namespace supported)",ea_name)); 74 cFYI(1,
75 ("illegal xattr request %s (only user namespace supported)",
76 ea_name));
75 /* BB what if no namespace prefix? */ 77 /* BB what if no namespace prefix? */
76 /* Should we just pass them to server, except for 78 /* Should we just pass them to server, except for
77 system and perhaps security prefixes? */ 79 system and perhaps security prefixes? */
78 } else { 80 } else {
79 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) 81 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
80 goto remove_ea_exit; 82 goto remove_ea_exit;
81 83
82 ea_name+=5; /* skip past user. prefix */ 84 ea_name += 5; /* skip past user. prefix */
83 rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,NULL, 85 rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, NULL,
84 (__u16)0, cifs_sb->local_nls, 86 (__u16)0, cifs_sb->local_nls,
85 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 87 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
86 } 88 }
@@ -91,23 +93,23 @@ remove_ea_exit:
91 return rc; 93 return rc;
92} 94}
93 95
94int cifs_setxattr(struct dentry * direntry, const char * ea_name, 96int cifs_setxattr(struct dentry *direntry, const char *ea_name,
95 const void * ea_value, size_t value_size, int flags) 97 const void *ea_value, size_t value_size, int flags)
96{ 98{
97 int rc = -EOPNOTSUPP; 99 int rc = -EOPNOTSUPP;
98#ifdef CONFIG_CIFS_XATTR 100#ifdef CONFIG_CIFS_XATTR
99 int xid; 101 int xid;
100 struct cifs_sb_info *cifs_sb; 102 struct cifs_sb_info *cifs_sb;
101 struct cifsTconInfo *pTcon; 103 struct cifsTconInfo *pTcon;
102 struct super_block * sb; 104 struct super_block *sb;
103 char * full_path; 105 char *full_path;
104 106
105 if(direntry == NULL) 107 if (direntry == NULL)
106 return -EIO; 108 return -EIO;
107 if(direntry->d_inode == NULL) 109 if (direntry->d_inode == NULL)
108 return -EIO; 110 return -EIO;
109 sb = direntry->d_inode->i_sb; 111 sb = direntry->d_inode->i_sb;
110 if(sb == NULL) 112 if (sb == NULL)
111 return -EIO; 113 return -EIO;
112 xid = GetXid(); 114 xid = GetXid();
113 115
@@ -115,7 +117,7 @@ int cifs_setxattr(struct dentry * direntry, const char * ea_name,
115 pTcon = cifs_sb->tcon; 117 pTcon = cifs_sb->tcon;
116 118
117 full_path = build_path_from_dentry(direntry); 119 full_path = build_path_from_dentry(direntry);
118 if(full_path == NULL) { 120 if (full_path == NULL) {
119 FreeXid(xid); 121 FreeXid(xid);
120 return -ENOMEM; 122 return -ENOMEM;
121 } 123 }
@@ -123,67 +125,69 @@ int cifs_setxattr(struct dentry * direntry, const char * ea_name,
123 /* return alt name if available as pseudo attr */ 125 /* return alt name if available as pseudo attr */
124 126
125 /* if proc/fs/cifs/streamstoxattr is set then 127 /* if proc/fs/cifs/streamstoxattr is set then
126 search server for EAs or streams to 128 search server for EAs or streams to
127 returns as xattrs */ 129 returns as xattrs */
128 if(value_size > MAX_EA_VALUE_SIZE) { 130 if (value_size > MAX_EA_VALUE_SIZE) {
129 cFYI(1,("size of EA value too large")); 131 cFYI(1, ("size of EA value too large"));
130 kfree(full_path); 132 kfree(full_path);
131 FreeXid(xid); 133 FreeXid(xid);
132 return -EOPNOTSUPP; 134 return -EOPNOTSUPP;
133 } 135 }
134 136
135 if(ea_name == NULL) { 137 if (ea_name == NULL) {
136 cFYI(1,("Null xattr names not supported")); 138 cFYI(1, ("Null xattr names not supported"));
137 } else if(strncmp(ea_name,CIFS_XATTR_USER_PREFIX,5) == 0) { 139 } else if (strncmp(ea_name, CIFS_XATTR_USER_PREFIX, 5) == 0) {
138 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) 140 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
139 goto set_ea_exit; 141 goto set_ea_exit;
140 if(strncmp(ea_name,CIFS_XATTR_DOS_ATTRIB,14) == 0) { 142 if (strncmp(ea_name, CIFS_XATTR_DOS_ATTRIB, 14) == 0) {
141 cFYI(1,("attempt to set cifs inode metadata")); 143 cFYI(1, ("attempt to set cifs inode metadata"));
142 } 144 }
143 ea_name += 5; /* skip past user. prefix */ 145 ea_name += 5; /* skip past user. prefix */
144 rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,ea_value, 146 rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, ea_value,
145 (__u16)value_size, cifs_sb->local_nls, 147 (__u16)value_size, cifs_sb->local_nls,
146 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 148 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
147 } else if(strncmp(ea_name, CIFS_XATTR_OS2_PREFIX,4) == 0) { 149 } else if (strncmp(ea_name, CIFS_XATTR_OS2_PREFIX, 4) == 0) {
148 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) 150 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
149 goto set_ea_exit; 151 goto set_ea_exit;
150 152
151 ea_name += 4; /* skip past os2. prefix */ 153 ea_name += 4; /* skip past os2. prefix */
152 rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,ea_value, 154 rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, ea_value,
153 (__u16)value_size, cifs_sb->local_nls, 155 (__u16)value_size, cifs_sb->local_nls,
154 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 156 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
155 } else { 157 } else {
156 int temp; 158 int temp;
157 temp = strncmp(ea_name,POSIX_ACL_XATTR_ACCESS, 159 temp = strncmp(ea_name, POSIX_ACL_XATTR_ACCESS,
158 strlen(POSIX_ACL_XATTR_ACCESS)); 160 strlen(POSIX_ACL_XATTR_ACCESS));
159 if (temp == 0) { 161 if (temp == 0) {
160#ifdef CONFIG_CIFS_POSIX 162#ifdef CONFIG_CIFS_POSIX
161 if(sb->s_flags & MS_POSIXACL) 163 if (sb->s_flags & MS_POSIXACL)
162 rc = CIFSSMBSetPosixACL(xid, pTcon,full_path, 164 rc = CIFSSMBSetPosixACL(xid, pTcon, full_path,
163 ea_value, (const int)value_size, 165 ea_value, (const int)value_size,
164 ACL_TYPE_ACCESS,cifs_sb->local_nls, 166 ACL_TYPE_ACCESS, cifs_sb->local_nls,
165 cifs_sb->mnt_cifs_flags & 167 cifs_sb->mnt_cifs_flags &
166 CIFS_MOUNT_MAP_SPECIAL_CHR); 168 CIFS_MOUNT_MAP_SPECIAL_CHR);
167 cFYI(1,("set POSIX ACL rc %d",rc)); 169 cFYI(1, ("set POSIX ACL rc %d", rc));
168#else 170#else
169 cFYI(1,("set POSIX ACL not supported")); 171 cFYI(1, ("set POSIX ACL not supported"));
170#endif 172#endif
171 } else if(strncmp(ea_name,POSIX_ACL_XATTR_DEFAULT,strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) { 173 } else if (strncmp(ea_name, POSIX_ACL_XATTR_DEFAULT,
174 strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) {
172#ifdef CONFIG_CIFS_POSIX 175#ifdef CONFIG_CIFS_POSIX
173 if(sb->s_flags & MS_POSIXACL) 176 if (sb->s_flags & MS_POSIXACL)
174 rc = CIFSSMBSetPosixACL(xid, pTcon,full_path, 177 rc = CIFSSMBSetPosixACL(xid, pTcon, full_path,
175 ea_value, (const int)value_size, 178 ea_value, (const int)value_size,
176 ACL_TYPE_DEFAULT, cifs_sb->local_nls, 179 ACL_TYPE_DEFAULT, cifs_sb->local_nls,
177 cifs_sb->mnt_cifs_flags & 180 cifs_sb->mnt_cifs_flags &
178 CIFS_MOUNT_MAP_SPECIAL_CHR); 181 CIFS_MOUNT_MAP_SPECIAL_CHR);
179 cFYI(1,("set POSIX default ACL rc %d",rc)); 182 cFYI(1, ("set POSIX default ACL rc %d", rc));
180#else 183#else
181 cFYI(1,("set default POSIX ACL not supported")); 184 cFYI(1, ("set default POSIX ACL not supported"));
182#endif 185#endif
183 } else { 186 } else {
184 cFYI(1,("illegal xattr request %s (only user namespace supported)",ea_name)); 187 cFYI(1, ("illegal xattr request %s (only user namespace"
188 " supported)", ea_name));
185 /* BB what if no namespace prefix? */ 189 /* BB what if no namespace prefix? */
186 /* Should we just pass them to server, except for 190 /* Should we just pass them to server, except for
187 system and perhaps security prefixes? */ 191 system and perhaps security prefixes? */
188 } 192 }
189 } 193 }
@@ -195,23 +199,23 @@ set_ea_exit:
195 return rc; 199 return rc;
196} 200}
197 201
198ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name, 202ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
199 void * ea_value, size_t buf_size) 203 void *ea_value, size_t buf_size)
200{ 204{
201 ssize_t rc = -EOPNOTSUPP; 205 ssize_t rc = -EOPNOTSUPP;
202#ifdef CONFIG_CIFS_XATTR 206#ifdef CONFIG_CIFS_XATTR
203 int xid; 207 int xid;
204 struct cifs_sb_info *cifs_sb; 208 struct cifs_sb_info *cifs_sb;
205 struct cifsTconInfo *pTcon; 209 struct cifsTconInfo *pTcon;
206 struct super_block * sb; 210 struct super_block *sb;
207 char * full_path; 211 char *full_path;
208 212
209 if(direntry == NULL) 213 if (direntry == NULL)
210 return -EIO; 214 return -EIO;
211 if(direntry->d_inode == NULL) 215 if (direntry->d_inode == NULL)
212 return -EIO; 216 return -EIO;
213 sb = direntry->d_inode->i_sb; 217 sb = direntry->d_inode->i_sb;
214 if(sb == NULL) 218 if (sb == NULL)
215 return -EIO; 219 return -EIO;
216 220
217 xid = GetXid(); 221 xid = GetXid();
@@ -220,42 +224,42 @@ ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name,
220 pTcon = cifs_sb->tcon; 224 pTcon = cifs_sb->tcon;
221 225
222 full_path = build_path_from_dentry(direntry); 226 full_path = build_path_from_dentry(direntry);
223 if(full_path == NULL) { 227 if (full_path == NULL) {
224 FreeXid(xid); 228 FreeXid(xid);
225 return -ENOMEM; 229 return -ENOMEM;
226 } 230 }
227 /* return dos attributes as pseudo xattr */ 231 /* return dos attributes as pseudo xattr */
228 /* return alt name if available as pseudo attr */ 232 /* return alt name if available as pseudo attr */
229 if(ea_name == NULL) { 233 if (ea_name == NULL) {
230 cFYI(1,("Null xattr names not supported")); 234 cFYI(1, ("Null xattr names not supported"));
231 } else if(strncmp(ea_name,CIFS_XATTR_USER_PREFIX,5) == 0) { 235 } else if (strncmp(ea_name, CIFS_XATTR_USER_PREFIX, 5) == 0) {
232 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) 236 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
233 goto get_ea_exit; 237 goto get_ea_exit;
234 238
235 if(strncmp(ea_name,CIFS_XATTR_DOS_ATTRIB,14) == 0) { 239 if (strncmp(ea_name, CIFS_XATTR_DOS_ATTRIB, 14) == 0) {
236 cFYI(1,("attempt to query cifs inode metadata")); 240 cFYI(1, ("attempt to query cifs inode metadata"));
237 /* revalidate/getattr then populate from inode */ 241 /* revalidate/getattr then populate from inode */
238 } /* BB add else when above is implemented */ 242 } /* BB add else when above is implemented */
239 ea_name += 5; /* skip past user. prefix */ 243 ea_name += 5; /* skip past user. prefix */
240 rc = CIFSSMBQueryEA(xid,pTcon,full_path,ea_name,ea_value, 244 rc = CIFSSMBQueryEA(xid, pTcon, full_path, ea_name, ea_value,
241 buf_size, cifs_sb->local_nls, 245 buf_size, cifs_sb->local_nls,
242 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 246 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
243 } else if(strncmp(ea_name, CIFS_XATTR_OS2_PREFIX,4) == 0) { 247 } else if (strncmp(ea_name, CIFS_XATTR_OS2_PREFIX, 4) == 0) {
244 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) 248 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
245 goto get_ea_exit; 249 goto get_ea_exit;
246 250
247 ea_name += 4; /* skip past os2. prefix */ 251 ea_name += 4; /* skip past os2. prefix */
248 rc = CIFSSMBQueryEA(xid,pTcon,full_path,ea_name,ea_value, 252 rc = CIFSSMBQueryEA(xid, pTcon, full_path, ea_name, ea_value,
249 buf_size, cifs_sb->local_nls, 253 buf_size, cifs_sb->local_nls,
250 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 254 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
251 } else if(strncmp(ea_name,POSIX_ACL_XATTR_ACCESS, 255 } else if (strncmp(ea_name, POSIX_ACL_XATTR_ACCESS,
252 strlen(POSIX_ACL_XATTR_ACCESS)) == 0) { 256 strlen(POSIX_ACL_XATTR_ACCESS)) == 0) {
253#ifdef CONFIG_CIFS_POSIX 257#ifdef CONFIG_CIFS_POSIX
254 if(sb->s_flags & MS_POSIXACL) 258 if (sb->s_flags & MS_POSIXACL)
255 rc = CIFSSMBGetPosixACL(xid, pTcon, full_path, 259 rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,
256 ea_value, buf_size, ACL_TYPE_ACCESS, 260 ea_value, buf_size, ACL_TYPE_ACCESS,
257 cifs_sb->local_nls, 261 cifs_sb->local_nls,
258 cifs_sb->mnt_cifs_flags & 262 cifs_sb->mnt_cifs_flags &
259 CIFS_MOUNT_MAP_SPECIAL_CHR); 263 CIFS_MOUNT_MAP_SPECIAL_CHR);
260/* else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { 264/* else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
261 __u16 fid; 265 __u16 fid;
@@ -272,39 +276,40 @@ ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name,
272 CIFSSMBClose(xid, pTcon, fid); 276 CIFSSMBClose(xid, pTcon, fid);
273 } 277 }
274 } */ /* BB enable after fixing up return data */ 278 } */ /* BB enable after fixing up return data */
275 279#else
276#else 280 cFYI(1, ("query POSIX ACL not supported yet"));
277 cFYI(1,("query POSIX ACL not supported yet"));
278#endif /* CONFIG_CIFS_POSIX */ 281#endif /* CONFIG_CIFS_POSIX */
279 } else if(strncmp(ea_name,POSIX_ACL_XATTR_DEFAULT, 282 } else if (strncmp(ea_name, POSIX_ACL_XATTR_DEFAULT,
280 strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) { 283 strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) {
281#ifdef CONFIG_CIFS_POSIX 284#ifdef CONFIG_CIFS_POSIX
282 if(sb->s_flags & MS_POSIXACL) 285 if (sb->s_flags & MS_POSIXACL)
283 rc = CIFSSMBGetPosixACL(xid, pTcon, full_path, 286 rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,
284 ea_value, buf_size, ACL_TYPE_DEFAULT, 287 ea_value, buf_size, ACL_TYPE_DEFAULT,
285 cifs_sb->local_nls, 288 cifs_sb->local_nls,
286 cifs_sb->mnt_cifs_flags & 289 cifs_sb->mnt_cifs_flags &
287 CIFS_MOUNT_MAP_SPECIAL_CHR); 290 CIFS_MOUNT_MAP_SPECIAL_CHR);
288#else 291#else
289 cFYI(1,("query POSIX default ACL not supported yet")); 292 cFYI(1, ("query POSIX default ACL not supported yet"));
290#endif 293#endif
291 } else if(strncmp(ea_name, 294 } else if (strncmp(ea_name,
292 CIFS_XATTR_TRUSTED_PREFIX,XATTR_TRUSTED_PREFIX_LEN) == 0) { 295 CIFS_XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0) {
293 cFYI(1,("Trusted xattr namespace not supported yet")); 296 cFYI(1, ("Trusted xattr namespace not supported yet"));
294 } else if(strncmp(ea_name, 297 } else if (strncmp(ea_name,
295 CIFS_XATTR_SECURITY_PREFIX,XATTR_SECURITY_PREFIX_LEN) == 0) { 298 CIFS_XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) == 0) {
296 cFYI(1,("Security xattr namespace not supported yet")); 299 cFYI(1, ("Security xattr namespace not supported yet"));
297 } else { 300 } else {
298 cFYI(1,("illegal xattr name request %s (only user namespace supported)",ea_name)); 301 cFYI(1,
302 ("illegal xattr request %s (only user namespace supported)",
303 ea_name));
299 } 304 }
300 305
301 /* We could add an additional check for streams ie 306 /* We could add an additional check for streams ie
302 if proc/fs/cifs/streamstoxattr is set then 307 if proc/fs/cifs/streamstoxattr is set then
303 search server for EAs or streams to 308 search server for EAs or streams to
304 returns as xattrs */ 309 returns as xattrs */
305 310
306 if(rc == -EINVAL) 311 if (rc == -EINVAL)
307 rc = -EOPNOTSUPP; 312 rc = -EOPNOTSUPP;
308 313
309get_ea_exit: 314get_ea_exit:
310 kfree(full_path); 315 kfree(full_path);
@@ -313,34 +318,34 @@ get_ea_exit:
313 return rc; 318 return rc;
314} 319}
315 320
316ssize_t cifs_listxattr(struct dentry * direntry, char * data, size_t buf_size) 321ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size)
317{ 322{
318 ssize_t rc = -EOPNOTSUPP; 323 ssize_t rc = -EOPNOTSUPP;
319#ifdef CONFIG_CIFS_XATTR 324#ifdef CONFIG_CIFS_XATTR
320 int xid; 325 int xid;
321 struct cifs_sb_info *cifs_sb; 326 struct cifs_sb_info *cifs_sb;
322 struct cifsTconInfo *pTcon; 327 struct cifsTconInfo *pTcon;
323 struct super_block * sb; 328 struct super_block *sb;
324 char * full_path; 329 char *full_path;
325 330
326 if(direntry == NULL) 331 if (direntry == NULL)
327 return -EIO; 332 return -EIO;
328 if(direntry->d_inode == NULL) 333 if (direntry->d_inode == NULL)
329 return -EIO; 334 return -EIO;
330 sb = direntry->d_inode->i_sb; 335 sb = direntry->d_inode->i_sb;
331 if(sb == NULL) 336 if (sb == NULL)
332 return -EIO; 337 return -EIO;
333 338
334 cifs_sb = CIFS_SB(sb); 339 cifs_sb = CIFS_SB(sb);
335 pTcon = cifs_sb->tcon; 340 pTcon = cifs_sb->tcon;
336 341
337 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) 342 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
338 return -EOPNOTSUPP; 343 return -EOPNOTSUPP;
339 344
340 xid = GetXid(); 345 xid = GetXid();
341 346
342 full_path = build_path_from_dentry(direntry); 347 full_path = build_path_from_dentry(direntry);
343 if(full_path == NULL) { 348 if (full_path == NULL) {
344 FreeXid(xid); 349 FreeXid(xid);
345 return -ENOMEM; 350 return -ENOMEM;
346 } 351 }
@@ -348,11 +353,11 @@ ssize_t cifs_listxattr(struct dentry * direntry, char * data, size_t buf_size)
348 /* return alt name if available as pseudo attr */ 353 /* return alt name if available as pseudo attr */
349 354
350 /* if proc/fs/cifs/streamstoxattr is set then 355 /* if proc/fs/cifs/streamstoxattr is set then
351 search server for EAs or streams to 356 search server for EAs or streams to
352 returns as xattrs */ 357 returns as xattrs */
353 rc = CIFSSMBQAllEAs(xid,pTcon,full_path,data,buf_size, 358 rc = CIFSSMBQAllEAs(xid, pTcon, full_path, data, buf_size,
354 cifs_sb->local_nls, 359 cifs_sb->local_nls,
355 cifs_sb->mnt_cifs_flags & 360 cifs_sb->mnt_cifs_flags &
356 CIFS_MOUNT_MAP_SPECIAL_CHR); 361 CIFS_MOUNT_MAP_SPECIAL_CHR);
357 362
358 kfree(full_path); 363 kfree(full_path);